How would some of you do this?

Hey, I'm very new to the forum and I'm not sure if I'm supposed to post this here but I have a school project that I have already completed. But I'm curious of how some of you might do this sequence, or if there is a better way than mine to solve it.

There were some components that I had to replace with LEDs because my school didn't have the hardware to test it, so do take note when you're viewing my code.

Components used:

  • Green LED
  • Red LED
  • 7 push buttons (1 start button, 1 stop button, 5 sensors)
  • actuator (replaced by LED)
  • heater (replaced by LED)
  • fan (replaced by LED)
  • 2 stepper motors for conveyors 1 and 2 (replaced by 2 LEDs each because the simulator I used didn't have stepper motors)

What is supposed to happen:

Before start button is pressed, none of the sensors should work. Initial state is Red light ON and everything else is OFF.

When start button is pressed, Red light turns OFF, Green light turns ON and conveyor 1 moves forward(motor turns clockwise).

When work piece activates sensor 1, conveyor 1 stops and actuator extends, pushing the work piece to conveyor 2.

When work piece hits sensor 2, actuator retracts and conveyor 2 moves forward(motor turns anti-clockwise).

When sensor 3 is activated, conveyor 2 stops and heater turns on(baking process) for 3 secs, turns off and conveyor 2 starts to move forward again.

When work piece activates sensor 4, conveyor 2 stops and fan turns on(cooling process) for 5 secs, turns off and conveyor 2 starts moving backwards to return to baking.

Baking and cooling processes together is one cycle. Once 3 cycles is completed, conveyor 2 will move forward towards the inspection station.

Press sensor 5 to indicate that work piece has reached the inspection station. If start button is pressed within 5 secs of sensor 5's activation, it means the work piece has passed inspection, green light will blink thrice, then remain on.

If start button is not pressed within 5 secs of sensor 5's activation, it means the inspection has failed, red light will blink thrice then off, green light remains on.

In any occasion where only the Conveyors are moving, if stop button is pressed, return to initial state. (I know that 'goto' is not the best method for this, but it was what my lecturer asked for, so I had to use it).

Please view my code in the next post.

int C1_1 = 3;
int C1_2 = 4;
int C2_1 = 5;
int C2_2 = 6;
int Act = 7;
int G = 8;
int R = 9;
int fan = 10;
int S1 = 12;
int heater = 13;
int btn1 = A0;
int btn2 = A1;
int S2 = A2;
int S3 = A3;
int S4 = A4;
int S5 = A5;
int btn1state;
int btn2state;
int s1state;
int s2state;
int s3state;
int s4state; 
int s5state;
int delaytime = 3;
int i = 0;
int heatingdone = 0;
int fail = 0;
int sensor = 0; // variable to ensure that sensors dont work before start button.
unsigned long time;
void C1_forward();
void C2_forward();
void heating();
void cooling();
void C2_backward();
void initial();

void setup() {
  // put your setup code here, to run once:
pinMode(C1_1, OUTPUT);
pinMode(C1_2, OUTPUT);
pinMode(C2_1, OUTPUT);
pinMode(C2_2, OUTPUT);
pinMode(Act, OUTPUT);
pinMode(G, OUTPUT);
pinMode(R, OUTPUT);
pinMode(fan, OUTPUT);
pinMode(heater, OUTPUT);
pinMode(S1, INPUT_PULLUP);
pinMode(S2, INPUT_PULLUP);
pinMode(S3, INPUT_PULLUP);
pinMode(S4, INPUT_PULLUP);
pinMode(S5, INPUT_PULLUP);
pinMode(btn1, INPUT_PULLUP);
pinMode(btn2, INPUT_PULLUP);
  Serial.begin(9600);
  initial(); //initial state
}

void loop() {
  e_stop: 
  // put your main code here, to run repeatedly:
  Serial.println("loop");
  
  btn1state = digitalRead(btn1);
  while(btn1state == LOW && sensor == 0) // if btn1 is pressed. Requires sensors to be at 0 to run.
  {
    digitalWrite(G, HIGH);
    digitalWrite(R, LOW);
    C1_forward(); // conveyor 1 moves forward, motor turns counter-clockwise.
    if(digitalRead(btn2) == LOW)
    {
      initial();
      goto e_stop;
    }
      
   
    
 s1state = digitalRead(S1);
  if(s1state == LOW) // if s1 is activated.
   {
    digitalWrite(C1_1, LOW);
    digitalWrite(C1_2, LOW); // conveyor 1 stops.
    delay(1000);
    digitalWrite(Act, HIGH); // actuator extends.
    sensor = 1; // set sensor to 1 so that s2 can work.
    break;
   }
  }

  while(digitalRead(S2)==LOW && sensor == 1) //if s2 is activated.
   {
    digitalWrite(Act, LOW); // actuator retracts.
    delay(1000);
   
    while(i < 4)
     {
       C2_forward(); // conveyor 2 moves forward, motor turns counter-clockwise.
       if(digitalRead(btn2) == LOW)
        {
         initial();
         goto e_stop;
        }
      Serial.println("while less than 4 loop");
      s3state = digitalRead(S3);
      if(s3state == LOW)
      {
        Serial.println("S3 pressed.");
        digitalWrite(C2_1, LOW);
        digitalWrite(C2_2, LOW); // conveyor 2 stops.
        delay(1000);
        Serial.println("heating start");
        heating(); // heating process.
        Serial.println("heating end");
        heatingdone = 1;
        delay(1000);
       while(heatingdone == 1) // when heating is complete.
        {
          Serial.println("heating done loop");
          C2_forward(); // counter-clockwise.
         if(digitalRead(btn2) == LOW)
         {
           initial();
           goto e_stop;
         }
          s4state = digitalRead(S4);
          if(s4state == LOW)
           {
             digitalWrite(C2_1, LOW);
             digitalWrite(C2_2, LOW); // conveyor 2 stops.
             delay(1000);
             cooling(); // cooling process.
             delay(1000);
             heatingdone = 0; //set heating to zero/not complete so that program goes back.
             i = i + 1;
             if(i < 4) // if i is smaller than 4.
              {
                Serial.println("less than 4");
                s3state = digitalRead(S3);
                while(s3state == HIGH)
                 {
                  
                   C2_backward(); // clockwise.
                  if(digitalRead(btn2) == LOW)
                   {
                    initial(); // goes back to initial state when e stop is pressed.
                    goto e_stop; // go to e stop destination.
                   }
                  s3state = digitalRead(S3);
                 }
               
              }
           }
            if(i == 4)
            {
              Serial.println("while4");
                s5state = digitalRead(S5);
                while(s5state == HIGH)
                 {
                  
          
                   C2_forward(); // counter-clockwise.
                  if(digitalRead(btn2) == LOW)
                   {
                    initial();
                    goto e_stop;
                   }
                   Serial.println("while5");
                  s5state = digitalRead(S5);
                 }
              sensor = 2;
              break; // exit loop.
            }
            }
         }
  
       
     }
    
   }
  
  s5state = digitalRead(S5);
  while(s5state == LOW && sensor == 2)
  {
    digitalWrite(C2_1, LOW);
    digitalWrite(C2_2, LOW); // conveyor 2 stops.
    time = millis() + 5000; // time is millis plus 5 seconds
    fail = 1; // set variable fail to 1.
    while(millis() < time) // if millis is smaller than the set time, then 5 second is not over.
    {
      btn1state = digitalRead(btn1);
      if(btn1state == LOW) // if button pressed, grrn light blinks
      {
        digitalWrite(G, HIGH);
        delay(500);
        digitalWrite(G, LOW);
        delay(500);
        digitalWrite(G, HIGH);
        delay(500);
        digitalWrite(G, LOW);
        delay(500);
        digitalWrite(G, HIGH);
        delay(500);
        digitalWrite(G, LOW);
        delay(500);
        digitalWrite(G, HIGH);
        fail = 0; // set fail to 0 if pass, so that program does not jump to inspection fail.
        sensor = 0;
      }
    }
       if(fail == 1) // if inspection fail, red light blinks.
       {
        digitalWrite(R, HIGH);
        delay(500);
        digitalWrite(R, LOW);
        delay(500);
        digitalWrite(R, HIGH);
        delay(500);
        digitalWrite(R, LOW);
        delay(500);
        digitalWrite(R, HIGH);
        delay(500);
        digitalWrite(R, LOW);
        delay(500);
         sensor = 0;
       }
    
      
  }
  }
  


void initial() //initial state.
{
  digitalWrite(R, HIGH);
  digitalWrite(G, LOW);
  digitalWrite(Act, LOW);
  digitalWrite(heater, LOW);
  digitalWrite(fan, LOW);
  sensor = 0;
}
void C1_forward() //counter-clockwise.
{
 digitalWrite(C1_1, HIGH);
  digitalWrite(C1_2, HIGH); 
  delay(delaytime); //pos1
  digitalWrite(C1_1, HIGH);
  digitalWrite(C1_2, LOW);
  delay(delaytime); //pos4
  digitalWrite(C1_1, LOW);
  digitalWrite(C1_2, LOW);
  delay(delaytime); //pos3
  digitalWrite(C1_1, LOW);
  digitalWrite(C1_2, HIGH);
  delay(delaytime); //pos2
}
void C2_forward() //counter-clockwise.
{
  digitalWrite(C2_1, HIGH);
  digitalWrite(C2_2, HIGH); 
  delay(delaytime); //pos1
  digitalWrite(C2_1, HIGH);
  digitalWrite(C2_2, LOW);
  delay(delaytime); //pos4
  digitalWrite(C2_1, LOW);
  digitalWrite(C2_2, LOW);
  delay(delaytime); //pos3
  digitalWrite(C2_1, LOW);
  digitalWrite(C2_2, HIGH);
  delay(delaytime); //pos2
}
  void heating() // heating process.
  {
    digitalWrite(heater, HIGH);
    delay(3000);
    digitalWrite(heater, LOW);
    
  }
  void cooling() //cooling process.
  {
    digitalWrite(fan, HIGH);
    delay(5000);
    digitalWrite(fan, LOW);
  }
void C2_backward() // clockwise.
{
  digitalWrite(C2_1, HIGH);
  digitalWrite(C2_2, HIGH);
  delay(delaytime); //pos1
  digitalWrite(C2_1, LOW);
  digitalWrite(C2_2, HIGH);
  delay(delaytime); //pos2
  digitalWrite(C2_1, LOW);
  digitalWrite(C2_2, LOW);
  delay(delaytime); //pos3
  digitalWrite(C2_1, HIGH);
  digitalWrite(C2_2, LOW);
  delay(delaytime); //pos4
}

(1) Data Types: not every variable needs to be an int. think about what would be the best data type for each. if it will never be more than 255 use the byte data type. if it will never change use the const. modifier.
for example:

const byte ledPin = 13;
const byte buttonPin = 11;

(2) Arrays: Anytime you have numbered variables of the same name is a good opportunity to use an array.

const byte ledPins[5] = {3, 4, 5, 6, 7};

void setup() { 
 for (byte i = 0; i < 5; i++)
  {
    pinMode (ledPins[i], OUTPUT);
  }
}

(3) delay(): this stops your Arduino from doing anything else (like reading a sensor or button) during a delay. we call this blocking code
Learn to use non-blocking state machines and millis() timing code (I.E. blinkWithoutDelay) to control things.

Demonstration code for several things at the same time

Planning and Implementing an Arduino Program

Multi-tasking the Arduino

@Hutkikz thank you very much for the advice, I’ll definitely remember them.^^ I am pretty much a beginner at Arduino as well and these are very helpful. Much appreciated :smiley:

Hope you also had some resistors to limit the current to the LEDs.

Paul

Question…which controller will you be using for your project ?
there is a lot of stuff you will need to get if you are going to be serious
I use USBASP cheap works very well over time I have acquired about 60-70
uCs (microcontrollers) just a lot of parts …I have learned this

Do not Give up on these things if you want to build something (you will cook some things )
Do not give up !

I recommend naming your variables to better reflect what they represent. "heater" and "fan" were a step in the right direction, but "C2_1" which I take to be a stepper coil driver output, could be better named "conveyorMotor2Phase1" or something like that. Your global variables should be commented to explain what hardware they are associated with.

I see a goto statement. Get rid of it now. Put down whatever you are doing and do it now so you won't forget. Believe me, there are enough control structures in C++ to do anything that you think you needed it for.

/ pseudocode - do not attempt to compile
  setup{
  state = 0;
}
loop {
  switch (state) {
    case 0: {
        set Red light ON and everything else OFF.
          if (start button pressed) state = 1;
      }
    case 1: {
        Red light OFF, Green light ON  conveyor 1 forward
        if (stop button) state = 0;
        if (sensor 1 active) state = 2;
      }
    case 2: {
        conveyor 1 stop, actuator extend
        if (sensor 2 active) state = 3;
      }
    case 3: {
        actuator retract, conveyor 2 forward(motor turns anti - clockwise).
        if (stop button) state = 0;
        etc.
      }
    // continue like this until:
    case final: {
        if (last condition met) state = 0;
      }

  }
}

*/

Paul_KD7HB: Hope you also had some resistors to limit the current to the LEDs.

Paul

I did. 220 ohm resostors to be precise.

bandmwhitt2013: Question..which controller will you be using for your project ? there is a lot of stuff you will need to get if you are going to be serious I use USBASP cheap works very well over time I have acquired about 60-70 uCs (microcontrollers) just a lot of parts ..I have learned this

Do not Give up on these things if you want to build something (you will cook some things ) Do not give up !

My school uses an ULN2003APG for the motors.

aarg: I recommend naming your variables to better reflect what they represent. "heater" and "fan" were a step in the right direction, but "C2_1" which I take to be a stepper coil driver output, could be better named "conveyorMotor2Phase1" or something like that. Your global variables should be commented to explain what hardware they are associated with.

I see a goto statement. Get rid of it now. Put down whatever you are doing and do it now so you won't forget. Believe me, there are enough control structures in C++ to do anything that you think you needed it for.

I'll definitely keep the naming of variables in mind. As for the goto statement, I read up on it and am very much aware that it is not a recommended method. But it was something that my lecturer wanted her students to use so I had to put it in. I wouldn't use it in my program otherwise.