IR remote test, based on Arduino IRRemote lib.

Dependencies:   mbed

IR remote test, based on Arduino IRremote lib.

https://www.pjrc.com/teensy/td_libs_IRremote.html

Uses PWM for carrier and timer for 50us sensor reads. for k64f, one could use CMT.

Committer:
manitou
Date:
Wed Apr 13 11:14:58 2016 +0000
Revision:
0:785739d5a30a
Child:
1:af81e02b8c7b
IR remote test

Who changed what in which revision?

UserRevisionLine numberNew contents of line
manitou 0:785739d5a30a 1 /*
manitou 0:785739d5a30a 2 IRtest
manitou 0:785739d5a30a 3 hack of maple version
manitou 0:785739d5a30a 4 http://www.arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
manitou 0:785739d5a30a 5 use PWM to generate mark/space at 38Khz
manitou 0:785739d5a30a 6 IR LED xmit pin to 100ohm to +IR - to grnd (short/flat)
manitou 0:785739d5a30a 7 use timer 50us to count mark/space on input
manitou 0:785739d5a30a 8 is it possible to run both xmit and recv?
manitou 0:785739d5a30a 9
manitou 0:785739d5a30a 10 */
manitou 0:785739d5a30a 11 #include "mbed.h"
manitou 0:785739d5a30a 12 #include "IRremote.h"
manitou 0:785739d5a30a 13
manitou 0:785739d5a30a 14 Ticker ticker;
manitou 0:785739d5a30a 15
manitou 0:785739d5a30a 16 // K64F pins
manitou 0:785739d5a30a 17 #define RecvPin D7
manitou 0:785739d5a30a 18 #define PWMPin D6
manitou 0:785739d5a30a 19 #define TestPin D13
manitou 0:785739d5a30a 20
manitou 0:785739d5a30a 21 PwmOut pwm(PWMPin);
manitou 0:785739d5a30a 22 DigitalIn recvpin(RecvPin);
manitou 0:785739d5a30a 23 DigitalOut testpin(TestPin); // jumper to D8 for test
manitou 0:785739d5a30a 24 DigitalOut myled(LED1);
manitou 0:785739d5a30a 25
manitou 0:785739d5a30a 26 volatile unsigned long myticks;
manitou 0:785739d5a30a 27 int rawbuf[RAWBUF], rawlen;
manitou 0:785739d5a30a 28 uint8_t rcvstate;
manitou 0:785739d5a30a 29 int results_decode_type; // NEC, SONY, RC5, UNKNOWN
manitou 0:785739d5a30a 30 unsigned long results_value;
manitou 0:785739d5a30a 31 int results_bits; // Number of bits in decoded value
manitou 0:785739d5a30a 32
manitou 0:785739d5a30a 33
manitou 0:785739d5a30a 34 void timer_ISR() {
manitou 0:785739d5a30a 35 // interrupt every 50us
manitou 0:785739d5a30a 36 uint8_t irdata = recvpin; // read IR sensor
manitou 0:785739d5a30a 37 myticks++;
manitou 0:785739d5a30a 38
manitou 0:785739d5a30a 39
manitou 0:785739d5a30a 40 if (rawlen >= RAWBUF) {
manitou 0:785739d5a30a 41 // Buffer overflow
manitou 0:785739d5a30a 42 rcvstate = STATE_STOP;
manitou 0:785739d5a30a 43 }
manitou 0:785739d5a30a 44 switch(rcvstate) {
manitou 0:785739d5a30a 45 case STATE_IDLE: // In the middle of a gap
manitou 0:785739d5a30a 46 if (irdata == MARK) {
manitou 0:785739d5a30a 47 if (myticks < GAP_TICKS) {
manitou 0:785739d5a30a 48 // Not big enough to be a gap.
manitou 0:785739d5a30a 49 myticks = 0;
manitou 0:785739d5a30a 50 }
manitou 0:785739d5a30a 51 else {
manitou 0:785739d5a30a 52 // gap just ended, record duration and start recording transmission
manitou 0:785739d5a30a 53 rawlen = 0;
manitou 0:785739d5a30a 54 rawbuf[rawlen++] = myticks;
manitou 0:785739d5a30a 55 myticks = 0;
manitou 0:785739d5a30a 56 rcvstate = STATE_MARK;
manitou 0:785739d5a30a 57 }
manitou 0:785739d5a30a 58 }
manitou 0:785739d5a30a 59 break;
manitou 0:785739d5a30a 60 case STATE_MARK: // timing MARK
manitou 0:785739d5a30a 61 if (irdata == SPACE) { // MARK ended, record time
manitou 0:785739d5a30a 62 rawbuf[rawlen++] = myticks;
manitou 0:785739d5a30a 63 myticks = 0;
manitou 0:785739d5a30a 64 rcvstate = STATE_SPACE;
manitou 0:785739d5a30a 65 }
manitou 0:785739d5a30a 66 break;
manitou 0:785739d5a30a 67 case STATE_SPACE: // timing SPACE
manitou 0:785739d5a30a 68 if (irdata == MARK) { // SPACE just ended, record it
manitou 0:785739d5a30a 69 rawbuf[rawlen++] = myticks;
manitou 0:785739d5a30a 70 myticks = 0;
manitou 0:785739d5a30a 71 rcvstate = STATE_MARK;
manitou 0:785739d5a30a 72 }
manitou 0:785739d5a30a 73 else { // SPACE
manitou 0:785739d5a30a 74 if (myticks > GAP_TICKS) {
manitou 0:785739d5a30a 75 // big SPACE, indicates gap between codes
manitou 0:785739d5a30a 76 // Mark current code as ready for processing
manitou 0:785739d5a30a 77 // Switch to STOP
manitou 0:785739d5a30a 78 // Don't reset timer; keep counting space width
manitou 0:785739d5a30a 79 rcvstate = STATE_STOP;
manitou 0:785739d5a30a 80 }
manitou 0:785739d5a30a 81 }
manitou 0:785739d5a30a 82 break;
manitou 0:785739d5a30a 83 case STATE_STOP: // waiting, measuring gap
manitou 0:785739d5a30a 84 if (irdata == MARK) { // reset gap timer
manitou 0:785739d5a30a 85 myticks = 0;
manitou 0:785739d5a30a 86 }
manitou 0:785739d5a30a 87 break;
manitou 0:785739d5a30a 88 }
manitou 0:785739d5a30a 89
manitou 0:785739d5a30a 90 }
manitou 0:785739d5a30a 91
manitou 0:785739d5a30a 92 // set up recv timer
manitou 0:785739d5a30a 93 void enableIRIn(){
manitou 0:785739d5a30a 94 ticker.attach_us(&timer_ISR,50);
manitou 0:785739d5a30a 95 rcvstate = STATE_IDLE;
manitou 0:785739d5a30a 96 rawlen = 0;
manitou 0:785739d5a30a 97 }
manitou 0:785739d5a30a 98
manitou 0:785739d5a30a 99 void irrecv_resume() {
manitou 0:785739d5a30a 100 rcvstate = STATE_IDLE;
manitou 0:785739d5a30a 101 rawlen = 0;
manitou 0:785739d5a30a 102 }
manitou 0:785739d5a30a 103
manitou 0:785739d5a30a 104 long decodeSony() {
manitou 0:785739d5a30a 105 long data = 0;
manitou 0:785739d5a30a 106 if (rawlen < 2 * SONY_BITS + 2) {
manitou 0:785739d5a30a 107 return ERR;
manitou 0:785739d5a30a 108 }
manitou 0:785739d5a30a 109 int offset = 1; // Skip first space
manitou 0:785739d5a30a 110 // Initial mark
manitou 0:785739d5a30a 111 if (!MATCH_MARK(rawbuf[offset], SONY_HDR_MARK)) {
manitou 0:785739d5a30a 112 return ERR;
manitou 0:785739d5a30a 113 }
manitou 0:785739d5a30a 114 offset++;
manitou 0:785739d5a30a 115
manitou 0:785739d5a30a 116 while (offset + 1 < rawlen) {
manitou 0:785739d5a30a 117 if (!MATCH_SPACE(rawbuf[offset], SONY_HDR_SPACE)) {
manitou 0:785739d5a30a 118 break;
manitou 0:785739d5a30a 119 }
manitou 0:785739d5a30a 120 offset++;
manitou 0:785739d5a30a 121 if (MATCH_MARK(rawbuf[offset], SONY_ONE_MARK)) {
manitou 0:785739d5a30a 122 data = (data << 1) | 1;
manitou 0:785739d5a30a 123 }
manitou 0:785739d5a30a 124 else if (MATCH_MARK(rawbuf[offset], SONY_ZERO_MARK)) {
manitou 0:785739d5a30a 125 data <<= 1;
manitou 0:785739d5a30a 126 }
manitou 0:785739d5a30a 127 else {
manitou 0:785739d5a30a 128 return ERR;
manitou 0:785739d5a30a 129 }
manitou 0:785739d5a30a 130 offset++;
manitou 0:785739d5a30a 131 }
manitou 0:785739d5a30a 132
manitou 0:785739d5a30a 133 // Success
manitou 0:785739d5a30a 134 results_bits = (offset - 1) / 2;
manitou 0:785739d5a30a 135 if (results_bits < 12) {
manitou 0:785739d5a30a 136 results_bits = 0;
manitou 0:785739d5a30a 137 return ERR;
manitou 0:785739d5a30a 138 }
manitou 0:785739d5a30a 139 results_value = data;
manitou 0:785739d5a30a 140 results_decode_type = SONY;
manitou 0:785739d5a30a 141 return DECODED;
manitou 0:785739d5a30a 142 }
manitou 0:785739d5a30a 143
manitou 0:785739d5a30a 144 void enableIROut(int khz) {
manitou 0:785739d5a30a 145 int freq = 1000 * khz;
manitou 0:785739d5a30a 146 pwm.period(1./freq);
manitou 0:785739d5a30a 147 pwm.write(0); // start PWM with low
manitou 0:785739d5a30a 148 }
manitou 0:785739d5a30a 149
manitou 0:785739d5a30a 150 void mark(int time) {
manitou 0:785739d5a30a 151 pwm.write(0.5); // PWM on
manitou 0:785739d5a30a 152 testpin=0; // test invert
manitou 0:785739d5a30a 153 wait_us(time);
manitou 0:785739d5a30a 154 }
manitou 0:785739d5a30a 155
manitou 0:785739d5a30a 156 void space(int time) {
manitou 0:785739d5a30a 157 pwm.write(0); // off
manitou 0:785739d5a30a 158 testpin=1;
manitou 0:785739d5a30a 159 wait_us(time);
manitou 0:785739d5a30a 160 }
manitou 0:785739d5a30a 161
manitou 0:785739d5a30a 162 void sendSony(unsigned long data, int nbits) {
manitou 0:785739d5a30a 163 enableIROut(40);
manitou 0:785739d5a30a 164 mark(SONY_HDR_MARK);
manitou 0:785739d5a30a 165 space(SONY_HDR_SPACE);
manitou 0:785739d5a30a 166 data = data << (32 - nbits);
manitou 0:785739d5a30a 167 for (int i = 0; i < nbits; i++) {
manitou 0:785739d5a30a 168 if (data & TOPBIT) {
manitou 0:785739d5a30a 169 mark(SONY_ONE_MARK);
manitou 0:785739d5a30a 170 space(SONY_HDR_SPACE);
manitou 0:785739d5a30a 171 }
manitou 0:785739d5a30a 172 else {
manitou 0:785739d5a30a 173 mark(SONY_ZERO_MARK);
manitou 0:785739d5a30a 174 space(SONY_HDR_SPACE);
manitou 0:785739d5a30a 175 }
manitou 0:785739d5a30a 176 data <<= 1;
manitou 0:785739d5a30a 177 }
manitou 0:785739d5a30a 178 }
manitou 0:785739d5a30a 179
manitou 0:785739d5a30a 180 void sendRaw(unsigned int buf[], int len, int khz)
manitou 0:785739d5a30a 181 {
manitou 0:785739d5a30a 182 enableIROut(khz);
manitou 0:785739d5a30a 183 for (int i = 0; i < len; i++) {
manitou 0:785739d5a30a 184 if (i & 1) {
manitou 0:785739d5a30a 185 space(buf[i]);
manitou 0:785739d5a30a 186 }
manitou 0:785739d5a30a 187 else {
manitou 0:785739d5a30a 188 mark(buf[i]);
manitou 0:785739d5a30a 189 }
manitou 0:785739d5a30a 190 }
manitou 0:785739d5a30a 191 space(0); // Just to be sure
manitou 0:785739d5a30a 192 }
manitou 0:785739d5a30a 193
manitou 0:785739d5a30a 194 main() {
manitou 0:785739d5a30a 195 long sonycmd[] = {0xA9A,0x91A,0x61A}; // power 0 7
manitou 0:785739d5a30a 196
manitou 0:785739d5a30a 197
manitou 0:785739d5a30a 198 pwm.period(1.);
manitou 0:785739d5a30a 199 pwm.write(0); // when no PWM, want pin low
manitou 0:785739d5a30a 200
manitou 0:785739d5a30a 201 enableIRIn();
manitou 0:785739d5a30a 202 while(true) {
manitou 0:785739d5a30a 203 printf("xmit\n");
manitou 0:785739d5a30a 204 myled=1;
manitou 0:785739d5a30a 205 sendSony(sonycmd[0],SONY_BITS);
manitou 0:785739d5a30a 206 myled=0;
manitou 0:785739d5a30a 207 wait(.006); // let gap time grow
manitou 0:785739d5a30a 208
manitou 0:785739d5a30a 209 if (rcvstate == STATE_STOP) {
manitou 0:785739d5a30a 210 if (decodeSony() ) {
manitou 0:785739d5a30a 211 printf("sony decoded. value %0x %d bits\n",results_value, results_bits);
manitou 0:785739d5a30a 212 }
manitou 0:785739d5a30a 213 printf("rawlen %d\n",rawlen);
manitou 0:785739d5a30a 214
manitou 0:785739d5a30a 215 for (int i=0; i < rawlen; i++) {
manitou 0:785739d5a30a 216 if (i%2) printf(" ");
manitou 0:785739d5a30a 217 printf("%d\n",rawbuf[i]*USECPERTICK);
manitou 0:785739d5a30a 218 }
manitou 0:785739d5a30a 219 irrecv_resume();
manitou 0:785739d5a30a 220 }
manitou 0:785739d5a30a 221
manitou 0:785739d5a30a 222 wait(2.0);
manitou 0:785739d5a30a 223 }
manitou 0:785739d5a30a 224 }