//#include //#include /* * IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv * An IR detector/demodulator must be connected to the input RECV_PIN. * Version 0.1 July, 2009 * Copyright 2009 Ken Shirriff * http://arcfn.com */ #include int RECV_PIN = A3; const int redPin = 5; const int greenPin = 6; const int bluePin = 9; const int relaisPin = 2; const int visjesPin = 3; const int blowerPin = 10; IRrecv irrecv(RECV_PIN); unsigned int redValue = 0; unsigned int greenValue = 0; unsigned int blueValue = 0; unsigned int dimValue = 255; // min = 0, max = 255 unsigned int blowerValue = 255; unsigned int savedDimValue; int on = 0; int inhibit_reply = 0; decode_results results; int applyDim(int value) { return (value*(dimValue+1))>>8; } void setColors() { analogWrite(redPin, applyDim(redValue)); analogWrite(greenPin, applyDim(greenValue)); analogWrite(bluePin, applyDim(blueValue)); } void setBlower() { analogWrite(blowerPin, (blowerValue < 24)?0:blowerValue); } void setOutput() { setColors(); setBlower(); } void setup() { Serial.begin(115200); // In case the interrupt driver crashes on setup, give a clue // to the user what's going on. //Serial.println("Enabling IRin"); irrecv.enableIRIn(); // Start the receiver //Serial.println("Enabled IRin"); pinMode(relaisPin, OUTPUT); pinMode(visjesPin, OUTPUT); pinMode(A5, OUTPUT); pinMode(A4, OUTPUT); pinMode(13, OUTPUT); // turn off builtin led digitalWrite(13, LOW); // provide power to IR receiver // such that it can be directly // connected to the arduino digitalWrite(A5, HIGH); digitalWrite(A4, LOW); digitalWrite(relaisPin, LOW); digitalWrite(visjesPin, LOW); setOutput(); //analogWrite(redPin, redValue); // analogWrite(greenPin, greenValue); // analogWrite(bluePin, blueValue); // analogWrite(blowerPin, blowerValue); } unsigned long command = 0; unsigned int repeat = 0; // 1 byte even/odd // 16 bytes data // 2 bytes checksum // 1 byte overhead for COBS encoding unsigned char buffer_in[20]; size_t buffer_in_size = 0; unsigned char buffer_out[20] = { 1, 1, 1 }; //RESET size_t buffer_out_size = 3; int even_odd = 0; // start with even void inc(unsigned int *foo) { if (*foo < 255) (*foo)++; } void dec(unsigned int *foo) { if (*foo > 0) (*foo)--; } #ifdef __arm__ // should use uinstd.h to define sbrk but Due causes a conflict extern "C" char* sbrk(int incr); #else // __ARM__ extern char *__brkval; #endif // __arm__ int freeMemory() { char top; #ifdef __arm__ return &top - reinterpret_cast(sbrk(0)); #elif defined(CORE_TEENSY) || (ARDUINO > 103 && ARDUINO != 151) return &top - __brkval; #else // __arm__ return __brkval ? &top - __brkval : &top - __malloc_heap_start; #endif // __arm__ } void loop() { unsigned int i; if (irrecv.decode(&results)) { //Serial.println(results.value, HEX); //Serial.println(Serial.available(), HEX); //Serial.println(freeMemory(), HEX); if (results.value != 0xFFFFFFFF) { command = results.value; repeat = 0; } else repeat++; switch (command) { case 0xFFE817L: for (i = 0; i < repeat; i++) inc(&blowerValue); break; case 0xFFC837L: for (i = 0; i < repeat; i++) dec(&blowerValue); break; case 0xFF28D7L: //if (redValue < 255) redValue++; for (i = 0; i <= repeat; i++) inc(&redValue); break; case 0xFF08F7L: //if (redValue > 0) redValue--; for (i = 0; i <= repeat; i++) dec(&redValue); break; case 0xFFA857L: for (i = 0; i <= repeat; i++) inc(&greenValue); //inc(&greenValue); break; case 0xFF8877L: for (i = 0; i <= repeat; i++) dec(&greenValue); //dec(&greenValue); break; case 0xFF6897L: for (i = 0; i <= repeat; i++) inc(&blueValue); //inc(&blueValue); break; case 0xFF48B7L: for (i = 0; i <= repeat; i++) dec(&blueValue); //dec(&blueValue); break; case 0xFF1AE5L: redValue = 255; greenValue = 0; blueValue = 0; break; case 0xFF9A65L: redValue = 0; greenValue = 255; blueValue = 0; break; case 0xFFA25DL: redValue = 0; greenValue = 0; blueValue = 255; break; case 0xFF18E7L: redValue = 255; greenValue = 255; blueValue = 0; break; case 0xFF9867L: redValue = 0; greenValue = 255; blueValue = 255; break; case 0xFF58A7L: redValue = 255; greenValue = 0; blueValue = 255; break; case 0xFF22DDL: redValue = 255; greenValue = 255; blueValue = 255; break; case 0xFF02FDL: //redValue = 0; //greenValue = 0; //blueValue = 0; if (repeat == 0) { if (on == 0) { on = 1; dimValue = savedDimValue; //digitalWrite(relaisPin, HIGH); } else { on = 0; //digitalWrite(relaisPin, LOW); savedDimValue = dimValue; dimValue = 0; } } break; case 0xFF3AC5L: for (i = 0; i < repeat; i++) { inc(&dimValue); //inc(&redValue); //inc(&greenValue); //inc(&blueValue); } break; case 0xFFBA45L: for (i = 0; i < repeat; i++) { dec(&dimValue); //dec(&redValue); //dec(&greenValue); //dec(&blueValue); } break; case 0xFF30CF: /* DIY1 */ inhibit_reply = 1; break; case 0xFFB04F: inhibit_reply = 0; break; case 0xFFD02F: if (repeat == 0) digitalWrite(visjesPin, !digitalRead(visjesPin)); break; } //Serial.println(redValue, HEX); //analogWrite(redPin, redValue); //analogWrite(greenPin, greenValue); //analogWrite(bluePin, blueValue); //analogWrite(blowerPin, blowerValue); setOutput(); irrecv.resume(); // Receive the next value //LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); } delay(100); } unsigned int fletcher16_calc(unsigned char *buf, unsigned int len) { unsigned int sum1 = 0, sum2 = 0; for (unsigned int i = 0; i < len; i++) { sum1 = (sum1 + buf[i])%255; sum2 = (sum2 + sum1)%255; } return (sum2<<8)|sum1; } int fletcher16_check(uint8_t *buf, size_t len) { return *((unsigned int*)(buf + len)) == fletcher16_calc(buf, len); } void inplace_COBS_encode() { unsigned char ctr = 1; size_t len = buffer_out_size; // we go through the buffer from back to front while (len--) { unsigned char next = buffer_out[len]; if (buffer_out[len] == 0x00) { next = ctr; ctr = 0; } ctr++; buffer_out[len+1] = next; } buffer_out[0] = ctr; } // we use the buffer_in / buffer_in_size int inplace_COBS_decode() { unsigned char run; unsigned char *buf = buffer_in; while (buffer_in_size) { run = *buf; if (run > buffer_in_size) return -1; // framing error buffer_in_size -= run; while (--run > 0) { *buf = *(buf + 1); if (*buf == 0) return -1; // illegal byte in packet buf++; } *(buf++) = 0; } buffer_in_size = buf - buffer_in - 1; return 0; } // serial protocol documented at: // https://snel.it/svn/misc/trunk/arduino_serial/README void serialEvent() { unsigned char in; while (Serial.available()) { in = Serial.read(); //Serial.print("Got char: "); //Serial.println(in, HEX); if (in == 0) { //Serial.print("got packet of size "); //Serial.println(buffer_in_size, DEC); if (buffer_in_size >= 3) { if (!inplace_COBS_decode()) { //Serial.print("after decoding: "); for (unsigned int k = 0; k < buffer_in_size; k++) { //Serial.print(' '); //Serial.print(buffer_in[k], HEX); } //Serial.print("\n"); buffer_in_size -= 2; // do not let the checksum // contribute to the length // of the packet // since the incoming data was // three bytes long, this will // not underflow (because COBS // decoded data is at least 2 bytes //Serial.println(fletcher16_calc(buffer_in, buffer_in_size), HEX); if (fletcher16_check(buffer_in, buffer_in_size)) { //Serial.write(*(char*)&buffer_in_size); //for (unsigned int k = 0; k < buffer_in_size; k++) { // Serial.write(buffer_in[k]); // } if (buffer_in_size == 0) { // RESET buffer_out_size = 0; even_odd = 0; *((unsigned int*)(buffer_out + buffer_out_size)) = fletcher16_calc(buffer_out, buffer_out_size); buffer_out_size += 2; inplace_COBS_encode(); buffer_out_size += 1; // test } else if ((buffer_in[0] == 0xAA && even_odd == 0) || (buffer_in[0] == 0x55 && even_odd == 1)) { even_odd = 1 - even_odd; buffer_out[0] = buffer_in[0]; buffer_out_size = 1; if (buffer_in_size > 1) { if (buffer_in[1] == 0x00) { // command: read blower value buffer_out[buffer_out_size] = *((unsigned char*)&blowerValue); buffer_out_size++; } else if (buffer_in[1] == 0x01) { // command: write blower value blowerValue = buffer_in[2]; //buffer_out[buffer_out_size] = 0x12; //*((unsigned char*)&blowerValue); //buffer_out_size++; setBlower(); //analogWrite(blowerPin, blowerValue); } else if (buffer_in[1] == 0x02) { // command: set color values redValue = buffer_in[2]; greenValue = buffer_in[3]; blueValue = buffer_in[4]; dimValue = 255; setColors(); } else if (buffer_in[1] == 0x03) { // read last IR command memcpy(buffer_out + 1, &command, 4); buffer_out_size += 4; } else if (buffer_in[1] == 0x04) { // write releas pin digitalWrite(relaisPin, buffer_in[2]); } else if (buffer_in[1] == 0x05) { // write visjes pin digitalWrite(visjesPin, buffer_in[2]); } else if (buffer_in[1] == 0x06) { // read relais pin buffer_out[buffer_out_size++] = digitalRead(relaisPin); } else if (buffer_in[1] == 0x07) { // read visjes pin buffer_out[buffer_out_size++] = digitalRead(visjesPin); } else if (buffer_in[1] == 0x08) { // read color values buffer_out[buffer_out_size++] = applyDim(redValue); buffer_out[buffer_out_size++] = applyDim(greenValue); buffer_out[buffer_out_size++] = applyDim(blueValue); } } *((unsigned int*)(buffer_out + buffer_out_size)) = fletcher16_calc(buffer_out, buffer_out_size); buffer_out_size += 2; inplace_COBS_encode(); buffer_out_size += 1; } if (!inhibit_reply) { Serial.write(buffer_out, buffer_out_size); Serial.write(0); } //Serial.println("checksum OK"); } //else Serial.println("checksum failed"); } // framing error / invalid COBS data } // else: packet invalid, because it is too small buffer_in_size = 0; } else { if (buffer_in_size == sizeof(buffer_in)) { // sent data is too long buffer_in_size = 0; } buffer_in[buffer_in_size++] = in; } } }