Following the example indicated in the previous post, I've modified the remote control code to a simpler version. I've deleted all the error checking because the code only acts upon a valid code (uses a switch statement) thus if a code is invalid, nothing will be done and therefore the error checking is not necessary. Just like before, it is interrupt driven.
The Sony TV remote protocol is the simplest to program because we only need to detect the start pulse and then determine if the length of the next 12 pulses (13 pulses total).
- The pulses are only measured while low
- The first pulse, the start pulse, lasts about 2.4 ms (2400 microseconds)
- The following pulses are 1.2 ms (1200 microseconds) for a 1, 0.6 ms (600 microseconds) for a 0
- Each data pulse is about 0.3 ms (300 microseconds) apart
- Every set of 13 pulses is about 20-30 ms apart from each other, repeating when a button is held down
The interrupt service routine is very simple. The remote signal is connected to pin 3 (which in Arduino is interrupt 1). When there is a pulse, an interrupt is generated and the service routine sets a flag:
void remoting() // The ISRAnd in the setup portion of the Arduino code, the interrupt routine is attached:
{
remoteOn=1;
}
attachInterrupt (1, remoting, FALLING);We detect the FALLING edge of the pulse because the pulses pull down. Once the flat is set (indicating that there is remote control signals, we proceed to detect and decode the pulses with the following code:
The while loop waits for the start pulse, however when there is no start pulse and we are still inside this loop, we need a way to exit this loop. We use the duration!=0 condition.int getIRKey() { int duration=1; int result=0; while((duration=pulseIn(IRPIN, LOW, 50000)) < 2200 && duration!=0) { //do nothing waiting for start pulse } int mask = 1; // set mask to bit 0 for (int idx = 0; idx < 12; idx++) // get all 12 bits { duration = pulseIn(IRPIN, LOW, 2000); // measure the bit pulse if (duration > ONEPULSE) // 1 bit? result |= mask; // yes, update ir code mask <<= 1; // shift mask to next bit } return result; }
In the main remote loop we detect the pulses and perform the functions specified by the codes as follows:
while (remoteOn==1)I found that I needed some delay to get rid of "spurious interrupts" (interrupts that resulted in invalid code). You may or may not need this delay. Invalid code are innocuous because they are ignored in the switch statement.
{
int key = getIRKey(); //Fetch the key
// Interpret the keys and do something: increase volume, etc
// I use a switch statement
delay (30);
remoteOn=0; //reset flag
}
Note: some parts of the code is missing. Please see the full code from the link above.
3 comments:
I’m not sure I understand your question. The ir command can be sent several hundred times a second. The camera is limited by it’s design to a few shots a second. Even if I have the intervalometer set as fast as it can go, my d40 shoots 3 frames per second until the card gets bogged down, and then it slows down.
Hi, could you please publish the whole version of the code with your changes. I don't see the link you are referring to. thanks
Rade M.
The link is in the side bar: v0.7 is the one I use now.
Post a Comment