Final Project로 실제 점검에 사용된 코드

Dependencies:   mbed Adafruit_GFX

Committer:
21400688
Date:
Sat Jun 15 20:52:15 2019 +0000
Revision:
0:22391cd705e2
vb

Who changed what in which revision?

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