IRC Helicopter "HonyBee" Propo decode test program
これは、赤外線コントロールヘリコプター"HonyBee"のPropoからの送信データを解析して、PCに表示させるテストプログラムです。 詳しくは、 http://suupen-make.blogspot.jp/2013/06/irc-helicopter-honybeembedtest-program.html を参照してください。
Revision 0:f9e49220c97a, committed 2013-06-23
- Comitter:
- suupen
- Date:
- Sun Jun 23 07:28:06 2013 +0000
- Commit message:
- IRC Helicopter "HonyBee" Propo decode test program
Changed in this revision
diff -r 000000000000 -r f9e49220c97a CodecIRPropoHonyBee/CodecHonyBee.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CodecIRPropoHonyBee/CodecHonyBee.h Sun Jun 23 07:28:06 2013 +0000 @@ -0,0 +1,72 @@ +/** + * Codec IR Propo of HonyBee common class + * Version 0.0 130623 + * + * Writer:suupen + */ + +#ifndef _CODECHonyBee_H_ +#define _CODECHonyBee_H_ + +#include <mbed.h> + + + +class CodecHonyBee { +public: + + typedef struct{ + uint8_t count; + uint8_t band; // 1 to 255 + float slottle; // 0(min) to 1.0(max) + float ladder; // -1.0(Left) to 1.0(Right) + float elevator; // not use (-1.0(backward) to 1.0(forward)) + float trim; // -1.0 to 1.0 + } normalizePropo_t; + + + + typedef struct{ + uint8_t count; // recive count [1/1 [recive]/count] + uint8_t band; // 0x0a:A band 0x0b:B 0x0c:C + uint8_t slottle; // 0x00:0 - 0x0e:14 + uint8_t trim; // 0x0f:Left 0x01:Right 0x00:neutral + int8_t ladder; // -3:Left3 -2:Left2 -1:Left1 0:Neutral 1:Right1 2:Right2 3:Right3 + } honyBeePropo_t; + + +static const uint8_t BAND_A = 0x00; +static const uint8_t BAND_B = 0x01; +static const uint8_t BAND_C = 0x02; + +static const uint8_t SLOTTLE_MIN = 0x00; +static const uint8_t SLOTTLE_MAX = 0x0e; + +//static const int8_t TRIM_MIN = 0; +//static const int8_t TRIM_MAX = 0x0f; +static const int8_t TRIM_LEFT = 15; +static const int8_t TRIM_RIGHT = 1; +static const int8_t TRIM_NEUTRAL = 0; + +static const int8_t LADDER_MIN = -3; +static const int8_t LADDER_MAX = 3; + +#if 0 // not use +static const int8_t ELEVATOR_MIN = -15; +static const int8_t ELEVATOR_MAX = 15; +#endif + +private: + + CodecHonyBee(); + + +}; + +#endif + + + + + +
diff -r 000000000000 -r f9e49220c97a CodecIRPropoHonyBee/DecodeHonyBee.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CodecIRPropoHonyBee/DecodeHonyBee.cpp Sun Jun 23 07:28:06 2013 +0000 @@ -0,0 +1,172 @@ +/** + * IR Propo Decode class + * Version 0.0 130623 + * + * Writer:suupen + */ + #include "CodecHonyBee.h" + #include "DecodeHonyBee.h" + + /** + * Constructor DecodeHonyBee + * + */ + DecodeHonyBee::DecodeHonyBee(){ + // nothing + } + + /** + * Destructor. + */ + DecodeHonyBee::~DecodeHonyBee(){ + // nothing + } + + +/** + * Get HonyBee controller data. + * + * @param data Pointer to propo recive data. + * + * @param HonyBee Pointer to HonyBee. + * + * @return receive answer : ture:recive ok false:recive ng. + */ +bool DecodeHonyBee::decode(uint8_t *data, CodecHonyBee::honyBeePropo_t *honyBee) { + + bool ans = false; + uint8_t wk1 = 0,wk2; + int8_t ladder; + uint8_t dat[3]; + uint8_t i; + + // MSB to LSB + for(i = 0; i < 8; i++){ + + dat[0] = dat[0] << 1; + dat[1] = dat[1] << 1; + dat[2] = dat[2] << 1; + + if(((data[0] >> i) & 0x01) == 0x01){dat[0] |= 0x01;} + if(((data[1] >> i) & 0x01) == 0x01){dat[1] |= 0x01;} + if(((data[2] >> i) & 0x01) == 0x01){dat[2] |= 0x01;} + } + + // parity calculate + for(uint8_t c=0; c < 8; c+=2){ + wk1 += ((dat[0] >> c) & 0x03); + wk1 += ((dat[1] >> c) & 0x03); + } + wk1 += ((dat[2] >> 6) & 0x02); + + wk1 &= 0x03; + if(wk1 == 0x00){wk1 = 0x03;} + else if(wk1 == 0x03){wk1 = 0x00;} + + wk2 = (dat[2] >> 5) & 0x03; + + if(wk1 == wk2){ + // parity ok + ans =true; + honyBee->count++; + honyBee->band = (dat[0] >> 2) & 0x03; + honyBee->slottle = ((dat[0] << 2) & 0x0c) | ((dat[1] >> 6) & 0x03); + honyBee->trim = (dat[1] >> 2) & 0x0f; + ladder = ((dat[1] << 1) & 0x06) | ((dat[2] >> 7) & 0x01); + if(0x04 == (ladder & 0x04)){ladder |= 0xf8;} + honyBee->ladder = ladder; + } + else{ + // parity ng + // nothing + ans = false; + honyBee->band = 0x0F; + } + + return ans; +} + + +/** + * Normalize HonyBee data. + * + * @param buf Pointer to propo recive data. + * + * @param propo normalize propo data. + * + * @return receive answer : ture:recive ok false:recive ng. + */ +bool DecodeHonyBee::normalize(uint8_t *buf, CodecHonyBee::normalizePropo_t *propo) { + bool ans = false; + bool decodeCheck =false; + + CodecHonyBee::honyBeePropo_t HonyBee; + decodeCheck = DecodeHonyBee::decode(buf, &HonyBee); + + if(decodeCheck == true){ + ans = true; + + propo->count++;// = HonyBee.count; + + switch(HonyBee.band){ + case CodecHonyBee::BAND_A: + propo->band = 1; + break; + case CodecHonyBee::BAND_B: + propo->band = 2; + break; + case CodecHonyBee::BAND_C: + propo->band = 3; + break; + default: + propo->band = 0; + break; + } + + if(HonyBee.slottle > CodecHonyBee::SLOTTLE_MAX){HonyBee.slottle = CodecHonyBee::SLOTTLE_MAX;} + propo->slottle = (float)HonyBee.slottle / CodecHonyBee::SLOTTLE_MAX; + + if(HonyBee.ladder >= 0){ + if(HonyBee.ladder > CodecHonyBee::LADDER_MAX){HonyBee.ladder = CodecHonyBee::LADDER_MAX;} + propo->ladder = (float)HonyBee.ladder / CodecHonyBee::LADDER_MAX; + } + else{ + if(HonyBee.ladder < CodecHonyBee::LADDER_MIN){HonyBee.ladder = CodecHonyBee::LADDER_MIN;} + propo->ladder = -((float)HonyBee.ladder / CodecHonyBee::LADDER_MIN); + } + +#if 0 // not use + if(HonyBee.elevator >= 0){ + if(HonyBee.elevator > CodecHonyBee::ELEVATOR_MAX){HonyBee.elevator = CodecHonyBee::ELEVATOR_MAX;} + propo->elevator = (float)HonyBee.elevator / CodecHonyBee::ELEVATOR_MAX; + } + else{ + if(HonyBee.elevator < CodecHonyBee::ELEVATOR_MIN){HonyBee.elevator = CodecHonyBee::ELEVATOR_MIN;} + propo->elevator = -((float)HonyBee.elevator / CodecHonyBee::ELEVATOR_MIN); + } +#endif // not use + + switch (HonyBee.trim){ + case CodecHonyBee::TRIM_LEFT: + propo->trim = -1.0; + break; + case CodecHonyBee::TRIM_RIGHT: + propo->trim = 1.0; + break; + default: +// case CodecHonyBee::TRIM_NEUTRAL: + propo->trim = 0.0; + break; + } + + } + else{ + // NG + ans = false; + } + + return ans; +} + + +
diff -r 000000000000 -r f9e49220c97a CodecIRPropoHonyBee/DecodeHonyBee.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CodecIRPropoHonyBee/DecodeHonyBee.h Sun Jun 23 07:28:06 2013 +0000 @@ -0,0 +1,63 @@ +/** + * Decode IR Propo HonyBee class + * Version 0.0 130623 + * + * Writer:suupen + */ + +#ifndef _DECODEHonyBee_H_ +#define _DECODEHonyBee_H_ + +#include <mbed.h> +#include "CodecHonyBee.h" + + +/** + * Decode class. + */ +class DecodeHonyBee { +public: + + +/** + * Constructor + */ + DecodeHonyBee(); + +/** + * Destructor. + */ + ~DecodeHonyBee(); + +/** + * Get HonyBee propo analysis data. + * + * @param data IR recive data + * + * @param HonyBee Pointer to HonyBee. + * + * @return receive answer : ture:recive ok false:recive ng. + */ + bool decode(uint8_t *data, CodecHonyBee::honyBeePropo_t *HonyBee); + +/** + * Normalize HonyBee data. + * + * @param buf Pointer to propo recive data. + * + * @param propo normalize propo data. + * + * @return receive answer : ture:recive ok false:recive ng. + */ +bool normalize(uint8_t *buf, CodecHonyBee::normalizePropo_t *propo); + +private: + + + + +}; + +#endif + +
diff -r 000000000000 -r f9e49220c97a CodecIRPropoSwift.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CodecIRPropoSwift.lib Sun Jun 23 07:28:06 2013 +0000 @@ -0,0 +1,1 @@ +CodecIRPropoSwift#000000000000
diff -r 000000000000 -r f9e49220c97a Propo_RemotoIR.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Propo_RemotoIR.lib Sun Jun 23 07:28:06 2013 +0000 @@ -0,0 +1,1 @@ +https://mbed.org/users/shintamainjp/code/RemoteIR/#268cc2ab63bd
diff -r 000000000000 -r f9e49220c97a Propo_RemotoIR/ReceiverIR.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Propo_RemotoIR/ReceiverIR.cpp Sun Jun 23 07:28:06 2013 +0000 @@ -0,0 +1,448 @@ +/** + * IR receiver (Version 0.0.4) + * + * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems) + * http://shinta.main.jp/ + * + * ------------------------------------------------------- + * 130616 suupen + * IRC Helicopter "SWIFT" Propo support + * Conditional compilation + * "SWIFT_PROTCOL" + * "IR_RAW_DATA_ANALYSIS" + *-------------------------------------------------------- + */ + +#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) { + +#ifdef IR_RAW_DATA_ANALYSIS + switch (work.state) { + case Idle: + if (work.c1 < 0){ + check.bitcount = 0; + check.timecount[check.bitcount++] = 0; + } else { + check.timecount[check.bitcount++] = timer.read_us() & ~1; + } + break; + case Receiving: + + if ((check.bitcount < 1000)) { + check.timecount[check.bitcount++] = timer.read_us() & ~1; + } + break; + default: + break; + } +#endif //IR_RAW_DATA_ANALYSIS + + 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; +#ifdef SWIFT_PROTCOL + } else if (InRange(a, RemoteIR::TUS_SWIFT * 10) && InRange(b, RemoteIR::TUS_SWIFT * 3)) { + /* + * SWIFT. + */ + data.format = RemoteIR::SWIFT; + work.state = Receiving; + data.bitcount = 0; +#endif // SWIFT_PROTCOL + } else { +#ifdef IR_RAW_DATA_ANALYSIS + data.format = RemoteIR::UNKNOWN; + work.state = Receiving; + data.bitcount = 0; +#else // ~IR_RAW_DATA_ANALYSIS + init_state(); +#endif // IR_RAW_DATA_ANALYSIS + } + } + 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(); +#ifdef SWIFT_PROTCOL + } else if (RemoteIR::SWIFT == data.format) { + work.d2 = timer.read_us(); + int a = work.d2 - work.d1; + if (InRange(a, RemoteIR::TUS_SWIFT * 2)) { + data.buffer[data.bitcount / 8] |= (1 << (7 - (data.bitcount % 8))); + } else if (InRange(a, RemoteIR::TUS_SWIFT * 1)) { + data.buffer[data.bitcount / 8] &= ~(1 << (7 - (data.bitcount % 8))); + } + data.bitcount++; +#if 0 + /* + * Length of SWIFT is always 32 bits. + */ + if (32 <= data.bitcount) { + work.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_SWIFT * 5); +#endif +#endif // SWIFT_PROTCOL + +#ifdef IR_RAW_DATA_ANALYSIS + } else if (RemoteIR::SWIFT == data.format) { + /* + * Set timeout for tail detection automatically. + */ + timeout.detach(); + timeout.attach_us(this, &ReceiverIR::isr_timeout, (work.c3 - work.c2) * 5); +#endif // IR_RAW_DATA_ANALYSIS + } + break; + case Received: + break; + default: + break; + } + UNLOCK(); +} + +void ReceiverIR::isr_rise(void) { + +#ifdef IR_RAW_DATA_ANALYSIS + switch (work.state) { + case Idle: + case Receiving: + check.timecount[check.bitcount++] = timer.read_us() | 1; + break; + default: + break; + } +#endif //IR_RAW_DATA_ANALYSIS + + 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(); +#ifdef SWIFT_PROTCOL + } else if (RemoteIR::SWIFT == data.format) { + work.d1 = timer.read_us(); +#endif // SWIFT_PROTCOL + } 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 + +#ifdef IR_RAW_DATA_ANALYSIS +#if 1 //debug + for ( int i = 0; i < check.bitcount; i++){ + printf("%02d : %06d , %06d , %04d \n", + i, + check.timecount[i], + check.timecount[i + 1], + (check.timecount[i + 1] - check.timecount[i])); + + if( (i % 2) != 0){printf("\n");} + } + printf("\n"); +#endif //debug +#endif //IR_RAW_DATA_ANALYSIS + + if (work.state == Receiving) { + work.state = Received; + work.c1 = -1; + work.c2 = -1; + work.c3 = -1; + work.d1 = -1; + work.d2 = -1; + } + UNLOCK(); +} + +
diff -r 000000000000 -r f9e49220c97a Propo_RemotoIR/ReceiverIR.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Propo_RemotoIR/ReceiverIR.h Sun Jun 23 07:28:06 2013 +0000 @@ -0,0 +1,120 @@ +/** + * IR receiver (Version 0.0.4) + * + * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems) + * http://shinta.main.jp/ + * + * ------------------------------------------------------- + * 130616 suupen + * IRC Helicopter "SWIFT" Propo support + * Conditional compilation + * "SWIFT_PROTCOL" + * "IR_RAW_DATA_ANALYSIS" + *-------------------------------------------------------- + */ + +#ifndef _RECEIVER_IR_H_ +#define _RECEIVER_IR_H_ + +#include <mbed.h> + +#include "RemoteIR.h" + +//#define IR_RAW_DATA_ANALYSIS + +/** + * 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[64]; + } data_t; + + typedef struct { + State state; + int c1; + int c2; + int c3; + int d1; + int d2; + } work_t; + + #ifdef IR_RAW_DATA_ANALYSIS + typedef struct { + State state; + int timecount[1000]; // Hi,Lo count (1/1 [us]/count) + int bitcount; + } check_t; +#endif //IR_RAW_DATA_ANALYSIS + + 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; + #ifdef IR_RAW_DATA_ANALYSIS + check_t check; +#endif //IR_RAW_DATA_ANALYSIS + + 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 +
diff -r 000000000000 -r f9e49220c97a Propo_RemotoIR/RemoteIR.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Propo_RemotoIR/RemoteIR.h Sun Jun 23 07:28:06 2013 +0000 @@ -0,0 +1,48 @@ +/** + * IR remote common class (Version 0.0.4) + * + * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems) + * http://shinta.main.jp/ + * + * ------------------------------------------------------- + * 130616 suupen + * IRC Helicopter "SWIFT" Propo support + * Conditional compilation + * "SWIFT_PROTCOL" + * "IR_RAW_DATA_ANALYSIS" + *-------------------------------------------------------- + */ + +#ifndef _REMOTE_IR_H_ +#define _REMOTE_IR_H_ + +#define SWIFT_PROTCOL // IRC Helicopter SWIFT protcol + + +class RemoteIR { +public: + + typedef enum { + UNKNOWN, + NEC, + NEC_REPEAT, + AEHA, + AEHA_REPEAT, + SONY, +#ifdef SWIFT_PROTCOL + SWIFT, +#endif // SWIFT_PROTCOL + } Format; + + static const int TUS_NEC = 562; + static const int TUS_AEHA = 425; + static const int TUS_SONY = 600; +#ifdef SWIFT_PROTCOL + static const int TUS_SWIFT = 350; +#endif // SWIFT_PROTCOL + +private: + RemoteIR(); +}; + +#endif
diff -r 000000000000 -r f9e49220c97a Propo_RemotoIR/TransmitterIR.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Propo_RemotoIR/TransmitterIR.cpp Sun Jun 23 07:28:06 2013 +0000 @@ -0,0 +1,300 @@ +/** + * IR transmitter (Version 0.0.4) + * + * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems) + * http://shinta.main.jp/ + */ + +#include "TransmitterIR.h" + +#define LOCK() +#define UNLOCK() + +/** + * Constructor. + * + * @param txpin Pin for transmit IR signal. + */ +TransmitterIR::TransmitterIR(PinName txpin) : tx(txpin) { + tx.write(0.0); + tx.period_us(26.3); + + work.state = Idle; + work.bitcount = 0; + work.leader = 0; + work.data = 0; + work.trailer = 0; + + data.format = RemoteIR::UNKNOWN; + data.bitlength = 0; +} + +/** + * Destructor. + */ +TransmitterIR::~TransmitterIR() { +} + +/** + * Get state. + * + * @return Current state. + */ +TransmitterIR::State TransmitterIR::getState(void) { + LOCK(); + State s = work.state; + UNLOCK(); + return s; +} + +/** + * Set data. + * + * @param format Format. + * @param buf Buffer of a data. + * @param bitlength Bit length of the data. + * + * @return Data bit length. + */ +int TransmitterIR::setData(RemoteIR::Format format, uint8_t *buf, int bitlength) { + LOCK(); + if (work.state != Idle) { + UNLOCK(); + return -1; + } + + work.state = Leader; + work.bitcount = 0; + work.leader = 0; + work.data = 0; + work.trailer = 0; + + data.format = format; + data.bitlength = bitlength; + const int n = bitlength / 8 + (((bitlength % 8) != 0) ? 1 : 0); + for (int i = 0; i < n; i++) { + data.buffer[i] = buf[i]; + } + + switch (format) { + case RemoteIR::NEC: + ticker.detach(); + ticker.attach_us(this, &TransmitterIR::tick, RemoteIR::TUS_NEC); + break; + case RemoteIR::AEHA: + ticker.detach(); + ticker.attach_us(this, &TransmitterIR::tick, RemoteIR::TUS_AEHA); + break; + case RemoteIR::SONY: + ticker.detach(); + ticker.attach_us(this, &TransmitterIR::tick, RemoteIR::TUS_SONY); + break; + } + + UNLOCK(); + return bitlength; +} + +void TransmitterIR::tick(void) { + LOCK(); + switch (work.state) { + case Idle: + work.bitcount = 0; + work.leader = 0; + work.data = 0; + work.trailer = 0; + break; + case Leader: + if (data.format == RemoteIR::NEC) { + /* + * NEC. + */ + static const int LEADER_NEC_HEAD = 16; + static const int LEADER_NEC_TAIL = 8; + if (work.leader < LEADER_NEC_HEAD) { + tx.write(0.5); + } else { + tx.write(0.0); + } + work.leader++; + if ((LEADER_NEC_HEAD + LEADER_NEC_TAIL) <= work.leader) { + work.state = Data; + } + } else if (data.format == RemoteIR::AEHA) { + /* + * AEHA. + */ + static const int LEADER_AEHA_HEAD = 8; + static const int LEADER_AEHA_TAIL = 4; + if (work.leader < LEADER_AEHA_HEAD) { + tx.write(0.5); + } else { + tx.write(0.0); + } + work.leader++; + if ((LEADER_AEHA_HEAD + LEADER_AEHA_TAIL) <= work.leader) { + work.state = Data; + } + } else if (data.format == RemoteIR::SONY) { + /* + * SONY. + */ + static const int LEADER_SONY_HEAD = 4; + static const int LEADER_SONY_TAIL = 0; + if (work.leader < LEADER_SONY_HEAD) { + tx.write(0.5); + } else { + tx.write(0.0); + } + work.leader++; + if ((LEADER_SONY_HEAD + LEADER_SONY_TAIL) <= work.leader) { + work.state = Data; + } + } else { + } + break; + case Data: + if (data.format == RemoteIR::NEC) { + /* + * NEC. + */ + if (work.data == 0) { + tx.write(0.5); + work.data++; + } else { + tx.write(0.0); + if (0 != (data.buffer[work.bitcount / 8] & (1 << work.bitcount % 8))) { + if (3 <= work.data) { + work.bitcount++; + work.data = 0; + } else { + work.data++; + } + } else { + if (1 <= work.data) { + work.bitcount++; + work.data = 0; + } else { + work.data++; + } + } + } + if (data.bitlength <= work.bitcount) { + work.state = Trailer; + } + } else if (data.format == RemoteIR::AEHA) { + /* + * AEHA. + */ + if (work.data == 0) { + tx.write(0.5); + work.data++; + } else { + tx.write(0.0); + if (0 != (data.buffer[work.bitcount / 8] & (1 << work.bitcount % 8))) { + if (3 <= work.data) { + work.bitcount++; + work.data = 0; + } else { + work.data++; + } + } else { + if (1 <= work.data) { + work.bitcount++; + work.data = 0; + } else { + work.data++; + } + } + } + if (data.bitlength <= work.bitcount) { + work.state = Trailer; + } + } else if (data.format == RemoteIR::SONY) { + /* + * SONY. + */ + if (work.data == 0) { + tx.write(0.0); + work.data++; + } else { + tx.write(0.5); + if (0 != (data.buffer[work.bitcount / 8] & (1 << work.bitcount % 8))) { + if (2 <= work.data) { + work.bitcount++; + work.data = 0; + } else { + work.data++; + } + } else { + if (1 <= work.data) { + work.bitcount++; + work.data = 0; + } else { + work.data++; + } + } + } + if (data.bitlength <= work.bitcount) { + work.state = Trailer; + } + } else { + } + break; + case Trailer: + if (data.format == RemoteIR::NEC) { + /* + * NEC. + */ + static const int TRAILER_NEC_HEAD = 1; + static const int TRAILER_NEC_TAIL = 2; + if (work.trailer < TRAILER_NEC_HEAD) { + tx.write(0.5); + } else { + tx.write(0.0); + } + work.trailer++; + if ((TRAILER_NEC_HEAD + TRAILER_NEC_TAIL) <= work.trailer) { + work.state = Idle; + //ticker.detach(); + } + } else if (data.format == RemoteIR::AEHA) { + /* + * AEHA. + */ + static const int TRAILER_AEHA_HEAD = 1; + static const int TRAILER_AEHA_TAIL = 8000 / RemoteIR::TUS_AEHA; + if (work.trailer < TRAILER_AEHA_HEAD) { + tx.write(0.5); + } else { + tx.write(0.0); + } + work.trailer++; + if ((TRAILER_AEHA_HEAD + TRAILER_AEHA_TAIL) <= work.trailer) { + work.state = Idle; + //ticker.detach(); + } + } else if (data.format == RemoteIR::SONY) { + /* + * SONY. + */ + static const int TRAILER_SONY_HEAD = 0; + static const int TRAILER_SONY_TAIL = 0; + if (work.trailer < TRAILER_SONY_HEAD) { + tx.write(0.5); + } else { + tx.write(0.0); + } + work.trailer++; + if ((TRAILER_SONY_HEAD + TRAILER_SONY_TAIL) <= work.trailer) { + work.state = Idle; + //ticker.detach(); + } + } else { + } + break; + default: + break; + } + UNLOCK(); +}
diff -r 000000000000 -r f9e49220c97a Propo_RemotoIR/TransmitterIR.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Propo_RemotoIR/TransmitterIR.h Sun Jun 23 07:28:06 2013 +0000 @@ -0,0 +1,83 @@ +/** + * IR transmitter (Version 0.0.4) + * + * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems) + * http://shinta.main.jp/ + */ + +#ifndef _TRANSMITTER_IR_H_ +#define _TRANSMITTER_IR_H_ + +#include <mbed.h> + +#include "RemoteIR.h" + +/** + * IR transmitter class. + */ +class TransmitterIR { +public: + + /** + * Constructor. + * + * @param txpin Pin for transmit IR signal. + */ + explicit TransmitterIR(PinName txpin); + + /** + * Destructor. + */ + ~TransmitterIR(); + + typedef enum { + Idle, + Leader, + Data, + Trailer + } State; + + /** + * Get state. + * + * @return Current state. + */ + State getState(void); + + /** + * Set data. + * + * @param format Format. + * @param buf Buffer of a data. + * @param bitlength Bit length of the data. + * + * @return Data bit length. + */ + int setData(RemoteIR::Format format, uint8_t *buf, int bitlength); + +private: + + typedef struct { + State state; + int bitcount; + int leader; + int data; + int trailer; + } work_t; + + typedef struct { + RemoteIR::Format format; + int bitlength; + uint8_t buffer[64]; + } data_t; + + PwmOut tx; + Ticker ticker; + data_t data; + work_t work; + + void tick(); + +}; + +#endif \ No newline at end of file
diff -r 000000000000 -r f9e49220c97a main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sun Jun 23 07:28:06 2013 +0000 @@ -0,0 +1,189 @@ +/** + * HonyBee Propo Decode test program + * 130623 + * + * Writer:suupen + * + * <circuit diagram> + * VU(mbed) + * | + * |Vcc + * --- (PL-IRM2161) IR Reciver + * | |Vout + * | |--- p5(mbed) + * | | + * --- + * |GND + * | + * GND(mbed) + * + * <PC termnal soft> + * tera term + * baudrate:38400[bps] + * data:8[bit] + * parity:none + * stopbit:1[bit] + */ + + +//#define PROPO_RAW_DATA // ari: zyusin data hyoji nasi:HonyBee kaiseki data hyoji +//#define HONYBEE_NORMALIZE // ari: HonyBee data seikika hyoji nasi: HonyBee data tujyo hyoji + +#include "mbed.h" +#include "ReceiverIR.h" + +#ifndef PROPO_RAW_DATA +#include "CodecHonyBee.h" +#include "DecodeHonyBee.h" +#endif // PROPO_RAW_DATA + +void display_format(RemoteIR::Format format); +void display_binary(uint8_t *buf, uint8_t cnt); + +Serial pc(USBTX,USBRX); + + +ReceiverIR ir_rx(p5); + +RemoteIR::Format format; + +#ifndef PROPO_RAW_DATA +DecodeHonyBee HonyBee; +CodecHonyBee::honyBeePropo_t HonyBeeData; + +#ifdef HONYBEE_NORMALIZE +CodecHonyBee::normalizePropo_t normalize; +#endif // HONYBEE_NORMALIZE + +#endif // PROPO_RAW_DATA + + +uint8_t buf[32]; +int bitcount; + +DigitalOut myled(LED1); +DigitalOut led2(LED2); +DigitalIn irtest(p20); + + +int main(){ + pc.baud(38400); + while(1){ + + myled =~myled; + led2 = irtest; + + + + #ifdef PROPO_RAW_DATA + if (ir_rx.getState() == ReceiverIR::Received) { + bitcount = ir_rx.getData(&format, buf, sizeof(buf) * 8); + + display_format(format); + display_binary(buf, ((bitcount + 7) / 8)); + } + else{ +#if 0 + switch(ir_rx.getState()){ + + case ReceiverIR::Idle: + printf("Idele\n"); + break; + case ReceiverIR::Receiving: + printf("Receiveing\n"); + break; + case ReceiverIR::Received: + printf("Received\n"); + break; + } +#endif + } +#endif // PROPO_RAW_DATA + +#ifndef PROPO_RAW_DATA + if (ir_rx.getState() == ReceiverIR::Received) { + bitcount = ir_rx.getData(&format, buf, sizeof(buf) * 8); +#ifdef HONYBEE_NORMALIZE + bool ans = HonyBee.normalize(buf, &normalize); + if(ans == true){ + printf("count = %02x band = %1d slottle = %f trim = %f ladder = %f elevator = %f\n",normalize.count,normalize.band,normalize.slottle,normalize.trim,normalize.ladder, normalize.elevator); + } + else{ + printf("NG\n"); + } +#else // ~HONYBEE_NORMALIZE + bool ans = HonyBee.decode(buf, &HonyBeeData); + if(ans == true){ + printf("count = %02x band = %02x slottle = %03d trim = %03d ladder = %03d \n",HonyBeeData.count,HonyBeeData.band,HonyBeeData.slottle,HonyBeeData.trim,HonyBeeData.ladder); + } + else{ + printf("NG\n"); + } +#endif// HONYBEE_NORMALIZE + + } +#endif // PROPO_RAW_DATA + + } + +} + +/** + * Display a format of a data. + */ +void display_format(RemoteIR::Format format) { + switch (format) { + case RemoteIR::UNKNOWN: + pc.printf("????????"); + break; + case RemoteIR::NEC: + pc.printf("NEC "); + break; + case RemoteIR::NEC_REPEAT: + pc.printf("NEC (R)"); + break; + case RemoteIR::AEHA: + pc.printf("AEHA "); + break; + case RemoteIR::AEHA_REPEAT: + pc.printf("AEHA (R)"); + break; + case RemoteIR::SONY: //HONEY_BEE: + pc.printf("SONY or HONEY_BEE "); + break; + +#ifdef Swift_PROTCOL + case RemoteIR::Swift: + pc.printf("Swift "); + break; +#endif // Swift_PROPO + default: + pc.printf("unknown "); + break; + } +} + +void display_binary(uint8_t *buf, uint8_t cnt){ + uint8_t i; + uint8_t bitcnt; + uint8_t dat; + uint16_t checkbit; + + for(i = 0; i < cnt; i++){ + checkbit = 0x0080; + dat = *(buf + i); + printf("%02x:",dat); + for(bitcnt = 0; bitcnt < 8; bitcnt++){ + if( checkbit & dat){printf("1");} + else {printf("0");} + + checkbit = checkbit >> 1; + if(bitcnt == 3){printf(" ");} + } + printf(" "); + } + printf("\n"); +} + + +
diff -r 000000000000 -r f9e49220c97a mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Sun Jun 23 07:28:06 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/b3110cd2dd17 \ No newline at end of file