I have a program that executes a while loop when the expression (capture < frames) is true. It works fine if the variable frames is greater than four, but for anything less is always captures 4 frames. Here is my code. I may have put something in there that is causing this error, but I can not find the issue. Any help or suggestions are much appreciated.
//while loop to implement equivalent time sampling at user defined parameters
while(capture < frames)
{
//if statement to capture first image at 0 EST
if(sample == 0)
{
//initializes time at current mS of program
currentMillis = millis();
previousMillis = currentMillis;
//while loop to keep currentMillis synced with millis
while (currentMillis - previousMillis < offTime)
{
currentMillis = millis();
}
//while loop that turns on DUTsig and triggers camera with equivalent time delay (sample)
while (currentMillis - previousMillis >= offTime)
{
//turns on DUT and camera sync to capture first image
previousMillis = currentMillis; //resets previousMillis to currentMillis
PORTB = B00000011;
_delay_us(1);
PORTB &= ~(1 << syncIn);
++capture;
sample += EST; //increments sample by the equivalent sampling time each cycle
}
//while loop to keep currentMillis synced with millis
while (currentMillis - previousMillis < onTime)
{
currentMillis = millis();
}
//while loop to turn DUTsig off when on time is timed out
while (currentMillis - previousMillis >= onTime)
{
previousMillis = currentMillis; //resets previousMillis to currentMillis
PORTB &= ~(1 << DUTsig);
}
}
//if statement for accurate 1 microsecond delay
if(sample == 1)
{
//while loop to keep currentMillis synced with millis
while (currentMillis - previousMillis < offTime)
{
currentMillis = millis();
}
//while loop that turns on DUTsig and triggers camera with equivalent time delay (sample)
while (currentMillis - previousMillis >= offTime)
{
previousMillis = currentMillis; //resets previousMillis to currentMillis
PORTB |= (1 << DUTsig); //writes DUTsig high
_delay_us(.82); //delays syncIn by an additional 1 to create an accurate equivalent time delay
PORTB |= (1 << syncIn); //writes syncIn high
_delay_us(1); //holds syncIn high for 1 microsecond
PORTB &= ~(1 << syncIn); //writes syncIn low
++capture; //increments capture to show number of frames that have been taken
sample += EST;
}
//while loop to keep currentMillis synced with millis
while (currentMillis - previousMillis < onTime)
{
currentMillis = millis();
}
//while loop to turn DUTsig off when on time is timed out
while (currentMillis - previousMillis >= onTime)
{
previousMillis = currentMillis; //resets previousMillis to currentMillis
PORTB &= ~(1 << DUTsig);
}
}
//if statement for accurate 2 microsecond delays
if(sample == 2)
{
//while loop to keep currentMillis synced with millis
while (currentMillis - previousMillis < offTime)
{
currentMillis = millis();
}
//while loop that turns on DUTsig and triggers camera with equivalent time delay (sample)
while (currentMillis - previousMillis >= offTime)
{
previousMillis = currentMillis; //resets previousMillis to currentMillis
PORTB |= (1 << DUTsig); //writes DUTsig high
_delay_us(1.82); //delays syncIn by an additional 2 to create an accurate equivalent time delay
PORTB |= (1 << syncIn); //writes syncIn high
_delay_us(1); //holds syncIn high for 1 microsecond
PORTB &= ~(1 << syncIn); //writes syncIn low
++capture; //increments capture to show number of frames that have been taken
sample += EST;
}
//while loop to keep currentMillis synced with millis
while (currentMillis - previousMillis < onTime)
{
currentMillis = millis();
}
//while loop to turn DUTsig off when on time is timed out
while (currentMillis - previousMillis >= onTime)
{
previousMillis = currentMillis; //resets previousMillis to currentMillis
PORTB &= ~(1 << DUTsig);
}
}
//if statement for delays in microseconds up to 16000
if(sample >= 3 && sample <= 15999)
{
//while loop to keep currentMillis synced with millis
while (currentMillis - previousMillis < offTime)
{
currentMillis = millis();
}
//while loop that turns on DUTsig and triggers camera with equivalent time delay (sample)
while (currentMillis - previousMillis >= offTime)
{
previousMillis = currentMillis; //resets previousMillis to currentMillis
PORTB |= (1 << DUTsig); //writes DUTsig high
_delay_us(.37); //correction delay
delayMicroseconds(sample); //delays by residual amount of uS after millisecond delay
PORTB |= (1 << syncIn); //writes syncIn high
_delay_us(1); //holds syncIn high for 1 microsecond
PORTB &= ~(1 << syncIn); //writes syncIn low
++capture; //increments capture to show number of frames that have been taken
sample += EST;
}
//while loop to keep currentMillis synced with millis
while (currentMillis - previousMillis < onTime)
{
currentMillis = millis();
}
//while loop to turn DUTsig off when on time is timed out
while (currentMillis - previousMillis >= onTime)
{
previousMillis = currentMillis; //resets previousMillis to currentMillis
PORTB &= ~(1 << DUTsig);
}
}
}
}
//while loop that turns on DUTsig and triggers camera with equivalent time delay (sample)
while (currentMillis - previousMillis >= offTime)
{
//turns on DUT and camera sync to capture first image
previousMillis = currentMillis; //resets previousMillis to currentMillis
PORTB = B00000011;
_delay_us(1);
PORTB &= ~(1 << syncIn);
++capture;
sample += EST; //increments sample by the equivalent sampling time each cycle
}
Just two things that caught my eye. Possibly not the cause of your problems.
What do you mean by that is not how you use millis? I essentially used the blinkwithoutdelay program, but fit it to my needs. That particular line is just to keep my variable currentMillis updated to millis(). I may have used it wrong, but that part is working as far as I can tell. Also my full code is too long to post here. It gave an error of too many characters. What I posted is the bulk of my program. I do have some more while loops and if statements to continue delaying at the variable sample. I have included those below. the first code and this code makes up my loop.
//if statement for delays over 16000 uS
if(sample >= 16000)
{
// if statement to delay in milliseconds
if(sample - uSdelay == 0)
{
//while loop to keep currentMillis synced with millis
while (currentMillis - previousMillis < offTime)
{
currentMillis = millis();
}
//while loop that turns on DUTsig and triggers camera with equivalent time delay (sample)
while (currentMillis - previousMillis >= offTime)
{
previousMillis = currentMillis; //resets previousMillis to currentMillis
PORTB |= (1 << DUTsig); //writes DUTsig high
delay(mSdelay); //delays the mS amount for each whole millisecond
PORTB |= (1 << syncIn); //writes syncIn high
_delay_us(1); //holds syncIn high for 1 microsecond
PORTB &= ~(1 << syncIn); //writes syncIn low
++capture; //increments capture to show number of frames that have been taken
sample += EST;
}
//while loop to keep currentMillis synced with millis
while (currentMillis - previousMillis < onTime)
{
currentMillis = millis();
}
//while loop to turn DUTsig off when on time is timed out
while (currentMillis - previousMillis >= onTime)
{
previousMillis = currentMillis; //resets previousMillis to currentMillis
PORTB &= ~(1 << DUTsig);
}
}
//if statement for accurate 1 microsecond delays
if(sample - uSdelay == 1)
{
//while loop to keep currentMillis synced with millis
while (currentMillis - previousMillis < offTime)
{
currentMillis = millis();
}
//while loop that turns on DUTsig and triggers camera with equivalent time delay (sample)
while (currentMillis - previousMillis >= offTime)
{
previousMillis = currentMillis; //resets previousMillis to currentMillis
PORTB |= (1 << DUTsig); //writes DUTsig high
delay(mSdelay); //delays by whole milliseconds
_delay_us(.82); //delays syncIn by an additional 1 to create an accurate equivalent time delay
PORTB |= (1 << syncIn); //writes syncIn high
_delay_us(1); //holds syncIn high for 1 microsecond
PORTB &= ~(1 << syncIn); //writes syncIn low
++capture; //increments capture to show number of frames that have been taken
sample += EST;
}
//while loop to keep currentMillis synced with millis
while (currentMillis - previousMillis < onTime)
{
currentMillis = millis();
}
//while loop to turn DUTsig off when on time is timed out
while (currentMillis - previousMillis >= onTime)
{
previousMillis = currentMillis; //resets previousMillis to currentMillis
PORTB &= ~(1 << DUTsig);
}
}
//if statement for accurate 2 microsecond delays
if(sample - uSdelay == 2)
{
//while loop to keep currentMillis synced with millis
while (currentMillis - previousMillis < offTime)
{
currentMillis = millis();
}
//while loop that turns on DUTsig and triggers camera with equivalent time delay (sample)
while (currentMillis - previousMillis >= offTime)
{
previousMillis = currentMillis; //resets previousMillis to currentMillis
PORTB |= (1 << DUTsig); //writes DUTsig high
delay(mSdelay); //delays by whole milliseconds
_delay_us(1.82); //delays syncIn by an additional 1 to create an accurate equivalent time delay
PORTB |= (1 << syncIn); //writes syncIn high
_delay_us(1); //holds syncIn high for 1 microsecond
PORTB &= ~(1 << syncIn); //writes syncIn low
++capture; //increments capture to show number of frames that have been taken
sample += EST;
}
//while loop to keep currentMillis synced with millis
while (currentMillis - previousMillis < onTime)
{
currentMillis = millis();
}
//while loop to turn DUTsig off when on time is timed out
while (currentMillis - previousMillis >= onTime)
{
previousMillis = currentMillis; //resets previousMillis to currentMillis
PORTB &= ~(1 << DUTsig);
}
}
//if statement for delays with both milliseconds and microseconds
if(sample >= accdelay)
{
//while loop to keep currentMillis synced with millis
while (currentMillis - previousMillis < offTime)
{
currentMillis = millis();
}
//while loop that turns on DUTsig and triggers camera with equivalent time delay (sample)
while (currentMillis - previousMillis >= offTime)
{
previousMillis = currentMillis; //resets previousMillis to currentMillis
PORTB |= (1 << DUTsig); //writes DUTsig high
delay(mSdelay); //delays by whole milliseconds
delayMicroseconds(sample-uSdelay); //delays by residual amount of uS after millisecond delay
PORTB |= (1 << syncIn); //writes syncIn high
_delay_us(1); //holds syncIn high for 1 microsecond
PORTB &= ~(1 << syncIn); //writes syncIn low
++capture; //increments capture to show number of frames that have been taken
sample += EST;
}
//while loop to keep currentMillis synced with millis
while (currentMillis - previousMillis < onTime)
{
currentMillis = millis();
}
//while loop to turn DUTsig off when on time is timed out
while (currentMillis - previousMillis >= onTime)
{
previousMillis = currentMillis; //resets previousMillis to currentMillis
PORTB &= ~(1 << DUTsig);
}
}
}
Then there is no need for the while or an if construction. Just use the functional statements as is.
If this runs once:
while (currentMillis - previousMillis >= offTime)
{
//turns on DUT and camera sync to capture first image
previousMillis = currentMillis; //resets previousMillis to currentMillis
PORTB = B00000011;
_delay_us(1);
PORTB &= ~(1 << syncIn);
++capture;
sample += EST; //increments sample by the equivalent sampling time each cycle
}
then it is equivalent to this:
PORTB = B00000011;
_delay_us(1);
PORTB &= ~(1 << syncIn);
++capture;
sample += EST; //increments sample by the equivalent sampling time each cycle
The basics of your program; I've added >> for comments and they assume that EST equals 1. Do you now see why we want complete programs; we have to assume something. We also have no idea where you reset any of those variables (and if you indeed do).
while (capture < frames)
{
if (sample == 0)
{
do something and increment capture and sample
}
>> sample is now either 0 or 1
>> capture is now either 0 or 1
if (sample == 1)
{
do something and increment capture and sample
}
>> sample is now either 0 or 2
>> capture is now either 0 or 2
if (sample == 2)
{
do something and increment capture and sample
}
>> sample is now either 0 or 3
>> capture is now either 0 or 3
if (sample >= 3 && sample <= 15999)
{
do something and increment capture and sample
}
>> sample is now either 0 or 4
>> capture is now either 0 or 4
}
Your while (capture < frames) contains 4 steps that each increment capture. So the minimum value of capture after one iteration is 4 and you will have taken 4 photos.
Thank you sterretje! I would have posted all of my code, but the forum would not allow me too. I apologize for that. You are right about the four steps. I took out the ++capture and and sample += EST from each while loop (currentMillis - previousMillis >= offTime) and moved it to the very end of my first while loop (capture < frames) and it fixed the problem. I do apologize for all of the confusion.