3

I'm still very new to this but I've put together some code that when a button is pressed, my servo runs continuously, a second button rotates it the other way and a third cancels everything.

A red or green comes on depending on the rotation and this can be one using an IR receiver also.

Issue I'm having is that randomly, 1/5 of the time, the red or green LED does not turn off. I can manually kill it using the third cancel button or just press it a couple times until it turns off as it should on the next push of the button.

Cant work out where im going wrong.

I also find my IR remote works maybe 60% of the time. Any help would be greatly appreciated.

#include <Servo.h>
Servo servo1;
int servoPin = 9;
#include "IRremote.h"

/----- Variables, Pins -----/

int receiver = 12; // Signal Pin of IR receiver to Arduino Digital Pin 6 int RledPin = 5; int GledPin = 3; int buttonApin = 7; int buttonBpin = 8; int buttonCpin = 4; unsigned long elapsedTime; unsigned long onTime;

/-----( Declare objects )-----/ // Setup of proper sequencing for Motor Driver Pins // In1, In2, In3, In4 in the sequence 1-3-2-4

IRrecv irrecv(receiver); // create instance of 'irrecv' decode_results results; // create instance of 'decode_results'

void setup() { irrecv.enableIRIn(); // Start the receiver servo1.attach(servoPin); servo1.write(90); pinMode(RledPin, OUTPUT); pinMode(GledPin, OUTPUT); pinMode(buttonApin, INPUT_PULLUP);
pinMode(buttonBpin, INPUT_PULLUP); pinMode(buttonCpin, INPUT_PULLUP);

}

void loop(){

if (digitalRead(buttonApin) == LOW) // Switch is closed to start LED timer { digitalWrite(RledPin, HIGH); // Red LED comes On digitalWrite(GledPin, LOW); // Green LED Goes Off servo1.attach(servoPin); //Servo is activated servo1.write(0); //Servo turns on clockwise onTime = millis(); //time set }

  if(onTime &gt; 0 &amp;&amp; millis() - onTime &gt; 1500)  //time limit target
        {      
        servo1.write(90); //Servo stops
        servo1.detach(); //servo deactivated
        delay(500); //used to sync the servo stop with the LED off
        digitalWrite(RledPin, LOW);  // LED goes off
          onTime = 0;  //time reset
        }

if (digitalRead(buttonCpin) == LOW) // Switch is closed to start LED timer { digitalWrite(GledPin, HIGH); // Green LED comes On digitalWrite(RledPin, LOW); // RED LED Goes Off servo1.attach(servoPin); //Servo is activated servo1.write(180); //Servo turns on anti-clockwise onTime = millis(); //time set }

  if(onTime &gt; 0 &amp;&amp; millis() - onTime &gt; 1500)  //time limit target
        {                 
        servo1.write(90); //Servo stops
        servo1.detach(); //servo deactivated
        delay(500);
        digitalWrite(GledPin, LOW);
          onTime = 0;  //time reset
        }

if (digitalRead(buttonBpin) == LOW) //Deactivation Sequence KILL SWITCH { digitalWrite(RledPin, LOW); digitalWrite(GledPin, LOW); servo1.write(90); servo1.detach(); onTime = 0; //time reset }

if (irrecv.decode(&results)) // have we received an IR signal?

{ switch(results.value)

{

  case 0xFFE01F: // DOWN button pressed
                  {
      digitalWrite(RledPin, HIGH);  // Red LED comes On
      digitalWrite(GledPin, LOW);  // Green LED Goes Off
      servo1.attach(servoPin); //Servo is activated
      servo1.write(0);  //Servo turns on clockwise
      onTime = millis();  //time set
      }

      if(onTime &gt; 0 &amp;&amp; millis() - onTime &gt; 2000)  //time limit target
        {      
        servo1.write(90); //Servo stops
        servo1.detach(); //servo deactivated
        digitalWrite(RledPin, LOW);  // LED goes off
         onTime = 0;  //time reset
        }
        break; 


  case 0xFF906F: // UP button pressed
                  {
      digitalWrite(GledPin, HIGH);  // Green LED comes On
      digitalWrite(RledPin, LOW);  // RED LED Goes Off
      servo1.attach(servoPin); //Servo is activated
      servo1.write(180);  //Servo turns on anticlockwise
      onTime = millis();  //time set
      }

  if(onTime &gt; 0 &amp;&amp; millis() - onTime &gt; 2000)  //time limit target
        {      
        servo1.write(90); //Servo stops
        servo1.detach(); //servo deactivated
        digitalWrite(GledPin, LOW);  // LED goes off
         onTime = 0;  //time reset
        } 
        break;

  case 0xFF02FD: // PAUSE button pressed
                  servo1.write(90);
                  servo1.detach();
                  digitalWrite(GledPin, LOW);
                  digitalWrite(GledPin, LOW);
                  break;

}

  irrecv.resume(); // receive the next value



} }/* --end main loop -- */

  • 1
    insert a layer of separation between the button press and the resulting action ... do same with IR codes .... pressing a button results is a flag variable being set doRed = true; ...... case 0xFFE01F: does the same thing .... neither of these do anything else, just set a flag and continue on ..... further down in loop(), act on the state of the flag if (doRed) { – jsotola May 16 '21 at 22:32
  • Please adopt an indenting style and stick to it. Your source is barely readable. Many problems reveal themselves by consistent indentation. – the busybee May 17 '21 at 06:10
  • Insert some debugging outputs to see what exactly happens in your program. – the busybee May 17 '21 at 06:11
  • Are you debouncing the buttons in hardware? If not, you need to debounce them in software using a debouncer. This will remove the random glitches as the switch contacts bounce when they change over. – tim May 17 '21 at 07:15
  • @jsotola Thanks for the reply, sorry to sound silly but when you say add a layer of separation, what does that mean? – Nathan Cooper May 17 '21 at 16:11
  • @tim Thanks for the suggestion, I ave read articles mentioning debouncers but don't know anything about them. I will go away and look into it, thank you. – Nathan Cooper May 17 '21 at 16:12
  • @NathanCooper ... not separated if button is pressed, then turn on LED.... separated if button is pressed, then set a flag .... if flag is set, then turn on LED .... multiple events can set the flag ... only one function checks the flag and activates the LED – jsotola May 17 '21 at 18:34

1 Answers1

3

Found the answer!

I added serial print to every line and realised that my kill process after the time elapsed was switching between the red led and green led.

I didn't need the if time elapsed function many times, just once. Deleted that portion and it worked perfectly. Seems to have fixed the IR troubles too.

Working code:


#include <Servo.h> Servo servo1; int servoPin = 9; #include "IRremote.h"

/----- Variables, Pins -----/

int receiver = 12; // Signal Pin of IR receiver to Arduino Digital Pin 6 int RledPin = 5; int GledPin = 3; int buttonApin = 7; int buttonBpin = 8; int buttonCpin = 4; unsigned long elapsedTime; unsigned long onTime;

/-----( Declare objects )-----/ // Setup of proper sequencing for Motor Driver Pins // In1, In2, In3, In4 in the sequence 1-3-2-4

IRrecv irrecv(receiver); // create instance of 'irrecv' decode_results results; // create instance of 'decode_results'

void setup() { irrecv.enableIRIn(); // Start the receiver servo1.attach(servoPin); servo1.write(90); pinMode(RledPin, OUTPUT); pinMode(GledPin, OUTPUT); pinMode(buttonApin, INPUT_PULLUP);
pinMode(buttonBpin, INPUT_PULLUP); pinMode(buttonCpin, INPUT_PULLUP); Serial.begin(9600); pinMode(LED_BUILTIN, HIGH);

}

void loop(){

if (digitalRead(buttonApin) == LOW) // Switch is closed to start LED timer { digitalWrite(RledPin, HIGH); // Red LED comes On Serial.println("RED comes on"); digitalWrite(GledPin, LOW); // Green LED Goes Off Serial.println("green off"); servo1.attach(servoPin); //Servo is activated Serial.println("red servo attach"); servo1.write(0); //Servo turns on clockwise Serial.println("red servo spins"); onTime = millis(); //time set }

if(onTime > 0 && millis() - onTime > 1500) //time limit target {
servo1.write(90); //Servo stops Serial.println("servo stops spinning"); digitalWrite(RledPin, LOW); // LED goes off digitalWrite(GledPin, LOW); // LED goes off Serial.println("red RED goes off"); delay(500); Serial.println("delay"); servo1.detach(); //servo deactivated Serial.println("servo Rled dettach");
onTime = 0; //time reset

     }

if (digitalRead(buttonCpin) == LOW) // Switch is closed to start LED timer { digitalWrite(GledPin, HIGH); // Green LED comes On Serial.println("green comes on"); digitalWrite(RledPin, LOW); // RED LED Goes Off Serial.println("RED goes off"); servo1.attach(servoPin); //Servo is activated Serial.println("green servo attached"); servo1.write(180); //Servo turns on clockwise Serial.println("green servo spins"); onTime = millis(); //time set }

if (digitalRead(buttonBpin) == LOW) //Dectivation Sequence KILL SWITCH { digitalWrite(RledPin, LOW); Serial.println("total red off"); digitalWrite(GledPin, LOW); Serial.println("total green off"); servo1.write(90); Serial.println("total servo off"); servo1.detach(); Serial.println("total detach"); onTime = 0; //time reset }

if (irrecv.decode(&results)) // have we received an IR signal?

{ switch(results.value)

{

  case 0xFFE01F: // DOWN button pressed
                  {
      digitalWrite(RledPin, HIGH);  // Red LED comes On
      digitalWrite(GledPin, LOW);  // Green LED Goes Off
      servo1.attach(servoPin); //Servo is activated
      servo1.write(0);  //Servo turns on clockwise
      onTime = millis();  //time set
      }
      break; 


  case 0xFF906F: // UP button pressed
                  {
      digitalWrite(GledPin, HIGH);  // Green LED comes On
      digitalWrite(RledPin, LOW);  // RED LED Goes Off
      servo1.attach(servoPin); //Servo is activated
      servo1.write(180);  //Servo turns on clockwise
      onTime = millis();  //time set
      }
      break;

  case 0xFF02FD: // PAUSE button pressed
      servo1.write(90);
      digitalWrite(GledPin, LOW);
      digitalWrite(GledPin, LOW);
      delay(500);
      servo1.detach();         
      break;               
}

  irrecv.resume(); // receive the next value



} }/* --end main loop -- */