i am currently writing a code where i intend to control the execution time for each statement in an if else statement,say 1ms for 'if' statement and 1ms for 'else' statement.I can use micros() and millis() to see how much time it takes for each execution but wondering is it possible to actually use micros() or some other function to control the execution time without interfering the hardware.Any suggestion will be of great help.
Thanks
wondering is it possible to actually use micros() or some other function to control the execution time
No. The code will take exactly as long as it needs to execute, regardless of your desires.
is it possible to actually use micros() or some other function to control the execution time without interfering the hardware.
Have a look at the BlinkWithoutDelay example in the IDE. It uses millis() to control the timing of LED blinking, The same principle can be used with micros() for shorter periods.
@UKHeliBob
thanks i am checking the BlinkWithoutDelay right now
BlinkWithoutDelay code actually does not change the execution time of any statement.It gives a condition where it executes the statement when it satisfies the timer "if(currentMillis - previousMillis >= interval)".What i want is to change the statement execution time itself.Probably PaulS is right.I have to try an alternate way.
Have another read of reply #1
@AWOL yes i read that,that is why i am trying another way so as not to depend on statement execution time.Thanks
bikas:
BlinkWithoutDelay code actually does not change the execution time of any statement.It gives a condition where it executes the statement when it satisfies the timer "if(currentMillis - previousMillis >= interval)".What i want is to change the statement execution time itself.Probably PaulS is right.I have to try an alternate way.
If I gave you a closed box with an LED blinking on top of it would you know whether the program instructions driving the LED were running fast or slow or whether clever programming was being used to create the effect ? Would it matter which was being used ?
If you explain why you want you do what you describe we may be able to give more help.
bikas:
@AWOL yes i read that,that is why i am trying another way so as not to depend on statement execution time.Thanks
Using the BWOD principle, perhaps.
@UKHeliBob,sorry if i sound rude here.Below i posted my code,its a small part i wrote now for discussion since the actual code will look messy.What i am trying to do was to generate a pulse of five blocks with ON and OFF depending on the value of 'm'.Below code will have 'ON' every five loop.I expected each pulse of equal length which i can manipulate for PWM later on.Using micros() i found that the 'LOW' takes less time than 'HIGH'(here its PORTB=32 for pin 13).And everytime i changes the 'm' the frequency also changes which i don't want.I am not sure why its happening.
void setup() {
Serial.begin(9600);
DDRB = DDRB | B00111110; // portB manipulation,pin 8-13
}
void loop() {
for (int k=0;k<5;k++){
int m=k%5;
if(m>3){
PORTB = 32;
delay(1000);
}
else {
PORTB=LOW;
delay(1000);
}
}
}
In your code k will have a value of 0, 1, 2, 3 or 4 (5 values)
When you do k % 5 you will get values of 0, 1, 2, 3 or 4 (5 values)
When you test if m > 3 it will be true for 1 value and false for 4 values. No wonder the HIGH/LOW ratio is not even
i am talking about individual 'HIGH' and 'LOW' here.The four 'LOW' here together wont have same width as one 'HIGH' offcourse but i expected EACH 'LOW' and 'HIGH' state to have same time width.Suppose i have 100ms time period and in the above code my 'LOW' was supposed to take 80ms(20ms for each 'LOW') and 20ms for 'HIGH'.But i found that is not the case.First time 'LOW' was very small and the 'HIGH' also has different period.Sorry for not clarifying properly
The demo several things at a time is an extended example of BWoD. The technique works just as well with micros().
If you want consistent timing this sytem works very well and is unaffected by small changes in the code that runs at the appointed times.
We could probably give more useful advice if you explain what your code is intended to control.
...R
@Robin2,below is my full code with explanation,AWOL had earlier helped me in this code and it worked perfectly fine and now i am extending it to use for PWM.Problem occured when i added the for loop at the bottom to control 'HIGH' pulse width.I am checking the start time to end time with micros() for PORTB for HIGH and LOW with each 'm' and its not satisfactory.
/* This sketch is used to blink LEDs based on the input from the terminal.
For example,
1000,1,0,0,0,1,
is entered on terminal,where each input is written and then printed after ENTER command from the keyboard.
After giving the input from terminal the SPACE bar is used which will ask for number of patterns(or rows) to
start the blinking process.Here one row is given hence '1' should be entered.
The above example will blink the first and fifth LED for 1000msec.
*/
int x1;
int i;
int j;
char byteRead;
/* Initialize the array,the number columns are constant but the rows can be changed */
int sunsensor_pattern[9][6]={{0,0,0,0,0,0},
{0,0,0,0,0,0},
{0,0,0,0,0,0},
{0,0,0,0,0,0},
{0,0,0,0,0,0},
{0,0,0,0,0,0},
{0,0,0,0,0,0},
{0,0,0,0,0,0},
{0,0,0,0,0,0}};
void setup() {
// put your setup code here, to run once:
// Turn the Serial Protocol ON and initialise x1 variables.
Serial.begin(9600);
x1=0;
i=0;
j=0;
DDRB = DDRB | B00111110; //port manipulation pin 8-13
}
void loop() {
// put your main code here, to run repeatedly:
while(Serial.available()){
integer_input();
}
}
void integer_input(){
/* read the most recent byte */
byteRead = Serial.read();
//listen for numbers between 0-9
if(byteRead>47 && byteRead<58){
//number found and stored in x1
x1=(x1*10)+(byteRead-48);
}
/*Checks the enter sign (byte code 13)
to calculate the answer and send it back to the
serial monitor screen*/
if(byteRead==13){
/*stores each elements of a row */
sunsensor_pattern[i][j]=x1;
/* prints each elements of row */
if(j<6){
Serial.print(sunsensor_pattern[i][j]);
Serial.print(",");
/* Reset the variables for the next round */
x1=0;
j++;
/*prints each row on separate line*/
if(j==6){
i++;
j=0;
Serial.println();
}
}
else{
Serial.println();
}
}
/* Checks the space bar to start the blinking process */
else if (byteRead==32){
LED_ON();
}
else {
Serial.print("");
}
}
void LED_ON(){
// put your main code here, to run repeatedly:
Serial.print(F("number of patterns: ")); /* each row of array has its own LED ON pattern */
delay(1500);
int x = Serial.parseInt();
Serial.print(x);
Serial.println();
delay(2000);
Serial.println(F("Duration LED1 LED2 LED3 LED4 LED5"));
delay(1500);
int y[6];
int byteRead = Serial.read();
while(byteRead != 27){
for (int i = 0;i<x;i++) { //number of patterns
for (int j = 0;j<6;j++){ //number of elements in each pattern
y[j]=sunsensor_pattern[i][j];
}
y[1] *=32;
y[2] *=16;
y[3] *=8;
y[4] *=4;
y[5] *=2;
/* the for loop is used to control the width of 'HIGH' pulse */
for (int k=0;k<5;k++){
int m=k%5;
if(m>0){
unsigned long startTime = micros();
Serial.println();
Serial.print("startTime = ");
Serial.println(startTime);
PORTB = ((y[1]+y[2]+y[3]+y[4]+y[5]));
unsigned long endTime = micros();
Serial.print("endTime =");
Serial.println(endTime);
Serial.println(endTime-startTime);
Serial.println();
}
else {
Serial.println();
Serial.println("LOW =");
unsigned long startTime = micros();
Serial.print("startTime = ");
Serial.println(startTime);
PORTB=LOW;
unsigned long endTime = micros();
Serial.print("endTime =");
Serial.println(endTime);
Serial.println(endTime-startTime);
Serial.println();
}
}
delay(y[0]);
}
}
}
.Suppose i have 100ms time period and in the above code my 'LOW' was supposed to take 80ms(20ms for each 'LOW') and 20ms for 'HIGH'.
If you want 80ms LOW and 20ms HIGH in each 100ms then you are going about it in a clumsy way.
Try something like this
const byte ledPin = 13;
unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
unsigned long intervals[] = {1000, 2000};
byte counter = 0;
void setup()
{
pinMode(ledPin, OUTPUT);
}
void loop()
{
currentMillis = millis();
if (currentMillis - previousMillis > intervals[counter % 2])
{
previousMillis = currentMillis;
counter ++;
digitalWrite(ledPin, !digitalRead(ledPin));
}
}
Obviously you need to adjust the intervals and may want to use micros() instead of millis()
Slightly OT hint:
if(byteRead>47 && byteRead<58){
//number found and stored in x1
x1=(x1*10)+(byteRead-48);
is much easier to read if you write it like this:
if(byteRead>= '0' && byteRead<= '9'){
//number found and stored in x1
x1=(x1*10)+(byteRead - '0');
I think this is how I would go about coding for LED on and off time using the BWoD technique
curMicros = micros();
if (ledON == false && curMicros - ledOFFmicros >= ledOFFinterval) {
PORTB = xxxx;
ledONmicros = curMicros;
ledON = true);
}
if (ledON == true && curMicros - ledONmicros >= ledONinterval) {
PORTB = yyyy;
ledOFFmicros = curMicros;
ledON = false;
}
It is probably not quite complete and it may be possible to simplify it.
By the way it is not good practice to use PORTB = nnnn because some of the PORTB pins are not at your disposal. You should use &= and |= to unset or set the specific pins you are using and leave the others unchanged. This is less of an issue with PORTB than with the other I/O ports.
...R