With newSoftSerial, system time not found

I´m trying to sync an Arduino FIO with XBee with the coordinator of my network. The code works as follows:

  1. A coordinator sends to arduino FIO its UNIX time.
  2. Arduino FIO receives the UNIX time of the server, process it and set the system time with setTime();

The time is set correctly but the system allways reports the same time (calling to hour(), minute() and second() ).

example:

11:17:58 2 12 2010
11:17:58 2 12 2010
11:17:58 2 12 2010
11:17:58 2 12 2010
11:17:58 2 12 2010
...
...
...
11:17:58 2 12 2010

It is possible that newSoftwareSerial disables the interrupts that works with the system time???

/**

  • This file is part of XBee-Arduino (Andrew Rapp)
  • XBee-Arduino is free software: you can redistribute it and/or modify
  • it under the terms of the GNU General Public License as published by
  • the Free Software Foundation, either version 3 of the License, or
  • (at your option) any later version.
  • XBee-Arduino is distributed in the hope that it will be useful,
  • but WITHOUT ANY WARRANTY; without even the implied warranty of
  • MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  • GNU General Public License for more details.
  • You should have received a copy of the GNU General Public License
  • along with XBee-Arduino. If not, see http://www.gnu.org/licenses/.
    */

#include <XBee.h>
#include <NewSoftSerial.h>
#include <Time.h>

#define TIME_MSG_LEN 10 // time sync to PC is HEADER followed by unix time_t as ten ascii digits
#define TIME_HEADER 'T' // Header tag for serial time sync message
#define TIME_REQUEST 7 // ASCII bell character requests a time sync message

XBee xbee = XBee();
XBeeResponse response = XBeeResponse();
// create reusable response objects for responses we expect to handle
ZBRxResponse rx = ZBRxResponse();
ModemStatusResponse msr = ModemStatusResponse();

// Define NewSoftSerial TX/RX pins
// Connect Arduino pin 9 to TX of usb-serial device
uint8_t ssRX = 9;
// Connect Arduino pin 10 to RX of usb-serial device
uint8_t ssTX = 10;
// Remember to connect all devices to a common Ground: XBee, Arduino and USB-Serial device
NewSoftSerial nss(ssRX, ssTX);

char message[10];
int sync=0;

void setup() {
//setSyncProvider( requestSync); //set function to call when sync required

// start serial
xbee.begin(57600);
nss.begin(57600);

nss.println("starting up yo!");
nss.println("Waiting for sync message");
}

// continuously reads packets, looking for ZB Receive or Modem Status
void loop() {

if(sync!=1)
{
requestTime();
}
else{
processSyncMessage();

if(timeStatus()!= timeNotSet)
{
digitalWrite(13,timeStatus() == timeSet); // on if synced, off if needs refresh
digitalClockDisplay();
}
delay(1000);
}
}

//TIME FUNCTIONS
void digitalClockDisplay(){
// digital clock display of the time
nss.print(hour());
printDigits(minute());
printDigits(second());
nss.print(" ");
nss.print(day());
nss.print(" ");
nss.print(month());
nss.print(" ");
nss.print(year());
nss.println();
}

void printDigits(int digits){
// utility function for digital clock display: prints preceding colon and leading 0
nss.print(":");
if(digits < 10)
nss.print('0');
nss.print(digits);
}

void processSyncMessage() {
// if time sync available from serial port, update time and return true
time_t pctime = 0;
for(int i=0; i < TIME_MSG_LEN ; i++){
int c = (int)message*; *
_ //nss.print(message*, DEC); [/color]_
_
//nss.println(c); _
_
if( c >= 0 && c <= 9){ _
_ pctime = (10 * pctime) + (c - 0) ; // convert digits to a number _
_
}_
_
} _
_
now();*_

* setTime(pctime); // Sync Arduino clock to the time received on the serial port*
}
time_t requestSync()
{
* nss.print(TIME_REQUEST,BYTE);
_
return 0; // the time will be sent later in response to serial mesg*_
}
//FUNCTIONS HEX TO ASCII
char hexNibbleToChar(char nibble)
{
* if (nibble >= '0' && nibble <= '9')*
* return nibble - '0';*
* else if (nibble >= 'a' && nibble <= 'f')*
* return 10 + nibble - 'a';*
* else*
* return 10 + nibble - 'A';*
}
void requestTime()
{
* xbee.readPacket();*
* if (xbee.getResponse().isAvailable()) {*
* // got something*
* nss.println("got something");*
* nss.println(xbee.getResponse().getApiId(), HEX); *
* if (xbee.getResponse().getApiId() == ZB_EXPLICIT_RX_RESPONSE ){
//if (ZB_RX_RESPONSE == ZB_RX_RESPONSE) {
_
// got a zb rx packet*_
* // now fill our zb rx class*
* xbee.getResponse().getZBRxResponse(rx);*
* nss.println("Got an rx packet!");*
* if (rx.getOption() == ZB_PACKET_ACKNOWLEDGED) {
_
// the sender got an ACK*_
* nss.println("packet acknowledged");*
* } *
* else {*
* nss.println("packet not acknowledged");*
* }*
* nss.print("checksum is ");*
* nss.println(rx.getChecksum(), HEX);*
* nss.print("packet length is ");*
* nss.println(rx.getPacketLength(), DEC);*
* for (int i = 6; i < rx.getDataLength(); i++) {*
* nss.print("frame data [");*
* nss.print(i, DEC);*
* nss.print("] is ");*
_ char stringOne = char(rx.getData());
* stringOne = hexNibbleToChar(stringOne);
message[i-6] = stringOne;
nss.println(rx.getData(), DEC);
nss.print(message[i-6], DEC);
}
//Check if we have a message with the time*

* sync=1;
}
}
else if (xbee.getResponse().isError()) {
nss.print("oh no!!! error code:");
nss.println(xbee.getResponse().getErrorCode());
}
}
[/quote]*_

It is possible that newSoftwareSerial disables the interrupts that works with the system time???

Don't know the details of NSS, could you try the hardware serial instead? If that works the NSS might interfere.

Furthermore I noticed the following in your code

 if(timeStatus()!= timeNotSet)  
    {
      digitalWrite(13,timeStatus() == timeSet); // on if synced, off if needs refresh  
      digitalClockDisplay();  
    }

The display of time is conditionally, think you should display it every iteration.

Finally there is the flag timeNeedsSync , could you check its value after setting the time?

From http://www.arduino.cc/playground/Code/Time
timeNeedsSync // the time had been set but a sync attempt did not succeed

It is possible that newSoftwareSerial disables the interrupts that works with the system time???

Don't know the details of NSS, could you try the hardware serial instead? If that works the NSS might interfere.

Furthermore I noticed the following in your code
Code:

if(timeStatus()!= timeNotSet)
{
digitalWrite(13,timeStatus() == timeSet); // on if synced, off if needs refresh
digitalClockDisplay();
}

The display of time is conditionally, think you should display it every iteration.

Finally there is the flag timeNeedsSync , could you check its value after setting the time?

From http://www.arduino.cc/playground/Code/Time
timeNeedsSync // the time had been set but a sync attempt did not succeed

Thanks for the reply!

I have do some changes in the code in order to debug the situation:

// continuously reads packets, looking for ZB Receive or Modem Status
void loop() {

if(sync!=1)
{
requestTime();
}
else{
processSyncMessage();

if(timeStatus()== timeSet)
{
digitalWrite(13,timeStatus() == timeSet); // on if synced, off if needs refresh
digitalClockDisplay();
nss.println("timeSet");
}else if(timeStatus()== timeNeedsSync)
{
nss.println("timeNeedsSync");
processSyncMessage();
}
delay(1000);
}
}

After the execution of requestTime() the timeStatus() is equal to timeSet. The register contains valid information but this time is freeze to the initial moment.

16:31:04 2 12 2010
timeSet
16:31:04 2 12 2010
timeSet
16:31:04 2 12 2010
timeSet
16:31:04 2 12 2010
timeSet
16:31:04 2 12 2010
timeSet

I think that the problem is newSoftwareSerial library. More ideas?

PLease try to replace

void digitalClockDisplay(){
  // digital clock display of the time
  nss.print(hour());
  printDigits(minute());
  printDigits(second());
  nss.print(" ");
  nss.print(day());
  nss.print(" ");
  nss.print(month());
  nss.print(" ");
  nss.print(year());
  nss.println();
}

with

void digitalClockDisplay()
{
  [glow]time_t t = now();[/glow]
  // digital clock display of the time
  nss.print(hour([glow]t[/glow]));
  printDigits(minute([glow]t[/glow]));
  printDigits(second([glow]t[/glow]));
  nss.print(" ");
  nss.print(day([glow]t[/glow]));
  nss.print(" ");
  nss.print(month([glow]t[/glow]));
  nss.print(" ");
  nss.print(year([glow]t[/glow]));
  nss.println();
}

Solved!!!

If I set the hour in the setup() function, the system shows the time correctly.

Thanks!!!