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:18:39 2016 +0000
Revision:
1:af81e02b8c7b
Parent:
0:785739d5a30a
edit

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