Is this possible in arduino? I'm building my first project. It's a traffic light simulation with seven segment display. I had everything working except for the counting part. It counts from 9-0 then executes the loop for the transition of lights. After the first count, it stops at 0 then runs the loop for the lights. Can't i run the loops simultaneously?
Benedict:
Can't i run the loops simultaneously?
Not really. But remember that loop() runs at some 100+k times a second so you can get the illusion of simultaneousness. (Unless your code is full of delay()s in which case you might need to re-think along the lines of BlinkWithoutDelay.)
edit.... This video shows how to get two things happening "simultaneously".
Can't i run the loops simultaneously
You never will however, they can be processed so they look like they are.
Show us your Code so we can see what you are doing.
See this image below (created by another member).
Is this homework?
You need to interleave the loops.
You only ever need - or use - one loop.
This loop consists of all your "lesser" loops "opened out" so that they chain from one to the other with the caveat that there is no "wait" or "delay" in any of them - they must check for conditions, act on them and immediately move on. They can be written as separate functions called one after another if it suits you though a good compiler would simply assemble them into one chain.
Here is a sketch for you to study (which deliberately does not do what I have detailed, if fact just the opposite, but should nevertheless give you some ideas on your project!):
// Pedestrian crossing lights
const int led13Pin = 13; // LED pin number
const int PgrnPin = 2;
const int PredPin = 3;
const int RgrnPin = 5;
const int RyelPin = 6;
const int RredPin = 7;
const int button1 = 10;
int led13State = LOW; // initialise the LED
int PgrnState = LOW;
int PredState = LOW;
int RgrnState = LOW;
int RyelState = LOW;
int RredState = LOW;
char bstate1 = 0;
boolean press = false;
unsigned long count1 = 0; // will store last time LED was updated
unsigned long count2 = 0;
unsigned long count3 = 0;
unsigned long count4 = 0;
unsigned long count5 = 0;
unsigned long bcount1 = 0; // button debounce timer. Replicate as necessary.
// Have we completed the specified interval since last confirmed event?
// "marker" chooses which counter to check
boolean timeout(unsigned long *marker, unsigned long interval) {
if (millis() - *marker >= interval) {
*marker += interval; // move on ready for next interval
return true;
}
else return false;
}
void setout(unsigned long *marker) {
*marker = millis(); // initialise
}
// Deal with a button read; true if button pressed and debounced is a new event
// Uses reading of button input, debounce store, state store and debounce interval.
boolean butndown(char button, unsigned long *marker, char *butnstate, unsigned long interval) {
switch (*butnstate) { // Odd states if was pressed, >= 2 if debounce in progress
case 0: // Button up so far,
if (button == HIGH) return false; // Nothing happening!
else {
*butnstate = 2; // record that is now pressed
*marker = millis(); // note when was pressed
return false; // and move on
}
case 1: // Button down so far,
if (button == LOW) return false; // Nothing happening!
else {
*butnstate = 3; // record that is now released
*marker = millis(); // note when was released
return false; // and move on
}
case 2: // Button was up, now down.
if (button == HIGH) {
*butnstate = 0; // no, not debounced; revert the state
return false; // False alarm!
}
else {
if (millis() - *marker >= interval) {
*butnstate = 1; // jackpot! update the state
return true; // because we have the desired event!
}
else
return false; // not done yet; just move on
}
case 3: // Button was down, now up.
if (button == LOW) {
*butnstate = 1; // no, not debounced; revert the state
return false; // False alarm!
}
else {
if (millis() - *marker >= interval) {
*butnstate = 0; // Debounced; update the state
return false; // but it is not the event we want
}
else
return false; // not done yet; just move on
}
default: // Error; recover anyway
{
*butnstate = 0;
return false; // Definitely false!
}
}
}
void setleds() {
digitalWrite(led13Pin, led13State);
digitalWrite(PredPin, PredState);
digitalWrite(PgrnPin, PgrnState);
digitalWrite(RredPin, RredState);
digitalWrite(RyelPin, RyelState);
digitalWrite(RgrnPin, RgrnState);
}
boolean ispress() { // One-directional read of button - sets but does not clear!
if (butndown(digitalRead(button1), &bcount1, &bstate1, 10UL )) {
press = true;
}
return(press);
}
void setup() {
Serial.begin(9600);
pinMode(led13Pin, OUTPUT);
pinMode(PgrnPin, OUTPUT);
pinMode(PredPin, OUTPUT);
pinMode(RgrnPin, OUTPUT);
pinMode(RyelPin, OUTPUT);
pinMode(RredPin, OUTPUT);
pinMode(button1, INPUT);
digitalWrite(button1,HIGH); // internal pullup all versions
press = false;
Serial.println("Starting ...");
}
void loop() {
// All red phase
RredState = HIGH;
RyelState = LOW;
RgrnState = LOW;
PredState = HIGH;
PgrnState = LOW;
setleds();
Serial.println("Red phase");
setout(&count3);
while (!timeout(&count3, 3000UL )) {
ispress(); // Check on the button
}
// Road Green
RredState = LOW;
RyelState = LOW;
RgrnState = HIGH;
PredState = HIGH;
PgrnState = LOW;
setleds();
Serial.println("Road green");
setout(&count3);
while (!timeout(&count3, 8000UL )) { // Reasonable time on green
ispress(); // Check on the button
}
Serial.println("Green stale, wait on button");
while ( press == false ) // Now wait for the button
{
if (timeout(&count2, 300UL )) {
if (led13State == LOW) {
led13State = HIGH;
}
else {
led13State = LOW;
}
digitalWrite(led13Pin, led13State);
}
ispress();
}
led13State = LOW;
digitalWrite(led13Pin, led13State);
Serial.println("Button sensed");
setout(&count3);
while (!timeout(&count3, 4000UL )) { // Do not respond immediately!
}
// Road Yellow
RredState = LOW;
RyelState = HIGH;
RgrnState = LOW;
PredState = HIGH;
PgrnState = LOW;
setleds();
Serial.println("Road yellow");
setout(&count3);
while (!timeout(&count3, 5000UL )) {
}
// Road Red
RredState = HIGH;
RyelState = LOW;
RgrnState = LOW;
PredState = HIGH;
PgrnState = LOW;
setleds();
Serial.println("Road red");
setout(&count3);
while (!timeout(&count3, 3000UL )) {
}
// Walk Green
RredState = HIGH;
RyelState = LOW;
RgrnState = LOW;
PredState = LOW;
PgrnState = HIGH;
setleds();
press = false;
Serial.println("Walk");
setout(&count3);
while (!timeout(&count3, 6000UL )) {
}
// Flash Don't Walk
RredState = HIGH;
RyelState = LOW;
RgrnState = LOW;
PgrnState = LOW;
Serial.println("Flash Don't Walk");
setout(&count3);
while (!timeout(&count3, 7000UL )) {
if (timeout(&count2, 500UL )) {
if (PredState == LOW) {
PredState = HIGH;
}
else {
PredState = LOW;
}
setleds();
}
ispress(); // Check on the button
}
}
void oldloop() {
// Toggle LED if button debounced
if (butndown(digitalRead(button1), &bcount1, &bstate1, 10UL )) {
if (led13State == LOW) {
led13State = HIGH;
}
else {
led13State = LOW;
}
digitalWrite(led13Pin, led13State);
}
// Act if the latter time (ms) has now passed on this particular counter,
if (timeout(&count2, 300UL )) {
if (PgrnState == LOW) {
PgrnState = HIGH;
}
else {
PgrnState = LOW;
}
digitalWrite(PgrnPin, PgrnState);
}
if (timeout(&count3, 600UL )) {
if (PredState == LOW) {
PredState = HIGH;
}
else {
PredState = LOW;
}
digitalWrite(PredPin, PredState);
}
if (timeout(&count4, 400UL )) {
if (RgrnState == LOW) {
RgrnState = HIGH;
}
else {
RgrnState = LOW;
}
digitalWrite(RgrnPin, RgrnState);
}
if (timeout(&count5, 800UL )) {
if (RredState == LOW) {
RredState = HIGH;
}
else {
RredState = LOW;
}
digitalWrite(RredPin, RredState);
}
}
