Hello!
I have worked through the BlinkWithoutDelay, and even modified it to get two LEDs blinking alternately, without using delay
. However, I've been staring and thinking and can't figure out how to use the same idea from BlinkWithoutDelay to work for my current project.
I have an IR Remote, red laser, and a servo. Here's my idea - when I press 1, 2, or 3 on the remote, the laser will turn on and be solid, or blink. Pressing 4 will start the Servo turning back and forth, and then pressing 5 will stop the servo. I would like it so that I can have the servo go back and forth independently of what the laser is doing (so I can have the servo rotate with the laser solid or blinking).
The code below works, almost. It can turn the laser on, blink the laser, and rotate the servo. However, here's the problem I hit: I turn the laser on (solid or blinking), but then when I start the Servo (by pressing '4' on my remote), the laser turns off and the servo starts turning. Also the reverse happens, if I have the laser off, and then start the Servo, if I try and have the laser blink, the delay
(I am assuming) in the code only turns the laser on and off ONCE before rotating the servo again.
I believe the solution would be to use the BlinkWithoutDelay idea (using millis
instead of delay
) to have the servo and laser operate independently. OR maybe I just need to "re-layer" or "re-distribute" the code so that I can have them both running? Anyways, sorry for the long-winded explanation, here's the code!
#include <IRremote.h>
#include <Servo.h>
const int LEDpin = 4; // set up LED Pin [not used below, was earlier to confirm upload was working]
const int laserPin = 12;
// IR SENSOR SETUP ------------
int IRpin = 5;
IRrecv irrecv(IRpin); // create instance of 'irrecv'
decode_results results; //create instance of 'decode_results'
int remoteBtn = 0; // set variable to determine which button on remote was pressed
// -------------------------
// SERVO SETUP -------
Servo myservo; // create servo object to control a servo
int pos = 0; // variable to store the servo position
int servoSweepvar = 0; // variable to determine if the servo should be sweeping or not.
// -------------------------
long previousMillis = 0; // will store last time laser was updated
void setup() {
Serial.begin(9600);
myservo.attach(9); //attached the servo on pin 9 to the servo object
pinMode(LEDpin, OUTPUT);
pinMode(laserPin, OUTPUT);
irrecv.enableIRIn(); // start the receiver
}
void loop() {
unsigned long currentMillis = millis(); // THIS is as far as I could figure out the 'delay' fix, but don't know where to put the
// currentMillis - previousMillis > interval stuff, I assume it'd be in my functions, not
// here?
if (irrecv.decode(&results)) { // have we rec'd an IR signal?
// Serial.println(results.value, HEX); // this will show the RAW value of remote press
translateIR();
irrecv.resume();
}
remoteEvents();
}
// ----- FUNCTIONS BELOW
void translateIR(){
switch(results.value) {
case 0xFF6897: Serial.println(" 1"); remoteBtn = 1; break;
case 0xFF9867: Serial.println(" 2"); remoteBtn = 2; break;
case 0xFFB04F: Serial.println(" 3"); remoteBtn = 3; break;
case 0xFF30CF: Serial.println(" 4"); remoteBtn = 4; servoSweepvar = 1; break;
case 0xFF18E7: Serial.println(" 5"); remoteBtn = 5; servoSweepvar = 0; break;
case 0xFF7A85: Serial.println(" 6"); remoteBtn = 6; break;
case 0xFF10EF: Serial.println(" 7"); remoteBtn = 7; break;
case 0xFF38C7: Serial.println(" 8"); remoteBtn = 8; break;
case 0xFF5AA5: Serial.println(" 9"); remoteBtn = 9; break;
case 0xFF42BD: Serial.println(" *"); remoteBtn = 10; break;
case 0xFF4AB5: Serial.println(" 0"); remoteBtn = 0; break;
case 0xFF52AD: Serial.println(" #"); remoteBtn = 11; break;
default: Serial.println(" other button ");
} // end Case
delay(500); // do not get immediate repeat
} //end translateIR
void remoteEvents(){ // Start the remote Events for the laser
if (servoSweepvar == 1) {
servoSweepStart();
} else if (servoSweepvar == 0) {
servoSweepStop();
}
switch (remoteBtn) {
case 1:
steadyLaser();
break;
case 2:
blinkingLaser();
break;
case 3:
blinkingfasterLaser();
break;
case 0:
offLaser();
break;
// default:
// offLaser();
// break;
}
}
void remoteEventsServo(){
switch(servoSweepvar){
case 0:
servoSweepStop();
break;
case 1:
servoSweepStart();
break;
}
}
void steadyLaser(){
digitalWrite(laserPin, HIGH);
}
void blinkingLaser(){
digitalWrite(laserPin, HIGH);
delay(450);
digitalWrite(laserPin, LOW);
delay(450);
}
void blinkingfasterLaser(){
digitalWrite(laserPin, HIGH);
delay(250);
digitalWrite(laserPin, LOW);
delay(250);
}
void offLaser(){
digitalWrite(laserPin, LOW);
}
void servoSweepStart(){
servoSweepvar = 1; // This sets servo sweep to '1' for the looping
for(pos = 5; pos < 175; pos +=1) { // goes from 5 degrees to 175 degrees in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // wait 15ms for the servo to reach the position
}
for (pos = 175; pos >= 6; pos -=1) { // goes from 175 degrees to 6 degrees
myservo.write(pos);
delay(15);
}
}
void servoSweepStop(){
servoSweepvar = 0;
myservo.write(pos); // return servo to 5 degrees
}
If there's an example online of what I'm trying to do, please let me know what I should look up and I can research it from there. I may have too many "functions within functions" or something?
Thanks for any help or ideas.