Stoplights Project help requested~

Hello!

I’m BRAND new to the Arduino scene; programming and pretty much everything related to this but also tend to take a more complicated approach on learning. I need advice on the coding of this project. I am intentionally avoiding the use of delay; trying to learn how to use for(); and just understanding how to approach the project itself. Thanks for taking the time to help with my endeavor.

Does the below schematic actually make sense?

Design concept:

The code below only makes the lights light up based on the initial setup, should I put the timers and what not inside the if() clauses?
How would you code this? and which areas could i make loops to simplify the coding?

int pedButton = 2; //pedestrian button pin
int Light = 3; //light button pin
//the state of each light
int ledState = LOW; //street 1 green
int ledState2 = LOW; //street 1 yellow
int ledState3 = LOW; //street 1 red
int ledState4 = LOW; //street 2 green
int ledState5 = LOW; //street 2 yellow
int ledState6 = LOW; //street 2 red
long previousMillis= 0; //will store the time the led was last used
const long interval = 5000; //how long green and red will be on
const long interval2 = 2000; //how long orange will be on
const long interval3 = 500; //how long the pause between red and green will be
long totalTime = 0; //placeholder for all intervals added together
long timeOn = 0; //placeholder for timeOn
void setup() 
{
  Serial.begin(9600); //feedback for error checking
  pinMode(pedButton, INPUT);
  for (int Light = 3; Light < 11; Light++)
  {
    pinMode(Light, OUTPUT);
  }
}

void loop()
{
  //This is the setup for the first stop light. is this even needed?
  digitalWrite(3, HIGH);
  digitalWrite(4, LOW);
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);
  digitalWrite(7, LOW);
  digitalWrite(8, HIGH);
  digitalWrite(9, HIGH);
  digitalWrite(10, LOW);

  unsigned long currentMillis = millis();
  previousMillis = currentMillis;
  timeOn = currentMillis - previousMillis;
  totalTime= interval*2+interval2*2+interval3*2;

  if (currentMillis - previousMillis > totalTime)    //Saves the time last time green started to blink 
  {	
    //street1 green
    if(ledState == LOW && timeOn < interval)  //x>5S
    {	
      ledState = HIGH;
    }
    else
    {
      ledState = LOW;
    }
    digitalWrite(3, ledState);

    //street1 yellow
    if(ledState2 == LOW && timeOn > interval && timeOn < interval + interval2) //5s<x<7s
    {
      ledState2 = HIGH;
    }
    else
    {
      ledState2 = LOW;
    }
    digitalWrite(4, ledState2);

    //street1 red
    if(ledState == LOW && timeOn > interval + interval2) //7s<x
    {	
      ledState3 = HIGH;
    }
    else
    {
      ledState3 = LOW;
    }
    digitalWrite(5, ledState3);

    //street2 green
    if(ledState2 == LOW && timeOn > interval + interval2 + interval3 && timeOn < interval*2 + interval2 + interval3) //7.5s<x<12.5s
    {
      ledState4 = HIGH;
    }
    else
    {
      ledState4 = LOW;
    }
    digitalWrite(6, ledState4);

    //street2 yellow
    if(ledState == LOW && timeOn > interval*2 + interval2 + interval3 && timeOn < interval*2 + interval2*2 + interval3) //12.5s<x<14.5s
    {	
      ledState5 = HIGH;
    }
    else
    {
      ledState5 = LOW;
    }
    digitalWrite(7, ledState5);

    //street2 red
    if(ledState2 == LOW && timeOn < interval + interval2 + interval3 && timeOn > interval*2 + interval2*2 +interval3) //7.5s>x & 14.5s<x
    {
      ledState6 = HIGH;
    }
    else
    {
      ledState6 = LOW;
    }
    digitalWrite(8, ledState6);
    delay(interval3);
    }	
  }

Sorry that schematic makes no sense at all. You can o ly drive 40mA through an arduino output pin, what are those lights? You don't connect outputs together.
Likewise with the design concept diagram, I just don't get it.
Without a good hardware schematic you can't begin to write any code.

Rgr,

Here is the concept verbalized then:

We have two stoplights; one is for the flow of traffic in one direction and the other is for the flow of traffic perpendicular to that. When the first stop light is green, its other two lights are not working and the other stoplight has red lit. The first stop light will then proceed to OJ and red; after a short delay, the second stoplight will then turn green, and the red light will go out. It will then proceed to follow the same steps as the first light.

In addition I want to add a pedestrian light to allow the crossing of people parallel to the flow of traffic to the first light.

Afterwards; I want to set it to only allow the flow of peds if the button is pressed (IE: the light stays red constantly and only turns green when the parrallel flow of traffic is active and only when the button has been pressed).

does this make more sense conceptually?

Getting closer.
Is this a modle or is this for real traffic and real people?
I'd it is real you will need big lights and that takes a lot of current so you need transistors overlays to do the switching.

it is a model using LED's.

Ok now you need to work on the schematic.
On each input you wire the switch between the input pin and ground. For each light you wire a resistor in seriese with one LED to one output.

2nd attempt

Grumpy_Mike:
Ok now you need to work on the schematic.
On each input you wire the switch between the input pin and ground. For each light you wire a resistor in seriese with one LED to one output.

That's pretty close to what it already looks like to me....except for the 5v short. :blush:

Stupidiot:
2nd attempt

That looks pretty good / a little clearer anyway. You CAN put resistor before or after the LED. Makes no difference here. Can do as in first or second schematic/diagram.

The only issue I see is with your button/switch. I'm assuming you want the Arduino to read it as LOW until pressed, then read it as HIGH...correct?

Try it like this -

With resistor from ground to button pin on Arduino, and button going between the pin-side-of-resistor and 5v.

Get rid of the resistor all together on your switch and enable the internal pullup. Coding wise you'll want to setup a finite state machine.

Thanks for your patience. I will work on the coding again.

Arrch:
Get rid of the resistor all together on your switch and enable the internal pullup. Coding wise you'll want to setup a finite state machine.

I was following the basic guide provided with the starter set and it had the resistor. Could you explain why it isn't needed and why it was included in the first place? The guide was for the Space ship interface sorry I can't find an electronic version of it.

Following your rendition, here is the schematic; however, the button resistor has not been removed yet.

The switch goes between the input pin and ground if you are using the internal pullup.

Stupidiot:
Could you explain why it isn’t needed

Because there are internal resistors that perform the same function and simplify the wiring.

Stupidiot:
why it was included in the first place

I didn’t write the starter set, so I have no idea.

Arcch~ Thanks for the feedback.

dc42:
The switch goes between the input pin and ground if you are using the internal pullup.

If I do that wouldn't there be a constant 5V going into the input, negating the use of the switch? or am I misunderstanding that?

Stupidiot:
If I do that wouldn't there be a constant 5V going into the input, negating the use of the switch? or am I misunderstanding that?

It would be "pulled" to 5V via the internal resistance. Once the switch is pressed, the input pin is shorted to GND.

With regard to the switch you should read this:-
http://www.thebox.myzen.co.uk/Tutorial/Inputs.html

Serious props Mike!

That website is awesome! It answered a ton of my questions on various topics! Also brought up a ton more~

Thanks.

Also brought up a ton more~

Ask away, that's why we are here. :slight_smile:

Right now my biggest issue is that I cannot get this to loop. I added the serial to show me how the numbers work past 30000 millis and it just keeps increasing.

I believe my issue is in here, but I cant figure it out. I shouldn’t have an issue I thought.

void loop() {
//timer
  long currentMillis = millis();
  long previousMillis = 0;
  long totalLength = 30000;
  long currentTime = currentMillis - previousMillis;
  if (currentMillis - previousMillis > totalLength) {  
    previousMillis = currentMillis;
    if (currentTime < totalLength/3)
    {
      digitalWrite(3, HIGH);
    }
    else {
      digitalWrite(3, LOW);
    }
  //... the rest of the script      
  }
}

here is the entire code

int pinOut = 3;

void setup() {
  for (pinOut = 3; pinOut < 11; pinOut++) {
	pinMode(pinOut, OUTPUT);
  }
  //Serial.begin(9600);
  //pinMode(2, INPUT); //this will be the switch for the ped crossing
}

void loop() {
//timer
  long currentMillis = millis();
  long previousMillis = 0;
  long totalLength = 30000;
  long currentTime = currentMillis - previousMillis;
  if (currentMillis - previousMillis > totalLength) {  
    previousMillis = currentMillis;
//light timers
    if (currentTime < totalLength/3) {
      digitalWrite(3, HIGH);
    }
    else {
      digitalWrite(3, LOW);
    }
    if (currentTime > totalLength/3 && currentTime < totalLength/2 - (totalLength/30)) {
      digitalWrite(4, HIGH);
    }
    else {
      digitalWrite(4, LOW);
    }
    if (currentTime > totalLength/2 - (totalLength/30)) {
      digitalWrite(5, HIGH);
    }
    else {
      digitalWrite(5, LOW);
    }
    if (currentTime > totalLength/2 && currentTime < totalLength*5/6 - (totalLength/30)) {
      digitalWrite(6, HIGH);
    }
    else {
      digitalWrite(6, LOW);
    }
    if (currentTime > totalLength*5/6 - (totalLength/30) && currentTime < totalLength - (totalLength/30)) {
      digitalWrite(7, HIGH);
    }
    else {
      digitalWrite(7, LOW);
    }
    if (currentTime > totalLength/2 && currentTime < totalLength - (totalLength/30)) {
      digitalWrite(8, LOW);
    }
    else {
      digitalWrite(8, HIGH);
    }
    Serial.println(previousMillis);      
  }
}

Replace this:

  long currentMillis = millis();
  long previousMillis = 0;
  long totalLength = 30000;
  long currentTime = currentMillis - previousMillis;

by this:

  unsigned long currentMillis = millis();
  static unsigned long previousMillis = 0;
  const unsigned long totalLength = 30000;
  unsigned long currentTime = currentMillis - previousMillis;

The main problem was that you were resetting previousMillis to 0 every time loop() was entered.

dc42:

  static unsigned long previousMillis = 0;

The use of static causes that to be only loaded once?

So would this also work?

unsigned long previousMillis = 0;

void setup() 
{//...
}
void loop()
{
//...
}

EDIT: Sorry for asking instead of testing, I left home and had already posted it before thinking about just testing it myself.