Delay works for a while and then doesn't delay

This is my loop

void loop() {
  int thrust;

  while(true) {
    setDirection('F');
    delay(2250);
    // for(thrust = 0; thrust <= 100; thrust += 10) {
    //   setThrust(thrust);
    //   delay(1000);
    // }
    // for(thrust -=10; thrust > 0; thrust -=10) {
    //   setThrust(thrust);
    //   delay(1000);
    // }
    setDirection('N');
    delay(2250);
    // for(thrust = 0; thrust <= 100; thrust += 10) {
    //   setThrust(thrust);
    //   delay(1000);
    // }
    // for(thrust -=10; thrust > 0; thrust -=10) {
    //   setThrust(thrust);
    //   delay(1000);
    // }
    
    setDirection('R');
    delay(2250);
    // delay(250);
    // for(int thrust = 0; thrust <= 100; thrust += 10) {
    //   setThrust(thrust);
    //   delay(1000);
    // }
    // for(thrust -=10; thrust > 0; thrust -=10) {
    //   setThrust(thrust);
    //   delay(1000);
    // }

    setDirection('N');
    delay(2250);
    // for(thrust = 0; thrust <= 100; thrust += 10) {
    //   setThrust(thrust);
    //   delay(1000);
    // }
    // for(thrust -=10; thrust > 0; thrust -=10) {
    //   setThrust(thrust);
    //   delay(1000);
    // }
  }
}

This code works for a while, then it loses its mind and delay no longer delays.

There are 2 arduinos involved, This code above is for the CANBUS sender and the CANBUS reciever is the one with the servo connected.

The receiver has a 9VDC external power supply that is powering the motor and both Arduinos are connected to the same USB hub, As of this moment, it's been running about 13 minutes without issue but it won't be too long before it start flying.

I've got Serial.print statements on both ends, the sender and receiver and when it starts going crazy, it is sending 1000s of messages a minute.

I don't think it is the short CANBUS I have since what I'm sending and what's being receive is printing out correctly.

But why would delay just quit delaying?

Would you mind posting both the sender and receiver codes is full, please? It may provide the critical clue to sort out your woes.

i tested the code you posted and got the following output.
seems ok

        0  F
     2249  N
     4500  R
     6750  N
     9000  F
    11250  N
    13501  R
    15751  N
    18001  F
    20251  N
    22502  R
    24752  N
    27002  F
    29252  N
    31503  R
    33753  N
    36003  F
    38253  N
    40504  R
    42754  N
    45004  F
    47254  N
    49505  R
    51755  N
    54005  F
    56255  N
    58506  R
    60756  N
    63006  F
    65257  N
    67507  R
    69757  N
    72007  F
    74258  N
    76508  R
    78758  N
    81008  F
    83259  N
    85509  R
    87759  N
    90009  F
    92260  N
    94510  R
    96760  N
    99010  F
   101261  N
   103511  R
   105761  N
   108011  F
   110262  N
   112513  R
   114762  N
   117013  F
   119263  N
char s [90];

void
setDirection (
    char c )
{
    sprintf (s, " %8lu  %c", millis (), c);
    Serial.println (s);
}

// -----------------------------------------------------------------------------
void loop() {
    int thrust;

    while(true) {
        setDirection('F');
        delay(2250);
        // for(thrust = 0; thrust <= 100; thrust += 10) {
            //   setThrust(thrust);
            //   delay(1000);
        // }
        // for(thrust -=10; thrust > 0; thrust -=10) {
            //   setThrust(thrust);
            //   delay(1000);
        // }
        setDirection('N');
        delay(2250);
        // for(thrust = 0; thrust <= 100; thrust += 10) {
            //   setThrust(thrust);
            //   delay(1000);
        // }
        // for(thrust -=10; thrust > 0; thrust -=10) {
            //   setThrust(thrust);
            //   delay(1000);
        // }

        setDirection('R');
        delay(2250);
        // delay(250);
        // for(int thrust = 0; thrust <= 100; thrust += 10) {
            //   setThrust(thrust);
            //   delay(1000);
        // }
        // for(thrust -=10; thrust > 0; thrust -=10) {
            //   setThrust(thrust);
            //   delay(1000);
        // }

        setDirection('N');
        delay(2250);
        // for(thrust = 0; thrust <= 100; thrust += 10) {
            //   setThrust(thrust);
            //   delay(1000);
        // }
        // for(thrust -=10; thrust > 0; thrust -=10) {
            //   setThrust(thrust);
            //   delay(1000);
        // }
    }
}

void
setup ()
{
    Serial.begin (9600);
}

Ran just fine for 27 minutes then I stepped away. When I came back at 71 minutes, it was running super fast. and the motor was not moving any longer.

Receiver code is

void setDirection(char direction) {
  switch(direction) {
    case 'F':
      digitalWrite(DIRA, LOW); //other way
      digitalWrite(DIRB, HIGH);
      Transmission.write(15);
      Serial.println("Transimission set to 15 ");
      break;
    case 'N':
      Transmission.write(90);
      Serial.println("Transimission set to 90 ");
      analogWrite(ENABLE, 0);
      break;
    case 'R':
      digitalWrite(DIRA, HIGH); //other way
      digitalWrite(DIRB, LOW);
      Transmission.write(180-15);
      Serial.println("Transimission set to 165 ");
      break;
    default:
      Serial.print("Direction(");Serial.print(direction); Serial.println(") is invalid");
      while(true);
  }

}
void setThrust(long thrust) {
  long analogThrust = map(thrust, 0, 100, 80, 254);
  analogWrite(ENABLE, analogThrust); //enable on
  Serial.print("Thrust = "); Serial.print(thrust); Serial.print(" ("); Serial.print(analogThrust); Serial.println(")");
  lastThrust = thrust;
}


void onReceive(int packetSize) {
  // received a packet
  Serial.println("CAN Receiver Callback");

  char buf[20];
  //Serial.print("Received ");

  if (CAN.packetExtended()) {
    Serial.print("extended ");
  }

  if (CAN.packetRtr()) {
    // Remote transmission request, packet contains no data
    Serial.print("RTR ");
  }

  //Serial.print("packet with id 0x");
  //Serial.print(CAN.packetId(), HEX);

  if (CAN.packetRtr()) {
    Serial.print(" and requested length ");
    Serial.println(CAN.packetDlc());
  } else {
    //Serial.print(" and length ");
    //Serial.println(packetSize);

    // only print packet data for non-RTR packets
    int i;
    for(i=0; i < sizeof(buf) && CAN.available(); ++i) {
      buf[i] = (uint8_t)CAN.read();
      //Serial.print("i="); Serial.print(i); Serial.print(" buf[i]="); Serial.println(buf[i], HEX);
    }
    buf[i] = 0;
    if(CAN.packetId() == 0x12) {
      Serial.print("Message: "); Serial.println(buf);
      if('T' == buf[0]) {
          long thrust = atoi(&buf[1]); // Should be between -100 and +100
          if(thrust != lastThrust) {
            setThrust(thrust);
          }
      } else if('D' == buf[0]) {
          setDirection(buf[1]);
      } else {
          Serial.println("Got a message I wasn't expecting!");
      }
    }
  }
}

I pushed the reset button on the sender and it's working again. Seems to be related to delay() but not sure why. Seems like delay would be ROCK solid. But it appears this is NOT the case. Going to go write my own delay routing using millis() and see what happens.

It's certainly more solid than the code we can not see. Complete code, or minimal example code which compiles and demonstrates the problem is what people who want to help you need to see.

wish i had known this sooner. i'll let it run overnight.

last time someone said their code was "rock solid" we had to rewrite it.

I suspect you are using the wrong type of variables.

But we can only be sure if you post ALL your code not just snippets.

Please see:-

1 Like

I’ve written my own version of delay, going to see how that works

Here is all the code BUT the problem isn't in the SW, the problem is in the Arduino board. I grabbed some cheap boards (I'm in Mexico so availability is limited). I have 2 of these cheap boards, sender and receiver and the receiver is working without a problem. The sender however was not. So, I took the 3rd Arduino (elegoo UNO R3) and the code that was failing (even with my own delay routine) is now working as expected. Looks like I need to order some better Arduinos!

I brought the delay down from 2250 to 250 and it has already run more than 2x as long as the failure case.

Wish I had some idea how to troubleshoot this quicker, these kinds of problems have cost too much time for this simple project!

#include <CAN.h>

const int THROTTLE_PIN = A0;
int setup_started = 0;
void setup() {
  if(setup_started) return;
  setup_started = 1;

  Serial.begin(9600);
  while (!Serial);
  Serial.println("CAN Sender initializing");

  pinMode(THROTTLE_PIN, INPUT_PULLUP);

  // start the CAN bus at 500 kbps
  if (!CAN.begin(500E3)) {
    Serial.println("Starting CAN failed!");
    while (1);
  }
  delay(3000);
  Serial.println("CAN Sender initialized");

}



void setThrust(int thrust) {
  uint8_t thrustString[6]; // Buffer to hold the string
  itoa(thrust, thrustString, 10);
  Serial.print("Sending thrust ... ");

  CAN.beginPacket(0x12);
  CAN.write('T');
  CAN.write(thrustString, strlen(thrustString));
  CAN.write(0);
  CAN.endPacket();
  Serial.print((char*)thrustString);

  Serial.println(" done.");

}

void setDirection(uint8_t direction) {
  Serial.print("Setting Direction ... ");

  CAN.beginPacket(0x12);
  CAN.write('D');
  CAN.write(direction);
  CAN.write(0);
  CAN.endPacket();

  Serial.print(direction); Serial.println(" done.");

}

unsigned long previousMillis = millis();
const unsigned long increment = 0x10000;
unsigned long overflowCount = increment;

unsigned long millis32()
{
  unsigned long currentMillis = millis();
  if(currentMillis < previousMillis) {
    overflowCount += increment;
  }
  previousMillis = currentMillis;
  return overflowCount + currentMillis;
}

void mydelay(unsigned long ms) {
  unsigned long endat = millis32() + ms;

  while(endat > millis32());
  // Serial.println(endat,HEX);
}


void loop() {
  int thrust=0;

  while(true) {
    Serial.println(thrust++);
    setDirection('F');
    mydelay(250);
    // for(thrust = 0; thrust <= 100; thrust += 10) {
    //   setThrust(thrust);
    //   delay(1000);
    // }
    // for(thrust -=10; thrust > 0; thrust -=10) {
    //   setThrust(thrust);
    //   delay(1000);
    // }
    setDirection('N');
    mydelay(250);
    // for(thrust = 0; thrust <= 100; thrust += 10) {
    //   setThrust(thrust);
    //   delay(1000);
    // }
    // for(thrust -=10; thrust > 0; thrust -=10) {
    //   setThrust(thrust);
    //   delay(1000);
    // }
    
    setDirection('R');
    mydelay(250);
    // delay(250);
    // for(int thrust = 0; thrust <= 100; thrust += 10) {
    //   setThrust(thrust);
    //   delay(1000);
    // }
    // for(thrust -=10; thrust > 0; thrust -=10) {
    //   setThrust(thrust);
    //   delay(1000);
    // }

    setDirection('N');
    mydelay(250);
    // for(thrust = 0; thrust <= 100; thrust += 10) {
    //   setThrust(thrust);
    //   delay(1000);
    // }
    // for(thrust -=10; thrust > 0; thrust -=10) {
    //   setThrust(thrust);
    //   delay(1000);
    // }
  }
}

adding 0x10000 on millis() rollover just to be able to to do a check on > millis32() can't be stable solution.

Imho your mydelay() and millis32() are broken by design.

Proposal: get rid of the delay() and make your sketch "non blocking" based on the example shown in "Blink without Delay".

if you haven't read about it, the

millis() - previousMillis > interval

will not fail on rollover with unsigned types.

When your program has to handle different states see how to implement a finite state machine.

when i got up tis morning it seemed to be running consistently, output every ~2 sec

I initially wrote the loop portion of the sender because of trouble controlling the motors. I added the delay() to have a better chance of figuring out what was going on, just to have delay freak out on me. I wrote millis32() to debug delay() and since it only needed to get past the 70 minutes, it's not broken, just not as robust as it needs to be.

In the end, replacing that one UNO with the Elegoo UNO R3 fixed the problem without changing the code. It did however manage to move the problem to the other UNO board (same maker) that was controlling the motors, where as before it was in the sending vs the rcving side of things. I've order 3 more of the Elegoo boards so I can continue the protoyping which doesn't use delay() at all and does have a finite state machine but that is a completely different beast and not something I would want in the picture while trying to solve problems like this.

Also during all of this troubleshooting there was a switch statement that didn't work for one of the cases and I had to change that to an if/else if/else. So I'm betting they used defective Atmega (or cloned) parts since they ground/washed the numbers off the chips and there was nothing wrong with the code, just the processors.

Same with the Elegoo board I drop into the circuit last night.

This is the board you do NOT want to purchase

https://www.amazon.com.mx/dp/B0D16KL7VP?psc=1&ref=ppx_yo2ov_dt_b_product_details

Amazon is typically very good with returns, so I would return these boards, and add a comment in the reviews for the boards on the Amazon site.

You seem to be taking a scatter gun approach to this project. If you want to get help then again post this code. We can't debug what we can't see.

You were either mistaken or you believe in magic it is not possible for this to happen.

This sounds like throwing good money after bad. We generally find here that the Elegoo boards are very poor and cause all sorts of problems.

The way you have to work here in order to solve your problem:-

  1. You post code.
  2. Someone makes a suggestion about changing it.
  3. You try the suggestion.
  4. You report back if it works or not, and exactly what it does or doesn't do.
  5. And you post your code again to show the code with the suggested changes, so we can check if you have done the changes correctly.

It is vital that you do this. Yes it is long winded but it is the only way to get something to work when you are trying to get code to work.

So far in this thread we have not touched on your hardware only software. It is entirely possible that there is something wrong about the way you have things wired up, and it is this that is giving you the problem. So can you please post a schematic of your hardware along with a photograph or two showing your circuit.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.