Data Type Conversion

I am using a Sainsmart 128x64 LCD. which requires an unsigned char* as a third parameter in it's displaystring() function. My problem is that the DS1307 RTC code is returning hour, min, and sec in uint8_t, so how can I convert so that I can display time on lcd?
uint8_t to unsigned char*

Thanks to all and any input!

GiGalo:
I am using a Sainsmart 128x64 LCD. which requires an unsigned char* as a third parameter in it's displaystring() function. My problem is that the DS1307 RTC code is returning hour, min, and sec in uint8_t, so how can I convert so that I can display time on lcd?
uint8_t to unsigned char*

Thanks to all and any input!

sprintf()

Could you give me an example on sprintf?

Here is what I got:

char buffer[6];//time returns 6 char
sprintf(buffer, "%d:%d", RTC.hour, RTC.minute);

LCDA.DisplayString(0,0, buffer, 16);

returns error:
invalid conversion from char to unsigned char.

What am I doing wrong?

If the DisplayString function requires an unsigned char* as its parameter, perhaps you should declare your buffer unsigned char rather than char?

Hello and welcome,

Try with type casting, like this:

char buffer[6];//time returns 6 char
sprintf(buffer, "%d:%d", RTC.hour, RTC.minute);

LCDA.DisplayString(0,0, (unsigned char*) buffer, 16);

It might be a better solution to modify the DisplayString function instead, or make an overloaded copy :slight_smile:

Professor Chaos - From what I am seeing, sprintf ( char * str, const char * format, ... ) requires char, hence, when I declare as unsigned char, arduino returns error: cannot convert unsigned char* to char**

guix - Thank you! Before attempting the sprintf() idea, I explored casting and the result was just a weird looking blob on screen. More like a char rather than int. However, attempting the code change you just recommended, the code compiled with no errors, but the lcd is blank. As far as editing the displaystring function, I dont know enough about c to do that. If pointed in the right direction i could probably figure it out though :slight_smile:

It's time to post ALL of your code. In the RTC class I use, hour and minute are methods, not fields. So, it looks to me like you are writing the address of the method to the string, not the time.

// #############################################################################
// #
// # Scriptname : DS1307new.h
// # Author     : Peter Schmelzer
// # Contributor: Oliver Kraus
// # contact    : schmelle2@googlemail.com
// # Date       : 2010-11-01
// # Version    : 0.2
// # License    : cc-by-sa-3.0
// #
// # Description:
// # Headerfile for the DS1307new Library
// # 
// #############################################################################
// *********************************************
// DEFINE
// *********************************************
#ifndef DS1307new_h
#define DS1307new_h

// *********************************************
// INCLUDE
// *********************************************
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
  
// *********************************************
// Library interface description
// *********************************************
class DS1307new
{
  public:
    DS1307new();
    uint8_t isPresent(void);
    void startClock(void);
    void stopClock(void);
    void setTime(void);
    void getTime(void);
    void getCTRL(void);
    void setCTRL(void);
    void getRAM(uint8_t rtc_addr, uint8_t * rtc_ram, uint8_t rtc_quantity);
    void setRAM(uint8_t rtc_addr, uint8_t * rtc_ram, uint8_t rtc_quantity);
    uint8_t second;
    uint8_t minute;
    uint8_t hour; 
    uint8_t dow;			// day of week, 0 = sunday
    uint8_t day;
    uint8_t month;
    uint16_t year;
  
  
    uint8_t ctrl;

    uint16_t ydn;		// day within the year (year day number, starts with 1 = 1. Jan)
    uint16_t cdn;		// days after 2000-01-01 (century day number, starts with 0)
    uint32_t time2000;	// seconds after 2000-01-01 00:00 (max value: 2136-02-07 06:28:15)
  
    void fillByCDN(uint16_t _cdn);
    void fillByTime2000(uint32_t _time2000);
    void fillByHMS(uint8_t h, uint8_t m, uint8_t s);
    void fillByYMD(uint16_t y, uint8_t m, uint8_t d);
    uint8_t isMEZSummerTime(void);

  private:
    uint8_t is_leap_year(uint16_t y);
    void calculate_ydn(void);			// calculate ydn from year, month & day
    void calculate_cdn(void);			// calculate cdn from year & ydn
    void calculate_dow(void);			// calculate dow from ydn
    void calculate_time2000(void);		// calculate time2000 from cdn, hour, minute & second

    uint16_t _corrected_year_day_number(void);
    void calculate_month_by_year_and_ydn(void);
    void calculate_day_by_month_year_and_ydn(void);

    uint8_t dec2bcd(uint8_t num);
    uint8_t bcd2dec(uint8_t num);
};

extern DS1307new RTC;

#endif

the cpp file exceeds forum allowable chars. The library is here:

http://code.google.com/p/ds1307new/downloads/detail?name=DS1307new_v1.23.zip&can=2&q=

And the sketch?

#include "LCD12864RSPI.h"
#include "Wire.h"
#include <DS1307new.h>


#define AR_SIZE( a ) sizeof( a ) / sizeof( a[0] )

uint16_t startAddr = 0x0000;            // Start address to store in the NV-RAM
uint16_t lastAddr; 

void setup()
{
   Wire.begin();
  LCDA.Initialise(); // INIT SCREEN
  delay(100);
  Serial.begin(9600);
   pinMode(2, INPUT);                    // Test of the SQW pin, D2 = INPUT
  digitalWrite(2, HIGH);  
  RTC.setRAM(0, (uint8_t *)&startAddr, sizeof(uint16_t));
  
 
 // unsigned char header[] = "Aquaria  Control";
  // LCDA.DisplayString(0,0,header,16);
  
   RTC.getTime();
   RTC.ctrl = 0x00;                // 0x00=disable SQW pin, 0x10=1Hz,
                                        // 0x11=4096Hz, 0x12=8192Hz, 0x13=32768Hz
   RTC.setCTRL();
   RTC.getTime();
   
  char buffer[6];
   sprintf(buffer, "%d:%d", RTC.hour, RTC.minute);
    LCDA.DisplayString(0,0,(unsigned char*) buffer,16);
  
     
}

void loop()
{

}

You have a Serial.begin() in setup(), but no Serial.print(ln), after getting the time. Why not? What is in hour and minute? If the values are not valid, then it is possible that you are overflowing the 6 element buffer, who's size expects hour and minute to result in not more than 2 characters per value.

After sprintf() does its thing, what is in buffer?

Given that the buffer size is 6, why does it appear that you are telling the function to print 16 characters?

The serial.begin was to initially print time to serial monitor. I just forgot to take the code back out. below is the working lines that print to serial monitor. I was figurin on 00,00,00 hour, min, sec for 6 char in buffer. Should it be bigger than six?

// Serial.print(RTC.hour, DEC);
    // Serial.print(":");
     //Serial.print(RTC.minute, DEC);

I was figurin on 00,00,00 hour, min, sec for 6 char in buffer.

You don't think it's important to count the commas"? I do.

You don't think it's important to count the terminating NULL"? I do.

Should it be bigger than six?

Yes.

OK so I was able to find an updated cpp file which had a displayInteger() function that I was able to add to my cpp file. This test code prints out my hour.

/*
LCD  Arduino
PIN1 = GND
PIN2 = 5V
RS(CS) = 8; 
RW(SID)= 9; 
EN(CLK) = 3;
PIN15 PSB = GND;
*/

#include "LCD12864RSPI.h"
#include "Wire.h"
#include <DS1307new.h>


#define AR_SIZE( a ) sizeof( a ) / sizeof( a[0] )

uint16_t startAddr = 0x0000;            // Start address to store in the NV-RAM
uint16_t lastAddr; 

void setup()
{
   Wire.begin();
  LCDA.Initialise(); // INIT SCREEN
  delay(100);
 
  pinMode(2, INPUT);                    // Test of the SQW pin, D2 = INPUT
  digitalWrite(2, HIGH);  
  
  RTC.setRAM(0, (uint8_t *)&startAddr, sizeof(uint16_t));
  
  unsigned char header[] = "Aquaria  Control";
  LCDA.DisplayString(0,0,header,16);
  
  RTC.getTime();
  RTC.ctrl = 0x00;                      // 0x00=disable SQW pin, 0x10=1Hz,
                                        // 0x11=4096Hz, 0x12=8192Hz, 0x13=32768Hz
  RTC.setCTRL();
  
  RTC.getTime();
  
  int hr = RTC.hour;
  LCDA.displayInteger(0,0,hr);
   
}

void loop()
{

}

So printing out the hour, min, and second are finally done! The problem is now, how do you format this output so that it is nice and tight on the lcd. Right now this print the time out accordingly but with an empty space between output. Any Ideas?

  int hr = RTC.hour;
  int minu = RTC.minute;
  int sec = RTC.second;
  unsigned char colon[] = ":";
  
 
   LCDA.displayInteger(0,0,hr);
   LCDA.DisplayString(0,1,colon,1);
   LCDA.displayInteger(0,2,minu);
   LCDA.DisplayString(0,3,colon,1);
   LCDA.displayInteger(0,4,sec);
  unsigned char colon[] = ":";

How does an array with one element offer any advantage over a scalar variable?

The sprintf() process should have worked.

unsigned char timeString[12];
sprintf((char *)timeString, "%02d:%02d:%02d", RTC.hour, RTC.minute, RTC.second);

LCDA.DisplayString(0,1,timeString, strlen(timeString));

I know it does not sound right, but without the array there is a conversion error for some reason.
Thank you very much for your feedback, it is greatly appreciated!

The provided code gives me a conversion error:
invalid conversion from unsigned char* to const char*
and
error intializing argument 1 of 'size_t strlen(const char*)'

Signed char, unsigned char, const signed char, and const unsigned char are all the same size. If a function expects one type, and you have another, lie to the function. Tell it that the type you have IS the type it expects.

If strlen() expects a const char *, and you have a unsigned char *, lie to it:

strlen((const char *)buffer)