The sketch for reading the IR codes for a new remote is below. We will be using Wiring Diagram#the The earlier Gemma v2 and Trinket Mini do not have a built-in hardware serial so we will be using Wiring Diagram #2 Gemma v2 with the USB to TTL Serial Cable. Be sure the Arduino serial console (Putty or screen also work) to 9600 baud, use 8 bits, 1 stop bit, no parity.
Plug in Gemma v2 to your computer with a USB cable and load up the following:
// SPDX-FileCopyrightText: 2018 Limor Fried/ladyada for Adafruit Industries // // SPDX-License-Identifier: CC-BY-SA-3.0 /* Trinket/Gemma compatible Raw IR decoder sketch This sketch/program uses an Adafruit Trinket or Gemma ATTiny85 based mini microcontroller and a PNA4602 to decode IR received. This can be used to make a IR receiver (by looking for a particular code) or transmitter (by pulsing an IR LED at ~38KHz for the durations pulse_index Based on Adafruit tutorial http://learn.adafruit.com/ir-sensor/using-an-ir-sensor and ATTiny program by TinyPCRemote Nathan Chantrell http://nathan.chantrell.net under Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) license SendSoftwareSerial Lirary modification by Nick Gammon from NewSoftwareSerial code GNU Lesser General Public License as published by the Free Software Foundation version 2.1 at http://gammon.com.au/Arduino/SendOnlySoftwareSerial.zip */ #include <SoftwareSerial.h> // use if you do not wish to use the lightweight library SoftwareSerial Serial(0,1); // Receive, Transmit (Receive not used) // We need to use the 'raw' pin reading methods because timing is very important here // and the digitalRead() procedure is slower! #define IRpin_PIN PINB // ATTiny85 had Port B pins #define IRpin 2 #define MAXPULSE 12000 // the maximum pulse we'll listen for - 5 milliseconds #define NUMPULSES 34 // max IR pulse pairs to sample #define RESOLUTION 2 // time between IR measurements #define STORED_BUTTON_CODES 4 // remote control codes stored // we will store up to 100 pulse pairs (this is -a lot-) uint16_t pulses[NUMPULSES]; // high and low pulses uint16_t pulse_index = 0; // index for pulses we're storing uint32_t irCode = 0; void setup(void) { Serial.begin(9600); Serial.println(); Serial.println("Ready to decode IR!"); pinMode(IRpin, INPUT); // Listen to IR receiver on Trinket/Gemma pin D2 } void loop(void) { // Wait for an IR Code uint16_t numpulse=listenForIR(); // Process the pulses to get a single number representing code for (int i = 0; i < NUMPULSES; i++) { Serial.print(pulses[i]); Serial.print(", "); } Serial.println("\n"); } uint16_t listenForIR() { // IR receive code pulse_index = 0; while (1) { unsigned int highpulse, lowpulse; // temporary storage timing highpulse = lowpulse = 0; // start out with no pulse length while (IRpin_PIN & _BV(IRpin)) { // got a high pulse highpulse++; delayMicroseconds(RESOLUTION); if (((highpulse >= MAXPULSE) && (pulse_index != 0))|| pulse_index == NUMPULSES) { return pulse_index; } } pulses[pulse_index] = highpulse; while (! (IRpin_PIN & _BV(IRpin))) { // got a low pulse lowpulse++; delayMicroseconds(RESOLUTION); if (((lowpulse >= MAXPULSE) && (pulse_index != 0))|| pulse_index == NUMPULSES) { return pulse_index; } } pulses[pulse_index] = lowpulse; pulse_index++; } }
Now that we have a way capture IR data, you can write your own program which uses these codes to do great things.
The demonstration uses a piezo speaker to make different beep tones depending based on four captured codes. This code is based on Wiring Diagram #3 - Trinket 5v with FTDI Friend.
// SPDX-FileCopyrightText: 2018 Mikey Sklar for Adafruit Industries // // SPDX-License-Identifier: MIT /* Trinket/Gemma compatible IR read sketch This sketch/program uses an Adafruit Trinket or Gemma ATTiny85 based mini microcontroller and a PNA4602 or TSOP38238 to read an IR code and perform a function. In this test program, tones are generated to a piezo speaker but you can use codes to trigger any function you wish. Based on Adafruit tutorial http://learn.adafruit.com/ir-sensor/using-an-ir-sensor and http://learn.adafruit.com/trinket-gemma-mini-theramin-music-maker */ // We need to use the 'raw' pin reading methods because timing is very important here // and the digitalRead() procedure is slower! #define IRpin_PIN PINB // ATTiny85 had Port B pins #define IRpin 2 // IR sensor - TSOP38238 on Pin GPIO #2 / D2 #define SPEAKERPIN 1 // Piezo speaker on Trinket/Gemma Pin GPIO #1/D1 #define MAXPULSE 5000 // the maximum pulse we'll listen for - 5 milliseconds #define NUMPULSES 100 // max IR pulse pairs to sample #define RESOLUTION 2 // // time between IR measurements // we will store up to 100 pulse pairs (this is -a lot-, reduce if needed) uint16_t pulses[100][2]; // pair is high and low pulse uint16_t currentpulse = 0; // index for pulses we're storing uint32_t irCode = 0; void setup() { pinMode(IRpin, INPUT); // Listen to IR receiver on Trinket/Gemma pin D2 pinMode(SPEAKERPIN, OUTPUT); // Output tones on Trinket/Gemma pin D1 } void loop() { irCode=listenForIR(); // Wait for an IR Code // Process the pulses to get our code for (int i = 0; i < 32; i++) { irCode=irCode<<1; if((pulses[i][0] * RESOLUTION)>0&&(pulses[i][0] * RESOLUTION)<500) { irCode|=0; } else { irCode|=1; } } if(irCode==0xe0c8A2DD) { // "1" on my remote, USE YOUR CODE HERE beep(SPEAKERPIN,400,500); } // Make a 400 Hz beep else if (irCode==0xe0c8a3dc) { // "2", USE YOUR OWN HEX CODE HERE beep(SPEAKERPIN,500,500); } // Make a 500 Hz beep else if (irCode==0xe0c8a41b) { // "3", USE YOUR OWN HEX CODE HERE beep(SPEAKERPIN,600, 500); } // Make a 600 Hz beep else if (irCode==0xe0c8a29d) { // "4", USE YOUR OWN HEX CODE HERE beep(SPEAKERPIN, 700, 500); // Make a 700 Hz beep } } // end loop uint16_t listenForIR() { // IR receive code currentpulse = 0; while (1) { unsigned int highpulse, lowpulse; // temporary storage timing highpulse = lowpulse = 0; // start out with no pulse length while (IRpin_PIN & _BV(IRpin)) { // got a high pulse highpulse++; delayMicroseconds(RESOLUTION); if (((highpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) { return currentpulse; } } pulses[currentpulse][0] = highpulse; while (! (IRpin_PIN & _BV(IRpin))) { // got a low pulse lowpulse++; delayMicroseconds(RESOLUTION); if (((lowpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) { return currentpulse; } } pulses[currentpulse][1] = lowpulse; currentpulse++; } } // Generate a tone on speakerPin - Trinket/Gemma/ATTiny85 compatible void beep (unsigned char speakerPin, int frequencyInHertz, long timeInMilliseconds) { // http://web.media.mit.edu/~leah/LilyPad/07_sound_code.html int x; long delayAmount = (long)(1000000/frequencyInHertz); long loopTime = (long)((timeInMilliseconds*1000)/(delayAmount*2)); for (x=0;x<loopTime;x++) { digitalWrite(speakerPin,HIGH); delayMicroseconds(delayAmount); digitalWrite(speakerPin,LOW); delayMicroseconds(delayAmount); } }
Page last edited January 21, 2025
Text editor powered by tinymce.