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 1:4e6dc3e5ab7c, committed 2014-08-24
- Comitter:
- yuki
- Date:
- Sun Aug 24 06:58:30 2014 +0000
- Parent:
- 0:7c39876eb334
- Commit message:
- ????;
Changed in this revision
--- a/RemoteIR.lib Sat Aug 09 07:24:12 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/shintamainjp/code/RemoteIR/#268cc2ab63bd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RemoteIR/ReceiverIR.cpp Sun Aug 24 06:58:30 2014 +0000 @@ -0,0 +1,330 @@ +/** + * IR receiver (Version 0.0.4) + * + * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems) + * http://shinta.main.jp/ + */ + +#include "ReceiverIR.h" + +#define LOCK() +#define UNLOCK() + +#define InRange(x,y) ((((y) * 0.7) < (x)) && ((x) < ((y) * 1.3))) + +/** + * Constructor. + * + * @param rxpin Pin for receive IR signal. + */ +ReceiverIR::ReceiverIR(PinName rxpin) : evt(rxpin) { + init_state(); + evt.fall(this, &ReceiverIR::isr_fall); + evt.rise(this, &ReceiverIR::isr_rise); + evt.mode(PullUp); + ticker.attach_us(this, &ReceiverIR::isr_wdt, 10 * 1000); +} + +/** + * Destructor. + */ +ReceiverIR::~ReceiverIR() { +} + +/** + * Get state. + * + * @return Current state. + */ +ReceiverIR::State ReceiverIR::getState() { + LOCK(); + State s = work.state; + UNLOCK(); + return s; +} + +/** + * Get data. + * + * @param format Pointer to format. + * @param buf Buffer of a data. + * @param bitlength Bit length of the buffer. + * + * @return Data bit length. + */ +int ReceiverIR::getData(RemoteIR::Format *format, uint8_t *buf, int bitlength) { + LOCK(); + + if (bitlength < data.bitcount) { + UNLOCK(); + return -1; + } + + const int nbits = data.bitcount; + const int nbytes = data.bitcount / 8 + (((data.bitcount % 8) != 0) ? 1 : 0); + *format = data.format; + for (int i = 0; i < nbytes; i++) { + buf[i] = data.buffer[i]; + } + + init_state(); + + UNLOCK(); + return nbits; +} + +void ReceiverIR::init_state(void) { + work.c1 = -1; + work.c2 = -1; + work.c3 = -1; + work.d1 = -1; + work.d2 = -1; + work.state = Idle; + data.format = RemoteIR::UNKNOWN; + data.bitcount = 0; + timer.stop(); + timer.reset(); + for (int i = 0; i < sizeof(data.buffer); i++) { + data.buffer[i] = 0; + } +} + +void ReceiverIR::isr_wdt(void) { + LOCK(); + static int cnt = 0; + if ((Idle != work.state) || ((0 <= work.c1) || (0 <= work.c2) || (0 <= work.c3) || (0 <= work.d1) || (0 <= work.d2))) { + cnt++; + if (cnt > 50) { +#if 0 + printf("# WDT [c1=%d, c2=%d, c3=%d, d1=%d, d2=%d, state=%d, format=%d, bitcount=%d]\n", + work.c1, + work.c2, + work.c3, + work.d1, + work.d2, + work.state, + data.format, + data.bitcount); +#endif + init_state(); + cnt = 0; + } + } else { + cnt = 0; + } + UNLOCK(); +} + +void ReceiverIR::isr_fall(void) { + LOCK(); + switch (work.state) { + case Idle: + if (work.c1 < 0) { + timer.start(); + work.c1 = timer.read_us(); + } else { + work.c3 = timer.read_us(); + int a = work.c2 - work.c1; + int b = work.c3 - work.c2; + if (InRange(a, RemoteIR::TUS_NEC * 16) && InRange(b, RemoteIR::TUS_NEC * 8)) { + /* + * NEC. + */ + data.format = RemoteIR::NEC; + work.state = Receiving; + data.bitcount = 0; + } else if (InRange(a, RemoteIR::TUS_NEC * 16) && InRange(b, RemoteIR::TUS_NEC * 4)) { + /* + * NEC Repeat. + */ + data.format = RemoteIR::NEC_REPEAT; + work.state = Received; + data.bitcount = 0; + work.c1 = -1; + work.c2 = -1; + work.c3 = -1; + work.d1 = -1; + work.d2 = -1; + } else if (InRange(a, RemoteIR::TUS_AEHA * 8) && InRange(b, RemoteIR::TUS_AEHA * 4)) { + /* + * AEHA. + */ + data.format = RemoteIR::AEHA; + work.state = Receiving; + data.bitcount = 0; + } else if (InRange(a, RemoteIR::TUS_AEHA * 8) && InRange(b, RemoteIR::TUS_AEHA * 8)) { + /* + * AEHA Repeat. + */ + data.format = RemoteIR::AEHA_REPEAT; + work.state = Received; + data.bitcount = 0; + work.c1 = -1; + work.c2 = -1; + work.c3 = -1; + work.d1 = -1; + work.d2 = -1; + } else { + init_state(); + } + } + break; + case Receiving: + if (RemoteIR::NEC == data.format) { + work.d2 = timer.read_us(); + int a = work.d2 - work.d1; + if (InRange(a, RemoteIR::TUS_NEC * 3)) { + data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8)); + } else if (InRange(a, RemoteIR::TUS_NEC * 1)) { + data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8)); + } + data.bitcount++; +#if 0 + /* + * Length of NEC is always 32 bits. + */ + if (32 <= data.bitcount) { + data.state = Received; + work.c1 = -1; + work.c2 = -1; + work.c3 = -1; + work.d1 = -1; + work.d2 = -1; + } +#else + /* + * Set timeout for tail detection automatically. + */ + timeout.detach(); + timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_NEC * 5); +#endif + } else if (RemoteIR::AEHA == data.format) { + work.d2 = timer.read_us(); + int a = work.d2 - work.d1; + if (InRange(a, RemoteIR::TUS_AEHA * 3)) { + data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8)); + } else if (InRange(a, RemoteIR::TUS_AEHA * 1)) { + data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8)); + } + data.bitcount++; +#if 0 + /* + * Typical length of AEHA is 48 bits. + * Please check a specification of your remote controller if you find a problem. + */ + if (48 <= data.bitcount) { + data.state = Received; + work.c1 = -1; + work.c2 = -1; + work.c3 = -1; + work.d1 = -1; + work.d2 = -1; + } +#else + /* + * Set timeout for tail detection automatically. + */ + timeout.detach(); + timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_AEHA * 5); +#endif + } else if (RemoteIR::SONY == data.format) { + work.d1 = timer.read_us(); + } + break; + case Received: + break; + default: + break; + } + UNLOCK(); +} + +void ReceiverIR::isr_rise(void) { + LOCK(); + switch (work.state) { + case Idle: + if (0 <= work.c1) { + work.c2 = timer.read_us(); + int a = work.c2 - work.c1; + if (InRange(a, RemoteIR::TUS_SONY * 4)) { + data.format = RemoteIR::SONY; + work.state = Receiving; + data.bitcount = 0; + } else { + static const int MINIMUM_LEADER_WIDTH = 150; + if (a < MINIMUM_LEADER_WIDTH) { + init_state(); + } + } + } else { + init_state(); + } + break; + case Receiving: + if (RemoteIR::NEC == data.format) { + work.d1 = timer.read_us(); + } else if (RemoteIR::AEHA == data.format) { + work.d1 = timer.read_us(); + } else if (RemoteIR::SONY == data.format) { + work.d2 = timer.read_us(); + int a = work.d2 - work.d1; + if (InRange(a, RemoteIR::TUS_SONY * 2)) { + data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8)); + } else if (InRange(a, RemoteIR::TUS_SONY * 1)) { + data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8)); + } + data.bitcount++; +#if 0 + /* + * How do I know the correct length? (6bits, 12bits, 15bits, 20bits...) + * By a model only? + * Please check a specification of your remote controller if you find a problem. + */ + if (12 <= data.bitcount) { + data.state = Received; + work.c1 = -1; + work.c2 = -1; + work.c3 = -1; + work.d1 = -1; + work.d2 = -1; + } +#else + /* + * Set timeout for tail detection automatically. + */ + timeout.detach(); + timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_SONY * 4); +#endif + } + break; + case Received: + break; + default: + break; + } + UNLOCK(); +} + +void ReceiverIR::isr_timeout(void) { + LOCK(); +#if 0 + printf("# TIMEOUT [c1=%d, c2=%d, c3=%d, d1=%d, d2=%d, state=%d, format=%d, bitcount=%d]\n", + work.c1, + work.c2, + work.c3, + work.d1, + work.d2, + work.state, + data.format, + data.bitcount); +#endif + if (work.state == Receiving) { + work.state = Received; + work.c1 = -1; + work.c2 = -1; + work.c3 = -1; + work.d1 = -1; + work.d2 = -1; + } + UNLOCK(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RemoteIR/ReceiverIR.h Sun Aug 24 06:58:30 2014 +0000 @@ -0,0 +1,98 @@ +/** + * IR receiver (Version 0.0.4) + * + * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems) + * http://shinta.main.jp/ + */ + +#ifndef _RECEIVER_IR_H_ +#define _RECEIVER_IR_H_ + +#include <mbed.h> + +#include "RemoteIR.h" + +/** + * IR receiver class. + */ +class ReceiverIR { +public: + + /** + * Constructor. + * + * @param rxpin Pin for receive IR signal. + */ + explicit ReceiverIR(PinName rxpin); + + /** + * Destructor. + */ + ~ReceiverIR(); + + /** + * State. + */ + typedef enum { + Idle, + Receiving, + Received + } State; + + /** + * Get state. + * + * @return Current state. + */ + State getState(); + + /** + * Get data. + * + * @param format Pointer to format. + * @param buf Buffer of a data. + * @param bitlength Bit length of the buffer. + * + * @return Data bit length. + */ + int getData(RemoteIR::Format *format, uint8_t *buf, int bitlength); + +private: + + typedef struct { + RemoteIR::Format format; + int bitcount; + uint8_t buffer[256]; + } data_t; + + typedef struct { + State state; + int c1; + int c2; + int c3; + int d1; + int d2; + } work_t; + + InterruptIn evt; /**< Interrupt based input for input. */ + Timer timer; /**< Timer for WDT. */ + Ticker ticker; /**< Tciker for tick. */ + Timeout timeout; /**< Timeout for tail. */ + + data_t data; + work_t work; + + void init_state(void); + + void isr_wdt(void); + void isr_fall(void); + void isr_rise(void); + + /** + * ISR timeout for tail detection. + */ + void isr_timeout(void); + +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RemoteIR/RemoteIR.h Sun Aug 24 06:58:30 2014 +0000 @@ -0,0 +1,31 @@ +/** + * IR remote common class (Version 0.0.4) + * + * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems) + * http://shinta.main.jp/ + */ + +#ifndef _REMOTE_IR_H_ +#define _REMOTE_IR_H_ + +class RemoteIR { +public: + + typedef enum { + UNKNOWN, + NEC, + NEC_REPEAT, + AEHA, + AEHA_REPEAT, + SONY + } Format; + + static const int TUS_NEC = 562; + static const int TUS_AEHA = 425; + static const int TUS_SONY = 600; + +private: + RemoteIR(); +}; + +#endif
--- a/main.cpp Sat Aug 09 07:24:12 2014 +0000 +++ b/main.cpp Sun Aug 24 06:58:30 2014 +0000 @@ -8,7 +8,8 @@ //TX dp16 = USBTX RX dp15 = USBRX Serial pc(USBTX, USBRX); -int receive(RemoteIR::Format *format, uint8_t *buf, int bufsiz, int timeout = 100) { +int receive(RemoteIR::Format *format, uint8_t *buf, int bufsiz, int timeout = 200) +{ int cnt = 0; while (ir_rx.getState() != ReceiverIR::Received) { cnt++; @@ -19,15 +20,15 @@ return ir_rx.getData(format, buf, bufsiz * 8); } -int main() { +int main() +{ pc.baud(9600); RemoteIR::Format format; - uint8_t buf[64]; + uint8_t buf[512]; int bufLength = 0; myled1 = myled2 = myled3 = 1; while(1) { myled1 = 0; - memset(buf, 0x00, sizeof(buf)); bufLength = receive(&format, buf, sizeof(buf)); if(bufLength < 0) continue; myled1 = 1;