delay on arduino dost count time good

This is the place for all suggestions, releases and feedback regarding Milovana Hardware efforts.
Post Reply
krishpants
Explorer
Explorer
Posts: 50
Joined: Mon Mar 26, 2018 12:09 am

Re: delay on arduino dost count time good

Post by krishpants »

Can we see your code?

I can only make a guess without seeing it but the REST of your code will need some time to run also.

This will mean things will fall out of sync over time if you are only using the delay(); to create the gaps.

This can be avoided using a time comparison rather than relying on the delay function.
ToTheBalls
Explorer
Explorer
Posts: 5
Joined: Tue Aug 21, 2018 5:30 pm

Re: delay on arduino dost count time good

Post by ToTheBalls »

I know this is old but I've been playing with Arduinos for a while now on my automated venus 2000 project. Im not much of a coder, I'm learning to code with this project from scratch. But I'm good at finding other peoples code and modifying it to work the way I want :).

With my project I wanted to have the venus to change stroke speeds and lengths timed with videos like Cock Heros or PMVs. The best way I've found to do this with an Arduino is using a clock interupt that ticks every second. You'll have your code for time changes in the interupt and all the code for actions with as many delays as you like in the main loop. With this you'll always keep up with the video. I'll include an example to copy paste if anyone needs it. My understanding is limited but searching for arduino clock interupts should help with questions.
Cheers.
Spoiler: show
#include <avr/io.h>
#include <avr/interrupt.h>

volatile byte sec = 0;
volatile byte min = 0;
volatile byte hr = 0;
String col = ":";


void setup() {
Serial.begin(9600); // initialize the serial port:

//Code doesnt run until user enters a number into the serial input
Serial.println("Press a number to start"); // Promt user for number input
while (Serial.available()==0){} // Wait for user input
Serial.println("3");
delay(1000);
Serial.println("2");
delay(1000);
Serial.println("1");
delay(1000);
Serial.println("Start");

// initialize Timer1
cli(); // disable global interrupts
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B

// set compare match register to desired timer count:
OCR1A = 15624;
// turn on CTC mode:
TCCR1B |= (1 << WGM12);
// Set CS10 and CS12 bits for 1024 prescaler:
TCCR1B |= (1 << CS10);
TCCR1B |= (1 << CS12);
// enable timer compare interrupt:
TIMSK1 |= (1 << OCIE1A);
// enable global interrupts:
sei();
}

ISR(TIMER1_COMPA_vect) { //1 second clock interupt, time code goes here
sec++;
if (sec == 60)
{
sec = 0;
min++;
}
else;
if(min == 60){
min = 0;
hr++;
}

String timer = hr + col + min + col + sec;
Serial.println(timer);

//**example code below
if ((min == 0) && (sec == 10)) {
Serial.println("slow");
speed = "slow";
}

if ((min == 0) && (sec == 20)) {
Serial.println("fast");
speed = "fast";
}

if ((min == 0) && (sec == 30)) {
Serial.println("stop");
speed = "stop";
}

if((min == 0) && (sec == 35)) {
loops = "12-12";
loopExit = "stop";
}

if((min == 1) && (sec == 14)) {
loops = "";
}

if ((min == 1) && (sec == 16)) {
Serial.println("fast");
speed = "fast";
}

} //end clock interupt

void loop() {
//Your none time realted code here
//**example code below of a part of my stepper motor changing positions code.

//sequence
if ((loops == "12-12")) {
while (loops == "12-12") {
speed = "vfast";
changeSpeed();
delay(800);
if (loops != "12-12") break;
speed = "slow";
changeSpeed();
delay(500);
if (loops != "12-12") break;
}
speed = loopExit; //so it changes to loopExit speed when sequence is done
changeSpeed(); // runs a speed change function
} //end sequence

//slow
if ((speed == "slow") && (edge == true)) {
Serial.println(F("EDGE stopped"));
cs = "stop"; //cs is current speed
speed = "";
}
else if ((speed == "slow") && (edge == false))
{
if (cs == "stop") {
myStepper.step(-22); // tells the stepper how far to move and what direction
speed = ""; // sets speed to blank
cs = "slow"; // sets new current speed
delay(100); // delay is for the stepper motor changing speeds more smoothly
allStop(); // turns all the coils off the stepper motor so it doesnt overheat
Serial.println(F("stop-slow")); // the (F) wrap is used just to save memory.
}
if ((cs == "slow") && (speed == "slow")) {
Serial.println(F("Already Slow"));
speed = "";
}
if (cs == "normal") {
myStepper.step(22);
speed = "";
cs = "slow";
delay(100);
allStop();
Serial.println(F("normal-slow"));
}
if (cs == "fast") {
myStepper.step(52);
speed = "";
cs = "slow";
delay(100);
allStop();
Serial.println(F("fast-slow"));
}
}
}


Hopefully this is helpful to somebody.
Last edited by ToTheBalls on Tue Aug 20, 2019 11:40 pm, edited 5 times in total.
Bandit224
Explorer At Heart
Explorer At Heart
Posts: 338
Joined: Tue Sep 27, 2011 4:35 am
Gender: Male
Sexual Orientation: Straight

Re: delay on arduino dost count time good

Post by Bandit224 »

Clock interrupts are almost always better than built-in delays. It is not good to use delays and clock interrupts in the same code though, as they can interfere with the other's timing.
krishpants
Explorer
Explorer
Posts: 50
Joined: Mon Mar 26, 2018 12:09 am

Re: delay on arduino dost count time good

Post by krishpants »

Yes or if you want a simpler solution without clock interrupts but avoiding using the dreaded delay!...

Code: Select all


long last_switch_time = 0;
bool toggle_thing = false;
long delay_time = 5000, //(5 seconds in milliseconds)

void loop(){

// So if the time now minus the time we change it last, is greater than the delay we have set, then change it.

if ( millis() - last_switch_time > delay_time){ 
	toggle_thing = !toggle_thing; //change the thing
	last_switch_time = millis(); //now record the change as the new time to use next time.
}

MORE_CODE;     //<<<See now all this code can keep running between switching rather than everything coming to a stop with a delay();

}




User avatar
hosenguy
Explorer At Heart
Explorer At Heart
Posts: 321
Joined: Sun Jun 14, 2015 11:22 pm
Gender: Male
I am a: None of the above

Re: delay on arduino dost count time good

Post by hosenguy »

krishpants wrote: Sun Aug 18, 2019 8:39 am Yes or if you want a simpler solution without clock interrupts but avoiding using the dreaded delay!...
edited because I got interrupted the first time and was not complete.

This is the method I first learned to use. Remember that the shorter the delay the more that a timing error of the delay length is possible.
If you have a timer (this code) set and a lot of code that branches after this the shortest timer is going to be the overall code loop time. If the timer delay is several times longer than the longest overall loop time, then it is more accurate.

But now I do this. Call the system time at the start of the timer and write it to memory. Then loop main code. Upon return to timer I read the new system time and subtract the start time from it. Compare difference to the desired timer length and react. This has a similar error as the other method above but it behaves better in some situations for me.

If your timer is a tenth second or longer either method should be good. And I really should get comfortable with interrupts! :whistle:
User avatar
hosenguy
Explorer At Heart
Explorer At Heart
Posts: 321
Joined: Sun Jun 14, 2015 11:22 pm
Gender: Male
I am a: None of the above

Re: delay on arduino dost count time good

Post by hosenguy »

ToTheBalls wrote: Sat Mar 23, 2019 10:21 pm I know this is old but I've been playing with Arduinos for a while now on my automated venus 2000 project. Im not much of a coder, I'm learning to code with this project from scratch. But I'm good at finding other peoples code and modifying it to work the way I want :).

With my project I wanted to have the venus to change stroke speeds and lengths timed with videos like Cock Heros or PMVs. The best way I've found to do this with an Arduino is using a clock interupt that ticks every second. You'll have your code for time changes in the interupt and all the code for actions with as many delays as you like in the main loop. With this you'll always keep up with the video. I'll include an example to copy paste if anyone needs it. My understanding is limited but searching for arduino clock interupts should help with questions.
Cheers.
Thank you this is very helpful as I am working on a similar project. That is why I need to learn interrupts!
ToTheBalls
Explorer
Explorer
Posts: 5
Joined: Tue Aug 21, 2018 5:30 pm

Re: delay on arduino dost count time good

Post by ToTheBalls »

Hope it works out for you.

For me the clock interupt was the simplest solution but use whatever is best for your project. I needed to be able to have events running at exact times, frequently over a few hours to match with videos. So it made coding much less stressful and efficient for me to have a stopwatch code counting up on a 1 second clock interupt. That way I have a duration time that I just call event changes bases on at the exact same time the video is on and it matches perfectly. Sometimes its easier to run a sequence of event changes and I use delays in that like you see in my example code(I've updated the example to include a sequence). I'm sure its best practice to not use delays, but I think delays are fine if you're OK with any event that might get called at that time in the clock interupt having to wait. You would be aware anyway that you have a sequence running so your next clock interupt event will be at a time that shouldnt interfear with the sequence. But even if it does that single event just waits until the seqence is done, the rest of the clock interupt events arnt effected and everything carrys on running on schedule.
Post Reply

Who is online

Users browsing this forum: vvvxxx115 and 24 guests