Forum >Replies by anonymous
userhead anonymous
Replies (20)
  • You Reply: Here is a schematic of what I imagine. If D is positive, the Green LED lights. If D is negative, the Red LED lights.

    [img]

    If D is configured as an input, both LEDs may glow very dimly but most likely be off if the resistors are large enough. I would suggest 1K-2K. These LEDs should not be too bright or draw too much current because people may want to light up as many as 8 of them at a time. 16 if possible. The LED could be two descrete 0805 LEDs like I drew or they could be one package with a dual LED red and green chip inside. Either way would work. The important part is the mechanics. The connector block they are mounted on has to fit side by side in the expansion shield so they can be no more than 0.1 inch thick and 0.3 inches deep. They can be as tall as you need.

    I would be willing to pay $2 each and I would want at least 16 of them so $32 for me.
  • You Reply: fj604, I need your help making a IrDA receiver driver. It would be similar to Arduino’s new virtual RS-232 software. IrDA is a communications protocol for PDA devices. It’s basically a modified version of RS-232 to communicate over IR. They shortened the pulse widths so it can flash the IrLED brighter and use less power.  My application is to use the small inexpensive readily available PDA keyboards with the Arduino using DFrobot’s IR receiver board. It could also be used to receive data from a PDA.
  • You Reply: Yes, This is just for low speed switching purposes. Programs that I later plan to use to drive large banks of relays. I've been working with I2C boards and also cascading multiple shift registers. There are so many outputs. I want to be able to see if my code is actually doing what I think it is. I have used a 16 channel relay board and just mostly watch the LEDs and put a lot of wear on the relays. Not really the prime thing for debugging. Little LEDs like this would be really helpful to just plug in and make sure you are outputting when and where you think you are.
  • You Reply: In most normal cases, these boards are really rugged, you can short the outputs, handle them without wearing any static protective straps, and even reverse the polarity on the input power. I've even put 15VDC in instead of 12VDC which they say is the maximum. But like hookedup said, you can not put more than +5V between the VCC and GND pins because there is no protection there.  Those pins are typically used for power output.
    You need one of these:
    [img]

    [url=http://www.arduino.cc/playground/Learning/9VBatteryAdapter]http://www.arduino.cc/playground/Learning/9VBatteryAdapter[/url]
    DFrobot should make some. They would be handy to have
  • You Reply: Nice job on that library and the game. That's some really good programming.
    I use this LCD & Keypad Shield and I also use the I2C LCD with the ADKeyboard Module
    DFR0075. which uses the exact same analog values as the built in keyboard on the LCD shield.

    The main problem I got was occasionally getting back incorrect key presses. If the processor happens to scan the keypad value right as you press a key and the waveform is still rising, you'll get a bad keypress. So what I did is I took a measurement waited 5ms then took another measurement to verify they were equal. This caused another problem which is if the analog value happens to be right between two bits it constantly switches so to totally solve the problem I had to take a measurement, wait 5ms take another measurement subtract the two, take the absolute value, then verify the result was less than 5. It ends up being a lot of code, but you get back perfect keypresses each time. Attaches is what I did. It makes these keyboards work much more reliably.

    [code]
    int read_LCD_buttons() //  read the buttons keyboard voltage test routine. Returns int ex: 'btnTEST' is #defined as '4'
        // button returned values centered at these values: 002, 130, 306, 478, 720 added approx 50 for buffer zone
        // use 'buttonTEST' program on seperate file to display the button values or troubleshoot
    {
    adc_key_in = analogRead(KEYPAD);  // read the value from the sensor for keypad and then test the value for button levels.
    delay(5); //switch debounce delay. Increase this delay if incorrect switch selections are returned.
    int k = (analogRead(KEYPAD) - adc_key_in); //gives the button a slight range to allow for a little contact resistance noise
    if (5 < abs(k)) return btnNONE;  // double checks the keypress. If the two readings are not equal +/-k value after debounce delay, it tries again. if (adc_key_in > 770)  return btnNONE;  // This is the 1st option for speed reasons since it will be the most likely result.
    if (adc_key_in > 770)  return btnNONE;  // This is the 1st option for speed reasons since it will be the most likely result.
    if (adc_key_in < 50)  return btnSINGLE;// SINGLE test            '>' button
    if (adc_key_in < 180)  return btnUP;    // UP  test number scroll '^' button
    if (adc_key_in < 355)  return btnDOWN;  // DOWN test number scroll 'v' button
    if (adc_key_in < 530)  return btnFAIL;  // FAILed re-test          '>>' button
    if (adc_key_in < 770)  return btnTEST;  // TEST all automatically  'TEST' button
    }

    [/code]

    I thought you may want to know about this simple interfacing digital to an analog world fact to make sure your library double checks the keypress with a pass through range.
  • You Reply: Nice job on that library and the game. That's some really good programming.
    I use this LCD & Keypad Shield and I also use the I2C LCD with the ADKeyboard Module
    DFR0075. which uses the exact same analog values as the built in keyboard on the LCD shield.

    The main problem I got was occasionally getting back incorrect key presses. If the processor happens to scan the keypad value right as you press a key and the waveform is still rising, you'll get a bad keypress. So what I did is I took a measurement waited 5ms then took another measurement to verify they were equal. This caused another problem which is if the analog value happens to be right between two bits it constantly switches so to totally solve the problem I had to take a measurement, wait 5ms take another measurement subtract the two, take the absolute value, then verify the result was less than 5. It ends up being a lot of code, but you get back perfect keypresses each time. Attaches is what I did. It makes these keyboards work much more reliably.

    [code]
    int read_LCD_buttons() //  read the buttons keyboard voltage test routine. Returns int ex: 'btnTEST' is #defined as '4'
        // button returned values centered at these values: 002, 130, 306, 478, 720 added approx 50 for buffer zone
        // use 'buttonTEST' program on seperate file to display the button values or troubleshoot
    {
    adc_key_in = analogRead(KEYPAD);  // read the value from the sensor for keypad and then test the value for button levels.
    delay(5); //switch debounce delay. Increase this delay if incorrect switch selections are returned.
    int k = (analogRead(KEYPAD) - adc_key_in); //gives the button a slight range to allow for a little contact resistance noise
    if (5 < abs(k)) return btnNONE;  // double checks the keypress. If the two readings are not equal +/-k value after debounce delay, it tries again. if (adc_key_in > 770)  return btnNONE;  // This is the 1st option for speed reasons since it will be the most likely result.
    if (adc_key_in > 770)  return btnNONE;  // This is the 1st option for speed reasons since it will be the most likely result.
    if (adc_key_in < 50)  return btnSINGLE;// SINGLE test            '>' button
    if (adc_key_in < 180)  return btnUP;    // UP  test number scroll '^' button
    if (adc_key_in < 355)  return btnDOWN;  // DOWN test number scroll 'v' button
    if (adc_key_in < 530)  return btnFAIL;  // FAILed re-test          '>>' button
    if (adc_key_in < 770)  return btnTEST;  // TEST all automatically  'TEST' button
    }

    [/code]

    I thought you may want to know about this simple interfacing digital to an analog world fact to make sure your library double checks the keypress with a pass through range.
  • You Reply: Nice job on that library and the game. That's some really good programming.
    I use this LCD & Keypad Shield and I also use the I2C LCD with the ADKeyboard Module
    DFR0075. which uses the exact same analog values as the built in keyboard on the LCD shield.

    The main problem I got was occasionally getting back incorrect key presses. If the processor happens to scan the keypad value right as you press a key and the waveform is still rising, you'll get a bad keypress. So what I did is I took a measurement waited 5ms then took another measurement to verify they were equal. This caused another problem which is if the analog value happens to be right between two bits it constantly switches so to totally solve the problem I had to take a measurement, wait 5ms take another measurement subtract the two, take the absolute value, then verify the result was less than 5. It ends up being a lot of code, but you get back perfect keypresses each time. Attaches is what I did. It makes these keyboards work much more reliably.

    [code]
    int read_LCD_buttons() //  read the buttons keyboard voltage test routine. Returns int ex: 'btnTEST' is #defined as '4'
        // button returned values centered at these values: 002, 130, 306, 478, 720 added approx 50 for buffer zone
        // use 'buttonTEST' program on seperate file to display the button values or troubleshoot
    {
    adc_key_in = analogRead(KEYPAD);  // read the value from the sensor for keypad and then test the value for button levels.
    delay(5); //switch debounce delay. Increase this delay if incorrect switch selections are returned.
    int k = (analogRead(KEYPAD) - adc_key_in); //gives the button a slight range to allow for a little contact resistance noise
    if (5 < abs(k)) return btnNONE;  // double checks the keypress. If the two readings are not equal +/-k value after debounce delay, it tries again. if (adc_key_in > 770)  return btnNONE;  // This is the 1st option for speed reasons since it will be the most likely result.
    if (adc_key_in > 770)  return btnNONE;  // This is the 1st option for speed reasons since it will be the most likely result.
    if (adc_key_in < 50)  return btnSINGLE;// SINGLE test            '>' button
    if (adc_key_in < 180)  return btnUP;    // UP  test number scroll '^' button
    if (adc_key_in < 355)  return btnDOWN;  // DOWN test number scroll 'v' button
    if (adc_key_in < 530)  return btnFAIL;  // FAILed re-test          '>>' button
    if (adc_key_in < 770)  return btnTEST;  // TEST all automatically  'TEST' button
    }

    [/code]

    I thought you may want to know about this simple interfacing digital to an analog world fact to make sure your library double checks the keypress with a pass through range.
  • You Reply: There is an LED and a switch on that board that you can use. I basically soldered in some machined pin receptacles in those holes next to the LED and the switch. Now I can easily install buss wire and use them. Here is a picture. I pulled this out of an old bin and I'm not sure what I was doing exactly. but it shows how the buss wire plugs into the machined pin sockets. I got the machined pin sockets by breaking them out of an old DIP socket.
    [img]
  • You Reply: also try working your contrast resistor back and forth a few times. Sometimes the wipers get dirty and they don't make contact. If you turn it back and forth a few times, it kind of wipes itself clean.
  • You Reply: also try working your contrast resistor back and forth a few times. Sometimes the wipers get dirty and they don't make contact. If you turn it back and forth a few times, it kind of wipes itself clean.
  • You Reply: also try working your contrast resistor back and forth a few times. Sometimes the wipers get dirty and they don't make contact. If you turn it back and forth a few times, it kind of wipes itself clean.
  • You Reply: I just tried mine again and it came right on displaying Hello, world!
    If you are using a 4 pin straight through connector like I am, make sure you are plugging into the un-shrouded connector because the shrouded one reverses the SDA and SCL lines. But I see you have already tried reversing them. You also get the backlight on I think you have to get the address right to get the backlight on.
    See if you can get the backlight to flash with this code. If the backlight flashes then you definitely have it hooked up and programming right. Then only two things could be wrong, your contrast resistor needs adjustment or your LCD display is defective. When all else fails, the only real way to figure that out is get another part.

    [code]

    //DFRobot.com
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>

    LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

    void setup()
    {
      lcd.init();                      // initialize the lcd

      // Print a message to the LCD.
      lcd.backlight();
      lcd.print("Flashing World");
     
    }

    void loop()
    {
      lcd.backlight();
      delay(100);
      lcd.noBacklight();
      delay(100);
    }
    [/code]
  • You Reply: I just tried mine again and it came right on displaying Hello, world!
    If you are using a 4 pin straight through connector like I am, make sure you are plugging into the un-shrouded connector because the shrouded one reverses the SDA and SCL lines. But I see you have already tried reversing them. You also get the backlight on I think you have to get the address right to get the backlight on.
    See if you can get the backlight to flash with this code. If the backlight flashes then you definitely have it hooked up and programming right. Then only two things could be wrong, your contrast resistor needs adjustment or your LCD display is defective. When all else fails, the only real way to figure that out is get another part.

    [code]

    //DFRobot.com
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>

    LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

    void setup()
    {
      lcd.init();                      // initialize the lcd

      // Print a message to the LCD.
      lcd.backlight();
      lcd.print("Flashing World");
     
    }

    void loop()
    {
      lcd.backlight();
      delay(100);
      lcd.noBacklight();
      delay(100);
    }
    [/code]
  • You Reply: I just tried mine again and it came right on displaying Hello, world!
    If you are using a 4 pin straight through connector like I am, make sure you are plugging into the un-shrouded connector because the shrouded one reverses the SDA and SCL lines. But I see you have already tried reversing them. You also get the backlight on I think you have to get the address right to get the backlight on.
    See if you can get the backlight to flash with this code. If the backlight flashes then you definitely have it hooked up and programming right. Then only two things could be wrong, your contrast resistor needs adjustment or your LCD display is defective. When all else fails, the only real way to figure that out is get another part.

    [code]

    //DFRobot.com
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>

    LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

    void setup()
    {
      lcd.init();                      // initialize the lcd

      // Print a message to the LCD.
      lcd.backlight();
      lcd.print("Flashing World");
     
    }

    void loop()
    {
      lcd.backlight();
      delay(100);
      lcd.noBacklight();
      delay(100);
    }
    [/code]
  • You Reply: If you use the Interface Shield For Arduino DFR0074 change the pins definitions as follows:
    Code: Select all
    #define SCLK 3  // (1) DFR0072 ShiftOut SCLK Serial-Clock Input
    #define iCS 8     // (3) DFR0072 ShiftOut /CS Chip-Select Input set low to receive data, set high to output
    #define DIN 9    // (5) DFR0072 ShiftOut DIN Serial-Data Input 
    
  • You Reply: That's the right library. I use that DFR0063 LCD I2C Display too.
    You need to install the libraries in the proper directory.
    I used c:\Programs\Arduino\libraries\LiquidCrystal_I2C on my computer
    in the LiquidCrystal_I2C directory you should have the files 
    keywords.txt
    LiquidCrystal_I2C.cpp
    LiquidCrystal_I2C.h
    LiquidCrystal_I2C.o
    Once you have all that, the code for Hello World is:
    [code]

    //DFRobot.com
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>

    LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

    void setup()
    {
      lcd.init();                      // initialize the lcd

      // Print a message to the LCD.
      lcd.backlight();
      lcd.print("Hello, world!");
    }

    void loop()
    {
    }
    [/code]
  • You Reply: That's the right library. I use that DFR0063 LCD I2C Display too.
    You need to install the libraries in the proper directory.
    I used c:\Programs\Arduino\libraries\LiquidCrystal_I2C on my computer
    in the LiquidCrystal_I2C directory you should have the files 
    keywords.txt
    LiquidCrystal_I2C.cpp
    LiquidCrystal_I2C.h
    LiquidCrystal_I2C.o
    Once you have all that, the code for Hello World is:
    [code]

    //DFRobot.com
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>

    LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

    void setup()
    {
      lcd.init();                      // initialize the lcd

      // Print a message to the LCD.
      lcd.backlight();
      lcd.print("Hello, world!");
    }

    void loop()
    {
    }
    [/code]
  • You Reply: That's the right library. I use that DFR0063 LCD I2C Display too.
    You need to install the libraries in the proper directory.
    I used c:\Programs\Arduino\libraries\LiquidCrystal_I2C on my computer
    in the LiquidCrystal_I2C directory you should have the files 
    keywords.txt
    LiquidCrystal_I2C.cpp
    LiquidCrystal_I2C.h
    LiquidCrystal_I2C.o
    Once you have all that, the code for Hello World is:
    [code]

    //DFRobot.com
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>

    LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

    void setup()
    {
      lcd.init();                      // initialize the lcd

      // Print a message to the LCD.
      lcd.backlight();
      lcd.print("Hello, world!");
    }

    void loop()
    {
    }
    [/code]
  • You Reply: Here is another program that uses all 16 bits at a time. You don't need to worry about PORTS let the program do it.
    Code: Select all
    
    /****************************************************************************** 
    Test Program for the 12C PCA9555 Board part number DFR0013 IIC TO GPIO module from dfrobot.com
    16 outputs that I used to drive this relay board made in Bulgaria
    http://www.denkovi.com/product/21/16-relay-board-for-your-pic-avr-project-12v.html
    it's a great little expansion board that can be used to drive LEDs or anything you want.
    made by [email protected]
    January 07th 2011
    My biggest problem was figuring out the I2C address of the PCA9555.
    If there are no jumpers the address is 1 0 0 '1 1 1'
    Jumpers make the address 1 0 0 '0 0 0'. This is opposite of what I expected.
    ******************************************************************************/ 
    
    #include <Wire.h> 
    
    //  with no jumpers the full address is   1 0 0 1 1 1    1 0 0 A2 A1 A0  0x27 is the default address for the DFR0013 board with no jumpers.
    #define PCA9555 0x27 // 0x27 is default address for the DFR0013 board with no jumpers.
                         // 0x20 is address for the DFR0013 board with all jumpers.
    // COMMAND BYTE TO REGISTER RELATIONSHIP FROM PCA9555 DATA SHEET
    // At reset, the device's ports are inputs with a high value resistor pull-ups to VDD
    // If relays turning on during power up are a problem. Add a pull down resistor to each relay transistor base.
    
    #define IN_P0 0x00 // Read Input port0
    #define IN_P1 0x01 // Read Input port1
    #define OUT_P0 0x02 // Write Output port0
    #define OUT_P1 0x03 // Write Output port1
    #define INV_P0 0x04 // Input Port Polarity Inversion port0 if B11111111 is written input polarity is inverted
    #define INV_P1 0x05 // Input Port Polarity Inversion port1 if B11111111 is written input polarity is inverted
    #define CONFIG_P0 0x06 // Configuration port0 configures the direction of the I/O pins 0 is output 1 is input
    #define CONFIG_P1 0x07 // Configuration port1 configures the direction of the I/O pins 0 is output 1 is input
    
    #define PAUSE 200
    
    void setup()
    {
      Wire.begin(PCA9555); // join i2c bus (address optional for master) tried to get working
      write_io (CONFIG_P0, B00000000); //defines all pins on Port0 are outputs
      write_io (CONFIG_P1, B00000000); //defines all pins on Port1 are outputs  
      write_io (OUT_P0, B00000000); //clears all relays
      write_io (OUT_P1, B00000000); //clears all relays
      delay (PAUSE);
    }
    
    
    void loop()
    {
      set_relay (0b0000000000000001);
      delay (PAUSE);
      set_relay (0b0000000000000010);
      delay (PAUSE);
      set_relay (0b0000000000000100);
      delay (PAUSE);
      set_relay (0b0000000000001000);
      delay (PAUSE);
      set_relay (0b0000000000010000);
      delay (PAUSE);
      set_relay (0b0000000000100000);
      delay (PAUSE);
      set_relay (0b0000000001000000);
      delay (PAUSE);
      set_relay (0b0000000010000000);
      delay (PAUSE);
      set_relay (0b0000000100000000);
      delay (PAUSE);
      set_relay (0b0000001000000000);
      delay (PAUSE);
      set_relay (0b0000010000000000);
      delay (PAUSE);
      set_relay (0b0000100000000000);
      delay (PAUSE);
      set_relay (0b0001000000000000);
      delay (PAUSE);
      set_relay (0b0010000000000000);
      delay (PAUSE);
      set_relay (0b0100000000000000);
      delay (PAUSE);
      set_relay (0b1000000000000000);
      delay (PAUSE);
      set_relay (0b0000000000000000);
      delay (PAUSE);
      set_relay (0b1111111111111111);
      delay (PAUSE);
      set_relay (0b0000000000000000);
      delay (PAUSE);
      set_relay (0b1111111111111111);
      delay (PAUSE);
      set_relay (0b0000000000000000);
      delay (PAUSE);
    }
     
      void set_relay (word data) //requires a word for the 16 bits
     {
      write_io(OUT_P0,lowByte(data)); // send low byte
      write_io(OUT_P1,highByte(data)); // send high byte
     }
    
      void write_io(int command, int value)
     {
      Wire.beginTransmission(PCA9555);
      Wire.send(command),Wire.send(value); // send command then send value
      Wire.endTransmission();
     }
    
    
    
    
  • You Reply: Thanks fj604 your code with the library worked, but like you said, the Sony remote works much better with it. I modified this program now to use the full 32 bits using unsigned longs. This gives you the control you need to make this remote work good from a distance. This program allows the user to set different bit thresholds needed for this remote. The bit start threshold is extra long for some reason. But now you can use it from across the room and it also gives less errors. Try it and you'll notice a big increase in distance and less errors. Also, if a key is undefined, the program returns the number of the key so you don't need to look up the number.

    Code: Select all
    
    /* Peter Strobl Test Electronics Jan 9th 2011
       changed the original program to use the full 32 Bits from the
       IR Kit For Arduino Model: DFR0107 32 bit controller. 
       All keypresses are sent to the serial monitor at 9600 baud.
       pulseIn is always HIGH. The phototransistor in the kit does not invert the signal.
       uses pin 13 for heartbeat debug
       32 bits requires an unsigned long variable.  
    */
    
    #define IR_BIT_LENGTH 32    // number of bits sent by IR remote
    #define BIT_1 1300          // Binary 1 threshold (Microseconds)
    #define BIT_0 300           // Binary 0 threshold (Microseconds)
    #define BIT_START 3000      // Start bit threshold (Microseconds)
    
    #define IR_PIN 10            // IR Sensor pin
    #define LED_PIN 13          // LED goes off when signal is received
    
    int debug = 0;              // flag as 1 to output raw IR pulse data stream length in microseconds
    int output_verify = 0;      // flag as 1 to print decoded verification integers. same number for all buttons
    int output_key = 0;         // flag as 1 to print decoded key integers
    
    void setup() {
      pinMode(LED_PIN, OUTPUT);	//This shows when ready to recieve
      pinMode(IR_PIN, INPUT);
      digitalWrite(LED_PIN, LOW);
      Serial.begin(9600);
    }
    
    void loop() {
      digitalWrite(LED_PIN, HIGH);
      unsigned long key = get_ir_key();
      
      digitalWrite(LED_PIN, LOW);  // turn LED off while processing response
      do_response(key);
      delay(130);                  // 2 cycle delay to cancel duplicate keypresses
    }
    
    /*
      wait for a keypress from the IR remote, and return the
      integer mapping of that key (e.g. power button on remote returns 
      the unsigned long 4278238976)
    */
    
    unsigned long get_ir_key() 
    {
      int pulse[IR_BIT_LENGTH];
      int bits[IR_BIT_LENGTH];
    
      do {} //Wait for a start bit
      while(pulseIn(IR_PIN, HIGH) < BIT_START);
    
      read_pulse(pulse);
      pulse_to_bits(pulse, bits);
      return bits_to_int(bits);
    }
    
    
    /*
      use pulseIn to receive IR pulses from the remote.
      Record the length of these pulses (in ms) in an array
    */
    
    void read_pulse(int pulse[])
    {
      for (int i = 0; i < IR_BIT_LENGTH; i++)
      {
        pulse[i] = pulseIn(IR_PIN, HIGH, 10000);
      }
    }
    
    /*
      IR pulses encode binary "0" as a short pulse, and binary "1"
      as a long pulse.  Given an array containing pulse lengths,
      convert this to an array containing binary values
    */
    
    void pulse_to_bits(int pulse[], int bits[])
    {
      if (debug) { Serial.println("-----"); }
      for(int i = 0; i < IR_BIT_LENGTH; i++) 
      {
        if (debug) { Serial.println(pulse[i]); }
        if(pulse[i] > BIT_1) //is it a 1?
        {
          bits[i] = 1;
        }  
        else if(pulse[i] > BIT_0) //is it a 0?
        {
          bits[i] = 0;
        } 
        else //data is invalid...
        {
          Serial.println("Error");
        }
      }
    }
    
    /*
      convert an array of binary values to a single base-10 integer
    */
    
    unsigned long bits_to_int(int bits[])
    {
      unsigned long result = 0;
      unsigned long seed = 1;
      
      //Convert bits to integer
      for(int i = 0 ; i < IR_BIT_LENGTH ; i++) 
      {		  
        if(bits[i] == 1) 
        {
    	result += seed;
        }   
        seed *= 2;
      }
      return result;
    }
    
    
    /* 
      respond to specific remote-control keys with different behaviors
    */
    
    void do_response(unsigned long key)
    {  
      
      if (output_key)
       {
          Serial.print("Key ");
          Serial.println(key);
       }
      
      switch (key)
      {
        case 4278238976:  // turns on UUT power
          Serial.println("POWER");
          break;
    
        case 4244815616:  // FUNC/STOP turns off UUT power
          Serial.println("FUNC/STOP");
          break;
    
        case 4211392256:  // |<< ReTest failed Test
          Serial.println("|<<");
          break;
    
        case 4194680576:  // >|| Test
          Serial.println(">||");
          break;
    
        case 4177968896:  // >>| perform selected test number
          Serial.println(">>|");
          break;
    
        case 4261527296:  // VOL+ turns on individual test beeper
          Serial.println("VOL+");
          break;
    
        case 4127833856:  // VOL- turns off individual test beeper
          Serial.println("VOL-");
          break;
    
        case 4144545536:  // v scroll down tests
          Serial.println("v");
          break;
    
        case 4111122176:  // ^ scroll up tests
          Serial.println("^");
          break;
    
        case 4060987136:  // EQ negative tests internal setup
          Serial.println("EQ");
          break;
    
        case 4044275456:  // ST/REPT Positive tests Select Test and Repeat Test
        Serial.println("ST/REPT");
          break;
    
        case 4077698816:  // 0
          Serial.println("0");
          break;
    
        case 4010852096:  // 1
          Serial.println("1");
          break;
    
        case 3994140416:  // 2
          Serial.println("2");
          break;
    
        case 3977428736:  // 3
          Serial.println("3");
          break;
    
        case 3944005376:  // 4
          Serial.println("4");
          break;
    
        case 3927293696:  // 5
          Serial.println("5");
          break;
    
        case 3910582016:  // 6
          Serial.println("6");
          break;
    
        case 3877158656:  // 7
          Serial.println("7");
          break;
    
        case 3860446976:  // 8
          Serial.println("8");
          break;
    
        case 3843735296:  // 9
          Serial.println("9");
          break;
         
        default:
          {
            Serial.print("Key ");
            Serial.print(key);
            Serial.println(" not programmed");
          }
        break;
      }
    }