Quadrature simulator feasibility

clinker8

Well-known member
I'd like to make a quadrature signal simulator. This will be used to test other code, which isn't part of the discussion. A real shaft encoder has two output signals, call them A and B. I'd like the simulator to behave reasonably like the real thing, save for maybe any edge bounce.

Tried using the TeensyTimerTool, and have a waveform, but it isn't close enough. The reason is because delayNanoseconds is blocking. Is there a simple way to create an A waveform of 50% duty factor (with controllable period) and a B waveform that is shifted from A a value that is 25% of the period (or 75% of the period when the direction reverses). There's probably a simple way to do this, but as a new user, it is escaping me.

Maybe I could run the timer at 4x the speed and use logic to set the conditions of A & B?
Code:
#include "TeensyTimerTool.h"

using namespace TeensyTimerTool;

Timer t1(TCK);  // Tick-Timer does not use any hardware timer (20 32bit channels)
Timer t2(TMR1); // First channel on TMR1 aka QUAD timer module. (TMR1 - TMR4, four 16bit channels each)
Timer t3(GPT1); // GPT1 module (one 32bit channel per module)
Timer t4(TMR1); // Second channel on TMR1

// Callbacks ===================================================================================

void a_ns(uint32_t myns)
{
  digitalWriteFast(1, HIGH);
  delayNanoseconds(myns);   // seems this is blocking, need a different approach!
  digitalWriteFast(1, LOW);
}

void b_ns(uint32_t myns)
{
  delayNanoseconds(myns/2);
  digitalWriteFast(2, HIGH);
  delayNanoseconds(myns);
  digitalWriteFast(2, LOW);
}


void setup() {
  // put your setup code here, to run once:
  for(unsigned pin=1; pin<=2; pin++) pinMode(pin, OUTPUT);

  t1.beginPeriodic( [] { a_ns(500);}, 1);    // this works somewhat!
  t2.beginPeriodic( [] { b_ns(500);}, 1);
}

void loop() {
  // put your main code here, to run repeatedly:

}
PXL_20220506_150736030_500.jpg
 
My bad. Thought it deserved it's own thread, rather than cluttering up yours. Should I continue on yours?
 
Maybe like this?

Code:
void quadrature() {
  static int state=0;
  switch (state & 3) {
    case 0: digitalWrite(2, HIGH); break;
    case 1: digitalWrite(3, HIGH); break;
    case 2: digitalWrite(2, LOW); break;
    case 3: digitalWrite(3, LOW); break;
  }
  state++;
}

void setup() {
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  static IntervalTimer mytimer;
  mytimer.begin(quadrature, 5.2);
}

void loop() {
}

file.png
 
Back
Top