keep a pin high as long as a key on a ir remote is held down

Hi everyone.I am configuring a sony tv IR remote to control several functions on an amplifier through arduino. I am using pmalmsten's code from http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1176098434 to decode the remote codes. I am only stuck on the volume up function which is supposed to keep a pin high as long as it is held down. My amplifier's volume is controlled through a motorized(via an H-bridge) pot.I need to keep the H-bridge's pin high as long as i hold down that volume key to keep the motor moving. Sony tv remote sends the same code repeatedly if you hold down the key. Any ideas on how to program that particular function?? I am new to arduino and programming.Thank You.

Look at the blink without delay example for a start.

You use the millis() function to make a note of the system time each time when you see the command, as well as putting the pin high.
Then in the loop() function you check that the last time you saw the command minus the current system time has not exceeded some time out threshold and if it has put the pin low.
Set the timeout threshold to just greater than the command repetition rate from your remote.

thanks. I wrote this.
this program keeps the pin high even when i release the button on remote.Please tell where I am wrong.

loop portion of the code.txt (644 Bytes)

thanks.here is the loop portion of the code:

void loop() {
  int key = getIRKey();//getIRKey() is the function to decode and provide a unique key for each button on remote
  Serial.print("Key Recieved: ");
  Serial.println(key);
  unsigned long currentmillis;// the variable to mark the time when the key was received
  switch(key){
    case 146://146 is the code for the volume up key on my remote
    digitalWrite(3, HIGH);// keep the pin high
    currentmillis = millis();//mark the time
    break;
    delay(200);
  }
  if((millis()-currentmillis)>500)//if it has been 0.5 seconds since the key was received put the pin to low
  { 
    digitalWrite(3, LOW);
  }
  
}

sorry i dont know how to put the codes in the post..

You select the code and hit the # icon. It will then be in a box. Go back and modify that last post.

However for a start define currentmillis outside the loop so it is not initialised each time through the loop and define it as a long.

still no luck.I wrote some lines to watch the activity on the serial monitor. Whenever i release the button arduino stops counting the time, so it never goes to the 'if' function. It seems to me that it waits for the getIRKey() function,then moves on to the next sections(well!thats how the loop works,right?). I think I need to execute the 'if' statement independent from the getIRKey(). Am I making any sense?

why not as an unsigned long?

I think,if you take (currentmillis - millis()),in the ‘if’ statement,it will give you negative values. an unsigned long asuumes only positive values.

You need to give currentMillis global or static scope. No point in having a delay after a break.

It's no good staying still no luck, you need to post what is not working. We can't guess what mistakes you are making.

soumya: I think,if you take (currentmillis - millis()),in the 'if' statement,it will give you negative values. an unsigned long asuumes only positive values.

his code:

if((millis()-currentmillis)>500)//if it has been 0.5 seconds since the key was received put the pin to low

and here's the beauty that I had to be reminded of: with unsigned a result that would return a small negative gets a large positive as result. If unsigned int currentmillis = 65000 = 0xFDE8 and unsigned int nowmillis = 464 = 0x1D0 then 0x1d0 - 0xfde8 = FFFFFFFFFFFF03E8 of which only the lowest 2 bytes are stored, 0x3E8 = 1000 which is the elapsed milliseconds to get from 65000 to 464 with 16 bits.

sorry Grumpy_Mike. At last I made it working. I looked for a non-blocking code for the IR decoding function, I got it here:http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1176098434/15
look for BroHogan’s post. Thanks to him.

then just added my desired functions there. and for the volume up thing I simply followed Grumpy_Mike.Thank You. Here is my complete code:

/* program to cotrol an amplifier's several functions through a sony tv remote. functions include
power on-off
volume up-down
six modes
one mute button
volume up-down keys control volume through a motorized pot via an H-Bridge
Ir decoding functions posted by BroHogan
Features added by soumya
*/
// pin definitions
#define pwr_pin 2
#define ir_pin 3
#define volUp_pin 10
#define volDown_pin 11
#define mute_pin 12
#define defMode_pin 4
#define modeTwo_pin 5
#define modeThree_pin 6
#define modeFour_pin 7
#define modeFive_pin 8
#define modeSix_pin 9


//variables
volatile boolean IR_Avail;             // flag set if IR has been  read
volatile unsigned int IR_Return;       // returns IR code received
volatile unsigned long ir_mask;        // Loads variable ir_string
volatile unsigned int ir_bit_seq;      // Records bit sequence in ir string
volatile unsigned int ir_string;       // Stores ir string

int volumeUpstate;      //state of volume up pin
int volumeDownstate;    //state of volume down pin
int powerState = 0;         //variable to hold power pin's state
int muteState;          //variable to hold mute pin's state
unsigned long currentmillisUp;     //variable to hold volume up time
unsigned long currentmillisDown;   //variable to hold volume down time

void setup() 
{
  pinMode(ir_pin, INPUT);
  pinMode(pwr_pin , OUTPUT);
  pinMode(volUp_pin , OUTPUT);
  pinMode(volDown_pin , OUTPUT);
  pinMode(mute_pin , OUTPUT);
  pinMode(defMode_pin , OUTPUT);
  pinMode(modeTwo_pin , OUTPUT);
  pinMode(modeThree_pin , OUTPUT);
  pinMode(modeFour_pin , OUTPUT);
  pinMode(modeFive_pin, OUTPUT);
  pinMode(modeSix_pin , OUTPUT);

 
  Serial.begin(9600);
}

void loop() {
  while(IR_Avail)// if key is available
  {
    int key = IR_Return;//Fetch the key
    Serial.print("Key Recieved: ");//print the key
    Serial.println(key);
    switch(key)     // key functions
    {
       case 21: powerOnOff(); break;
       case 18: volUp(); break;
       case 19: volDown(); break;
       case 20: muteOnOff(); break;
       case 0 : defaultmode();break;
       case 1 : modeTwo(); break;
       case 2 : modeThree(); break;
       case 3 : modeFour(); break;
       case 4 : modeFive(); break;
       case 5 : modeSix(); break;
        
       delay(200);
     }
      
      IR_Avail = 0;
    } 
   
   if(volumeUpstate == HIGH)
  {
    stopVolUpswitch();
  } 
   if(volumeDownstate == HIGH)
   {
     stopVolDownswitch();
   }

attachInterrupt(1,IR_ISR,FALLING);
}

void IR_ISR(){ // This ISR is called for EACH pulse of the IR sensor
  if(ir_bit_seq == 0){                 // it is the long start pulse
    for(int i = 0; i<20; i++){         // see if it lasts at least 2 ms
      delayMicroseconds(100); // 100
      if(digitalRead(ir_pin)) return;  // it's doesn't so get out (low active)
    }  
    ir_bit_seq = 1;                    // mark that the start pulse was received
    ir_mask = 1;                       // set up a mask for the next bits
    return;
  }

  delayMicroseconds(900);              // wait 900 us and test
  if(!digitalRead(ir_pin)) ir_string = ir_string | ir_mask;  // Stores 1 in bit
  ir_mask = ir_mask << 1;              // shifts ir_mask by one to the left
  ir_bit_seq++;                        // ir_bit_seq is incrimented by one
  if(ir_bit_seq == 12){                // after remote sends 12 bits it's done
    ir_mask = 63;                     // only want the last 6 bits - the command
    ir_string = ir_string & ir_mask;  // only keep last 6 bits
    IR_Return = ir_string;             // final result
    IR_Avail = true;                   // indicate new command received
    //digitalWrite(led_pin,HIGH);
    ir_bit_seq = 0;                    // clean up
    ir_string = 0;
    ir_mask = 0;
    for(int i = 0; i<25; i++){         // delay to stop repeat 10ms / loop ~250ms about right
      delayMicroseconds(10000);        // 16383 is maximum value so need to repeat
    }
  }
} 
void powerOnOff()
{
       powerState = 1 - powerState;
       if(powerState)
      {
         digitalWrite(pwr_pin, HIGH);
         digitalWrite(defMode_pin, HIGH);
         delay(500);
    
       }
    
       else
      {
         digitalWrite(pwr_pin, LOW);
         digitalWrite(defMode_pin, LOW);
         digitalWrite(modeTwo_pin, LOW);
         digitalWrite(modeThree_pin, LOW);
         digitalWrite(modeFour_pin, LOW);
         digitalWrite(modeFive_pin, LOW);
         digitalWrite(modeSix_pin, LOW);
         digitalWrite(mute_pin, LOW);
         powerState = 0;
         delay(500);
    
      }
}

void volUp()
{    
      if(powerState)
     {
       if(!muteState)
       {
         volumeUpstate = HIGH;
         digitalWrite(volUp_pin, volumeUpstate);
         Serial.println(" vol up On ");
         currentmillisUp = millis();
         Serial.print(" CurrentmillisUp: ");
         Serial.println(currentmillisUp);
       }
     }
}

void volDown()
{     if(powerState)
     { 
       if(!muteState)
       {
        volumeDownstate = HIGH;
        digitalWrite(volDown_pin, volumeDownstate);
        Serial.println(" vol down On ");
        currentmillisDown = millis();
        Serial.print(" CurrentmillisDown: ");
        Serial.println(currentmillisDown);
       }
     }
     
}
 
void stopVolUpswitch()
{
  Serial.print("time: ");
  Serial.println(millis());
  int diffUp =( millis()-currentmillisUp);
  Serial.print(" DifferenceUp: ");
  Serial.println(diffUp);
  if(diffUp > 45)
  {
    volumeUpstate = LOW;
    digitalWrite(volUp_pin, volumeUpstate);
    Serial.println(" OffVolUp ");
}
}
void stopVolDownswitch()
{ 
   Serial.print("time: ");
  Serial.println(millis());
  int diffDown =( millis()-currentmillisDown);
  Serial.print(" DifferenceDown: ");
  Serial.println(diffDown);
  if(diffDown > 45)
  {
    volumeDownstate = LOW;
    digitalWrite(volDown_pin, volumeDownstate);
    Serial.println(" OffVolDown ");
  }
}

void muteOnOff()
{    if(powerState)
     {
       muteState = 1 - muteState;
       if(muteState)
      {
         digitalWrite(mute_pin, HIGH);
    
       }
    
       else
      {
         digitalWrite(mute_pin, LOW);
         muteState = 0;
    
      }
     }
}

void defaultmode()
{
  if(powerState)
 { digitalWrite(defMode_pin, HIGH);
   digitalWrite(modeTwo_pin, LOW);
   digitalWrite(modeThree_pin, LOW);
   digitalWrite(modeFour_pin, LOW);
   digitalWrite(modeFive_pin, LOW);
   digitalWrite(modeSix_pin, LOW);
 }
}
void modeTwo()
{
  if(powerState)
 { digitalWrite(defMode_pin, LOW);
   digitalWrite(modeTwo_pin, HIGH);
   digitalWrite(modeThree_pin, LOW);
   digitalWrite(modeFour_pin, LOW);
   digitalWrite(modeFive_pin, LOW);
   digitalWrite(modeSix_pin, LOW);
 }
}
void modeThree()
{
  if(powerState)
 { digitalWrite(defMode_pin, LOW);
   digitalWrite(modeTwo_pin, LOW);
   digitalWrite(modeThree_pin, HIGH);
   digitalWrite(modeFour_pin, LOW);
   digitalWrite(modeFive_pin, LOW);
   digitalWrite(modeSix_pin, LOW);
 }
}  
void modeFour()
{
  if(powerState)
 { digitalWrite(defMode_pin, LOW);
   digitalWrite(modeTwo_pin, LOW);
   digitalWrite(modeThree_pin, LOW);
   digitalWrite(modeFour_pin, HIGH);
   digitalWrite(modeFive_pin, LOW);
   digitalWrite(modeSix_pin, LOW);
 }
}
void modeFive()
{
  if(powerState)
 { digitalWrite(defMode_pin, LOW);
   digitalWrite(modeTwo_pin, LOW);
   digitalWrite(modeThree_pin, LOW);
   digitalWrite(modeFour_pin, LOW);
   digitalWrite(modeFive_pin, HIGH);
   digitalWrite(modeSix_pin, LOW);
 }
}
void modeSix()
{
  if(powerState)
 { digitalWrite(defMode_pin, LOW);
   digitalWrite(modeTwo_pin, LOW);
   digitalWrite(modeThree_pin, LOW);
   digitalWrite(modeFour_pin, LOW);
   digitalWrite(modeFive_pin, LOW);
   digitalWrite(modeSix_pin, HIGH);
 }
}