Hello,
I have been trying to build a media center remote using Arduino Uno.
- IR sensor with Arduino is explained here, Overview | IR Sensor | Adafruit Learning System, very through tutorial and works perfectly.
- HID keyboard implementation explained here, Arduino Forum and http://mitchtech.net/arduino-usb-hid-keyboard/, the two tutorials complete each other.
The problem is the combination of those two. See example code below.
After flashing “Arduino-keyboard-0.3.hex” bootloader, restarting Arduino, I press the remote button and the code runs only once, I see my led indicator on pin 13 .
What could be the problem?
#define IRpin_PIN PIND
#define IRpin 2
// the maximum pulse we'll listen for - 65 milliseconds is a long time
#define MAXPULSE 1500
// what our timing resolution should be, larger is better
// as its more 'precise' - but too large and you wont get
// accurate timing
#define RESOLUTION 10
// What percent we will allow in variation to match the same code
#define FUZZINESS 30
// we will store up to 100 pulse pairs (this is -a lot-)
uint16_t pulses[100][2] ={0}; // pair is high and low pulse
uint8_t currentpulse = 0; // index for pulses we're storing
uint8_t buf[8] = {0}; /* Keyboard report buffer */
int Rarrow[] = {715, 354,46, 43,44, 45,44, 44,46, 43,44, 46,43, 44,46, 43,44, 46,43, 134,43, 133,46, 133,44, 133,44, 133,46, 133,44, 43,46, 133,44, 133,43, 134,45, 44,44, 133,46, 133,44, 43,46, 43,44, 46,43, 44,46, 43,44, 133,46, 44,43, 46,44, 133,44, 133,45, 134,43, 0};
void setup(void)
{
delay(3000);
Serial.begin(9600);
pinMode(13, OUTPUT);
}
void loop(void) {
int numberpulses = 0;
numberpulses = listenForIR();
/*buf[2] =17;
Serial.write(buf, 8); // Send keypress
releaseKey();*/
if (IRcompare(numberpulses, Rarrow))
{
digitalWrite(13, HIGH); // set the LED on
//Serial.print("------>");
buf[2] = 79;
Serial.write(buf, 8); // Send keypress
releaseKey();
}
/*
if (IRcompare(numberpulses, Larrow))
{
digitalWrite(13, HIGH); // set the LED on
//Serial.print("<------");
buf[2] = 80;
Serial.write(buf, 8); // Send keypress
releaseKey();
}
if (IRcompare(numberpulses, Uparrow))
{
digitalWrite(13, HIGH); // set the LED on
// Serial.print("UParrow");
buf[2] = 82;
Serial.write(buf, 8); // Send keypress
releaseKey();
}
if (IRcompare(numberpulses, Downarrow))
{
digitalWrite(13, HIGH); // set the LED on
//Serial.print("Down arrow");
buf[2] = 81;
Serial.write(buf, 8); // Send keypress
releaseKey();
}
if (IRcompare(numberpulses,Ok))
{
digitalWrite(13, HIGH); // set the LED on
//Serial.print("OKKK");
buf[2] = 88;
Serial.write(buf, 8); // Send keypress
releaseKey();
}
*/
// digitalWrite(13, HIGH); // set the LED on
delay(100);
digitalWrite(13, LOW); // set the LED on
}//void
void releaseKey()
{
buf[0] = 0;
buf[2] = 0;
Serial.write(buf, 8); // Release key
delay(100);
}
int listenForIR()
{
currentpulse = 0;
while (1) {
if(Serial.available() >0 ){return 0;}
uint16_t highpulse, lowpulse; // temporary storage timing
highpulse = lowpulse = 0; // start out with no pulse length
// while (digitalRead(IRpin)) { // this is too slow!
while (IRpin_PIN & _BV(IRpin)) {
if(Serial.available() >0 ){return 0;}
// pin is still HIGH
// count off another few microseconds
highpulse++;
delayMicroseconds(RESOLUTION);
// If the pulse is too long, we 'timed out' - either nothing
// was received or the code is finished, so print what
// we've grabbed so far, and then reset
if ((highpulse >= MAXPULSE) && (currentpulse != 0)) {
return currentpulse;
}
}
// we didn't time out so lets stash the reading
pulses[currentpulse][0] = highpulse;
// same as above
while (! (IRpin_PIN & _BV(IRpin)) ) {//_BV(IRpin) same as (1 << IRpin)
if(Serial.available() >0 ){return 0;}
// pin is still LOW
lowpulse++;
delayMicroseconds(RESOLUTION);
if ((lowpulse >= MAXPULSE) && (currentpulse != 0)) {
return currentpulse;
}
}
pulses[currentpulse][1] = lowpulse;
// we read one high-low pulse successfully, continue!
currentpulse++;
}
}
boolean IRcompare(int numpulses, int Signal[])
{
if (numpulses > 3) {
for (int i=0; i< numpulses-1; i++) {
int oncode = pulses[i][1] * RESOLUTION / 10;
int offcode = pulses[i+1][0] * RESOLUTION / 10;
// check to make sure the error is less than FUZZINESS percent
if ( abs(oncode - Signal[i*2 + 0]) <= (Signal[i*2 + 0] * FUZZINESS / 100)) {
// Serial.print(" (ok)");
}
else {
// Serial.print(" (x)");
return false;
}
if ( abs(offcode - Signal[i*2 + 1]) <= (Signal[i*2 + 1] * FUZZINESS / 100)) {
// Serial.print(" (ok)");
} else {
// Serial.print(" (x)");
// we didn't match perfectly, return a false match
return false;
}
// Serial.println();
}
// Everything matched!
return true;
}
else
return false;
}