Hello everyone,
I'm trying to create a dynamic array of strings, using the RTC module. I've managed to retrieve the time as a pointer to a char array in the format of "12/3/12 14:45:44". Now, I'm trying to capture them as a separate char array of arrays to store as a global variable, with the push of a button. It is sort of a data logger, but it stores the values as a big array. (i'll be using the char array of arrays to communicate between two nRLF2401+ modules).
Below is my code. The bottom functions are for the RTC Clock. The trouble I believe I'm running into is within void(loop).
#include <SPI.h>
#include <String.h>
const int cs = 6; // chip select for the RTC module
const int maxRecordings = 100;
char * myStrings[maxRecordings] = {};
const int timeSaveButton = 2; // Button pin for saving time and reading time
int n = 0;
int saveButtonState; // Interrupt states for buttons
int saveLastButtonState = 0;
void setup(){
Serial.begin(9600);
pinMode(timeSaveButton, INPUT);
RTC_init();
Serial.begin(9600);
}
void loop(){
//when button is pressed;
saveButtonState = digitalRead(timeSaveButton);
if (saveButtonState != saveLastButtonState && saveLastButtonState == HIGH) {
for (int i = 0; i <= n; i++){
if (i == n) {
myStrings[i] = readTimeDate();
}
Serial.print("Recording #");
Serial.print(i);
Serial.print(": ");
Serial.println(myStrings[i]);
}
n++;
Serial.println("");
}
saveLastButtonState = saveButtonState;
delay(1000);
}
int RTC_init(){
pinMode(cs, OUTPUT); // chip select
// start the SPI library:
SPI.begin();
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE3); // both mode 1 & 3 should work
//set control register
digitalWrite(cs, LOW);
SPI.transfer(0x8E);
SPI.transfer(0x60); //60= disable Osciallator and Battery SQ wave @1hz, temp compensation, Alarms disabled
digitalWrite(cs, HIGH);
delay(10);
}
//=====================================
int setTimeDate(int d, int mo, int y, int h, int mi, int s){
int TimeDate [7]={s,mi,h,0,d,mo,y};
for(int i=0; i<=6;i++){
if(i==3)
i++;
int b= TimeDate[i]/10;
int a= TimeDate[i]-b*10;
if(i==2){
if (b==2)
b=B00000010;
else if (b==1)
b=B00000001;
}
TimeDate[i]= a+(b<<4);
digitalWrite(cs, LOW);
SPI.transfer(i+0x80);
SPI.transfer(TimeDate[i]);
digitalWrite(cs, HIGH);
}
}
//=====================================
char * readTimeDate(){
String temp;
int TimeDate [7]; //second,minute,hour,null,day,month,year
for(int i=0; i<=6; i++) {
if(i==3)
i++;
digitalWrite(cs, LOW);
SPI.transfer(i+0x00);
unsigned int n = SPI.transfer(0x00);
digitalWrite(cs, HIGH);
int a=n & B00001111;
if(i==2){
int b=(n & B00110000)>>4; //24 hour mode
if(b==B00000010)
b=20;
else if(b==B00000001)
b=10;
TimeDate[i]=a+b;
}
else if(i==4){
int b=(n & B00110000)>>4;
TimeDate[i]=a+b*10;
}
else if(i==5){
int b=(n & B00010000)>>4;
TimeDate[i]=a+b*10;
}
else if(i==6){
int b=(n & B11110000)>>4;
TimeDate[i]=a+b*10;
}
else{
int b=(n & B01110000)>>4;
TimeDate[i]=a+b*10;
}
}
temp.concat(TimeDate[4]);
temp.concat("/") ;
temp.concat(TimeDate[5]);
temp.concat("/") ;
temp.concat(TimeDate[6]);
temp.concat(" ") ;
temp.concat(TimeDate[2]);
temp.concat(":") ;
temp.concat(TimeDate[1]);
temp.concat(":") ;
temp.concat(TimeDate[0]);
// added the below bit to return a char array, easier to save in EEPROM.
const int len = 51;
char buf[len];
temp.toCharArray(buf, len);
return buf;
}
The result of this code is such:
Recording #0: 22/2/12 3:49:18
Recording #0: 22/2/12 3:49:18
Recording #1: 22/2/12 3:49:23
Recording #0: 22/2/12 3:49:23
Recording #1: 22/2/12 3:49:23
Recording #2: 22/2/12 3:49:29
As you can see, once the pointer is updated with readTimeDate(), it changes all the myStrings values, since essentially they are the same pointers. How can I store the value readTimeDate() is initially pointing to?
Additionally, re: the way myStrings is declared is a little confusing.
const int maxRecordings = 100;
char * myStrings[maxRecordings] = {};
Do I always have to say the length of my char arrays? Is it not possible to create a dynamic array that grows whenever I wish to input a value? The below code compiles correctly, however returns jibberish once I actually open the serial monitor.
//const int maxRecordings = 100;
char * myStrings[] = {};
Any help would be greatly appreciated. Original code for the RTC functions can be found in the Sparkfun website below.
http://www.sparkfun.com/datasheets/BreakoutBoards/DS3234_Example_Code.c
All the best,
Mert