Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 0:785739d5a30a, committed 2016-04-13
- Comitter:
- manitou
- Date:
- Wed Apr 13 11:14:58 2016 +0000
- Child:
- 1:af81e02b8c7b
- Commit message:
- IR remote test
Changed in this revision
--- /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