What's wrong with my callback?

Hi all, I’m making a candy machine for halloween that has two stepper motors. In my code, I didn’t want to use a delay so I used a callback. So the stepper motor goes up, but not back down like it should.

    stepper->step(stepsDown);
    Timer callBack(1800, [this](){stepper->step(-stepsUp);}, true);
    callBack.start();

Like I said, the stepper goes up but not down. Any ideas how to fix the callback? My full code is below:

    // This #include statement was automatically added by the Particle IDE.
    #include <LiquidCrystal.h>

    // This #include statement was automatically added by the Particle IDE.
    #include <Stepper.h>

    const int stepsUp = 240;  
    const int stepsDown = 230;  
    LiquidCrystal lcd(B0, B1, B2, B3, B4, B5);

    void updateLCD(int remSec);

    struct Dispenser {
      Dispenser(int pin, int lstate, Stepper* stpr){
          buttonPin = pin;
          lastState = lstate;
          stepper = stpr;
          stepper->setSpeed(60);
      };
      int buttonPin;
      int lastState;
      Stepper* stepper;
      bool lockout;
      uint32_t lockoutStart;
      uint32_t lastSecond;

      void dispenseCandy()///////this is where the callback is!!!!!!
      {
        /*
        stepper->step(stepsDown);
        Timer callBack(1800, [this](){stepper->step(-stepsUp);}, true);
        callBack.start();
        */
        
            stepper->step(stepsDown);
            delay(1000);
            stepper->step(-stepsUp);

      }
    };

    Stepper stepperLeft(200, 3, 4, 5, 6);
    Stepper stepperRight(200, C0, C1, C2, C3);
    Dispenser dispenser[] = {{D0, 1, &stepperLeft}, {C5, 1, &stepperRight}};

    void setup(void)
    {
      Serial.begin(9600);
      lcd.begin(16, 2);
      lcd.print("Candy  Dispenser");
      for (auto disp : dispenser)
      {
        pinMode(disp.buttonPin, INPUT);
      }
      Serial.println("GO");
    }

    void loop(void)
    {
      int i = 0;
      for (auto& disp : dispenser)
      {
        if (!disp.lockout)
        {
          int buttonState = digitalRead(disp.buttonPin);
          if (buttonState != disp.lastState)
          {
            if (disp.lastState == true)
            {
              Serial.print(i);
              Serial.println("Press");
              disp.dispenseCandy();
              disp.lockout = true;
              disp.lockoutStart = millis();
            }
          disp.lastState = buttonState;
          }
        }
        else
        {
          int remainingSeconds = 10 - (millis() - disp.lockoutStart) / 1000;
          if (!remainingSeconds)
          {
            disp.lockout = false;
            lcd.setCursor(0, i);
            lcd.print("READY 2 DISPENSE");
            Serial.println("READY 2 DISPENSE");
          }
          else if (remainingSeconds != disp.lastSecond)
          {
            updateLCD(remainingSeconds, i);
            disp.lastSecond = remainingSeconds;
            Serial.println(disp.lastSecond);
          }
        }
        i++;
      }
    }

    void updateLCD(int remSec, int row)
    {
      lcd.setCursor(0, row);
      char printBuffer[17];
      sprintf(printBuffer, "Locked %6dsec", remSec);
      lcd.print(printBuffer);
      Serial.println(printBuffer);
    }

Providing you have that block activated - in your full code it’s not:

One thing is that your callBack object is only a local instance and hence will die as soon the instantiating function leaves.

1 Like