Hi,
I've uploaded a sketch containing most of the example date & time sketch and synced it up via processing. The Duemilanove 328 is connected to a wall plug and has not been unplugged. The date & time was fine for a little while - maybe 20 minutes or less. But now it suddenly shows a different month & time on the LCD and changes every few minutes.
What would cause the date to suddenly change?
Could this be power related issue? (I don't think so, but do have 2 temp sensors hooked up as well)
This is my first time using date & time.
Thanks
Perhaps the serial port is getting bad data that its trying to sync to.
Can you post your sketch.
Here is my sketch.
When the date/time go bad it is no longer connected to my computer, but is already running and working fine.
/*
* A simple sketch that uses WiServer to send a tweet with the current system time every 5 minutes
*/
#include <DateTime.h>
#include <DateTimeStrings.h>
#include <LiquidCrystal.h>
//LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
LiquidCrystal lcd(4, 3, 8, 7, 6, 5);
#define TIME_MSG_LEN 11 // time sync to PC is HEADER followed by unix time_t as ten ascii digits
#define TIME_HEADER 255 // Header tag for serial time sync message
char temp_val[3];
char temps[3] ="";
char* weather = " ";
int inPin = 5; // select the input pin for analog temp value 5= out, 4 = in.
int inVal;
int i;
int samples[8];
int t=0;
int ti=0;
char n[6] = " ";
int x=0;
char* place=" ";
int r;
int inVal3=0;
int samples2[8];
int counter=0;
int custom_0[] = {0x0e, 0x0e, 0x04, 0x0e, 0x1b, 0x0a, 0x0e, 0x11};
// Define a custom char in lcd
int defineCharacter(int ascii, int *data) {
int baseAddress = (ascii * 8) + 64;
// baseAddress = 64 | (ascii << 3);
lcd.command(baseAddress);
for (int i = 0; i < 8; i++)
lcd.write(data[i]);
lcd.command(128);
return ascii;
}
void setup() {
Serial.begin(57600);
defineCharacter(0, custom_0);
lcd.begin(16,2);
lcd.print("Robo Temp 3000");
lcd.setCursor(0,1);
lcd.print((char)229);
lcd.print(" ");
lcd.print((char)224);
lcd.print(" ");
lcd.print((char)225);
lcd.print(" ");
lcd.print((char)226);
lcd.print(" ");
lcd.print((char)227);
lcd.print(" ");
lcd.print((char)218);
lcd.print(" ");
lcd.write(0);
delay(2000);
}
void TempWrit()
{
lcd.setCursor(0, 0);
lcd.clear();
lcd.print(place);
lcd.print(" temp ");
lcd.print(x);
lcd.print((char)223);
lcd.print(" F.");
lcd.setCursor(0,1);
lcd.print(weather);
delay(2500);
// lcd.setCursor(16,1);
//lcd.autoscroll();
// for (int thisChar = 0; thisChar < 16; thisChar++) {
// lcd.print(" ");
// delay(400);
// }
lcd.clear();
// lcd.noAutoscroll();
}
void WeatherOut()
{
inPin = 5;
for(i = 0;i<=7;i++) // gets 8 samples of temperature
{
samples[i]= ( 5.0 * analogRead(inPin) * 100.0) / 1024.0;
inVal = inVal + samples[i];
}
inVal = inVal/8.0; // better precision
t = ((inVal * 9)/ 5 + 32);
Serial.print("Weather out ");
Serial.println(t);
inVal = 0; //reset variable
x=t;
itoa(t,temp_val,10);
place="Out";
}
void WeatherIn()
{
inPin = 4;
for(i = 0;i<=7;i++) // gets 8 samples of temperature
{
samples[i]= ( 5.0 * analogRead(inPin) * 100.0) / 1024.0;
inVal = inVal + samples[i];
}
inVal = inVal/8.0; // better precision
ti = ((inVal * 9)/ 5 + 32);
inVal = 0; //reset variable
x=ti;
itoa(ti,temp_val,10);
place="In";
}
void GetSun() {
// photocellReading = analogRead(3);
for(i = 0;i<=7;i++) // gets 8 samples of temperature
{
samples2[i]= (analogRead(3));
inVal3 = inVal3 + samples2[i];
}
inVal3 = inVal3/8.0; // better precision with 8 samples
if (inVal3 < 8) {
weather = "Night Time";
} else if (inVal3 < 110) {
weather = "Cloudy";
} else if (inVal3 < 200) {
weather = "Partly Cloudy";
} else if (inVal3 < 280) {
weather="Partly Sunny";
} else {
weather = "Sunny";
}
Serial.print("Sun level ");
Serial.print(inVal3);
Serial.print(" ");
Serial.println(weather);
}
void loop()
{
//update time
unsigned long prevtime;
if( getPCtime()) { // try to get time sync from pc
Serial.print("Clock synced at: ");
Serial.println(DateTime.now(),DEC);
}
if(DateTime.available()) { // update clocks if time has been synced
digitalWrite(13,LOW); // first flash the LED
prevtime = DateTime.now();
while( prevtime == DateTime.now() ) // wait for the second to rollover
;
DateTime.available(); //refresh the Date and time properties
// send our time to any app at the other end of the serial port
Serial.print( TIME_HEADER,BYTE); // this is the header for the current time
Serial.println(DateTime.now());counter++;
}
if (counter>=4)
{
lcd.clear();
lcd.print ("Robo Temp 3000");
lcd.setCursor(0,1);
lcd.print((char)229);
lcd.print(" ");
lcd.print((char)224);
lcd.print(" ");
lcd.print((char)225);
lcd.print(" ");
lcd.print((char)226);
lcd.print(" ");
lcd.print((char)227);
lcd.print(" ");
lcd.print((char)218);
lcd.print(" ");
lcd.write(0);
counter=0;
delay(2000);
lcd.clear();
}
WeatherOut();
GetSun();
TempWrit();
WeatherIn();
weather=" ";
TempWrit();
digitalClockDisplay( ); // update digital clock
}
boolean getPCtime() {
// if time sync available from serial port, update time and return true
while(Serial.available() >= TIME_MSG_LEN ){ // time message consists of a header and ten ascii digits
if( Serial.read() == TIME_HEADER ) {
time_t pctime = 0;
for(int i=0; i < TIME_MSG_LEN -1; i++){
char c= Serial.read();
if( c >= '0' && c <= '9'){
pctime = (10 * pctime) + (c - '0') ; // convert digits to a number
}
}
DateTime.sync(pctime); // Sync Arduino clock to the time received on the serial port
return true; // return true if time message received on the serial port
}
}
return false; //if no message return false
}
void digitalClockDisplay(){
lcd.clear();// digital clock display of current date and time
Serial.print(DateTime.Hour,DEC);
lcd.print(DateTime.Hour,DEC);
printDigits(DateTime.Minute);
Serial.print(" ");
lcd.print(" ");
Serial.print(DateTimeStrings.dayStr(DateTime.DayofWeek));
lcd.print(DateTimeStrings.dayStr(DateTime.DayofWeek));
Serial.print(" ");
lcd.print(" ");
Serial.print(DateTimeStrings.monthStr(DateTime.Month));
lcd.setCursor(0,1);
lcd.print(DateTimeStrings.monthStr(DateTime.Month));
Serial.print(" ");
lcd.print(" ");
Serial.println(DateTime.Day,DEC);
lcd.print(DateTime.Day,DEC);
delay(2500);
}
void printDigits(byte digits){
// utility function for digital clock display: prints preceding colon and leading 0
Serial.print(":");
lcd.print(":");
if(digits < 10)
{
Serial.print('0');
lcd.print('0');
}
Serial.print(digits,DEC);
lcd.print(digits,DEC);
}
Pauly, you will have a problem if the temperature goes above 99 degrees (your buffer only holds two digits plus the terminating null) but I guess that may not be the issue here.
Can you check the wall wart and see how much voltage it is feeding to Arduino. The LCD backlight draws a lot power and the onboard regulator may be overheating.
If thats not it, try commenting out the following lines in loop:
/* temporarily comment out these lines:
WeatherOut();
GetSun();
TempWrit();
WeatherIn();
weather=" ";
TempWrit();
*/
This will tell us if we need to look at those functions or somewhere else
Ok, I commented out the lines you suggested and still received the same results, so it is not that part of the code.
My wall wart is giving me 9 volts.
I have the lcd (usually the backlight is on), 2 temp sensors, 1 light resist sensor and 1 led hooked up. Do you think it is a power issue?
When running from the wall wart does the voltage regulator (a chip near the power socket) get hot?
does the problem occur when powered from usb?
The same problem occurs when powered via USB without any sensors or leds added, so I'm guessing it is not power related, but code related.
a good test would be to run the DateTime example code to see if that has a similar problem.
My thoughts exactly. I ran the example code and it has the same problem. After about 10-15 minutes it changes the date and time to something incorrect. I tested it on a Diecimilia 328.
Not sure what to do now if the example doesn't work. :-?
// DateTime.pde
// example sketch for the DateTime library
#include <DateTime.h>
#include <DateTimeStrings.h>
#define TIME_MSG_LEN 11 // time sync to PC is HEADER followed by unix time_t as ten ascii digits
#define TIME_HEADER 255 // Header tag for serial time sync message
void setup(){
Serial.begin(19200);
pinMode(13,OUTPUT); // we flash the LED each second
}
void loop(){
unsigned long prevtime;
if( getPCtime()) { // try to get time sync from pc
Serial.print("Clock synced at: ");
Serial.println(DateTime.now(),DEC);
}
if(DateTime.available()) { // update clocks if time has been synced
digitalWrite(13,LOW); // first flash the LED
prevtime = DateTime.now();
while( prevtime == DateTime.now() ) // wait for the second to rollover
;
DateTime.available(); //refresh the Date and time properties
digitalClockDisplay( ); // update digital clock
// send our time to any app at the other end of the serial port
Serial.print( TIME_HEADER,BYTE); // this is the header for the current time
Serial.println(DateTime.now());
digitalWrite(13,HIGH);
}
delay(100);
}
boolean getPCtime() {
// if time sync available from serial port, update time and return true
while(Serial.available() >= TIME_MSG_LEN ){ // time message consists of a header and ten ascii digits
if( Serial.read() == TIME_HEADER ) {
time_t pctime = 0;
for(int i=0; i < TIME_MSG_LEN -1; i++){
char c= Serial.read();
if( c >= '0' && c <= '9'){
pctime = (10 * pctime) + (c - '0') ; // convert digits to a number
}
}
DateTime.sync(pctime); // Sync Arduino clock to the time received on the serial port
return true; // return true if time message received on the serial port
}
}
return false; //if no message return false
}
void digitalClockDisplay(){
// digital clock display of current date and time
Serial.print(DateTime.Hour,DEC);
printDigits(DateTime.Minute);
printDigits(DateTime.Second);
Serial.print(" ");
Serial.print(DateTimeStrings.dayStr(DateTime.DayofWeek));
Serial.print(" ");
Serial.print(DateTimeStrings.monthStr(DateTime.Month));
Serial.print(" ");
Serial.println(DateTime.Day,DEC);
}
void printDigits(byte digits){
// utility function for digital clock display: prints preceding colon and leading 0
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits,DEC);
}
Perhaps we can tell something from the data. Can you paste a fragment of the output showing the last few correct times and then a bunch of incorrect times.
Hi,
I've posted data received from the Serial Monitor
and from Processing as they are slightly different.
Arduino Serial Monitor
Clock synced at: 1254422090
18:34:ber 1
ÿ1254422091
18:34:52 Thursday Oc18:34:ursday October 1
ÿ1254422093
18:34:54 Thursday Oc18:34:2095
18:35:41 Thursday October 1
18:35:42 Thu18:35:43 Thursday October 1
18:35:44 Thu11:38:50 Fri11:38:5232
11:38:53 Friday November 20
ÿ1258717133
11:38:5ovember 20
ÿ1258717134
11:38:55 Friday Novemberÿ1258717135
Processing
Native lib Version = RXTX-2.1-7
Java lib Version = RXTX-2.1-7
[0] "/dev/tty.modem"
[1] "/dev/cu.modem"
[2] "/dev/tty.usbserial-A40014V7"
[3] "/dev/cu.usbserial-A40014V7"
Connecting to -> /dev/tty.usbserial-A40014V7
51 Thursday Octotober 1
[ch711]1254422092
53 Thtober 1
[ch711]1254422094
55 Thursday October 1
[ch711]125442tober 1
[ch711]1254422096
rsday October 1
[ch711]1254422144
day November 20
[ch711]1258717131
Friday November 20
[ch711]125871714 Friday N 20
er 20
You seem to be losing characters from the serial messages. Here is a test sketch that increments and prints a count every second. The header is sent so you can use the Processing sketch to view the output there to check it's the same as on the Arduino Serial monitor. If you don't see the numbers increase in sequence every second then perhaps there is some problem with your board or the serial connection.
#define TIME_HEADER 255
unsigned long count = 1254422090; // a starting count
void setup(){
Serial.begin(19200);
pinMode(13,OUTPUT); // we flash the LED each second
}
void loop(){
digitalWrite(13,LOW); // first flash the LED
delay(500);
digitalWrite(13,HIGH);
delay(500);
Serial.print( TIME_HEADER,BYTE);
Serial.println(count);
count = count + 1;
}
I get a perfect sequence of numbers in Arduino Serial monitor when running your sketch. Haven't tried Processing yet.
Try this, it's similar to the code from the playground example but it does not use any data from the serial port to set the time. If this sequences ok then you need to look at what is coming down the serial port.
#include <DateTime.h>
#include <DateTimeStrings.h>
#define TIME_HEADER 255
unsigned long count = 1254422090; // a starting count
void setup(){
Serial.begin(19200);
pinMode(13,OUTPUT); // we flash the LED each second
DateTime.sync(count);
}
void loop(){
unsigned long prevtime;
prevtime = DateTime.now();
while( prevtime == DateTime.now() ) // wait for the second to rollover
{
digitalWrite(13,!digitalRead(13)); // toggle the LED
delay(250);
}
DateTime.available(); //refresh the Date and time properties
digitalClockDisplay( ); // update digital clock
Serial.print( TIME_HEADER,BYTE); // this is the header for the current time
Serial.println(DateTime.now());
while(Serial.available() )
Serial.print((char)Serial.read()) ;
Serial.println();
}
void digitalClockDisplay(){
// digital clock display of current date and time
Serial.print(DateTime.Hour,DEC);
printDigits(DateTime.Minute);
printDigits(DateTime.Second);
Serial.print(" ");
Serial.print(DateTimeStrings.dayStr(DateTime.DayofWeek));
Serial.print(" ");
Serial.print(DateTimeStrings.monthStr(DateTime.Month));
Serial.print(" ");
Serial.println(DateTime.Day,DEC);
}
void printDigits(byte digits){
// utility function for digital clock display: prints preceding colon and leading 0
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits,DEC);
}
The code will print incoming serial data in this format:
18:35:28 Thursday October 2
ÿ1254422128
18:35:29 Thursday October 2
ÿ1254422129
18:35:30 Thursday October 2
ÿ1254422130
asdfasdf << this is data received on the serial port
18:35:31 Thursday October 2
ÿ1254422131
Your latest code is sequencing correctly.
How do I look at what is coming down the serial port?
The code I posted echoes characters to the serial monitor, see my previous post. You can enhance the Serial.print statement that handles the echoed characters if you want to make this output easier to see.