// generate a quadrature signal with code.
//
// outputs two square wave signals 90° out of phase
// see also: https://forum.arduino.cc/index.php?topic=383189.msg2730013#msg2730013
// divide-by-two vars
bool mainClockQ;
bool phaseAQ;
bool phaseBQ;
bool risingEdge;
bool risingEdgeSetup;
bool fallingEdge;
bool fallingEdgeSetup;
const uint8_t aPhasePin = 11;
const uint8_t bPhasePin = 6;
const uint8_t mainClkPin = 3;
const uint8_t reverse = A3;
unsigned long currentMillis;
int interval = 600; // square wave frequency = interval * 2
void setup() {
Serial.begin(115200);
digitalWrite(aPhasePin, 1);
digitalWrite(bPhasePin, 1);
pinMode(aPhasePin, OUTPUT);
pinMode(bPhasePin, OUTPUT);
pinMode(mainClkPin, OUTPUT);
pinMode(reverse, INPUT_PULLUP);
}
void loop() {
if (millis() - currentMillis > interval) {
// generate main clock square wave
mainClockQ = !mainClockQ; // toggle
currentMillis = millis();
}
// main clock drives one-shots for phase clocking
// risingEdge and fallingEdge are true one scan only at transition of mainClockQ
risingEdge = (mainClockQ and risingEdgeSetup);
risingEdgeSetup = !mainClockQ;
fallingEdge = (!mainClockQ and fallingEdgeSetup);
fallingEdgeSetup = mainClockQ;
// clock the phase square wave generators
if (digitalRead(reverse) == 0) {
if (risingEdge) phaseAQ = !phaseAQ; // toggle the phase with a one-shot
if (fallingEdge) phaseBQ = !phaseBQ;
}
// reverse direction
else {
if (fallingEdge) phaseAQ = !phaseAQ;
if (risingEdge) phaseBQ = !phaseBQ;
}
// make results visible
digitalWrite(aPhasePin, phaseAQ);
digitalWrite(bPhasePin, phaseBQ);
digitalWrite(mainClkPin, mainClockQ);
}
mainClockQ
phase A
phase B
reverse direction