// this program decodes a clock string sent via XBee radio // the end result is six integer variables that hold the current year, month, day, hour, minute and second // // the time string is in the following format: // *20061003143227 // where the year is 2006, month is October, day is the 3rd, hour is 14 (2 p.m.), minute is 32 and second is 27 // // by Rob Faludi // http://www.faludi.com ////// DEBUG OUTPUT IS HANDY, BUT NOT NECESSARY FOR CLOCK DECODING /////// #include int rx=6, tx=7; // pins 6 and 7 will have a debug output SoftwareSerial softSerial(rx, tx); // creates SoftwareSerial on pins 6 and 7 /////////////////////////////////////////////////////////////// int ledPin = 13; int year; byte month, day, hour, minute, second; void setup() { pinMode(ledPin, OUTPUT); pinMode (rx,INPUT); pinMode (tx,OUTPUT); // start up the serial connection with 9600-8-n-1-true (non-inverted): Serial.begin(9600); // start hardware serial process softSerial.begin(9600); // start software serial process // blink the status LED blinkLED(ledPin, 2, 200); softSerial.println(); // do a linefeed on the debug port delay(500); softSerial.println("starting..."); // show startup on the debug port setupXBee(); } void loop() { Serial.flush(); // clear the serial buffer before reading new data char timeString[15]; // create a string to hold the time value when it's read memset(timeString,'\0',15); // initialize that string to all NULL characters boolean timeStringValid = false; // declare and initialize a variable to track whether the string has all valid characters Serial.print("GET"); byte inByte = '\0'; // declare and initialize a byte to read in serial data long startTime = millis();//makes the start time = to now int timeout = 1000; // timeout after one second while(millis() - startTime < timeout && inByte != '*') { inByte = Serial.read(); // read data and wait for an asterisk character } if (inByte == '*') { // if we got the correct start character (instead of a timeout) timeStringValid = true; // declare and initialize a variable to track whether the string has all valid characters long startTime = millis();//makes the start time = to now int timeout = 1000; // timeout after one second while(millis() - startTime < timeout && Serial.available() < 14) { ; //wait for enough data to be available (14 characters of time string), while doing nothing else } for (int i=0; i < 14; i++) { timeString[i] = Serial.read(); // reach each time string character into a character array if(timeString[i] < '0' || timeString[i] > '9') { timeStringValid = false; // if any character is bad then the whole string is bad } } softSerial.print("Time: "); softSerial.println(timeString); } if (timeStringValid == true) { char yearString[5]; // create a string to hold the year part of the string memset(yearString,'\0',5); // initialize that string to all NULL characters strncpy( yearString, timeString, 4); // copy the first four characters of timeString into the year string year = atoi(yearString); // convert ASCII year string to integer and store in the year integer variable softSerial.print("Year: "); softSerial.println(year, DEC); char monthString[3]; // create a string to hold the month part of the string memset(monthString,'\0',3); // initialize that string to all NULL characters strncpy( monthString, timeString+4, 2); // skip four characters, then copy the next two of timeString into the month string month = atoi(monthString); // convert ASCII month string to integer and store in the month integer variable softSerial.print("Month: "); softSerial.println(month, DEC); char dayString[3]; memset(dayString,'\0',3); strncpy( dayString, timeString+6, 2); day = atoi(dayString); softSerial.print("Day: "); softSerial.println(day, DEC); char hourString[3]; memset(hourString,'\0',3); strncpy( hourString, timeString+8, 2); hour = atoi(hourString); softSerial.print("Hour: "); softSerial.println(hour, DEC); char minuteString[3]; memset(minuteString,'\0',3); strncpy( minuteString, timeString+10, 2); minute = atoi(minuteString); softSerial.print("Minute: "); softSerial.println(minute, DEC); char secondString[3]; memset(secondString,'\0',3); strncpy( secondString, timeString+12, 2); second = atoi(secondString); softSerial.print("Second: "); softSerial.println(second, DEC); } softSerial.println(""); // print a blank line delay(1000); // wait for a moment so that output is readable } void setupXBee() { boolean success = false; int ctr = 0; while (success == false && ctr < 6) { // an arbitrary byte to wake up the XBee Serial.print("X"); delay(1100); // put the XBee in command mode Serial.print("+++"); delay(1100); Serial.flush(); // clear the serial buffer before sending and reading new data // set the PAN (personal area network) ID number Serial.print("ATIDC,"); // set the MY (16 bit address) Serial.print("MY1,"); // set the Destination High to 0x0 Serial.print("DH0,"); // set the Destination Low (16 bit address) Serial.print("DL0,"); // exit command mode (note that we use Serial.printLN here to issue a linefeed that completes the command sequence) Serial.println("CN"); if (checkFor("OK", 1000)) { // if an OK was received then continue // debugPrintln("setup done"); softSerial.println("setup done"); success = true; } else { // debugPrintln("setup failed"); softSerial.println("setup failed"); success = false; } ctr++; } } ///////////////////////////////// UTILITY FUNCTIONS ////////////////////////////////////////// // this function checks for a specific response on the serial port // it accepts a string to look for and a timeout in milliseconds int checkFor(char* desiredResponse, int timeout) { int result = 0; int length = 40; char incomingResponse[41]; memset(incomingResponse,0,length); // initialize all incomingResponse string positions to null char inByte = NULL; long startTime = millis();//makes the start time = to now char* ptr_incomingResponse = incomingResponse; // while we haven't timed out or gotten back the string that we are looking for while (millis() - startTime < timeout && strstr(incomingResponse,desiredResponse) == NULL ) { //strstr compares strings if (Serial.available() > 0) { // if there are any bytes waiting to be read inByte = Serial.read(); // read one byte if (incomingResponse > ptr_incomingResponse-length) { // if we haven't read in 80 characters yet *ptr_incomingResponse = inByte; // put the byte into the current position in the string ptr_incomingResponse++; // advance to the next position in the string } else { //move the last char to be next to last, and so forth until we reach the end of the array. for (int i = 0; i < length; i++) { incomingResponse[i] = incomingResponse[i+1]; } incomingResponse[length-1] = inByte; // put the byte into the current position in the string } } } softSerial.println(incomingResponse); if (strstr(incomingResponse,desiredResponse) != NULL ) { // if the desired string is found result = 1; } else { result = 0; } return result; } // this function blinks the an LED light as many times as requested void blinkLED(int targetPin, int numBlinks, int blinkRate) { for (int i=0; i