Help with my first program.

Hi! Just ought my first Arduino UNO and have started programming it.
Its the first time that I work with Arduino, first time with a microcontroller at all actually…
Im going to use it to control a road barrier.
For this, I will use this digital pins:

3 - Output - Barrier up
4 - Output - Barrier down
5 - Input - Barrier down microswitch
6 - Input - Barrier up microswitch
7 - Input - Open barrier button
8 - Input - Offbutton (not yet a part of the program.)
9 - Input - Movementsensor

I want it to work like this:

When I press Open barrier button (7) the road barrier goes ut by output 3.
When its open (input6) arduino counts to 20sec and then close it again. If the sensor is triggered during this time, the counter will start over again.
After 20sec the barrier will go down by activating output 4 until input 5 is triggered.

I have made a program (first time, maybe totally wrong but im new in this) and it works. First time.
When everything is finished and I press the open button again, it stop working and looks like its jumping inside my code (serial monitoring so I can see where it is).

But if I wait for maybe 10-20 seconds after the first time before I press it again, it works.
Its like it need time to rest before I can start the sequence again.
Really need help with this to get it stable.
Someone who can help me??
Here is the code:

// barrieropen = digitalWrite(3)
// barrierclose = digitalWrite(4)
// inputbarrierclosed = digitalRead(5)
// inputbarrieropen = digitalRead(6)
// inputopenbutton = digitalRead(7)
// inputoff = digitalRead(8)
// inputsensor = digitalRead(9)
int t = 0;

void setup() {
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, INPUT);
  pinMode(6, INPUT);
  pinMode(7, INPUT);
  pinMode(8, INPUT);
  pinMode(9, INPUT);
  Serial.begin(9600);
}

void loop() {
  
  //Input 7 is the pushbutton for opening the barrier
  if (digitalRead(7) == 1)
    {
      Serial.print("Openbutton");
      
      
      openup:
      //Drive the road barrier up until input 6 (barrier open switch) is on.
      
      do
        {
          Serial.print("Opening");
          digitalWrite(3, HIGH);
          delay(30);
        } while(digitalRead(6) == 0);
        
        
        //Stops the motor when the barrier is fully open.
       digitalWrite(3, LOW);
       
       
       //Counts to 20 before closing the barrier again.
      do
        {
        delay(1000);
        //If the sensor is triggered, this will reset the counter again.
        if (digitalRead(9) == 1)
          {
            t = 0;
            Serial.print("Sensor");
          }
        else
          {
            t = t + 1;
            Serial.print(t);
          } 
        } while(t<20);
        
      //Reset the counter until next time.
      t = 0;
      
      //Closing the barrier by driving the engine until input 5 is high. (Barrier closed switch)
      do
      {
        //Reset ewerything if sensor is triggered and goes back to open the barrier.
        if (digitalRead(9) == 0)
        {
          Serial.print("Closing");
          digitalWrite(4, HIGH);
          delay(30);
        }
        else
        {
          goto openup;
        }
        
        
      } while(digitalRead(5) == 0);
      //Stopping the engine when barrier is open.
        digitalWrite(4, LOW);
    }
   else;
   {
     Serial.print(digitalRead(7));
     delay(30);
   }
}

Moderator edit: Quote box replaced with code box to eliminate smilies

You may be having problems because of all the delays. When the Arduino is doing a delay() it can't be doing anything else, like checking inputs.

One way to avoid delays is to make a state machine. Have one variable that keeps track of the current state:

emun state {CLOSED, OPENING, OPEN, CLOSING);

Then in loop() you have a switch/case statement to act based on the current state:

switch (state)
    {
case CLOSED:
    if (digitalRead(OpenButton))
        {
        state = OPENING;
        digitalWrtite(OpenMotor, HIGH);
        }
    break;

case OPENING:
    if (digitalRead(IsOpenSwitchPin))
        {
        state = OPEN;
        digitalWrite(OpenMotor, LOW);
        OpenTimer = millis();
        }
    break;

case OPEN:
    if (digitalRead(MotionSensor))
        {
        OpenTimer = millis();  // Reset the open timer
        }
    if (millis() - OpenTimer > 20000)
        {
        state = CLOSING;
        digitalWrite(CloseMotor, HIGH);
        }
    beak;
etc.

Thank you so much! Learned something new here;) This was alot easier to look over also..

but I get an error when verifying the code.

btw, where should I put the "enum sta..." line? I put it in the top before void setup(). Is that correct?

here is the error:

error: expected primary-expression before ')' token

this line is highlighted: switch (state) {

We need to see all of your code. You need to have a variable that can take on one of the enum values, not the name of the enum, in the switch statement (John's example is in error).

John's example didn't finish either. I think he was providing direction only.

I hope there's more than 1 sensor for objects that the barrier might hit when descending. They can all tie to one pin but if it clonks one person on the head (person can come from almost any direction) and they are not terrorist there will no doubt be trouble!

BTW, line labels and goto code --- better off to make functions can call them.

johnwasser: emun state {CLOSED, OPENING, OPEN, CLOSING);

Oops. I spelled "ENUM" (short for ENUMERATION wrong and didn't declare the variable 'state' properly. Should be:

enum {CLOSED, OPENING, OPEN, CLOSING) state;

And yes, it goes above "void setup()"

The code is not complete, of course. Just some examples to show how it's done. Each state checks for those few conditions that cause the system to enter a new state. When you enter a new state there is typically some action to perform (turning a motor on or off, for example).

curly braces?

enum {CLOSED, OPENING, OPEN, CLOSING} state;

theepdinker: curly braces?

enum {CLOSED, OPENING, OPEN, CLOSING} state;

Yes. I had the first one right. :)

Here's a version of the makeshift example that actually compiles:

enum {
  CLOSED, OPENING, OPEN, CLOSING} 
state;

const int OpenButtonPin = 2;
const int MotionSensorPin = 3;
const int IsOpenSwitchPin = 4;
const int IsClosedSwitchPin = 5;

const int OpenMotorPin = 6;
const int CloseMotorPin = 7;

unsigned long OpenTimer = 0;

void setup() {
  pinMode(OpenButtonPin, INPUT);
  pinMode(MotionSensorPin, INPUT);
  pinMode(IsOpenSwitchPin, INPUT);
  pinMode(IsClosedSwitchPin, INPUT);

  pinMode(OpenMotorPin, OUTPUT);
  pinMode(CloseMotorPin, OUTPUT);
}

void loop()
{
  switch (state)
  {
  case CLOSED:
    if (digitalRead(OpenButtonPin))
    {
      state = OPENING;
      digitalWrite(OpenMotorPin, HIGH);
    }
    break;

  case OPENING:
    if (digitalRead(IsOpenSwitchPin))
    {
      state = OPEN;
      digitalWrite(OpenMotorPin, LOW);
      OpenTimer = millis();
    }
    break;

  case OPEN:
    if (digitalRead(MotionSensorPin))
    {
      OpenTimer = millis();  // Reset the open timer
    }
    if (millis() - OpenTimer > 20000)
    {
      state = CLOSING;
      digitalWrite(CloseMotorPin, HIGH);
    }
    break;
  }
}

So I was reading this and had a question:

When the program is in a state, does it loop in that state until one of the conditions for state change occurs?

Hi John. I don't see a case for CLOSING there. Also -why- are the constants for things like pin numbers ints instead of bytes? Sure there's only 6....

Permanewb, look into the switch statement and see where the state would change.

Smoke, I do see where the state would change. Thanks for the response. My question is more along the lines of if the state change condition isn't met initially, will the program keep checking for state change, or will it just check once and then twiddle its thumbs

In that code once the state becomes CLOSING it will loop forever doing nothing buuuuuut since the code was just dashed out and is not finished I would say it is something that would be caught and debugged pretty quickly. Pretty much ALL code goes through that state before (and if) it ever becomes working code.

loop() runs 'forever'. When loop() is done it runs loop() again. So the switch/case runs again and again. Whatever value state holds only controls what code is executed. You could say the code is -checking- state but you might take a different view and say that the code is -driven- by state. It makes the code easier to understand and easier to write IMO.

Permanewb: So I was reading this and had a question:

When the program is in a state, does it loop in that state until one of the conditions for state change occurs?

Yes, that's how a state machine works. When you are in a state you are mostly waiting until you get whatever input tells you to go to another state. The loop() function gets called repeatedly. The state machine keeps track of what state you are in and therefore what states you might go into next and why.

For example, if there was a contact sensor on the gate you might add code to the "CLOSING" state to check it and switch to the "OPENING" state if the gate hits anything. You wouldn't need to check the contact sensor in the OPEN, OPENING, or CLOSED states if you are only concerned about the closing gate hitting something and you don't want anyone to be able to open the closed gate by pressing the contact sensor.

Thank you so much!

this line made it work:

enum {
  CLOSED, OPENING, OPEN, CLOSING} 
state;

Learned much about arduino doing this little code. Looks like I need to buy more of them and make something else;=)

The Arduino board is a development board. It is capable of programming ATmega chips and some other chips to run stand-alone if you choose.

Thanks for clarifying that for me

Consider that ATmega328P chips cost less than $5 and have internal clock up to 8 MHz. All these chips can run and do something with only power and I/O.

Just one source of many: http://www.mouser.com/Search/Refine.aspx?N=1323043&Keyword=Atmega328P&Ns=Pricing|0&FS=True

Caveat, Arduino UNO uses one Atmega328P of many, to use others with the Arduino IDE requires changing some file data as told in some forum threads so ask or find the changes before buying.

Here is in-progress Playground article on standalone: http://www.arduino.cc/playground/Learning/AtmegaStandalone

Here is programming ATtiny chips with Arduino. Note that bigger chips can be programmed much the same: http://hlt.media.mit.edu/?p=1229

Here is Youtube showing How-to do that: http://www.youtube.com/watch?v=30rPt802n1k&feature=list_related&playnext=1&list=SP23C82C496271F7B9

And while not perfected, this one is pretty fantastic and the maker (a member here) has a great site! http://www.youtube.com/watch?v=vX1tDk_iwOo

Hope this adds focus to clarity.