Skip to content

Commit

Permalink
[driver] Driver for AB (incremental) encoder output
Browse files Browse the repository at this point in the history
  • Loading branch information
rleh committed Jun 14, 2020
1 parent 7d1f7cc commit 7755151
Show file tree
Hide file tree
Showing 4 changed files with 220 additions and 7 deletions.
16 changes: 9 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,56 +190,58 @@ can easily configure them for you specific needs.
<td align="center">DS1631</td>
<td align="center">DS18B20</td>
<td align="center">EA-DOG</td>
<td align="center">ENCODER-OUTPUT</td>
<td align="center">FT245</td>
<td align="center">FT6X06</td>
</tr><tr>
<td align="center">FT6X06</td>
<td align="center">HCLAx</td>
<td align="center">HD44780</td>
<td align="center">HMC58x</td>
<td align="center">HMC6343</td>
<td align="center">HX711</td>
<td align="center">I2C-EEPROM</td>
</tr><tr>
<td align="center">I2C-EEPROM</td>
<td align="center">ITG3200</td>
<td align="center">L3GD20</td>
<td align="center">LAWICEL</td>
<td align="center">LIS302DL</td>
<td align="center">LIS3DSH</td>
<td align="center">LM75</td>
</tr><tr>
<td align="center">LM75</td>
<td align="center">LP503X</td>
<td align="center">LSM303A</td>
<td align="center">LTC2984</td>
<td align="center">MAX6966</td>
<td align="center">MAX7219</td>
<td align="center">MCP23X17</td>
</tr><tr>
<td align="center">MCP23X17</td>
<td align="center">MCP2515</td>
<td align="center">NOKIA5110</td>
<td align="center">NRF24</td>
<td align="center">TFT-DISPLAY</td>
<td align="center">PAT9125EL</td>
<td align="center">PCA8574</td>
</tr><tr>
<td align="center">PCA8574</td>
<td align="center">PCA9535</td>
<td align="center">PCA9548A</td>
<td align="center">PCA9685</td>
<td align="center">SIEMENS-S65</td>
<td align="center">SIEMENS-S75</td>
<td align="center">SK6812</td>
</tr><tr>
<td align="center">SK6812</td>
<td align="center">SK9822</td>
<td align="center">SSD1306</td>
<td align="center">SX1276</td>
<td align="center">TCS3414</td>
<td align="center">TCS3472</td>
<td align="center">TLC594X</td>
</tr><tr>
<td align="center">TLC594X</td>
<td align="center">TMP102</td>
<td align="center">TMP175</td>
<td align="center">VL53L0</td>
<td align="center">VL6180</td>
<td align="center">WS2812</td>
</tr><tr>
</tr>
</table>
<!--/drivertable-->
Expand Down
86 changes: 86 additions & 0 deletions src/modm/driver/encoder/encoder_output.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// coding: utf-8
/*
* Copyright (c) 2019, Raphael Lehmann
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// ----------------------------------------------------------------------------

#ifndef MODM_ENCODER_OUTPUT_HPP
#define MODM_ENCODER_OUTPUT_HPP

#include <modm/processing/timer/periodic_timer.hpp>

namespace modm
{

/**
* @ingroup modm_driver_encoder_output
* @author Raphael Lehmann
*
* @brief This driver generates a AB (incremental) encoder signal to
* emulate a hardware encoder with a microcontroller.
*
* @tparam PinA First modm::platform::Gpio pin to output the encoder signal.
* @tparam PinB Second modm::platform::Gpio pin to output the encoder signal.
* @tparam PositionType Data type (integer) of the position value, default `int32_t`.
* @tparam PeriodicTimer Defaults to `modm::PeriodicTimer`, must be replaced for
* encoder frequencies above 1kHz by a class that offers
* time steps less than 1ms, e.g. `modm::PrecisePeriodicTimer`.
* @tparam period Timebase for the output signal. This limits the maximal
* frequency of the encoder signal. Defaults to `1`.
*/
template <
class PinA,
class PinB,
typename PositionType = int32_t,
class PeriodicTimer = modm::PeriodicTimer,
uint32_t period = 1
>
class EncoderOutput {
public:
/**
* @brief Initializes the Encoder.
*
* Sets pins (PinA and PinB) as output pins.
*
* @param initialValue for the encoder. Useful with unsigned PositionType
* data types. Defaults to 0.
*/
EncoderOutput(PositionType initialValue);

/**
* @brief Update method. Generates the encoder signal.
*
* Call this function in your main loop.
*/
void update();

/**
* @brief Set the position for the encoder.
* @param position The position setpoint for the encoder.
*/
void setPosition(PositionType position) { setpoint = position; };

private:
PositionType setpoint;
PositionType actualValue;
PeriodicTimer timer;
enum class State : uint8_t {
State0,
State1,
State2,
State3,
};
State state;
};

}

#include "encoder_output_impl.hpp"

#endif
33 changes: 33 additions & 0 deletions src/modm/driver/encoder/encoder_output.lb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2019, Raphael Lehmann
#
# This file is part of the modm project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# -----------------------------------------------------------------------------


def init(module):
module.parent = "driver"
module.name = "encoder.output"
module.description = """\
# Encoder Output
This driver generates a AB (incremental) encoder signal to
emulate a hardware encoder with a microcontroller.
"""

def prepare(module, options):
module.depends(
":architecture:gpio",
":processing:timer")
return True

def build(env):
env.outbasepath = "modm/src/modm/driver/encoder"
env.copy("encoder_output.hpp")
env.copy("encoder_output_impl.hpp")
92 changes: 92 additions & 0 deletions src/modm/driver/encoder/encoder_output_impl.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// coding: utf-8
/*
* Copyright (c) 2019, Raphael Lehmann
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// ----------------------------------------------------------------------------

#ifndef MODM_ENCODER_OUTPUT_HPP
# error "Don't include this file directly, use 'encoder_output.hpp' instead!"
#endif
#include "encoder_output.hpp"

template <
class PinA,
class PinB,
typename PositionType,
class PeriodicTimer,
uint32_t period
>
modm::EncoderOutput<PinA, PinB, PositionType, PeriodicTimer, period>::EncoderOutput(PositionType initialValue) :
setpoint(initialValue), actualValue(initialValue), timer(period), state(State::State0)
{
PinA::setOutput();
PinB::setOutput();
PinA::set();
PinB::set();
setpoint = initialValue;
actualValue = initialValue;
}

template <
class PinA,
class PinB,
typename PositionType,
class PeriodicTimer,
uint32_t period
>
void
modm::EncoderOutput<PinA, PinB, PositionType, PeriodicTimer, period>::update()
{
if(timer.execute()){
if(setpoint > actualValue) {
// generate forward tick
switch(state) {
case State::State0:
PinA::reset();
state = State::State1;
break;
case State::State1:
PinB::reset();
state = State::State2;
break;
case State::State2:
PinA::set();
state = State::State3;
break;
case State::State3:
PinB::set();
state = State::State0;
break;
}
actualValue++;
}
else if(setpoint < actualValue) {
// generate backward tick
switch(state) {
case State::State0:
PinB::reset();
state = State::State3;
break;
case State::State1:
PinA::reset();
state = State::State0;
break;
case State::State2:
PinB::set();
state = State::State1;
break;
case State::State3:
PinA::set();
state = State::State2;
break;
}
actualValue--;
}
}
}

0 comments on commit 7755151

Please sign in to comment.