for a homework assignment i am making a stoplight junction.
It will have 2 separate cycles [Day - Nighttime].
While at daytime the sketch will do a full cycle every 2 minutes.
[ In the test sketch as it is right now this is shorter. ]
While at night time the car lane will be showing green light,
until a biker shows up on the bicycle lane.
The LDR sensor will detect as well the day or night time,
and the faint light from bicycles.
Once a biker shows up the cycle gets activated.
But to make sure the next biker will not immediately trigger
the next cycle, I want to implement a timeout, so the cars
have time to pass also. After this, when no new bikers,
the lights go back to the default night time cycle as long it is night.
The problem: I have followed the steps of a few tutorials that
let me set up 2 variables, 1 for the start value and 1 for the current milliseconds.
Then they sell me to use if (curMillis - preMillis > interval) {} else {}
But then nothing happens. Bikers cycle does not even gets triggered.
Of cause if (curMillis - preMillis < interval) {} else {}
does gets triggered, but then it will not use the timeout and straightly activates
the bike cycle again if a new biker is present.
What do i need to do in order to get this timeout function to work ?
Many thanks in advance for the help. Much appreciated!.
dougp:
That code looks like it would fit in a post.
It does....
// Stoplight assignment
// Educational lesson 7
const int cl[] = {
2,
3,
4
};
const int bl[] = {
8,
9,
10
};
const byte sensor = A5;
// Delay timers for light stages.
// Together in a loop of 2 minutes.
unsigned long greenLightTimerBikes = 5000; //20000;
unsigned long greenLightTimerCars = 5000; //90000;
unsigned long redLightTimerCars = 5000; //20000;
unsigned long orangeLightBlinker = 350;
unsigned long switchDelay = 3000;
// Give cars time to pass on the night cycle.
unsigned long preMillis = 0; // Store last value.
unsigned long curMillis = millis();
long interval = 60000;
int active = 0; // STORE: If activated or not.
int threshold = 600; // value when concidered evening.
int BGLight = 300; // Counts for background lights.
int sState = 0;
void setup() {
Serial.begin(9600);
// Initialize car lights.
for (int i = cl[0]; i < cl[2] + 1; i++) {
pinMode(i, OUTPUT);
}
// Initialize bike lights
for (int i = bl[0]; i < bl[2] + 1; i++) {
pinMode(i, OUTPUT);
}
// Start with both lights red.
digitalWrite(cl[0], HIGH);
digitalWrite(bl[0], HIGH);
}
void loop() {
sState = analogRead(sensor);
Serial.println("-----------------------------------");
Serial.print("sState = ");
Serial.println(sState);
Serial.print("Threshold = ");
Serial.println(threshold);
Serial.print("BGLights = ");
Serial.println(BGLight);
Serial.println("-----------------------------------");
if (active == 1) return;
if (sState > threshold) {
return daylightRoutine();
} else {
return nightlightRoutine();
}
}
/////////////////////////////////////////////////////
////////////////// DAY LIGHT ROUTINE ////////////////
/////////////////////////////////////////////////////
void daylightRoutine() {
active = 1;
Serial.println("-----------------------------------");
Serial.println("DAYLIGHT ROUTINE");
Serial.println("-----------------------------------");
// Turn red light off if active.
if (digitalRead(cl[0]) == HIGH) digitalWrite(cl[0], LOW);
// Set green light for cars active.
digitalWrite(cl[2], HIGH);
// Set red light for bikers.
digitalWrite(bl[0], HIGH);
delay(greenLightTimerCars);
// Deactivate green light for cars.
digitalWrite(cl[2], LOW);
// Start red light warning for the cars.
for (int i = 0; i < 5; i++) {
digitalWrite(cl[1], HIGH);
delay(orangeLightBlinker);
digitalWrite(cl[1], LOW);
delay(orangeLightBlinker);
}
// Set cars to have a red light.
digitalWrite(cl[0], HIGH);
delay(switchDelay);
// Set green light for bikers.
digitalWrite(bl[0], LOW);
digitalWrite(bl[2], HIGH);
delay(greenLightTimerBikes);
digitalWrite(bl[2], LOW);
// Start red light warning for the bikers.
for (int i = 0; i < 5; i++) {
digitalWrite(bl[1], HIGH);
delay(orangeLightBlinker);
digitalWrite(bl[1], LOW);
delay(orangeLightBlinker);
}
// Set red light for bikers.
digitalWrite(bl[0], HIGH);
delay(switchDelay);
// deactivate the system
digitalWrite(cl[0], LOW);
active = 0;
return loop();
}
/////////////////////////////////////////////////////
///////////////// NIGHT LIGHT ROUTINE ///////////////
/////////////////////////////////////////////////////
void nightlightRoutine() {
active = 1;
Serial.println("-----------------------------------");
Serial.println("NIGHTLIGHT ROUTINE");
Serial.println("-----------------------------------");
digitalWrite(cl[0], LOW);
digitalWrite(cl[2], HIGH);
Serial.println(curMillis - preMillis);
if (curMillis - preMillis >= interval) {
preMillis = curMillis;
// If the sensors value is lower
// then the background noise.
if (sState <= BGLight) {
active = 0;
return loop();
}
digitalWrite(cl[2], LOW);
for (int i = 0; i < 5; i++) {
digitalWrite(cl[1], HIGH);
delay(orangeLightBlinker);
digitalWrite(cl[1], LOW);
delay(orangeLightBlinker);
}
// Set carlane to red
digitalWrite(cl[0], HIGH);
delay(switchDelay);
// Set bikelane to green
digitalWrite(bl[0], LOW);
digitalWrite(bl[2], HIGH);
delay(greenLightTimerBikes);
digitalWrite(bl[2], LOW);
// Start red light warning for the bikers.
for (int i = 0; i < 5; i++) {
digitalWrite(bl[1], HIGH);
delay(orangeLightBlinker);
digitalWrite(bl[1], LOW);
delay(orangeLightBlinker);
}
// Set red lights for bikers.
digitalWrite(bl[0], HIGH);
delay(switchDelay);
active = 0;
return loop();
} else {
return loop();
}
}
Apart from the function being void, and thus not able to return anything in the first place, even if the function wasn't void, could the return even be a function name?
Lose the return statements. The "void" in front of the definition for the loop function literally means that it returns nothing. So having return statements in a function like that is totally missing the point.
return loop();
Again here. I think you have a fundamental misunderstanding of what return does. You just need to delete this line entirely. Since your function was called from loop, it will return to loop once it finishes. That's not what the return statement does. That's for returning values from functions.
The only language knowledge i have thus far is Javascript.
So at some times i can get a little confused to some little things that are different here.
I am use to return all functions and ending of code blocks.
I know it returns to loop automatically, just felt good to physically return it.
I shell try to dis-learn that behavior here haha.
I understand now the void problem. I am returning a value that later needs to be checked.
and as i am returning nothing, nothing will happen.
I will try out your advice in a moment and update the topic.
Haha okey, seems i did not need a timed timeout function at all.
I was simply able to do it with a simple switch and a delay for this specific sketch.
Well at least learned how to use functions now in Arduino
Cleaned it up and made it a but more modular.
// Stoplight assignment
// Educational lesson 7
const int cl[] = {2,3,4};
const int bl[] = {8,9,10};
const byte sensor = A5;
// Delay timers for light stages.
// Together in a loop of 2 minutes.
unsigned long greenLightTimerBikes = 20000; // 20 Sec green light bikers
unsigned long greenLightTimerCars = 90000; // 90 Sec green light cars
unsigned long redLightTimerCars = 20000; // 20 Sec red light cars
int orangeLightBlinker = 350; // (3500 / 5) / 2 || for 5 blinks
int switchDelay = 3000; // DELAY: to make sure the road is clear
int nightCycleDelay = 20000; // DELAY: to give cars time to pass [Night Cycle]
int active = 0; // STORE: If cycle is active
int threshold = 600; // VALUE: when concidered evening
int BGLight = 400; // VALUE: Counts for background noise [light]
int sState = 0; // PULLDOWN: sensor status
byte sLane = 0; // STORE: nightCycleDelay switch
void setup() {
// Initialize car lights.
for (int i = cl[0]; i < cl[2] + 1; i++) {
pinMode(i, OUTPUT);
}
// Initialize bike lights
for (int i = bl[0]; i < bl[2] + 1; i++) {
pinMode(i, OUTPUT);
}
// Start with both lights red.
digitalWrite(cl[0], HIGH);
digitalWrite(bl[0], HIGH);
}
void loop() {
sState = analogRead(sensor); // Current Sensor State
if (active == 1) return; // If cycle is active return
if (sState > threshold){ // Check for day or night time
daylightRoutine(); // IF: daytime do daylightRoutine
} else {
nightlightRoutine(); // IF: Nighttime do nightlightRoutine
}
}
void daylightRoutine() { // Daytime Routine
active = 1; // SET: cycle switch to active
// SET / RESET the lights for a new loop
digitalWrite(cl[0], LOW);
digitalWrite(cl[2], HIGH);
// Start the daytime cycle
delay(greenLightTimerCars);
switchLight(cl[2]);
blinkWarning(cl[1]);
switchLight(cl[0]);
delay(switchDelay);
switchLight(bl[0]);
switchLight(bl[2]);;
delay(greenLightTimerBikes);
switchLight(bl[2]);
blinkWarning(bl[1]);
switchLight(bl[0]);
delay(switchDelay);
switchLight(cl[0]);
active = 0; // SET: Deactivate cycle switch
}
void nightlightRoutine() {
active = 1; // SET: cycle switch to active
// SET / RESET the lights for a new loop
digitalWrite(cl[0], LOW);
digitalWrite(cl[2], HIGH);
// Delay the next cycle if bikers already passed
// to give cars time to pass also.
if (sLane == 1) {
delay(nightCycleDelay);
active = 0; // SET: cycle switch to active
sLane = 0; // SET: Disable switch lanes
return;
}
// Counts for background noise (light)
if (sState <= BGLight) {
active = 0; // SET: Deactivate cycle switch
return;
}
// Start the night cycle
switchLight(cl[2]);
blinkWarning(cl[1]);
switchLight(cl[0]);
delay(switchDelay);
switchLight(bl[0]);
switchLight(bl[2]);
delay(greenLightTimerBikes);
switchLight(bl[2]);
blinkWarning(bl[1]);
switchLight(bl[0]);
delay(switchDelay);
active = 0; // SET: Deactivate cycle switch
sLane = 1; // SET: Enable switch lanes
}
// Start orange light blink warning.
void blinkWarning(char vehicle) {
for (int i = 0; i < 5; i++) {
switchLight(vehicle);
delay(orangeLightBlinker);
switchLight(vehicle);
delay(orangeLightBlinker);
}
}
// Switch the led status.
void switchLight(char pin) {
byte value = digitalRead(pin);
value = !value;
digitalWrite(pin, value);
}