I'm working on a project where I need three inputs to control a single pin. The inputs are
IR Sensor
Serial
Physical button
To get things started I've tried to get serial and the IR sensor working but my code is buggy. I've written two functions one for the IR and one for the serial. These functions work independently but when I try to use them in tandem no beans. How can I get these to work and what needs to be done to include a button?
Thanks for looking!
Rich
int statLED5 = 13;
int irPin = A0; //Sensor pin 1 wired to Arduino's pin A5
int statLED_state5 = LOW; //mac
// IR sensor variables
int start_bit = 2200; //Start bit threshold (Microseconds)
int bin_1 = 1000; //Binary 1 threshold (Microseconds)
int bin_0 = 400; //Binary 0 threshold (Microseconds)
int incomingByte = 0;
void setup(){
Serial.begin(9600);
pinMode(statLED5, OUTPUT);
pinMode(irPin, INPUT);
digitalWrite(statLED5, statLED_state5); //mac
}
void loop(){
while (Serial.available() == 0);
//Read the Input
int val = Serial.read() - '0';
switch(val)
{
case 2:
Serial.println("Circuit 5 Serial");
if(statLED_state5 != LOW)
statLED_state5 = LOW;
else
statLED_state5 = HIGH;
digitalWrite(statLED5, statLED_state5); //mac
Serial.println("OFF");
delay(250);
break;
}
int key = getIRKey(); //Fetch the key
if(key != 0) //Ignore keys that are zero
{
Serial.print("Key ");
Serial.print(key);
Serial.println(" Recieved: ");
switch(key)
{
case 1302: // Button 1 AXD7381 Pioneer AV Remote
Serial.println("Circuit 5 IR");
if(statLED_state5 != LOW)
statLED_state5 = LOW;
else
statLED_state5 = HIGH;
digitalWrite(statLED5, statLED_state5); //mac
delay(250);
break;
}
}
}
int getIRKey() {
int data[12];
int i;
while(pulseIn(irPin, LOW) < start_bit); //Wait for a start bit
for(i = 0 ; i < 11 ; i++)
data[i] = pulseIn(irPin, LOW); //Start measuring bits, I only want low pulses
for(i = 0 ; i < 11 ; i++) //Parse them
{
if(data[i] > bin_1) //is it a 1?
data[i] = 1;
else if(data[i] > bin_0) //is it a 0?
data[i] = 0;
else
return -1; //Flag the data as invalid; I don't know what it is! Return -1 on invalid data
}
int result = 0;
for(i = 0 ; i < 11 ; i++) //Convert data bits to integer
if(data[i] == 1) result |= (1<<i);
return result; //Return key number
}
Cool, that makes sense but it's not working yet. I think what I need is an or statement so something like
if (val==2 || key==1302)
So far neither one works.
When I test it I'm able to read from the IR sensor one time and that's it, it's not able to recieve additional signals and the it seems to ignore serial terminal input.
Here's what the code looks like now.
int statLED5 = 13;
int irPin = A0; //Sensor pin 1 wired to Arduino's pin A5
int statLED_state5 = LOW; //mac
// IR sensor variables
int start_bit = 2200; //Start bit threshold (Microseconds)
int bin_1 = 1000; //Binary 1 threshold (Microseconds)
int bin_0 = 400; //Binary 0 threshold (Microseconds)
int incomingByte = 0;
void setup(){
Serial.begin(9600);
pinMode(statLED5, OUTPUT);
pinMode(irPin, INPUT);
digitalWrite(statLED5, statLED_state5); //mac
}
void loop(){
int key = getIRKey(); //Fetch the key
while (Serial.available() == 0);
//Read the Input
int val = Serial.read() - '0';
if (val==2 || key==1302){
Serial.println("Circuit 5 Serial");
if(statLED_state5 != LOW)
statLED_state5 = LOW;
else
statLED_state5 = HIGH;
digitalWrite(statLED5, statLED_state5); //mac
Serial.println("OFF");
delay(250);
}
}
int getIRKey() {
int data[12];
int i;
while(pulseIn(irPin, LOW) < start_bit); //Wait for a start bit
for(i = 0 ; i < 11 ; i++)
data[i] = pulseIn(irPin, LOW); //Start measuring bits, I only want low pulses
for(i = 0 ; i < 11 ; i++) //Parse them
{
if(data[i] > bin_1) //is it a 1?
data[i] = 1;
else if(data[i] > bin_0) //is it a 0?
data[i] = 0;
else
return -1; //Flag the data as invalid; I don't know what it is! Return -1 on invalid data
}
int result = 0;
for(i = 0 ; i < 11 ; i++) //Convert data bits to integer
if(data[i] == 1) result |= (1<<i);
return result; //Return key number
}
Add some extra serial prints to see what val and key are?
void loop(){
int key = getIRKey(); //Fetch the key
Serial.print(key); //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
while (Serial.available() == 0);
//Read the Input
int val = Serial.read() - '0';
Serial.print(val); //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
if (val==2 || key==1302){
Here it is with print statements. The setup print statement works.
When I first open the serial terminal I can't send IR signals but when I enter 2 into the terminal it's echoed on the screen. From there I can send 3 or 4 IR signals at which point it stops taking input from both sources ; IR or Serial.
int statLED5 = 13;
int irPin = A0; //Sensor pin 1 wired to Arduino's pin A5
int statLED_state5 = LOW; //mac
// IR sensor variables
int start_bit = 2200; //Start bit threshold (Microseconds)
int bin_1 = 1000; //Binary 1 threshold (Microseconds)
int bin_0 = 400; //Binary 0 threshold (Microseconds)
int incomingByte = 0;
void setup(){
Serial.begin(9600);
pinMode(statLED5, OUTPUT);
pinMode(irPin, INPUT);
digitalWrite(statLED5, statLED_state5); //mac
Serial.print("Hey, is this thing on?");
}
void loop(){
while (Serial.available() == 0);
//Read the Input
int val = Serial.read() - '0';
Serial.print(val);
int key = getIRKey(); //Fetch the key
Serial.print(key);
if (val==2 || key==1302){
Serial.println("Circuit 5 Serial");
if(statLED_state5 != LOW)
statLED_state5 = LOW;
else
statLED_state5 = HIGH;
digitalWrite(statLED5, statLED_state5); //mac
Serial.println("OFF");
delay(250);
}
}
int getIRKey() {
int data[12];
int i;
while(pulseIn(irPin, LOW) < start_bit); //Wait for a start bit
for(i = 0 ; i < 11 ; i++)
data[i] = pulseIn(irPin, LOW); //Start measuring bits, I only want low pulses
for(i = 0 ; i < 11 ; i++) //Parse them
{
if(data[i] > bin_1) //is it a 1?
data[i] = 1;
else if(data[i] > bin_0) //is it a 0?
data[i] = 0;
else
return -1; //Flag the data as invalid; I don't know what it is! Return -1 on invalid data
}
int result = 0;
for(i = 0 ; i < 11 ; i++) //Convert data bits to integer
if(data[i] == 1) result |= (1<<i);
return result; //Return key number
}
When I first open the serial terminal I can't send IR signals
Because loop() is blocked waiting for serial data. That is not a good way to write a responsive program. You can store the value received from the sensor and deal with it when there is serial input, without blocking.
It isn't clear why you have serial input or IR input controlling an LED. It isn't clear why you aren't using Ken Shirrif's IRremote library.
Wow that library is awesome! It will defensibility change the way I'm writing the code for this project. After checking out the examples I would highly recommend this for anyone using IR in their projects. Here's where you can get the library
So I re wrote the code using the IR library which helped clean things up. Now I'm back to my main question how can I have serial and IR signals change the state of a pin? I have the IR and Serial working below in separate if statements. But what I'm after is something like the following; remember I would like to add a button in the future as well.
if (Serial.available() == 0);
{
int valSerial = Serial.read() - '0'; //Read the serial port
If NO serial data is available, read serial and interpret that?
As for inputs changing the state of the led, use one variable to hold the state of the led and have your sensing and serial code sections change that variable as desired then, last thing, use the variable to digitalWrite the led pin.
If you map your logic in comments before you write the code then you can work out the steps in simplified form before getting down to syntax AND your comments might actually help in debugging.