Continuing the discussion from Generation of three phase square wave using arduino(SIMPLE CODING) and its OP:
How about:
// https://wokwi.com/projects/385290804310887425
// modified from
// https://forum.arduino.cc/t/generation-of-three-phase-square-wave-using-arduino-simple-coding/407769
// See https://blog.orientalmotor.com/stepper-motor-basics-pm-vs-vr-vs-hybrid
// for the layout of a 3 phase motor with a 12 coil stator and 8 pole rotor
// 12coils/3 phases = 4 cycles per rev
unsigned long delayInterval = 3333UL; // 500UL*1000; //
unsigned long nowUs = 0;
unsigned long nowMs = 0;
unsigned long now = 0;
const byte pinA = 7;
const byte pinB = 8;
const byte pinC = 9;
const byte speedPin = A0;
const byte phaseTable6[] = {0b001, 0b011, 0b010, 0b110, 0b100, 0b101};
// one coil at a time:
const byte phaseTable3[] = {0b001, 0b010, 0b100, 0b001, 0b010, 0b100};
byte phase = 0; // global variable to track phase state
void setup() {
Serial.begin(115200);
// initialize digital pin 13,12&8 as an output.
pinMode(pinA, OUTPUT);
pinMode(pinB, OUTPUT);
pinMode(pinC, OUTPUT);
}
void loop() {
now = micros();
stepPhases6(delayInterval);
// stepPhases6Blocking(delayInterval);
updateSpeed();
}
void writePhases(byte phase) {
digitalWrite(pinA, phase & 0b001);
digitalWrite(pinB, phase & 0b010);
digitalWrite(pinC, phase & 0b100);
}
void stepPhases6(unsigned long interval) {
static long last = -10000;
int dir = 1;
if (now - last > interval) {
writePhases(phaseTable6[phase++]);
if (phase >= 6) phase = 0;
last = now;
}
}
void stepPhases6Blocking(unsigned long interval) {
// closer to https://forum.arduino.cc/t/generation-of-three-phase-square-wave-using-arduino-simple-coding/407769
// but simplified with functions and a lookup table
writePhases(phaseTable6[phase++]);
if (phase >= 6) {
phase = 0;
}
delay(interval);
}
void updateSpeed(void) {
const unsigned long interval = 100000UL;
static unsigned long last = 0;
const int coils = 12;
const int phases = 3;
constexpr int stepsPerRev = 6 * coils/phases;
if (now - last >= interval ) {
static int lastReading = -1;
int currentReading = 1023 - analogRead(speedPin);
if (currentReading != lastReading) {
lastReading = currentReading;
delayInterval = (currentReading) * 4096UL + 1000;
Serial.print(delayInterval);
Serial.print("us ");
Serial.print(60UL * 1000000.0 / delayInterval / stepsPerRev, 4);
Serial.print("RPM ");
}
last = now;
}
}
and
https://wokwi.com/projects/385290804310887425
It isn't as "simple" as blocking code with hard-coded pins, and it has the complication of a variable speed control with analog change detection, but it makes the basics of generating a multiphase square wave easier to understand.