#include <EncSim.h>
#include <QuadEncoder.h>
#include <SerialCommand.h>
#include <IntervalTimer.h>
EncSim tachsim( 0, 1, 2 ); // pins A(0), B(1), M(2)
QuadEncoder Enc(3, 4, 5, 0); // Enc 3 of 4, A(pin4), B(pin5), PullupsReq(0)
SerialCommand sCmd; // SerialCommand object
IntervalTimer timer; // periodic timer
uint32_t ppr = 1200; // pulses per rev (*4 for quadrature)
float rpm = 1000; // rpm = (60*frq)/(ppr*4)
float frq = (ppr*4)*(fabs(rpm)/60); // keep this relationship
bool update = true; // update = true to trigger one print
void LED_on();
void LED_off();
void rpmCommand();
void pprCommand();
void frqCommand();
void default_fn( const char *command );
elapsedMillis ms;
void setup()
{
pinMode( LED_BUILTIN, OUTPUT ); // Configure the onboard LED for output
digitalWrite( LED_BUILTIN, LOW ); // default to LED off
// Setup callbacks for SerialCommand commands
sCmd.addCommand( "on", LED_on ); // Turns LED on
sCmd.addCommand( "off", LED_off ); // Turns LED off
sCmd.addCommand( "rpm", rpmCommand ); // rpm followed by new rpm value
sCmd.addCommand( "ppr", pprCommand ); // ppr followed by new ppr value
sCmd.addCommand( "frq", frqCommand ); // frq followed by new ppr value
sCmd.setDefaultHandler( default_fn ); // Handler for command that isn't matched (says "What?")
Serial.begin( 115200 );
delay( 1000 );
Serial.printf( "Application TachSim0 %s %s\n", __DATE__, __TIME__ );
Enc.setInitConfig(); //
Enc.init();
tachsim.begin(); // begin()
tachsim // CONFIGURATION
.setPhase( 90 ) // normal 90 deg phase shift
.setTotalBounceDuration( 0 ) // no bouncing
.setPeriod( ppr*4 ) // marker every ppr A/B pulses
.setFrequency( frq ); // frequency = f(ppr,rpm)
tachsim.setContinuousMode( true ); // don't stop at target
tachsim.moveRelAsync( rpm >= 0.0 ? +1 : -1 ); // +/- direction
ms = 0;
timer.begin( timerHandler, 100.0 ); // 10 kHz -> period = 100 us
timer.priority( 0 ); // set to highest priority
}
//---------------------------------------------------------------------
// IntervalTimer handler and variables to compute encoder delta/sum
//---------------------------------------------------------------------
uint32_t timerCount; // counts are always unsigned
uint32_t encNow; // unsigned encoder count
uint32_t encPrev; // unsigned encoder count
int32_t encDelta; // signed delta
int32_t encSum; // signed sum
void timerHandler( void ) {
timerCount++; // count interrupts
encNow = Enc.read(); // read running encoder count
encDelta = encNow - encPrev; // compute delta
encSum = encSum + encDelta; // update running sum
encPrev = encNow; // save for next time
}
void loop()
{
sCmd.readSerial();
if (update == true) {
Serial.printf( "ppr = %4lu rpm = %6.1f frq = %8.1f\n", ppr, rpm, frq );
update = false;
}
else if (ms >= 1000) {
// print running sum of encoder counts and interrupt counts, then zero
Serial.printf( "encoder counts = %8d IRQ count = %8lu\n", encSum, timerCount );
encSum = 0;
timerCount = 0;
ms -= 1000;
}
}
void LED_on() { digitalWrite( LED_BUILTIN, HIGH ); }
void LED_off() { digitalWrite( LED_BUILTIN, LOW ); }
void rpmCommand()
{
char *arg = sCmd.next();
if (arg == NULL) {
Serial.println( "No arguments" );
}
else {
rpm = atoi(arg); // char* to integer
frq = (ppr*4)*(fabs(rpm)/60); // compute new frequency
tachsim.moveRelAsync( rpm >= 0 ? +1 : -1); // set direction = f(rpm)
tachsim.setFrequency( frq ); // set frequency
}
update = true;
}
void pprCommand()
{
char *arg = sCmd.next();
if (arg == NULL) {
Serial.println( "No arguments" );
}
else {
int temp = atoi(arg); // char* to integer
if (temp > 0) { // if valid ppr
ppr = temp; // set ppr
frq = (ppr*4)*(fabs(rpm)/60); // compute new frequency
tachsim.setPeriod( ppr*4 ); // marker every ppr pulses
tachsim.setFrequency( frq ); // set frequency
}
}
update = true;
}
void frqCommand()
{
char *arg = sCmd.next();
if (arg == NULL) {
Serial.println( "No arguments" );
}
else {
frq = (float)atoi(arg); // char* to integer
rpm = (60*frq)/(ppr*4); // back-calc rpm
tachsim.setFrequency( frq ); // set frequency
}
update = true;
}
// This gets set as the default handler, and gets called when no other command matches.
void default_fn( const char *command )
{
Serial.println( "What?" );
}