Go Down

Topic: Using the Arduino as an Apple Remote (Read 1 time) previous topic - next topic

hylkepylke

Hi there,

I found this article on the web (http://www.instructables.com/id/DIY-Apple-Remote-Shield-for-the-Arduino/) to make the Arduino function like an Apple Remote. All is going well, but there's this one bug, where I can't send another command within 5 seconds of the previous command. For instance, when I pause/play, iTunes starts playing, but when I press pause/play again it does nothing. If I wait for 5 second and then press the button again, it works again.

I'm sure this is very easy to solve, but I'm not experienced enough to find the fault. The guy who wrote the library says it has something to do with the repeat-code of the NEC IR protocol (which is used by the Apple Remote), but when I try to implement the repeat-code, it doesn't solve anything.

Can someone please help me? The IR-code is made up of 4 bytes, the first one is the unique Apple Remote identifier, the second one is the actual button press, and the last two are the Apple Device identifiers.

Here are the files:
http://dl.dropbox.com/u/575730/AppleRemote2.zip

LAVco

Code: [Select]
void AppleRemoteSender::send(byte remote_id, byte key)
{
     // Timekeeping to make the signal 110ms long
     int time = 0;
     
     //prepare data
     long temp = remote_id;
     temp = temp << 8;
     temp += key;
     temp = temp << 16;
     temp += APPLE_ID;
     
     //send preamble
     oscWrite(9000);
     delayMicroseconds(4500);

     byte bit = 0;
     //send data
     for(int i = 0; i < 32; i++)
     {
           bit = temp % 2;
           temp = temp >> 1;
           //space
           oscWrite(560);
           time += 560;

           //data
           if(bit == 0)
           {
                 delayMicroseconds(565);
                 time += 565;
           }
           else
           {
                 delayMicroseconds(1690);
                 time += 1690;
           }
     }
     //end of data header
     oscWrite(560);
     time += 560;
     
     delayMicroseconds(110000 - 9000 - 4500 - time);
     
}


Here is the section with the most delays...I would start there.  Also read up on Apple's IR protocol to see what their specs state for transmission delays (e.g. how to long should you wait before sending the next message).

Eric
Common sense is not so common...

hylkepylke

Well that's the point, according to the NEC IR protocol all that should be working. I haven't implemented the repeat code yet, but when I try to do that it doesn't work.

Gido

In the constructor of the AppleRemoteSender class, it's talking to pins. In your code, you're initialising the class in global memory.

I recently learned that this might be a bad idea, and although I doubt it will solve your problem, it is an unnecessary risk.

I suggest to move the initialisation to the setup() method:

Code: [Select]
//Arduino Apple Remote

#include <AppleRemote2.h> //Stuff for the remote controller

int irLed = 13;      // IR LED connected to digital pin 13
int lastSent;

byte remoteID = 0x05; //Stuff for the remote controller
AppleRemoteSender ars; // Declare ars (EDITED)

//Control Buttons
int play = 10;
int next = 8;
int previous = 12;
int volUp = 9;
int volDown = 11;

// The setup() method runs once, when the sketch starts
void setup()   {
 ars = AppleRemoteSender(irLed, remoteID); // Init ars (EDITED)            
 // initialize the digital pin as an output:
 pinMode(play, INPUT);
 pinMode(next, INPUT);
 pinMode(previous, INPUT);
 pinMode(volUp, INPUT);
 pinMode(volDown, INPUT);
 digitalWrite(next, HIGH);
 digitalWrite(previous, HIGH);
 digitalWrite(volUp, HIGH);
 digitalWrite(volDown, HIGH);
 digitalWrite(play, HIGH);
 
}


But why, in your loop() method, do you send each command three times?

Code: [Select]
 if(digitalRead(play) == LOW){
     if(lastSent == play){
           ars.repeat();
           ars.repeat();
           ars.repeat();
     }
     else{
           ars.play(); //Transmit the codes for Play/Pause
           ars.play();
           ars.play();
           lastSent = play;
     }
 }


Is that needed for something?

Go Up