Hi All, very much a newbie with this stuff so sorry if some of your tech help goes over my head. i am trying to achieve a timeline of 8 outputs triggering at various intervals and various times in a timeline, sometimes an output may need to be triggered several times on the same timeline.
this idea/project is to try to control an array of air rams and solenoids in a timed sequence, then delay then repeat the sequence, etc etc.
as i mentioned complete newbie and i've just started by playing around with 4 outputs to LED's using millis, but not sure how i can tell a certain output to come on at a certain time of the time line (i.e not triggered from time line Zero). i've attached my first effort and also a drawing to give you a visual on what i'm trying to achieve just in case my explanation is a little rambling.
// These variables store the flash pattern
// and the current state of the LED
int ledPin1 = 10; // the number of the LED pin
int ledState1 = LOW; // ledState used to set the LED
unsigned long previousMillis1 = 0; // will store last time LED was updated
long OnTime1 = 1000; // milliseconds of on-time
long OffTime1 = 9000; // milliseconds of off-time
int ledPin2 = 11; // the number of the LED pin
int ledState2 = LOW; // ledState used to set the LED
unsigned long previousMillis2 = 0; // will store last time LED was updated
long OnTime2 = 2000; // milliseconds of on-time
long OffTime2 = 8000; // milliseconds of off-time
int ledPin3 = 12; // the number of the LED pin
int ledState3 = LOW; // ledState used to set the LED
unsigned long previousMillis3 = 0; // will store last time LED was updated
long OnTime3 = 3000; // milliseconds of on-time
long OffTime3 = 7000; // milliseconds of off-time
int ledPin4 = 13; // the number of the LED pin
int ledState4 = LOW; // ledState used to set the LED
unsigned long previousMillis4 = 0; // will store last time LED was updated
long OnTime4 = 4000; // milliseconds of on-time
long OffTime4 = 6000; // milliseconds of off-time
void setup()
{
// set the digital pin as output:
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
pinMode(ledPin4, OUTPUT);
}
void loop()
{
// check to see if it's time to change the state of the LED
unsigned long currentMillis = millis();
if((ledState1 == HIGH) && (currentMillis - previousMillis1 >= OnTime1))
{
ledState1 = LOW; // Turn it off
previousMillis1 = currentMillis; // Remember the time
digitalWrite(ledPin1, ledState1); // Update the actual LED
}
else if ((ledState1 == LOW) && (currentMillis - previousMillis1 >= OffTime1))
{
ledState1 = HIGH; // turn it on
previousMillis1 = currentMillis; // Remember the time
digitalWrite(ledPin1, ledState1); // Update the actual LED
}
if((ledState2 == HIGH) && (currentMillis - previousMillis2 >= OnTime2))
{
ledState2 = LOW; // Turn it off
previousMillis2 = currentMillis; // Remember the time
digitalWrite(ledPin2, ledState2); // Update the actual LED
}
else if ((ledState2 == LOW) && (currentMillis - previousMillis2 >= OffTime2))
{
ledState2 = HIGH; // turn it on
previousMillis2 = currentMillis; // Remember the time
digitalWrite(ledPin2, ledState2); // Update the actual LED
}
if((ledState3 == HIGH) && (currentMillis - previousMillis3 >= OnTime3))
{
ledState3 = LOW; // Turn it off
previousMillis3 = currentMillis; // Remember the time
digitalWrite(ledPin3, ledState3); // Update the actual LED
}
else if ((ledState3 == LOW) && (currentMillis - previousMillis3 >= OffTime3))
{
ledState3 = HIGH; // turn it on
previousMillis3 = currentMillis; // Remember the time
digitalWrite(ledPin3, ledState3); // Update the actual LED
}
if((ledState4 == HIGH) && (currentMillis - previousMillis4 >= OnTime4))
{
ledState4 = LOW; // Turn it off
previousMillis4 = currentMillis; // Remember the time
digitalWrite(ledPin4, ledState4); // Update the actual LED
}
else if ((ledState4 == LOW) && (currentMillis - previousMillis4 >= OffTime4))
{
ledState4 = HIGH; // turn it on
previousMillis4 = currentMillis; // Remember the time
digitalWrite(ledPin4, ledState4); // Update the actual LED
}
}
Instead of just looking at the led state to decide which time to use for the next interval, you need an array of the on/off times for each of the waveforms, and a variable which increments for each edge (so you know the index next value to use from the array).
When you detect an edge with the millis() logic, you need to toggle the output and move to the next element in the array. When you reach the end of the array, reset the index back to zero.
Also, if you want to keep the waveforms “in step” with respect to each other and not drift, you need to do this to set the previous time...
previousMillis1 = previousMillis1 + onOffTime1;
Just using currentMillis is not good enough. It doesn’t consider what happens if the current time has ticked slightly past the required on/off time. When that happens with the supplied code you introduce a minuscule random error with each edge, and over time these errors add up, but differently for each waveform giving drift.
This is very important but regrettably then reference guide for using millis() doesn’t mention or explain this.
#define SIZE1 4
unsigned long onOffTimes1[SIZE1] { 100, 200, 300, 400 };
int index1 = 0;
if(currentMillis - onOffTimes1[index1] >= previousMillis1)
{
ledState1 = !ledState1; // Toggle it
digitalWrite(ledPin1, ledState1); // Update the actual LED
previousMillis1 += onOffTimes1[index1]; // Remember the time
index1++; // Next on/off time
if (index1 >= SIZE1) index1 = 0;
}
Repeat for each of your waveforms.
Edit: Oh, and if you want a different start offset for each waveform....
#define SIZE1 4
unsigned long interval1 = 50; // start offset
unsigned long onOffTimes1[SIZE1] { 100, 200, 300, 400 };
int index1 = 0;
if(currentMillis - interval1 >= previousMillis1)
{
ledState1 = !ledState1; // Toggle it
digitalWrite(ledPin1, ledState1); // Update the actual LED
previousMillis1 += interval1; // Remember the time
index1++; // Next on/off time
if (index1 >= SIZE1) index1 = 0;
interval1 = onOffTimes[index1];
}
thanks pcbbc for the quick reply. Sorry most has gone over my head because of my inexperience, but i'll try getting my head around to make that code you suggest work
getting errors with the 'if' statement so i'll have to google and read up further so i get grasp your comments more clearly.
phil91:
thanks pcbbc for the quick reply. Sorry most has gone over my head because of my inexperience, but i'll try getting my head around to make that code you suggest work
getting errors with the 'if' statement so i'll have to google and read up further so i get grasp your comments more clearly.
Which one? What’s the error?
The supplied code is just a snippet supplied as an example to get you started and wasn’t tested. There may be minor errors or typos despite me checking it several times.
As you’ve already seen/started, explore two outputs, and figure it out, then move to an array of the outputs & timer values, which will shrink your code significantly, and reduce the chance of cut & paste typos.
You may consider a struct to contain the details of each output, which will also,let you organise your code better, and add readability in the process.
Hi Guys i did manage to find this code somewhere on the forum which has helped me be able to set TIME ON and TIME OFF periods of 4 outputs to LEDS.
what i'd ideally like to do and help with would be rather than say having output 1 FLASH (EVERY 5 seconds) or whatever the time period is set to,be able to make the code run so when the on period is reached in the timeline (say 5 sec point) then that output will go on for the designated PERIOD time (1sec), it dont really want that output to flash EVERY 5 seconds for 1 second, would like it to flash for 1 second at the 5 second point of my loop/(timeline). Doing this over all the output channels at various points along the timeline.
So summary trying to make LED's come on and off at certain points for certain lengths of time (sometime the same output may need to be ON a few times during the timeline), then after the time line peroid (example say 40 seconds) has passed the whole scenario starts again.
//blink 4 LEDs, each with different periods on/off