#include #include #include #include IRsend irsend; #define ONE_WIRE_PIN 4 #define NEC 'N' #define SONY 'S' #define RC5 'r' #define RC6 'R' #define JVC 'J' #define SERIAL 1 // set to 1 to also report readings on the serial port #define DEBUG 0 // set to 1 to display each loop() run #define MEASURE_PERIOD 600 // how often to measure, in tenths of seconds #define RETRY_PERIOD 10 // how soon to retry if ACK didn't come in #define RETRY_LIMIT 5 // maximum number of times to retry #define ACK_TIME 10 // number of milliseconds to wait for an ack #define REPORT_EVERY 5 // report every N measurement cycles // The scheduler makes it easy to perform various tasks at various times: enum { MEASURE, REPORT, TASK_END }; static word schedbuf[TASK_END]; Scheduler scheduler (schedbuf, TASK_END); // Other variables used in various places in the code: static byte reportCount; // count up until next report, i.e. packet send static byte myNodeID; // node ID used for this unit unsigned long rctoggle = 0; // used for RC5 protocol code toggling // This defines the structure of the packets which get sent out by wireless: struct { int temp : 10; // temperature: -500..+500 (tenths) } payload; // Conditional code, depending on which sensors are connected and how: #if ONE_WIRE_PIN #define TEMPERATURE_PRECISION 12 #include #include // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) OneWire oneWire(ONE_WIRE_PIN); // Pass our oneWire reference to Dallas Temperature. DallasTemperature sensors(&oneWire); DeviceAddress deviceAddress; #endif // UNUSED. // wait a few milliseconds for proper ACK to me, return true if indeed received //static byte waitForAck() { // MilliTimer ackTimer; // while (!ackTimer.poll(ACK_TIME)) { // if (rf12_recvDone() && rf12_crc == 0 && // see http://talk.jeelabs.net/topic/811#post-4712 // rf12_hdr == (RF12_HDR_DST | RF12_HDR_CTL | myNodeID)) // return 1; // } // return 0; //} // periodic report, i.e. send out a packet and optionally report on serial port static void doReport() { while (!rf12_canSend()) rf12_recvDone(); rf12_sendStart(0, &payload, sizeof payload); } static void doMeasure() { // payload.lobat = rf12_lowbat(); #if ONE_WIRE_PIN sensors.requestTemperatures(); payload.temp = sensors.getTempC(deviceAddress) * 10; #endif } // Processing of RF12 data. // X YY YY YY YY // X = protocol (N, S, R, r, J) // YY YY YY YY = code static void doIncoming() { char protocol = (rf12_data[0]); // covert rf12_data back to hex. long unsigned int codehex; codehex = (((long) rf12_data[1] <<24) + ((long) rf12_data[2] <<16) + ((long) rf12_data[3] <<8) + ((long) rf12_data[4]) ); //transmit IR signal if (protocol == NEC) { irsend.sendNEC(codehex, 32); } else if (protocol == SONY) { // Send Sony code 3 times irsend.sendSony(codehex, 12); delay(50); irsend.sendSony(codehex, 12); delay(50); irsend.sendSony(codehex, 12); } else if (protocol == RC5) { // Filp the RC5 toggle bit codehex = codehex ^ (rctoggle << 11); rctoggle = 1 - rctoggle; irsend.sendRC5(codehex, 12); } else if (protocol == RC6) { // Flip the RC6 toggle bit codehex = codehex ^ (rctoggle << 16); rctoggle = 1 - rctoggle; irsend.sendRC6(codehex, 20); } else if (protocol == JVC) { irsend.sendJVC(codehex, 16,0); // hex value, 16 bits, no repeat delayMicroseconds(50); // see http://www.sbprojects.com/knowledge/ir/jvc.php for information irsend.sendJVC(codehex, 16,1); // hex value, 16 bits, repeat delayMicroseconds(50); } void setup () { #if SERIAL || DEBUG Serial.begin(57600); Serial.print("\n[IRTxNode.1]"); myNodeID = rf12_config(); #else myNodeID = rf12_config(0); // don't report info on the serial port #endif #if ONE_WIRE_PIN sensors.begin(); #if SERIAL || DEBUG Serial.print("Locating OneWire devices..."); Serial.print("Found "); Serial.print(sensors.getDeviceCount(), DEC); Serial.println(" devices."); #endif if (sensors.getAddress(deviceAddress, 0)) { sensors.setResolution(deviceAddress, TEMPERATURE_PRECISION); } else { #if SERIAL || DEBUG Serial.println("Unable to find address for Device 0"); #endif } #endif reportCount = REPORT_EVERY; // report right away for easy debugging scheduler.timer(MEASURE, 0); // start the measurement loop going } void loop () { #if DEBUG Serial.print('.'); delay(2); #endif // process incoming data packet if (rf12_recvDone() && rf12_crc == 0 && rf12_len >0 && rf12_hdr == (RF12_HDR_DST | myNodeID)) { #if SERIAL || DEBUG Serial.print("GOT"); for (byte i = 0; i < rf12_len; ++i) { Serial.print(".."); Serial.print((int)rf12_data[i]); } Serial.println(); #endif doIncoming(); } switch (scheduler.poll()) { case MEASURE: // reschedule these measurements periodically scheduler.timer(MEASURE, MEASURE_PERIOD); doMeasure(); // every so often, a report needs to be sent out if (++reportCount >= REPORT_EVERY) { reportCount = 0; scheduler.timer(REPORT, 0); } break; case REPORT: doReport(); break; } }