Code stops after some time using delay

Hello, I wrote this code and it does what I want but it will stop working after some hours. I need this code to run as long as needed. It is to raise and lower sharpies onto 3D printing filament at different intervals. I gather it is from the use of Delay instead of millis, but I dont know enough about programming to do that on my own.

Is there a way to add a piece of code to the end to clear the memory (due to filling up from the use of delay i guess?)

Or any guidance to change it to the use of millies without rewriting the entire code?

Any help is much appreciated!

#include <Servo.h>

// constants won't change

const int SERVO_PIN_A = 9;
const int SERVO_PIN_B = 10; 
const int SERVO_PIN_C = 11;
const int SERVO_PIN_D = 3;
const int button = 5;
const int angleA = 0;         
const int angleB = 90;
const int time1 = 1000;
const int time2 = 2000;
const int time3 = 3000;
const int min = 0;
const int max = 1023;
const int ledR = 0;
const int ledY = 1;
const int ledG = 2;
const int ledW = 4;



Servo servo_A; // create servo object to control a servo
Servo servo_B;
Servo servo_C;
Servo servo_D;



void setup() {
 
  servo_A.attach(SERVO_PIN_A);           // attaches the servo on pin 9 to the servo object
  servo_B.attach(SERVO_PIN_B);           // attaches the servo on pin 9 to the servo object
  servo_C.attach(SERVO_PIN_C);           // attaches the servo on pin 9 to the servo object
  servo_D.attach(SERVO_PIN_D);           // attaches the servo on pin 9 to the servo object
  
  pinMode(ledR, OUTPUT);
  pinMode(ledY, OUTPUT);
  pinMode(ledG, OUTPUT);
  pinMode(ledW, OUTPUT);
  
  randomSeed(analogRead(0));// seads ranodm number from analog pin from 0 to 1023)
  
}


void loop() {
  
  int sensorReading = analogRead(A0); //maps pin to pot
  int range = map(sensorReading, min, max, 0, 4); //maps pot into sections
  
 
 
    
    switch (range) {
    
    case 0:
      
    digitalWrite(ledG, HIGH);
	digitalWrite(ledY, LOW);
    digitalWrite(ledR, LOW);
    digitalWrite(ledW, LOW);
      
      
   	servo_A.write(angleB);
    servo_B.write(angleA);
    servo_C.write(angleA);
    servo_D.write(angleA);
 	delay(time1);
  
  	servo_A.write(angleA);
    servo_B.write(angleB);
    servo_C.write(angleA);
    servo_D.write(angleA);
 	delay(time1);
 
	servo_A.write(angleA);
    servo_B.write(angleA);
    servo_C.write(angleB);
    servo_D.write(angleA);
 	delay(time1);

 	servo_A.write(angleA);
    servo_B.write(angleA);
    servo_C.write(angleA);
    servo_D.write(angleB);
	delay(time1);
    
    
    break;
    
    
    case 1:
      
    digitalWrite(ledG, LOW);
	digitalWrite(ledY, HIGH);
    digitalWrite(ledR, LOW);
    digitalWrite(ledW, LOW); 

   	servo_A.write(angleB);
    servo_B.write(angleA);
    servo_C.write(angleA);
    servo_D.write(angleA);
 	delay(time2);
  
  	servo_A.write(angleA);
    servo_B.write(angleB);
    servo_C.write(angleA);
    servo_D.write(angleA);
 	delay(time2);
 
	servo_A.write(angleA);
    servo_B.write(angleA);
    servo_C.write(angleB);
    servo_D.write(angleA);
 	delay(time2);

 	servo_A.write(angleA);
    servo_B.write(angleA);
    servo_C.write(angleA);
    servo_D.write(angleB);
	delay(time2);
    
    
    break;
    
    case 2:
      
    digitalWrite(ledG, LOW);
	digitalWrite(ledY, LOW);
    digitalWrite(ledR, HIGH);
    digitalWrite(ledW, LOW);

   	servo_A.write(angleB);
    servo_B.write(angleA);
    servo_C.write(angleA);
    servo_D.write(angleA);
 	delay(time3);
  
  	servo_A.write(angleA);
    servo_B.write(angleB);
    servo_C.write(angleA);
    servo_D.write(angleA);
 	delay(time3);
 
	servo_A.write(angleA);
    servo_B.write(angleA);
    servo_C.write(angleB);
    servo_D.write(angleA);
 	delay(time3);

 	servo_A.write(angleA);
    servo_B.write(angleA);
    servo_C.write(angleA);
    servo_D.write(angleB);
	delay(time3);
    
    
    break;
    

    case 3:
      
    digitalWrite(ledG, LOW);
	digitalWrite(ledY, LOW);
    digitalWrite(ledR, LOW);
    digitalWrite(ledW, HIGH);

   	servo_A.write(angleB);
    servo_B.write(angleA);
    servo_C.write(angleA);
    servo_D.write(angleA);
 	delay(random(100, 20000)); //random between min and max milliseconds
  
  	servo_A.write(angleA);
    servo_B.write(angleB);
    servo_C.write(angleA);
    servo_D.write(angleA);
 	delay(random(100, 2000));
 
	servo_A.write(angleA);
    servo_B.write(angleA);
    servo_C.write(angleB);
    servo_D.write(angleA);
 	delay(random(100, 2000));

 	servo_A.write(angleA);
    servo_B.write(angleA);
    servo_C.write(angleA);
    servo_D.write(angleB);
	delay(random(100, 2000));
    
    
    break;

    }
}

Have you tried serial printing the range number to see if you are really getting what you intend?
Paul

Do you really want the line

 	delay(random(100, 20000)); //random between min and max milliseconds

Which will potentially stop the program for 20 seconds, perhaps maybe having you think it has stopped running?

Hey all,

so how the code is intended to work is to have the servos (4) to raise and lower in 4 time interval settings, fast - medium - slow. This is for different size color bands as the printer puts down layer by layer. The random function is an additional "setting" to get random sized bands. It all works as intended, but it stalls out after several hours (3d prints can take a long time), and the code wont reset with the reset button. The only way it starts working normally again is if I re-upload the code.

Does that make sense?

Does it stall out equally in all 4 cases? Can any one case run longer than the others?

How are the Servos powered?

what happens if range has the value of 4?

what kind of sensor is connected to A0.

may be good to specify the default case in the switch.

can't rule out a problem (memory leak) in the Servo code, although unlikely

i agree with Paul's suggestion except if there is a serious problem, the Serial I/F may die as well. I've used LEDs to indicate the code is find the last thing the code did

Hello,

The a0 is connected to a potentiometer, you turn it to get the different modes. After it stalls out, you can switch modes, leds are hooked up to each to show what case it’s on. It just doesn’t move any servos after it stalls out. The servos are the mini hobby ones sg90. I am using a ketestudio arduino clone that is supposed to have more output from the 5v pin, and should’ve enough to fire the servos as coded. Only one servo moves at one time, with a long delay between. Everything I read to try to troubleshoot it point to maybe having something to do with using the delay function instead of milis due to memory being taken up over time

Any thoughts?

huh? neither delay() nor millis() consume memory.

are you powering the servos thru the Arduino, which might cause noise on the supply that could affect the Arduino?

Do not power the servos from the Arduino. Set up a separate power supply. I have seen where an sg90 can draw 550 ma.

The data sheet for the unit is output of 2A on the 5V DC rail. It is supposed to be built to be able to drive small motors without a sep power source... supposadly. Would this cause the issue?

I played around with it and if I move the arms of the servos unconnected to power, then plug it back in the motors move back to where is stalled out?

sounds like you're using an external supply rated at 5V to drive both the arduino and servos. (still potentially a problem) (See Feeding power to Arduino)

you're not driving the servos thru the on-board regulator of the Arduino. right?

i hope you see it would be better to provide a higher voltage to Arduino Vin and let it's on-board regulator supply the processor and either power the servos directly from the external supply or thru a regulator

I think I fixed it, I deleted the constant int for the times, and put the times directly in the delay function. Seems to work fine overnight.

thank you all for the help. If I keep having issues I will use a external power source.

Here is the link to the board I am using. It is supposed to be able to handle the power directly, using the recommended power supply (9V)

1 Like

i remember a project where our code would break on a particular unit. had the unit shipped back from san diego and starting investigating.

came in one morning and it was still running. sent out emails. came back 5 mins later and it had broken.

i'd be very surprised if you fixed by the change you described

You would have to look at the compiled code to see if there is any difference.

If you find the approach you have taken is indeed successful it would be important to switch back to the const int version of the code to see if it breaks again.

If you can turn the problem on and off with argument for delay(), then you have possibly discovered some sort of compiler bug which deserves further investigation.

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