char[] problem

Hi

i’m making a clock using an input from the serial port. This input is formatted as following:

;;;;;;;

i read this feed and convert is to char to use it in my arduino sketch.

the receiving part works fine, but i’m having some problems with the decoding.

this is my code:

#include <MI0283QT2.h>
#include "time.h"

MI0283QT2 lcd;
Time time;
int cntr = 0;

void setup()
{
  lcd.init(2);
  lcd.clear(RGB(0,0,0));
  
  Serial.begin(9600);
}

void loop()
{
  if(Serial.available()>0)
  {
    char tempTime[11];
    
    for(int i=0; i<11; i++)
    {
        tempTime[i]=32;
    }
    
    Serial.readBytesUntil(';', tempTime, Serial.available());
    
    tempTime[10] = '\0';
    
    time.setTimePart(tempTime, cntr);
    
    if(cntr>8)
      cntr=0;
    
    cntr++;
    
    lcd.drawText(10,10,time.dayName,1,RGB(60,60,60),RGB(0,0,0));
    lcd.drawText(16,23,time.dayNr,3,RGB(60,60,60),RGB(0,0,0));
    //lcd.drawText(100,10,"Data received",2,RGB(0,0,0),RGB(0,0,0)); i'll explain this 'outcommenting' later
    
  }
}
#ifndef time_h
#define time_h

#include "Arduino.h"

class Time
{
	public:
		char dayNr[11];
		char dayName[11];
		
		char monthNr[11];
		char monthName[11];
		
		char year[11];
		
		char hour[11];
		char minute[11];
		char second[11];
		
                void setTimeFromData(char DayName[], char DayNr[], char MonthName[], char MonthNr[], char Year[], char Hour[], char Minute[], char Second[]);
                void setTimePart(char data[], int cnt);
};

#endif
#include "Arduino.h"
#include "time.h"

void Time::setTimeFromData(char DayName[], char DayNr[], char MonthName[], char MonthNr[], char Year[], char Hour[], char Minute[], char Second[])
{
  strcpy(dayName, DayName);
  strcpy(dayNr, DayNr);
  
  strcpy(monthNr, MonthNr);
  strcpy(monthName,MonthName);
  
  strcpy(year, Year);
  
  strcpy(hour, Hour);
  strcpy(minute, Minute);
  strcpy(second, Second);
}

void Time::setTimePart(char data[], int cnt)
{
  if(cnt==1)
    strcpy(dayName, data);
  if(cnt==2)
    strcpy(dayNr, data);
  if(cnt==3)
    strcpy(monthName, data);
  if(cnt==4)
    strcpy(monthNr, data);
  if(cnt==5)
    strcpy(year, data);
  if(cnt==6)
    strcpy(hour, data);
}

in the beginning i get what i expect, but it’s not how it should be.
as you can see i commented one line out: lcd.drawText(100,10,“Data received”,2,RGB(0,0,0),RGB(0,0,0));
this instruction needs to be executed in order to get it to work, if i comment this line out, all i get is garbage (like the year instead of the dayname, and the month instead of the daynr etc etc)
so it’s not real garbage, everything just gets mixed up…

i was wondering how this is possible? i only send the input once per second, so it does not get overflowed by serial data (i suppose)

Thanks
Nick

btw, i use the watterott MI0823QT-2 screen, but that doesn’t really matter i think

  if(Serial.available()>0)
  {
    char tempTime[11];
    
    for(int i=0; i<11; i++)
    {
        tempTime[i]=32;
    }

Why are you initializing the every element in the array to space?

    Serial.readBytesUntil(';', tempTime, Serial.available());

Back to the documentation for you. The third argument is the size of the array to write to, not the number of bytes currently available to read. With that call, if the ; has not arrived yet, the call won’t wait for it.

The function returns the number of bytes read. That defines where the NULL goes. It does not necessarily go in position 10.

    time.setTimePart(tempTime, cntr);

How does this class do anything useful with the data as strings?

Serial.print() and Serial.println() to confirm what you actually get would be useful. I don’t think you are getting whet you think you are getting.

i got it solved, thanks PaulS

this is the current code (in case you’re interested):

#include <MI0283QT2.h>
#include "time.h"

//PROTOCOL: maandag;29;juli;7;2012;13;29;12 = <dayName>;<day>;<monthName>;<month>;<year>;<hour>;<minute>;<second>;

MI0283QT2 lcd;
Time time;
int cntr = 0;

void setup()
{
  lcd.init(2);
  lcd.clear(RGB(0,0,0));
  Serial.begin(9600);
}

void loop()
{
  if(Serial.available()>0)
  {
    for(int i=1; i<9; i++)
    {
      char tempTime[11];
      tempTime[Serial.readBytesUntil(';', tempTime, sizeof(tempTime)/sizeof(tempTime[0]))] = '\0';
      time.setTimePart(tempTime, i);
    }
    updateTime();
  }
}

void updateTime()
{
  lcd.drawText(10,10,time.dayNr,1,RGB(60,60,60),RGB(0,0,0));
  lcd.drawText(10,30,time.dayName,1,RGB(60,60,60),RGB(0,0,0));
  lcd.drawText(10,50,time.monthNr,1,RGB(60,60,60),RGB(0,0,0));
  lcd.drawText(10,70,time.monthName,1,RGB(60,60,60),RGB(0,0,0));
  lcd.drawText(10,90,time.year,1,RGB(60,60,60),RGB(0,0,0));
  lcd.drawText(10,110,time.hour,1,RGB(60,60,60),RGB(0,0,0));
  lcd.drawText(10,130,time.minute,1,RGB(60,60,60),RGB(0,0,0));
  lcd.drawText(10,150,time.second,1,RGB(60,60,60),RGB(0,0,0));
  //Serial.println("ok");
}