diff --git a/pousseseringue-arduino.cpp b/pousseseringue-arduino.cpp index 0286217979723e31c4c5ab267213f2a2bc49fd81..c755570c49f282962c1eb294e7b8050f517f4de9 100644 --- a/pousseseringue-arduino.cpp +++ b/pousseseringue-arduino.cpp @@ -44,31 +44,23 @@ #define STEPPER_RPM 60 // some value is necessary for the driver XXXXX see below -#define STEP_DURATION_MIN_MS 2 -#define STEP_DURATION_DEFAULT_MS 5 +#define STEPpS_MIN 2 +#define STEPpS_DEFAULT 5 #include <ESP8266WiFi.h> // internal, wifi library #include <DNSServer.h> // internal, access point mode +#include <Schedule.h> #if !CORE_MOCK #include <SSD1306AsciiWire.h> // https://github.com/greiman/SSD1306Ascii SSD1306AsciiWire oled; -#if USE_A4988 - -#include <A4988.h> // https://github.com/laurb9/StepperDriver -A4988 a4988(MOTOR_STEPS, DIR, STEP, SLEEP); - -#else - #include <AccelStepper.h> // https://github.com/waspinator/AccelStepper AccelStepper stepper(AccelStepper::DRIVER, STEP, DIR); -#endif - #endif // !CORE_MOCK #include "Debouncer.h" // local, debouncer, short counter, long detector @@ -90,19 +82,19 @@ DNSServer dnsServer; char ssid[65]; -Modes mode = Modes::TURN; +Modes mode = Modes::RPM; +bool stepperMoving = false; millis_t lastMoveMs = 0; int move = 0; // TURN mode constexpr float step2deg = 360.0 / MOTOR_STEPS / MICROSTEPS_CONF; // deg for 1 step -int steps = MOTOR_STEPS * MICROSTEPS_CONF / 100; // =1/100 turn +int steps = MOTOR_STEPS * MICROSTEPS_CONF / 4; // =1/4 turn // RPM mode -int stepsPerDuration = 1; -int stepDurationMs = STEP_DURATION_DEFAULT_MS; -float stepsPerDuration2rpm () { return 60.0 * stepsPerDuration / ((MOTOR_STEPS * MICROSTEPS_CONF) * (stepDurationMs / 1000.0)); } +int stepsPerSeconds = MOTOR_STEPS * MICROSTEPS_CONF / 2; +float stepsPerSeconds2rpm () { return 60.0 * stepsPerSeconds / (MOTOR_STEPS * MICROSTEPS_CONF); } int rpming = 0; // -1, 0 or +1 // single syringe global instance @@ -137,28 +129,28 @@ void oledRedisplay () switch (mode) { case Modes::TURN: - oled.printf("<%g dR <<turn", steps * step2deg); + oled.printf("<%g dR <<360 dR", steps * step2deg); oledPrintMode(); oled.printf("\n"); - oled.printf("\n<%g dL <<turn", steps * step2deg); + oled.printf("\n<%g dL <<360 d ", steps * step2deg); break; case Modes::TURNSetup: - oled.printf("<+1 << +10 steps"); + oled.printf("<+1step << +1/16T"); oledPrintMode(); - oled.printf("\n current:%d (%g d)", steps, steps * step2deg); - oled.printf("\n<-1 << -10 steps"); + oled.printf("\n steps:%d (%g d)", steps, steps * step2deg); + oled.printf("\n<-1step << -1/16T"); break; case Modes::RPM: oled.printf("<stop <<start"); oledPrintMode(); - oled.printf("\n %g rpm", stepsPerDuration2rpm()); + oled.printf("\n %g rpm", stepsPerSeconds2rpm()); oled.printf("\n<stop <<start"); break; case Modes::RPMSetup: - oled.printf("<+1st <<+1ms st:%d", stepsPerDuration); + oled.printf("<+1s/s <<+1/4T/s"); oledPrintMode(); - oled.printf("\n %g rpm", stepsPerDuration2rpm()); - oled.printf("\n<-1st <<-1ms t:%dms", stepDurationMs); + oled.printf("\ns/s:%d RPM:%g", stepsPerSeconds, stepsPerSeconds2rpm()); + oled.printf("\n<-1s/s <<-1/4T/s"); break; case Modes::INFO: oled.printf("IP:%s", WiFi.localIP().toString().c_str()); @@ -189,7 +181,6 @@ void changeMode () } - // button status management, per mode void buttons (int shortp, int longp) @@ -197,40 +188,82 @@ void buttons (int shortp, int longp) // log debug on serial console Serial.printf("button change: short:%d long:%d\n", shortp, longp); +#if !CORE_MOCK + cli(); + stepper.stop(); + sei(); + while (stepperMoving) + yield(); +#endif // !CORE_MOCK + + auto oldrpming = rpming; rpming = 0; // anything stops rpming switch (mode) { case Modes::TURN: + Serial.printf("move: %d -> ", move); move += shortp * steps; - move += longp * MOTOR_STEPS * MICROSTEPS_CONF; + move += longp * MOTOR_STEPS * MICROSTEPS_CONF; // long: one turn + Serial.printf("%d\n", move); +#if !CORE_MOCK + cli(); + stepper.moveTo(move); + sei(); +#endif // !CORE_MOCK break; + case Modes::TURNSetup: steps += shortp; - steps += longp * 10; + steps += longp * MOTOR_STEPS * MICROSTEPS_CONF / 16; oledRedisplay(); break; + case Modes::RPM: if (longp) - rpming = longp; // move will be increased in main loop - if (shortp) - move = 0; // stop moving + { + rpming = longp? (oldrpming > 1? -1: 1): 0; + if (rpming) + { +#if !CORE_MOCK + cli(); + stepper.setSpeed(stepsPerSeconds); + sei(); +#endif // !CORE_MOCK + Serial.printf("StepPerSecs=%d (%g RPM)\n", stepsPerSeconds, stepsPerSeconds2rpm()); + //stepper.setMaxSpeed(400); + } + } break; + case Modes::RPMSetup: - if ((stepDurationMs += longp) < STEP_DURATION_MIN_MS) - stepDurationMs = STEP_DURATION_MIN_MS; - if ((stepsPerDuration += shortp) < 1) - stepsPerDuration = 1; + if ((stepsPerSeconds += longp * MOTOR_STEPS * MICROSTEPS_CONF / 16) < 1) + stepsPerSeconds = 1; + if ((stepsPerSeconds += shortp) < 1) + stepsPerSeconds = 1; oledRedisplay(); break; + default: Serial.printf("press not handled in buttons()\n"); } } +#if !CORE_MOCK +IRAM_ATTR +void stepperRun () +{ + cli(); + if (rpming) + stepperMoving = stepper.runSpeed(); + else + stepperMoving = stepper.run(); + sei(); +} +#endif // !CORE_MOCK void setup() { @@ -251,16 +284,9 @@ void setup() oled.clear(); oled.println("Booting...\n"); -#if USE_A4988 - a4988.begin(STEPPER_RPM); // some value is necessary - a4988.setEnableActiveState(LOW); - a4988.setMicrostep(MICROSTEPS_CONF); - a4988.enable(); -#else stepper.setMaxSpeed(10000); stepper.setAcceleration(10000); - stepper.moveTo(200); -#endif + #endif // !CORE_MOCK @@ -289,6 +315,20 @@ void setup() pinMode(BTNC, INPUT_PULLUP); oledRedisplay(); + +#if !CORE_MOCK +#ifdef ISR_ATTR + timer1_isr_init(); + timer1_enable(TIM_DIV1, TIM_EDGE, TIM_LOOP); + timer1_attachInterrupt(stepperRun); + timer1_write(microsecondsToClockCycles(100)); +#else + #warning =================================================================================================== + #warning "Please use the ISR version of AccelStepper (git clone -b isr https://github.com/d-a-v/AccelStepper)" + #warning =================================================================================================== + schedule_recurrent_function_us([](){ stepperRun(); return true; }, 1); +#endif +#endif } @@ -333,53 +373,7 @@ void loop() if (longB) changeMode(); (void)shortB; - - move = 0; - } - -#if !CORE_MOCK - - // Stepper - -#if USE_A4988 - // MOVE THIS BLOCK INTO A TIMER/ISR - // (it is randomly slowed down by prints / web / wifi) - // (or? use A4988 RPM mode, related: a4988.begin(STEPPER_RPM);) - if (lastMoveMs - nowMs > (millis_t)stepDurationMs) - { - if (rpming && move < MOTOR_STEPS * MICROSTEPS_CONF && move > -(MOTOR_STEPS * MICROSTEPS_CONF)) - { - move += rpming * MOTOR_STEPS * MICROSTEPS_CONF; - //Serial.printf("feeding %d\n", move); - } - - if (move >= stepsPerDuration) - { - move -= stepsPerDuration; - a4988.move(stepsPerDuration); // forward revolution - } - if (move <= -stepsPerDuration) - { - move += stepsPerDuration; - a4988.move(-stepsPerDuration); // backward revolution - } - - lastMoveMs += stepDurationMs; - - } -#else - - if (stepper.distanceToGo() == 0) - { - stepper.moveTo(-stepper.currentPosition()); - Serial.println("Rotating Motor in opposite direction..."); } - stepper.run(); - -#endif - -#endif // !CORE_MOCK - console.loop(Serial); webLoop(); diff --git a/pousseseringue-arduino.ino b/pousseseringue-arduino.ino index 8629455d7b9b3a8250b3441bdd4c7442fc2884e4..e3e70bcc95a52ecce0d4c4136ec6f8aaa52acae7 100644 --- a/pousseseringue-arduino.ino +++ b/pousseseringue-arduino.ino @@ -1,7 +1,7 @@ // please edit this file: pousseseringue-arduino.cpp -// Pour la compilation locale sur le PC +// needed for compilation on host #if CORE_MOCK #include "pousseseringue-arduino.cpp" #include "web.cpp"