나중에 급하게 PID 알고리즘을 적용해 짜본 코드... 시간이 충분치 않아서 그냥 원래 있던 코드를 수정해서 하기로 했기에 버려진 코드지만, 교수님께 참고용으로 Publish를 했다.

Dependencies:   mbed Adafruit_GFX

Committer:
21400688
Date:
Sat Jun 15 20:39:39 2019 +0000
Revision:
0:c4c874d702f9
first commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
21400688 0:c4c874d702f9 1 /**
21400688 0:c4c874d702f9 2 * IR receiver (Version 0.0.4)
21400688 0:c4c874d702f9 3 *
21400688 0:c4c874d702f9 4 * Copyright (C) 2010 Shinichiro Nakamura (CuBeatSystems)
21400688 0:c4c874d702f9 5 * http://shinta.main.jp/
21400688 0:c4c874d702f9 6 */
21400688 0:c4c874d702f9 7
21400688 0:c4c874d702f9 8 #include "ReceiverIR.h"
21400688 0:c4c874d702f9 9
21400688 0:c4c874d702f9 10 #define LOCK()
21400688 0:c4c874d702f9 11 #define UNLOCK()
21400688 0:c4c874d702f9 12
21400688 0:c4c874d702f9 13 #define InRange(x,y) ((((y) * 0.7) < (x)) && ((x) < ((y) * 1.3)))
21400688 0:c4c874d702f9 14
21400688 0:c4c874d702f9 15 /**
21400688 0:c4c874d702f9 16 * Constructor.
21400688 0:c4c874d702f9 17 *
21400688 0:c4c874d702f9 18 * @param rxpin Pin for receive IR signal.
21400688 0:c4c874d702f9 19 */
21400688 0:c4c874d702f9 20 ReceiverIR::ReceiverIR(PinName rxpin) : evt(rxpin) {
21400688 0:c4c874d702f9 21 init_state();
21400688 0:c4c874d702f9 22 evt.fall(this, &ReceiverIR::isr_fall);
21400688 0:c4c874d702f9 23 evt.rise(this, &ReceiverIR::isr_rise);
21400688 0:c4c874d702f9 24 evt.mode(PullUp);
21400688 0:c4c874d702f9 25 ticker.attach_us(this, &ReceiverIR::isr_wdt, 10 * 1000);
21400688 0:c4c874d702f9 26 }
21400688 0:c4c874d702f9 27
21400688 0:c4c874d702f9 28 /**
21400688 0:c4c874d702f9 29 * Destructor.
21400688 0:c4c874d702f9 30 */
21400688 0:c4c874d702f9 31 ReceiverIR::~ReceiverIR() {
21400688 0:c4c874d702f9 32 }
21400688 0:c4c874d702f9 33
21400688 0:c4c874d702f9 34 /**
21400688 0:c4c874d702f9 35 * Get state.
21400688 0:c4c874d702f9 36 *
21400688 0:c4c874d702f9 37 * @return Current state.
21400688 0:c4c874d702f9 38 */
21400688 0:c4c874d702f9 39 ReceiverIR::State ReceiverIR::getState() {
21400688 0:c4c874d702f9 40 LOCK();
21400688 0:c4c874d702f9 41 State s = work.state;
21400688 0:c4c874d702f9 42 UNLOCK();
21400688 0:c4c874d702f9 43 return s;
21400688 0:c4c874d702f9 44 }
21400688 0:c4c874d702f9 45
21400688 0:c4c874d702f9 46 /**
21400688 0:c4c874d702f9 47 * Get data.
21400688 0:c4c874d702f9 48 *
21400688 0:c4c874d702f9 49 * @param format Pointer to format.
21400688 0:c4c874d702f9 50 * @param buf Buffer of a data.
21400688 0:c4c874d702f9 51 * @param bitlength Bit length of the buffer.
21400688 0:c4c874d702f9 52 *
21400688 0:c4c874d702f9 53 * @return Data bit length.
21400688 0:c4c874d702f9 54 */
21400688 0:c4c874d702f9 55 int ReceiverIR::getData(RemoteIR::Format *format, uint8_t *buf, int bitlength) {
21400688 0:c4c874d702f9 56 LOCK();
21400688 0:c4c874d702f9 57
21400688 0:c4c874d702f9 58 if (bitlength < data.bitcount) {
21400688 0:c4c874d702f9 59 UNLOCK();
21400688 0:c4c874d702f9 60 return -1;
21400688 0:c4c874d702f9 61 }
21400688 0:c4c874d702f9 62
21400688 0:c4c874d702f9 63 const int nbits = data.bitcount;
21400688 0:c4c874d702f9 64 const int nbytes = data.bitcount / 8 + (((data.bitcount % 8) != 0) ? 1 : 0);
21400688 0:c4c874d702f9 65 *format = data.format;
21400688 0:c4c874d702f9 66 for (int i = 0; i < nbytes; i++) {
21400688 0:c4c874d702f9 67 buf[i] = data.buffer[i];
21400688 0:c4c874d702f9 68 }
21400688 0:c4c874d702f9 69
21400688 0:c4c874d702f9 70 init_state();
21400688 0:c4c874d702f9 71
21400688 0:c4c874d702f9 72 UNLOCK();
21400688 0:c4c874d702f9 73 return nbits;
21400688 0:c4c874d702f9 74 }
21400688 0:c4c874d702f9 75
21400688 0:c4c874d702f9 76 void ReceiverIR::init_state(void) {
21400688 0:c4c874d702f9 77 work.c1 = -1;
21400688 0:c4c874d702f9 78 work.c2 = -1;
21400688 0:c4c874d702f9 79 work.c3 = -1;
21400688 0:c4c874d702f9 80 work.d1 = -1;
21400688 0:c4c874d702f9 81 work.d2 = -1;
21400688 0:c4c874d702f9 82 work.state = Idle;
21400688 0:c4c874d702f9 83 data.format = RemoteIR::UNKNOWN;
21400688 0:c4c874d702f9 84 data.bitcount = 0;
21400688 0:c4c874d702f9 85 timer.stop();
21400688 0:c4c874d702f9 86 timer.reset();
21400688 0:c4c874d702f9 87 for (int i = 0; i < sizeof(data.buffer); i++) {
21400688 0:c4c874d702f9 88 data.buffer[i] = 0;
21400688 0:c4c874d702f9 89 }
21400688 0:c4c874d702f9 90 }
21400688 0:c4c874d702f9 91
21400688 0:c4c874d702f9 92 void ReceiverIR::isr_wdt(void) {
21400688 0:c4c874d702f9 93 LOCK();
21400688 0:c4c874d702f9 94 static int cnt = 0;
21400688 0:c4c874d702f9 95 if ((Idle != work.state) || ((0 <= work.c1) || (0 <= work.c2) || (0 <= work.c3) || (0 <= work.d1) || (0 <= work.d2))) {
21400688 0:c4c874d702f9 96 cnt++;
21400688 0:c4c874d702f9 97 if (cnt > 50) {
21400688 0:c4c874d702f9 98 #if 0
21400688 0:c4c874d702f9 99 printf("# WDT [c1=%d, c2=%d, c3=%d, d1=%d, d2=%d, state=%d, format=%d, bitcount=%d]\n",
21400688 0:c4c874d702f9 100 work.c1,
21400688 0:c4c874d702f9 101 work.c2,
21400688 0:c4c874d702f9 102 work.c3,
21400688 0:c4c874d702f9 103 work.d1,
21400688 0:c4c874d702f9 104 work.d2,
21400688 0:c4c874d702f9 105 work.state,
21400688 0:c4c874d702f9 106 data.format,
21400688 0:c4c874d702f9 107 data.bitcount);
21400688 0:c4c874d702f9 108 #endif
21400688 0:c4c874d702f9 109 init_state();
21400688 0:c4c874d702f9 110 cnt = 0;
21400688 0:c4c874d702f9 111 }
21400688 0:c4c874d702f9 112 } else {
21400688 0:c4c874d702f9 113 cnt = 0;
21400688 0:c4c874d702f9 114 }
21400688 0:c4c874d702f9 115 UNLOCK();
21400688 0:c4c874d702f9 116 }
21400688 0:c4c874d702f9 117
21400688 0:c4c874d702f9 118 void ReceiverIR::isr_fall(void) {
21400688 0:c4c874d702f9 119 LOCK();
21400688 0:c4c874d702f9 120 switch (work.state) {
21400688 0:c4c874d702f9 121 case Idle:
21400688 0:c4c874d702f9 122 if (work.c1 < 0) {
21400688 0:c4c874d702f9 123 timer.start();
21400688 0:c4c874d702f9 124 work.c1 = timer.read_us();
21400688 0:c4c874d702f9 125 } else {
21400688 0:c4c874d702f9 126 work.c3 = timer.read_us();
21400688 0:c4c874d702f9 127 int a = work.c2 - work.c1;
21400688 0:c4c874d702f9 128 int b = work.c3 - work.c2;
21400688 0:c4c874d702f9 129 if (InRange(a, RemoteIR::TUS_NEC * 16) && InRange(b, RemoteIR::TUS_NEC * 8)) {
21400688 0:c4c874d702f9 130 /*
21400688 0:c4c874d702f9 131 * NEC.
21400688 0:c4c874d702f9 132 */
21400688 0:c4c874d702f9 133 data.format = RemoteIR::NEC;
21400688 0:c4c874d702f9 134 work.state = Receiving;
21400688 0:c4c874d702f9 135 data.bitcount = 0;
21400688 0:c4c874d702f9 136 } else if (InRange(a, RemoteIR::TUS_NEC * 16) && InRange(b, RemoteIR::TUS_NEC * 4)) {
21400688 0:c4c874d702f9 137 /*
21400688 0:c4c874d702f9 138 * NEC Repeat.
21400688 0:c4c874d702f9 139 */
21400688 0:c4c874d702f9 140 data.format = RemoteIR::NEC_REPEAT;
21400688 0:c4c874d702f9 141 work.state = Received;
21400688 0:c4c874d702f9 142 data.bitcount = 0;
21400688 0:c4c874d702f9 143 work.c1 = -1;
21400688 0:c4c874d702f9 144 work.c2 = -1;
21400688 0:c4c874d702f9 145 work.c3 = -1;
21400688 0:c4c874d702f9 146 work.d1 = -1;
21400688 0:c4c874d702f9 147 work.d2 = -1;
21400688 0:c4c874d702f9 148 } else if (InRange(a, RemoteIR::TUS_AEHA * 8) && InRange(b, RemoteIR::TUS_AEHA * 4)) {
21400688 0:c4c874d702f9 149 /*
21400688 0:c4c874d702f9 150 * AEHA.
21400688 0:c4c874d702f9 151 */
21400688 0:c4c874d702f9 152 data.format = RemoteIR::AEHA;
21400688 0:c4c874d702f9 153 work.state = Receiving;
21400688 0:c4c874d702f9 154 data.bitcount = 0;
21400688 0:c4c874d702f9 155 } else if (InRange(a, RemoteIR::TUS_AEHA * 8) && InRange(b, RemoteIR::TUS_AEHA * 8)) {
21400688 0:c4c874d702f9 156 /*
21400688 0:c4c874d702f9 157 * AEHA Repeat.
21400688 0:c4c874d702f9 158 */
21400688 0:c4c874d702f9 159 data.format = RemoteIR::AEHA_REPEAT;
21400688 0:c4c874d702f9 160 work.state = Received;
21400688 0:c4c874d702f9 161 data.bitcount = 0;
21400688 0:c4c874d702f9 162 work.c1 = -1;
21400688 0:c4c874d702f9 163 work.c2 = -1;
21400688 0:c4c874d702f9 164 work.c3 = -1;
21400688 0:c4c874d702f9 165 work.d1 = -1;
21400688 0:c4c874d702f9 166 work.d2 = -1;
21400688 0:c4c874d702f9 167 } else {
21400688 0:c4c874d702f9 168 init_state();
21400688 0:c4c874d702f9 169 }
21400688 0:c4c874d702f9 170 }
21400688 0:c4c874d702f9 171 break;
21400688 0:c4c874d702f9 172 case Receiving:
21400688 0:c4c874d702f9 173 if (RemoteIR::NEC == data.format) {
21400688 0:c4c874d702f9 174 work.d2 = timer.read_us();
21400688 0:c4c874d702f9 175 int a = work.d2 - work.d1;
21400688 0:c4c874d702f9 176 if (InRange(a, RemoteIR::TUS_NEC * 3)) {
21400688 0:c4c874d702f9 177 data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8));
21400688 0:c4c874d702f9 178 } else if (InRange(a, RemoteIR::TUS_NEC * 1)) {
21400688 0:c4c874d702f9 179 data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8));
21400688 0:c4c874d702f9 180 }
21400688 0:c4c874d702f9 181 data.bitcount++;
21400688 0:c4c874d702f9 182 #if 0
21400688 0:c4c874d702f9 183 /*
21400688 0:c4c874d702f9 184 * Length of NEC is always 32 bits.
21400688 0:c4c874d702f9 185 */
21400688 0:c4c874d702f9 186 if (32 <= data.bitcount) {
21400688 0:c4c874d702f9 187 data.state = Received;
21400688 0:c4c874d702f9 188 work.c1 = -1;
21400688 0:c4c874d702f9 189 work.c2 = -1;
21400688 0:c4c874d702f9 190 work.c3 = -1;
21400688 0:c4c874d702f9 191 work.d1 = -1;
21400688 0:c4c874d702f9 192 work.d2 = -1;
21400688 0:c4c874d702f9 193 }
21400688 0:c4c874d702f9 194 #else
21400688 0:c4c874d702f9 195 /*
21400688 0:c4c874d702f9 196 * Set timeout for tail detection automatically.
21400688 0:c4c874d702f9 197 */
21400688 0:c4c874d702f9 198 timeout.detach();
21400688 0:c4c874d702f9 199 timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_NEC * 5);
21400688 0:c4c874d702f9 200 #endif
21400688 0:c4c874d702f9 201 } else if (RemoteIR::AEHA == data.format) {
21400688 0:c4c874d702f9 202 work.d2 = timer.read_us();
21400688 0:c4c874d702f9 203 int a = work.d2 - work.d1;
21400688 0:c4c874d702f9 204 if (InRange(a, RemoteIR::TUS_AEHA * 3)) {
21400688 0:c4c874d702f9 205 data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8));
21400688 0:c4c874d702f9 206 } else if (InRange(a, RemoteIR::TUS_AEHA * 1)) {
21400688 0:c4c874d702f9 207 data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8));
21400688 0:c4c874d702f9 208 }
21400688 0:c4c874d702f9 209 data.bitcount++;
21400688 0:c4c874d702f9 210 #if 0
21400688 0:c4c874d702f9 211 /*
21400688 0:c4c874d702f9 212 * Typical length of AEHA is 48 bits.
21400688 0:c4c874d702f9 213 * Please check a specification of your remote controller if you find a problem.
21400688 0:c4c874d702f9 214 */
21400688 0:c4c874d702f9 215 if (48 <= data.bitcount) {
21400688 0:c4c874d702f9 216 data.state = Received;
21400688 0:c4c874d702f9 217 work.c1 = -1;
21400688 0:c4c874d702f9 218 work.c2 = -1;
21400688 0:c4c874d702f9 219 work.c3 = -1;
21400688 0:c4c874d702f9 220 work.d1 = -1;
21400688 0:c4c874d702f9 221 work.d2 = -1;
21400688 0:c4c874d702f9 222 }
21400688 0:c4c874d702f9 223 #else
21400688 0:c4c874d702f9 224 /*
21400688 0:c4c874d702f9 225 * Set timeout for tail detection automatically.
21400688 0:c4c874d702f9 226 */
21400688 0:c4c874d702f9 227 timeout.detach();
21400688 0:c4c874d702f9 228 timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_AEHA * 5);
21400688 0:c4c874d702f9 229 #endif
21400688 0:c4c874d702f9 230 } else if (RemoteIR::SONY == data.format) {
21400688 0:c4c874d702f9 231 work.d1 = timer.read_us();
21400688 0:c4c874d702f9 232 }
21400688 0:c4c874d702f9 233 break;
21400688 0:c4c874d702f9 234 case Received:
21400688 0:c4c874d702f9 235 break;
21400688 0:c4c874d702f9 236 default:
21400688 0:c4c874d702f9 237 break;
21400688 0:c4c874d702f9 238 }
21400688 0:c4c874d702f9 239 UNLOCK();
21400688 0:c4c874d702f9 240 }
21400688 0:c4c874d702f9 241
21400688 0:c4c874d702f9 242 void ReceiverIR::isr_rise(void) {
21400688 0:c4c874d702f9 243 LOCK();
21400688 0:c4c874d702f9 244 switch (work.state) {
21400688 0:c4c874d702f9 245 case Idle:
21400688 0:c4c874d702f9 246 if (0 <= work.c1) {
21400688 0:c4c874d702f9 247 work.c2 = timer.read_us();
21400688 0:c4c874d702f9 248 int a = work.c2 - work.c1;
21400688 0:c4c874d702f9 249 if (InRange(a, RemoteIR::TUS_SONY * 4)) {
21400688 0:c4c874d702f9 250 data.format = RemoteIR::SONY;
21400688 0:c4c874d702f9 251 work.state = Receiving;
21400688 0:c4c874d702f9 252 data.bitcount = 0;
21400688 0:c4c874d702f9 253 } else {
21400688 0:c4c874d702f9 254 static const int MINIMUM_LEADER_WIDTH = 150;
21400688 0:c4c874d702f9 255 if (a < MINIMUM_LEADER_WIDTH) {
21400688 0:c4c874d702f9 256 init_state();
21400688 0:c4c874d702f9 257 }
21400688 0:c4c874d702f9 258 }
21400688 0:c4c874d702f9 259 } else {
21400688 0:c4c874d702f9 260 init_state();
21400688 0:c4c874d702f9 261 }
21400688 0:c4c874d702f9 262 break;
21400688 0:c4c874d702f9 263 case Receiving:
21400688 0:c4c874d702f9 264 if (RemoteIR::NEC == data.format) {
21400688 0:c4c874d702f9 265 work.d1 = timer.read_us();
21400688 0:c4c874d702f9 266 } else if (RemoteIR::AEHA == data.format) {
21400688 0:c4c874d702f9 267 work.d1 = timer.read_us();
21400688 0:c4c874d702f9 268 } else if (RemoteIR::SONY == data.format) {
21400688 0:c4c874d702f9 269 work.d2 = timer.read_us();
21400688 0:c4c874d702f9 270 int a = work.d2 - work.d1;
21400688 0:c4c874d702f9 271 if (InRange(a, RemoteIR::TUS_SONY * 2)) {
21400688 0:c4c874d702f9 272 data.buffer[data.bitcount / 8] |= (1 << (data.bitcount % 8));
21400688 0:c4c874d702f9 273 } else if (InRange(a, RemoteIR::TUS_SONY * 1)) {
21400688 0:c4c874d702f9 274 data.buffer[data.bitcount / 8] &= ~(1 << (data.bitcount % 8));
21400688 0:c4c874d702f9 275 }
21400688 0:c4c874d702f9 276 data.bitcount++;
21400688 0:c4c874d702f9 277 #if 0
21400688 0:c4c874d702f9 278 /*
21400688 0:c4c874d702f9 279 * How do I know the correct length? (6bits, 12bits, 15bits, 20bits...)
21400688 0:c4c874d702f9 280 * By a model only?
21400688 0:c4c874d702f9 281 * Please check a specification of your remote controller if you find a problem.
21400688 0:c4c874d702f9 282 */
21400688 0:c4c874d702f9 283 if (12 <= data.bitcount) {
21400688 0:c4c874d702f9 284 data.state = Received;
21400688 0:c4c874d702f9 285 work.c1 = -1;
21400688 0:c4c874d702f9 286 work.c2 = -1;
21400688 0:c4c874d702f9 287 work.c3 = -1;
21400688 0:c4c874d702f9 288 work.d1 = -1;
21400688 0:c4c874d702f9 289 work.d2 = -1;
21400688 0:c4c874d702f9 290 }
21400688 0:c4c874d702f9 291 #else
21400688 0:c4c874d702f9 292 /*
21400688 0:c4c874d702f9 293 * Set timeout for tail detection automatically.
21400688 0:c4c874d702f9 294 */
21400688 0:c4c874d702f9 295 timeout.detach();
21400688 0:c4c874d702f9 296 timeout.attach_us(this, &ReceiverIR::isr_timeout, RemoteIR::TUS_SONY * 4);
21400688 0:c4c874d702f9 297 #endif
21400688 0:c4c874d702f9 298 }
21400688 0:c4c874d702f9 299 break;
21400688 0:c4c874d702f9 300 case Received:
21400688 0:c4c874d702f9 301 break;
21400688 0:c4c874d702f9 302 default:
21400688 0:c4c874d702f9 303 break;
21400688 0:c4c874d702f9 304 }
21400688 0:c4c874d702f9 305 UNLOCK();
21400688 0:c4c874d702f9 306 }
21400688 0:c4c874d702f9 307
21400688 0:c4c874d702f9 308 void ReceiverIR::isr_timeout(void) {
21400688 0:c4c874d702f9 309 LOCK();
21400688 0:c4c874d702f9 310 #if 0
21400688 0:c4c874d702f9 311 printf("# TIMEOUT [c1=%d, c2=%d, c3=%d, d1=%d, d2=%d, state=%d, format=%d, bitcount=%d]\n",
21400688 0:c4c874d702f9 312 work.c1,
21400688 0:c4c874d702f9 313 work.c2,
21400688 0:c4c874d702f9 314 work.c3,
21400688 0:c4c874d702f9 315 work.d1,
21400688 0:c4c874d702f9 316 work.d2,
21400688 0:c4c874d702f9 317 work.state,
21400688 0:c4c874d702f9 318 data.format,
21400688 0:c4c874d702f9 319 data.bitcount);
21400688 0:c4c874d702f9 320 #endif
21400688 0:c4c874d702f9 321 if (work.state == Receiving) {
21400688 0:c4c874d702f9 322 work.state = Received;
21400688 0:c4c874d702f9 323 work.c1 = -1;
21400688 0:c4c874d702f9 324 work.c2 = -1;
21400688 0:c4c874d702f9 325 work.c3 = -1;
21400688 0:c4c874d702f9 326 work.d1 = -1;
21400688 0:c4c874d702f9 327 work.d2 = -1;
21400688 0:c4c874d702f9 328 }
21400688 0:c4c874d702f9 329 UNLOCK();
21400688 0:c4c874d702f9 330 }