Is it possible to set a constant run time for running trough a loop?
I have a program to control 2 actuators. I am also toggling a pin state and reading it with a oscilloscope.
What I see in the oscilloscope is that the speed change everytime, so that means that the excecution of the code in the loop is changing all the time.
7.6KHz
6.9KHz
6.2Khz
7.0Khz
etc.
what i want is a constant speed for execution the code in the loop.
1Khz is perfect for the execution of the code.
Does anyone know if this is possible?
Robin2
January 20, 2019, 7:34pm
2
First thing is to post your program.
Second thing is to tell us about your project so we can understand the context of your questions.
In most situations where someone is relying on the time for loop() to repeat it is because the program is nor designed properly
...R
Be easy to set up Blink Without Delay so that the code runs every 0.001 second (1000 microseconds)
You can use a compare interrupt on Timer0. Toggle a pin at 1kHz:
volatile byte
bFlag;
#define TIMER_INT 0x01
const int dbgPin = 13;
bool
dbgPinState;
void setup()
{
pinMode( dbgPin, OUTPUT );
digitalWrite( dbgPin, LOW );
dbgPinState = 0;
//setup a T0 compare interrupt that will happen each millisecond (or close to it...)
OCR0A = 0xA0;
TIMSK0 |= _BV( OCIE0A );
//flag
// - ISR sets TIMER_INT
// - mainline looks for flag each pass
bFlag = 0;
}//setup
void loop()
{
//has a 1mS timer compare interrupt occurred?
if( bFlag & TIMER_INT )
{
//yes
DoTimeSensitiveThing();
//when done time-sensitive thing,
//clear the flag. I halt interrupts
//to ensure write intentions are met
noInterrupts();
bFlag &= ~TIMER_INT;
interrupts();
}//if
//do non-critical stuff here
//must ensure main loop can run at > 1kHz
//so don't use delay() etc
//.
//.
//.
}//loop
//Timer Compare interrupt handler
SIGNAL(TIMER0_COMPA_vect)
{
bFlag |= TIMER_INT;
}//timer compare int
void DoTimeSensitiveThing( void )
{
//for demo, toggle debug pin
//should toggle at 1kHz
digitalWrite( dbgPin, (dbgPinState)?HIGH:LOW );
dbgPinState ^= 1;
}//DoTimeSensitiveThing
or, a slight variant, calling the time-sensitive function from within the ISR. Toggle an LED at 4Hz:
const int dbgPin = 13;
#define BLINK 250
bool
dbgPinState;
uint16_t
cnt;
void setup()
{
pinMode( dbgPin, OUTPUT );
digitalWrite( dbgPin, LOW );
dbgPinState = 0;
//setup a T0 compare interrupt that will happen each millisecond (or close to it...)
OCR0A = 0xA0;
TIMSK0 |= _BV( OCIE0A );
cnt = BLINK;
}//setup
void loop()
{
//do non-critical stuff here
//must ensure main loop can run at > 1kHz
//so don't use delay() etc
//.
//.
//.
}//loop
//Timer Compare interrupt handler
SIGNAL(TIMER0_COMPA_vect)
{
DoTimeSensitiveThing();
}//timer compare int
//be very disciplined to keep this as short as possible
void DoTimeSensitiveThing( void )
{
//for demo, toggle debug pin
//should toggle at 4Hz
cnt--;
if( !cnt )
{
digitalWrite( dbgPin, (dbgPinState)?HIGH:LOW );
dbgPinState ^= 1;
cnt = BLINK;
}//if
}//DoTimeSensitiveThing
MorganS
January 20, 2019, 11:05pm
5
I often put this at the bottom of loop()...
const unsigned long loopPeriod = 1; //milliseconds
static unsigned long lastLoop;
while(millis()-lastLoop < loopPeriod) {
//do nothing while we wait for the fixed period to expire
}
lastLoop = millis();