Skip to content

[driver] gray-code decoder for STM32 Timer #775

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Nov 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -607,72 +607,73 @@ you specific needs.
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ds1631">DS1631</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ds18b20">DS18B20</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ea_dog">EA-DOG</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-encoder_input">ENCODER-INPUT</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-encoder_input-bitbang">ENCODER-INPUT-BITBANG</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-encoder_output-bitbang">ENCODER-OUTPUT-BITBANG</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-encoder_output-bitbang">ENCODER-OUTPUT-BITBANG</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ft245">FT245</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ft6x06">FT6X06</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-gpio_sampler">GPIO-SAMPLER</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-hclax">HCLAx</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-hd44780">HD44780</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-hmc58x">HMC58x</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-hmc58x">HMC58x</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-hmc6343">HMC6343</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-hx711">HX711</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-i2c-eeprom">I2C-EEPROM</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ili9341">ILI9341</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-is31fl3733">IS31FL3733</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-itg3200">ITG3200</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-itg3200">ITG3200</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-l3gd20">L3GD20</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-lan8720a">LAN8720A</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-lawicel">LAWICEL</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-lis302dl">LIS302DL</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-lis3dsh">LIS3DSH</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-lis3mdl">LIS3MDL</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-lis3mdl">LIS3MDL</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-lm75">LM75</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-lp503x">LP503X</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-lsm303a">LSM303A</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-lsm6ds33">LSM6DS33</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ltc2984">LTC2984</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-max6966">MAX6966</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-max6966">MAX6966</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-max7219">MAX7219</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-mcp23x17">MCP23X17</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-mcp2515">MCP2515</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-mmc5603">MMC5603</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-nokia5110">NOKIA5110</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-nrf24">NRF24</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-nrf24">NRF24</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-parallel_tft_display">TFT-DISPLAY</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-pat9125el">PAT9125EL</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-pca8574">PCA8574</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-pca9535">PCA9535</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-pca9548a">PCA9548A</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-pca9685">PCA9685</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-pca9685">PCA9685</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-sh1106">SH1106</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-siemens_s65">SIEMENS-S65</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-siemens_s75">SIEMENS-S75</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-sk6812">SK6812</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-sk9822">SK9822</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ssd1306">SSD1306</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ssd1306">SSD1306</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-st7586s">ST7586S</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-stts22h">STTS22H</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-stusb4500">STUSB4500</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-sx1276">SX1276</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-tcs3414">TCS3414</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-tcs3472">TCS3472</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-tcs3472">TCS3472</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-tlc594x">TLC594X</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-tmp102">TMP102</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-tmp12x">TMP12X</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-tmp175">TMP175</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-touch2046">TOUCH2046</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-vl53l0">VL53L0</a></td>
</tr><tr>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-vl53l0">VL53L0</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-vl6180">VL6180</a></td>
<td align="center"><a href="https://modm.io/reference/module/modm-driver-ws2812">WS2812</a></td>
</tr>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,14 @@
// ----------------------------------------------------------------------------

#include <modm/board.hpp>
#include <modm/driver/encoder/bitbang_encoder_input.hpp>
#include <modm/math/algorithm/prescaler.hpp>
#include <modm/processing/timer.hpp>
#include <modm/math/algorithm/prescaler.hpp>
#include <modm/driver/encoder/bitbang_encoder_input.hpp>

using namespace modm::platform;

// Connect the encoders outputs to D7 and D8 Pins (usually the outer pins)
// The common third pin (usually in the middle) is connected to GND.
// Don't add any resistors or filters. It's all in the MCU and the driver.
modm::BitBangEncoderInput<Board::D11, Board::D12, 4> encoder;

MODM_ISR(TIMER2_COMPA)
Expand Down Expand Up @@ -48,22 +47,19 @@ main()
Board::initialize();
LedD13::setOutput();

encoder.connect();

encoder.initialize();
init_Timer2();
enableInterrupts();

int value(0);

modm::ShortPeriodicTimer heartbeat(500ms);
modm::ShortPeriodicTimer outputValue(1000ms);

while (true)
{
if (heartbeat.execute()) Board::LedD13::toggle();
if (outputValue.execute())
{
value += encoder.getIncrement();
if (heartbeat.execute()) {
Board::LedD13::toggle();
value += encoder.getDelta();
MODM_LOG_INFO << "value: " << value << modm::endl;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<library>
<extends>modm:arduino-nano</extends>
<options>
<option name="modm:build:build.path">../../../build/arduino_nano/encoder_input</option>
<option name="modm:build:build.path">../../../build/arduino_nano/encoder_input_bitbang</option>
</options>
<modules>
<module>modm:build:scons</module>
Expand Down
74 changes: 74 additions & 0 deletions examples/blue_pill_f103/encoder_input/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright (c) 2021, Thomas Sommer
*
* 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/.
*/
// ----------------------------------------------------------------------------

#include <modm/board.hpp>
#include <modm/debug/logger.hpp>
#include <modm/processing/timer.hpp>
#include <modm/driver/encoder/encoder_input.hpp>

// ----------------------------------------------------------------------------
// Set the log level
#undef MODM_LOG_LEVEL
#define MODM_LOG_LEVEL modm::log::INFO

// Create an IODeviceWrapper around the Uart Peripheral we want to use
modm::IODeviceWrapper< Usart2, modm::IOBuffer::BlockIfFull > loggerDevice;

// Set all four logger streams to use the UART
modm::log::Logger modm::log::debug(loggerDevice);
modm::log::Logger modm::log::info(loggerDevice);
modm::log::Logger modm::log::warning(loggerDevice);
modm::log::Logger modm::log::error(loggerDevice);

int
main()
{
Board::initialize();

Usart2::connect<GpioOutputA2::Tx>();
Usart2::initialize<Board::SystemClock, 115200_Bd>();

// Each Timer can drive one Encoder
// For Timer2 and Timer3 you have 2 Gpio options
// When using one of PB3 or PB4 you also have to disable JTAG debugging during shared pins

// Timer1:
modm::EncoderInput<Timer1, GpioInputA8, GpioInputA9> encoder;

// Timer2:
// modm::EncoderInput<Timer2, GpioInputA0, GpioInputA1> encoder;
// modm::EncoderInput<Timer2, GpioInputA15, GpioInputB3> encoder;
// AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_JTAGDISABLE;

// Timer3:
// modm::EncoderInput<Timer3, GpioInputA6, GpioInputA7> encoder;
// modm::EncoderInput<Timer3, GpioInputB4, GpioInputB5> encoder;
// Disable JTAG to make PB3, PB4 available as Gpio
// AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_JTAGDISABLE;

// Timer4:
// modm::EncoderInput<Timer4, GpioInputB6, GpioInputB7> encoder;

encoder.initialize(true);

modm::ShortPeriodicTimer heartbeat(500ms);

while (true)
{
if(heartbeat.execute()) {
Board::LedGreen::toggle();
MODM_LOG_INFO << "Encoder Delta: " << encoder.getDelta() << modm::endl;
MODM_LOG_INFO << "Encoder Absolut: " << encoder.getValue() << modm::endl;
}
}

return 0;
}
2 changes: 2 additions & 0 deletions examples/blue_pill_f103/encoder_input/openocd.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Replace this with your custom programmer
source [find interface/stlink-v2.cfg]
18 changes: 18 additions & 0 deletions examples/blue_pill_f103/encoder_input/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<library>
<extends>modm:blue-pill-f103</extends>
<options>
<option name="modm:build:build.path">../../../build/blue_pill_f103/encoder_input</option>
<option name="modm:build:openocd.cfg">openocd.cfg</option>
</options>
<modules>
<module>modm:debug</module>
<module>modm:platform:uart:2</module>
<module>modm:processing:timer</module>
<module>modm:driver:encoder_input</module>
<module>modm:platform:timer:1</module>
<module>modm:platform:timer:2</module>
<module>modm:platform:timer:3</module>
<module>modm:platform:timer:4</module>
<module>modm:build:scons</module>
</modules>
</library>
82 changes: 82 additions & 0 deletions examples/blue_pill_f103/encoder_input_bitbang/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright (c) 2021, Thomas Sommer
*
* 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/.
*/
// ----------------------------------------------------------------------------

#include <modm/board.hpp>
#include <modm/debug/logger.hpp>
#include <modm/processing/timer.hpp>
#include <modm/driver/encoder/bitbang_encoder_input.hpp>

// ----------------------------------------------------------------------------
// Set the log level
#undef MODM_LOG_LEVEL
#define MODM_LOG_LEVEL modm::log::INFO

// Create an IODeviceWrapper around the Uart Peripheral we want to use
modm::IODeviceWrapper< Usart2, modm::IOBuffer::BlockIfFull > loggerDevice;

// Set all four logger streams to use the UART
modm::log::Logger modm::log::debug(loggerDevice);
modm::log::Logger modm::log::info(loggerDevice);
modm::log::Logger modm::log::warning(loggerDevice);
modm::log::Logger modm::log::error(loggerDevice);

// Connect the encoders outputs to D7 and D8 Pins (usually the outer pins)
// The common third pin (usually in the middle) is connected to GND.
modm::BitBangEncoderInput<GpioInputB6, GpioInputB7, 4, int16_t> encoder;

MODM_ISR(TIM2)
{
Timer2::acknowledgeInterruptFlags(Timer2::InterruptFlag::Update);
encoder.update();
}

void
init_Timer2(const uint16_t period)
{
Timer2::enable();
Timer2::setMode(Timer2::Mode::UpCounter);

Timer2::template setPeriod<Board::SystemClock>(period);
Timer2::enableInterruptVector(true, 10);
Timer2::enableInterrupt(Timer2::Interrupt::Update);

Timer2::applyAndReset();
Timer2::start();
}

int
main()
{
Board::initialize();

Usart2::connect<GpioOutputA2::Tx>();
Usart2::initialize<Board::SystemClock, 115200_Bd>();

encoder.initialize();
init_Timer2(1000); // 1ms period

int value(0);

modm::ShortPeriodicTimer heartbeat(1s);

while (true)
{
if (heartbeat.execute()) {
Board::LedGreen::toggle();

const auto delta = encoder.getDelta();
MODM_LOG_INFO << "Delta: " << delta << modm::endl;

value += delta;
MODM_LOG_INFO << "Encoder Absolut: " << value << modm::endl;
}
}
}
2 changes: 2 additions & 0 deletions examples/blue_pill_f103/encoder_input_bitbang/openocd.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Replace this with your custom programmer
source [find interface/stlink-v2.cfg]
15 changes: 15 additions & 0 deletions examples/blue_pill_f103/encoder_input_bitbang/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<library>
<extends>modm:blue-pill-f103</extends>
<options>
<option name="modm:build:build.path">../../../build/blue_pill_f103/encoder_input_bitbang</option>
<option name="modm:build:openocd.cfg">openocd.cfg</option>
</options>
<modules>
<module>modm:debug</module>
<module>modm:platform:uart:2</module>
<module>modm:processing:timer</module>
<module>modm:driver:encoder_input.bitbang</module>
<module>modm:platform:timer:2</module>
<module>modm:build:scons</module>
</modules>
</library>
23 changes: 12 additions & 11 deletions src/modm/driver/encoder/bitbang_encoder_input.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,19 @@ namespace modm
*
* @tparam SignalA First modm::platform::Gpio pin to input the encoder signal.
* @tparam SignalB Second modm::platform::Gpio pin to input the encoder signal.
* @tparam POSTSCALER n_cycles to count as one in-/decrement.
* @tparam DeltaType Must be signed integer and fit at least POSTSCALER. The Bigger
* @tparam PRESCALER n_cycles to count as one in-/decrement.
* @tparam DeltaType Must be signed integral and fit at least PRESCALER. The Bigger
* DeltaType, the more inc-/decrements can be stored temporarily.
* @tparam ValueType Must be unsigned integral.
*/
template<typename SignalA, typename SignalB, uint8_t POSTSCALER = 4,
template<typename SignalA, typename SignalB, uint8_t PRESCALER = 4,
std::signed_integral DeltaType = int8_t>
class BitBangEncoderInput
{
static_assert(std::popcount(POSTSCALER) == 1,
"POSTSCALER must be an integer to basis 2 and not 0: 1, 2, 4, 8, 16, ...");
static_assert(POSTSCALER <= std::numeric_limits<DeltaType>::max(),
"DeltaType is to small for POSTSCALER.");
static_assert(std::popcount(PRESCALER) == 1,
"PRESCALER must be an integer to basis 2 and not 0: 1, 2, 4, 8, 16, ...");
static_assert(PRESCALER <= std::numeric_limits<DeltaType>::max(),
"DeltaType is to small for PRESCALER.");

using Signals = modm::platform::SoftwareGpioPort<SignalA, SignalB>;

Expand All @@ -47,19 +48,19 @@ class BitBangEncoderInput
uint8_t inline getRaw();

public:
using ValueType = DeltaType;
BitBangEncoderInput() : raw_last(0), delta(0){};

using InputType = modm::platform::Gpio::InputType;
// Connect SingalA and SignalB and store power-up state
inline void
connect();
initialize(const modm::platform::Gpio::InputType inputType = modm::platform::Gpio::InputType::PullUp);

// Call @1kHz for manual movement
inline void
update();

ValueType
getIncrement();
DeltaType
getDelta();

private:
uint8_t raw_last;
Expand Down
2 changes: 1 addition & 1 deletion src/modm/driver/encoder/bitbang_encoder_input.lb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def init(module):
module.description = """
# Quadrature Encoder Input

This driver decodes a AB (incremental) encoder signal.
This driver decodes an AB (incremental) encoder signal.
Ported from code created by Peter Dannegger:
https://www.mikrocontroller.net/articles/Drehgeber.
"""
Expand Down
Loading