#include #include #include #include SoftwareSerial BTSerial(4, 3); // RX, TX //#define ONE_WIRE_PIN 5 #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 300 // 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 1 // 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 int KeyPin = A0; int addressLength = 10; const int inBufferLen = 255; uint8_t inPtr = 0; char inBuffer[inBufferLen+1]; char noDevice = 0; // This defines the structure of the packets which get sent out by wireless: struct { // int temp: // 10; // temperature: -500..+500 (tenths) char BTdata[10]; // Returned data from BT scan } 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; //} void readSerial() { int inByte = BTSerial.read(); switch(inByte) { case '\n': if(inPtr > addressLength){ //if we have at least addresslength from response plus +INQ prefix for (int i = 0; i < addressLength; i++) { payload.BTdata[i] = inBuffer[i+4]; //remove +INQ text from response } } else { for (int i = 0; i < addressLength; i++) { payload.BTdata[i] = inBuffer[0]; //if no match send oooooooooo for jeenode to decode } for (int i = 0; i < inPtr; i++) { Serial.print(inBuffer[i]); } Serial.println(); } inPtr = 0; doReport(); break; default: if(inPtr < inBufferLen) { inBuffer[inPtr] = inByte; inPtr++; inBuffer[inPtr] = '\0'; } } } // periodic report, i.e. send out a packet and optionally report on serial port static void doReport() { #if SERIAL || DEBUG Serial.print("payload to send "); Serial.println(payload.BTdata); #endif 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 BTSerial.write("AT+INQ\r\n"); #if SERIAL || DEBUG Serial.println("sending INQ"); #endif } static void doIncoming() { } void setup () { pinMode(KeyPin, OUTPUT); digitalWrite(KeyPin, HIGH); #if SERIAL || DEBUG Serial.begin(57600); Serial.print("\n[BlueNode.1]"); myNodeID = rf12_config(); #else myNodeID = rf12_config(0); // don't report info on the serial port #endif BTSerial.begin(9600); delay(200); BTSerial.write("AT+ROLE=1\r\n"); delay(500); BTSerial.write("AT+INQM=0,5,15\r\n"); delay(500); BTSerial.write("AT+RESET\r\n"); delay(500); BTSerial.begin(38400); delay(200); BTSerial.write("AT+INIT\r\n"); #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 onewire Device"); #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(); } while(BTSerial.available()) { readSerial(); } while(Serial.available()) { BTSerial.write(Serial.read()); } 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; } }