The sketch below is a take on blink without delay, with two variables; hitime and lotime; that is, the time that the led pin is HIGH then LOW. Very low level application and simple code at this stage.
I notice that hitime and lotime cannot have the same value - the led will not blink according to the variable timings.
However, if hitime is incremented by 1ms (or more than lotime), the led blinks in sync with the variable timing, but not the other way round - in practice this does not affect the intended use. But I would like to know what is going on.
Serial output does not reflect the 1ms difference in the timings.
Is this behaviour something to do with the way I have written the sketch, or the way Arduino timing works?
I have been looking for a way to implement changing and multiple timing variables with various libraries without success. This seems to be the simplest application for what I want to achieve and would like to improve the sketch.
Board is a Duemilanove 168.
const int led = 13;
int lotime = 500;
int hitime = 501;
long previousMillis = 0;
long previousMillis1 = 0;
void setup(){
 pinMode(led, OUTPUT);
 Serial.begin(9600);
}
void on_off_time(){
 unsigned long currentMillis = millis();
 unsigned long currentMillis1 = millis();
 if(currentMillis - previousMillis >= lotime) {
  digitalWrite(led, HIGH);
  // save the last time you blinked the LED
  previousMillis = currentMillis1;Â
  if(currentMillis1 - previousMillis1 >= hitime) {
   // save the last time you blinked the LED
   digitalWrite(led, LOW);
   previousMillis1 = currentMillis;
  Â
   Serial.println(currentMillis);
   Serial.println(currentMillis1);
  }
 }
}
void loop(){Â
 on_off_time();
}
You do not need to dublicate variables, since they store the same vlues:
  unsigned long currentMillis = millis();
  unsigned long currentMillis1 = millis();
This way you are only wasting space on your chip, cause currentMillis and currentMillis1 are ALWAYS gonna have the same value - just use currentMillis and remove the other one.
I think you are just confusing yourself with having two timer varibles. What you actually need - is keep the record of the current LED state and use the hiTime/loTime variables accoringly. Something like this:
int led = 13;
int currentLEDState = LOW;
int hiTime = 50;
int loTime = 50;
int currentTime = 0; // it starts with a loTime, cause its off
unsigned long previousMillis;
unsigned long currentMillis;
void setup () {
  pinMode(led, OUTPUT);
}
void loop () {
  currentMillis = millis();
  if (currentMillis >= previousMillis) { // check if timeout was reached
  if (currentLEDState == LOW) {
    currentLEDState = HIGH;
    currentTime = hiTime; // set next timeout to hiTime
  }
  else {
  currentLEDState = LOW;
  currentTime = loTime; // set next timeout to loTime
  }
    previousMillis = currentMillis + currentTime;
    digitalWrite(led, currentLEDState);
  }
}
Regarding timing - I recently discovered tht having Serial in your code can make it run significantly slower.
Try removing it and see how it goes.
RowlandC:
The sketch below is a take on blink without delay, with two variables; hitime and lotime; that is, the time that the led pin is HIGH then LOW. Very low level application and simple code at this stage.
Personally I like it better to define a "ON time" and a blink "repeat period" for the timing.
Such like that for a blinker at pin-13 for a 500 ms ON time and a repeat period of 2500 ms:
// first define a suitable structure for a blinking pin
struct blinker_t {byte pin; uint16_t onTime; uint16_t cycleDuration; uint32_t cycleStartTime;};
blinker_t myBlinker={13,500,2500}; // pin-13, 500 ms ON, 2500 ms repeat period
void myBlinkerUpdate()
{
unsigned long now=millis();
if (now-myBlinker.cycleStartTime >= myBlinker.cycleDuration) myBlinker.cycleStartTime+=myBlinker.cycleDuration;
boolean isOn= (now-myBlinker.cycleStartTime < myBlinker.onTime);
digitalWrite(myBlinker.pin, isOn);
}
void setup() {
pinMode(myBlinker.pin, OUTPUT);
}
void loop() {
myBlinkerUpdate();
}
For an equal timing you would set "myBlinker.onTime=500;" and "myBlinker.cycleDuration=1000;"
Advantage: When doing so, you just need to set "myBlinker.onTime=0" to stop the pin from blinking and don't need any other fancy handling of "blinker ON" and "blinker OFF".
For clarification. Both hitime and lotime values change, one or the other, or both, as needed. The difficulty has been writing a sketch with that flexibility. I want to turn the led on and off in a more random way.
You do not need to dublicate variables, since they store the same vlues:
unsigned long currentMillis = millis();
unsigned long currentMillis1 = millis();
This way you are only wasting space on your chip, cause *currentMillis* and *currentMillis1* are ALWAYS gonna have the same value - just use *currentMillis* and remove the other one.
2) I think you are just confusing yourself with having two timer varibles. What you actually need - is keep the record of the current LED state and use the hiTime/loTime variables accoringly. Something like this:
int led = 13;
int currentLEDState = LOW;
int hiTime = 50;
int loTime = 50;
int currentTime = 0; // it starts with a loTime, cause its off
unsigned long previousMillis;
unsigned long currentMillis;
void setup () {
pinMode(led, OUTPUT);
}
void loop () {
currentMillis = millis();
if (currentMillis >= previousMillis) { // check if timeout was reached
if (currentLEDState == LOW) {
currentLEDState = HIGH;
currentTime = hiTime; // set next timeout to hiTime
}
else {
currentLEDState = LOW;
currentTime = loTime; // set next timeout to loTime
}