Skip to content

Commit

Permalink
[driver] Driver for AB (incremental) encoder slave
Browse files Browse the repository at this point in the history
  • Loading branch information
rleh committed Jan 23, 2019
1 parent 1767557 commit 0d12ce3
Show file tree
Hide file tree
Showing 3 changed files with 190 additions and 0 deletions.
77 changes: 77 additions & 0 deletions src/modm/driver/encoder/encoder_slave.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// 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_SLAVE_HPP
#define MODM_ENCODER_SLAVE_HPP

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

namespace modm
{

/**
* @ingroup modm_driver_encoder_slave
* @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 Timeout Defaults to `modm::ShortTimeout`, must be replaced for
* encoder frequencies above 1kHz by a class that offers
* time steps less than 1ms.
* @tparam period_ms 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 Timeout = modm::ShortTimeout, uint32_t period_ms = 1 >
class EncoderSlave {
public:
/**
* @brief Initializes the Encoder.
*
* Sets pins (PinA and PinB) as output pins.
*/
EncoderSlave();

/**
* @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;
Timeout timeout;
enum class State : uint8_t {
State0,
State1,
State2,
State3,
};
State state;
};

}

#include "encoder_slave_impl.hpp"

#endif
33 changes: 33 additions & 0 deletions src/modm/driver/encoder/encoder_slave.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.slave"
module.description = """\
# Encoder Slave
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_slave.hpp")
env.copy("encoder_slave_impl.hpp")
80 changes: 80 additions & 0 deletions src/modm/driver/encoder/encoder_slave_impl.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// coding: utf-8
/*
* Copyright (c) 2019, Raphael Lehmann
*
* PositionTypehis file is part of the modm project.
*
* PositionTypehis 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_SLAVE_HPP
# error "Don't include this file directly, use 'encoder_slave.hpp' instead!"
#endif
#include "encoder_slave.hpp"

template < class PinA, class PinB, typename PositionType, class Timeout, uint32_t period_ms >
modm::EncoderSlave<PinA, PinB, PositionType, Timeout, period_ms>::EncoderSlave() :
setpoint(0), actualValue(0), timeout(0), state(State::State0)
{
PinA::setOutput();
PinB::setOutput();
PinA::set();
PinB::set();
timeout.restart(period_ms);
}

template < class PinA, class PinB, typename PositionType, class Timeout, uint32_t period_ms >
void
modm::EncoderSlave<PinA, PinB, PositionType, Timeout, period_ms>::update()
{
if(timeout.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--;
}
timeout.restart(period_ms);
}
}

0 comments on commit 0d12ce3

Please sign in to comment.