tom dunigan / Mbed 2 deprecated IRtest

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
manitou
Date:
Wed Apr 13 11:14:58 2016 +0000
Child:
1:af81e02b8c7b
Commit message:
IR remote test

Changed in this revision

IRremote.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IRremote.h	Wed Apr 13 11:14:58 2016 +0000
@@ -0,0 +1,60 @@
+#define RECV_TIMER 2
+// maple pwm pin/timer/channel predefined and vary by processor
+//  maple RET6
+#define PWM_PIN 24
+#define PWM_TIMER 4
+#define PWM_TIMER_CH TIMER_CH4
+#define PWM_DUTY 2    //2 50%   4 25% hi
+
+#define RAWBUF 76 // Length of raw duration buffer
+
+#define USECPERTICK 50  // microseconds per clock interrupt tick
+
+// Marks tend to be 100us too long, and spaces 100us too short
+// when received due to sensor lag.
+#define MARK_EXCESS 100
+
+// Values for decode_type
+#define NEC 1
+#define SONY 2
+#define RC5 3
+#define RC6 4
+#define UNKNOWN -1
+
+#define TOLERANCE 25  // percent tolerance in measurements
+#define LTOL (1.0 - TOLERANCE/100.) 
+#define UTOL (1.0 + TOLERANCE/100.) 
+
+#define TICKS_LOW(us) (int) (((us)*LTOL/USECPERTICK))
+#define TICKS_HIGH(us) (int) (((us)*UTOL/USECPERTICK + 1))
+
+#define MATCH(measured_ticks, desired_us) ((measured_ticks) >= TICKS_LOW(desired_us) && (measured_ticks) <= TICKS_HIGH(desired_us))
+#define MATCH_MARK(measured_ticks, desired_us) MATCH(measured_ticks, (desired_us) + MARK_EXCESS)
+#define MATCH_SPACE(measured_ticks, desired_us) MATCH((measured_ticks), (desired_us) - MARK_EXCESS)
+
+
+#define _GAP 5000 // Minimum gap between transmissions  us
+#define GAP_TICKS (_GAP/USECPERTICK)
+
+// receiver states
+#define STATE_IDLE     2
+#define STATE_MARK     3
+#define STATE_SPACE    4
+#define STATE_STOP     5
+
+// IR detector output is active low
+#define MARK  0
+#define SPACE 1
+
+#define TOPBIT 0x80000000
+
+#define ERR 0
+#define DECODED 1
+
+// duration in us
+#define SONY_HDR_MARK   2400
+#define SONY_HDR_SPACE  600
+#define SONY_ONE_MARK   1200
+#define SONY_ZERO_MARK  600
+#define SONY_RPT_LENGTH 45000
+#define SONY_BITS 12
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Apr 13 11:14:58 2016 +0000
@@ -0,0 +1,224 @@
+/*
+  IRtest
+     hack of maple version
+      http://www.arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
+    use PWM to generate mark/space at 38Khz
+     IR LED xmit   pin to 100ohm to +IR  - to grnd (short/flat)
+    use timer 50us to count mark/space on input
+    is it possible to run both xmit and recv?
+
+*/
+#include "mbed.h"
+#include "IRremote.h"
+
+Ticker ticker;
+
+// K64F pins 
+#define RecvPin D7
+#define PWMPin D6
+#define TestPin D13
+
+PwmOut pwm(PWMPin);
+DigitalIn recvpin(RecvPin);
+DigitalOut testpin(TestPin);    // jumper to D8 for test
+DigitalOut myled(LED1);
+
+volatile unsigned long myticks;
+int rawbuf[RAWBUF], rawlen;
+uint8_t rcvstate;
+int results_decode_type; // NEC, SONY, RC5, UNKNOWN
+unsigned long results_value;
+int results_bits; // Number of bits in decoded value
+
+
+void timer_ISR() {
+    // interrupt every 50us
+    uint8_t irdata = recvpin;   // read IR sensor
+    myticks++;
+
+
+  if (rawlen >= RAWBUF) {
+    // Buffer overflow
+    rcvstate = STATE_STOP;
+  }
+  switch(rcvstate) {
+  case STATE_IDLE: // In the middle of a gap
+    if (irdata == MARK) {
+      if (myticks < GAP_TICKS) {
+        // Not big enough to be a gap.
+        myticks = 0;
+      }
+      else {
+        // gap just ended, record duration and start recording transmission
+        rawlen = 0;
+        rawbuf[rawlen++] = myticks;
+        myticks = 0;
+        rcvstate = STATE_MARK;
+      }
+     }
+    break;
+  case STATE_MARK: // timing MARK
+    if (irdata == SPACE) {   // MARK ended, record time
+      rawbuf[rawlen++] = myticks;
+      myticks = 0;
+      rcvstate = STATE_SPACE;
+    }
+    break;
+  case STATE_SPACE: // timing SPACE
+    if (irdata == MARK) { // SPACE just ended, record it
+      rawbuf[rawlen++] = myticks;
+      myticks = 0;
+      rcvstate = STATE_MARK;
+    }
+    else { // SPACE
+      if (myticks > GAP_TICKS) {
+        // big SPACE, indicates gap between codes
+        // Mark current code as ready for processing
+        // Switch to STOP
+        // Don't reset timer; keep counting space width
+        rcvstate = STATE_STOP;
+      }
+    }
+    break;
+  case STATE_STOP: // waiting, measuring gap
+    if (irdata == MARK) { // reset gap timer
+      myticks = 0;
+    }
+    break;
+  }
+
+}
+
+// set up recv timer
+void enableIRIn(){
+    ticker.attach_us(&timer_ISR,50);
+    rcvstate = STATE_IDLE;
+    rawlen = 0;
+}
+
+void irrecv_resume() {
+    rcvstate = STATE_IDLE;
+    rawlen = 0;
+}
+
+long decodeSony() {
+  long data = 0;
+  if (rawlen < 2 * SONY_BITS + 2) {
+    return ERR;
+  }
+  int offset = 1; // Skip first space
+  // Initial mark
+  if (!MATCH_MARK(rawbuf[offset], SONY_HDR_MARK)) {
+    return ERR;
+  }
+  offset++;
+
+  while (offset + 1 < rawlen) {
+    if (!MATCH_SPACE(rawbuf[offset], SONY_HDR_SPACE)) {
+      break;
+    }
+    offset++;
+    if (MATCH_MARK(rawbuf[offset], SONY_ONE_MARK)) {
+      data = (data << 1) | 1;
+    }
+    else if (MATCH_MARK(rawbuf[offset], SONY_ZERO_MARK)) {
+      data <<= 1;
+    }
+    else {
+      return ERR;
+    }
+    offset++;
+  }
+
+  // Success
+  results_bits = (offset - 1) / 2;
+  if (results_bits < 12) {
+    results_bits = 0;
+    return ERR;
+  }
+  results_value = data;
+  results_decode_type = SONY;
+  return DECODED;
+}
+
+void enableIROut(int khz) {
+    int freq = 1000 * khz;
+    pwm.period(1./freq);
+    pwm.write(0);  //  start PWM with low
+}
+
+void mark(int time) {
+    pwm.write(0.5);  // PWM on
+    testpin=0;          // test   invert
+    wait_us(time);
+}
+
+void space(int time) {
+    pwm.write(0);  // off
+    testpin=1;
+    wait_us(time);
+}
+
+void sendSony(unsigned long data, int nbits) {
+  enableIROut(40);
+  mark(SONY_HDR_MARK);
+  space(SONY_HDR_SPACE);
+  data = data << (32 - nbits);
+  for (int i = 0; i < nbits; i++) {
+    if (data & TOPBIT) {
+      mark(SONY_ONE_MARK);
+      space(SONY_HDR_SPACE);
+    }
+    else {
+      mark(SONY_ZERO_MARK);
+      space(SONY_HDR_SPACE);
+    }
+    data <<= 1;
+  }
+}
+
+void sendRaw(unsigned int buf[], int len, int khz)
+{
+  enableIROut(khz);
+  for (int i = 0; i < len; i++) {
+    if (i & 1) {
+      space(buf[i]);
+    }
+    else {
+      mark(buf[i]);
+    }
+  }
+  space(0); // Just to be sure
+}
+
+main() {
+  long sonycmd[] = {0xA9A,0x91A,0x61A}; // power 0 7
+  
+
+  pwm.period(1.);
+  pwm.write(0);  //  when no PWM, want pin low
+
+  enableIRIn();
+  while(true) {   
+        printf("xmit\n");
+        myled=1;
+        sendSony(sonycmd[0],SONY_BITS); 
+        myled=0;
+        wait(.006);   // let gap time grow
+
+        if (rcvstate == STATE_STOP) {
+            if (decodeSony() ) {
+                printf("sony decoded. value %0x  %d bits\n",results_value, results_bits);
+            }
+            printf("rawlen %d\n",rawlen);
+
+            for (int i=0; i < rawlen; i++) {
+                if (i%2) printf(" ");
+                printf("%d\n",rawbuf[i]*USECPERTICK);
+            }
+            irrecv_resume();
+        } 
+
+        wait(2.0);
+  }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed Apr 13 11:14:58 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/99a22ba036c9
\ No newline at end of file