Pages: [1]   Go Down
Author Topic: Using the Arduino as an Apple Remote  (Read 1243 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 6
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Nova Scotia, CA
Offline Offline
Jr. Member
**
Karma: 0
Posts: 64
A world that runs on bits and bytes!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
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
Logged

Common sense is not so common...

0
Offline Offline
Newbie
*
Karma: 0
Posts: 6
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Netherlands
Offline Offline
Newbie
*
Karma: 0
Posts: 30
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
//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:
 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?
Logged

Pages: [1]   Go Up
Jump to: