Jump to content
43oh

Weird problem with string and library


Recommended Posts

I'm trying to build a radio, with a 5110 display (SPI), RTC and Si74703 (I2C) but it does not seem to be working.

#include "LCD_5110.h"
#include <Si4703_Breakout.h>
#include <Wire.h>
#include "RTClib.h"

/////////////////////// RADIO
int resetPin = P1_4 ;
int SDIO = P1_7;
int SCLK = P1_6;

Si4703_Breakout radio(resetPin, SDIO, SCLK);
int channel;
int volume;
char rdsBuffer[10];

////////////////////// CLOCK
RTC_DS1307 RTC;
DateTime now = DateTime(__DATE__, "01:01:01") ;

////////////////////// LCD
LCD_5110 lcd_screen;
boolean    backlight = false;

void setup()
{
 lcd_screen.begin();
 
 lcd_screen.setBacklight(backlight);
 lcd_screen.text(0, 0, "Initializing");
 
 Serial.begin(9600);
 
 Wire.begin() ;
 RTC.begin();
 
/* radio.powerOn();
 radio.setVolume(3);
 */

 //if(!RTC.isrunning())
 {
//  RTC.adjust(DateTime(__DATE__, __TIME__));
   RTC.adjust(DateTime(__DATE__, "01:01:01"));
 }

 lcd_screen.clear();
 lcd_screen.text(0, 0, "Done");
 
 displayTime() ;
 lcd_screen.text(0, 5, "Kikou");
}

void loop()
{
 displayTime() ;

 delay(1000);
}

void displayTime()
{
 lcd_screen.text(0, 0, "Test");

 now = RTC.now() ;

 lcd_screen.setFont(1);
 String time_str = leadZero(now.hour()) ;
 time_str.concat(":") ;
 time_str.concat(leadZero((int)now.minute())) ;
 
 lcd_screen.text(0, 0, time_str) ;
 String min_str = "" ;
 min_str += ":" ;
 min_str += leadZero(now.second()) ;
 
 lcd_screen.setFont(0) ;
 lcd_screen.text(10, 1, min_str) ;
 Serial.println(min_str) ;
}

String leadZero(int val)
{
 String str = "" ;
 if(val<10)
 {
  str = "0" ;
 }
 str.concat(val) ;
 return str ;
}

when it display the time I got

01:0 :0

on the LCD or on Serial.print and when the number of second id >= 10

01:0 :10

if I comment out

Si4703_Breakout radio(resetPin, SDIO, SCLK);

I got the right display

01:01:01 .... 01:01:02 ... 01:01:15 etc 

The RTC device and the radio are on I2C both, but the constructor of the radio object does nothing...

 

Before this version of code I got all sort of problem with the strings manipulation of the time.

 

Looks like an memory problem between String and one or more of the library to me....

Link to post
Share on other sites

These is not a whole lot of dynamic memory used by the radio object when you only instantiate it but it could be enough for the String library to go into the weeds.

String on MSP430 is particularly bad since it only has 512 bytes but on top of that, the realloc() in the String library was replaced with a free()/alloc() which could fragment memory.

Could you post the output of msp430-size <your elf file>.elf?

 

If you are on windows then open a command prompt and run msp430-size on the elf file. msp430-size.exe is located in your Energia folder under hardware\tools\msp430\bin\

You can copy the path to your elf file from the black window in Energia. Be sure to turn on verbose output during compilation in file->preferences. The output should look something like this:

 

   text   data    bss    dec    hex filename
    284      0     12    296    128 sketch_feb05a.cpp.elf
 
text is the number of bytes of flash used and bss is the number of bytes of RAM used.
Link to post
Share on other sites

String is notorious for blowing your heap and screwing with memory.  On the Arduino forums, back in the day when I used them, the use of String was STRONGLY discouraged even on the ATmega328 with 2KB SRAM.

 

Hum, didn't find this information on google but I was thinking of something like that... The LCD_5110 library use String so it's one reason I used them and one hope to simplify string manipulations.... but no.

 

EDIT : It's the LCD_5110 which using String not the RTC one

Link to post
Share on other sites

I redone the code to use only char but still got problems. Been a long time since the last time I use string (char arrays ones) in C. more of Php time, get some bad habits ;-)

char time_buff[6] ;
...
void displayTime()
{ 
 lcd_screen.setFont(1);
 strcpy(time_buff, headZero(now.hour())) ;
 strcat(time_buff, ":") ;
 strcat(time_buff, headZero(now.minute())) ;
 Serial.println(time_buff) ;
 lcd_screen.text(0, 0, time_buff) ;
 
 strcpy(time_buff, ":") ;
 strcat(time_buff, headZero(now.second())) ;
 
 lcd_screen.setFont(0) ;
 lcd_screen.text(10, 1, time_buff) ; 
 Serial.println(time_buff) ;
 
 strcpy(time_buff, headZero(now.day())) ;
 strcat(time_buff, "/") ;
 strcat(time_buff, headZero(now.month())) ;
 Serial.println(time_buff) ;
 lcd_screen.text(0, 2, time_buff) ; 
}

char *headZero(unsigned char val)
{
 Serial.println(val, DEC) ;
 char str[3] ;
 if(val<10)
 {
  char val_str[2] ;
  itoa(val, val_str, 10) ;
  strcpy(str, "0") ;
  strcat(str, val_str) ; 
 }
 else
 {
  itoa(val, str, 10) ;
 }

 str[3] = NULL ;

 return str ;
}

I edit LCD_5110 to get ride of the references to String (fairly easy) too.

 

trace in headZero some times return weird things 2 not becoming 02 but

Link to post
Share on other sites
char *headZero(unsigned char val)
{
 Serial.println(val, DEC) ;
 char str[3] ;
 if(val<10)
 {
  char val_str[2] ;
  itoa(val, val_str, 10) ;
  strcpy(str, "0") ;
  strcat(str, val_str) ; 
 }
 else
 {
  itoa(val, str, 10) ;
 }

 str[3] = NULL ;

 return str ;

I think time_buff is probably big enough the way you're using it, but it'd be easier to allocate a larger array instead of doing things in pieces.

 

One problem is your headZero returns a pointer to an array str that's stored on the stack. Its value is no longer valid in the caller. Pass the address of where to store the string to this routine. Probably better to just do something like this untested code:

 

char * headZero (unsigned char val, char * dp)
{
  *dp++ = '0' + (val / 10);
  *dp++ = '0' + (val % 10);
  return dp;
}

void displayTime()
{
  char * dp = time_buf; 
  lcd_screen.setFont(1);
  dp = headZero(now.hour(), dp);
  *dp++ = ':';
  dp = headZero(now.minute(), dp);
  *dp = 0;
  Serial.println(time_buff) ;
  lcd_screen.text(0, 0, time_buff) ;
 
  /* etc. */
}
Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...