Saving timestamp to char

Im recording humidity and temperature at a given time. T/H comes from a dht11 and time from the sim900’s network. I need to take 8 samples so I created a structure with time, temp and hum variables. An alarm is set to go off every 10 seconds and sample and store that 3d structure variable into an array. The array will print the values after the 7th sample. But I only get 1 for the timestamps of all 7 samples.

My code is here:

#include <Time.h>
#include <TimeLib.h>
#include <TimeAlarms.h>
#include "SIM900z.h"
#include <SoftwareSerial.h>
int count = 0;
SoftwareSerial sim900(9,10);
char timestamp;

int smsSampleCount=0;
typedef struct {
  uint32_t timeStamp;
  double tempSample;
  double humSample;
} samplePoint;

samplePoint finalDataArray[10];

void setup() {
  Serial.begin(9600);
  Serial.println("Setup");
  Alarm.timerRepeat(10, MainAlarm);
}

void loop() {
  Alarm.delay(1000); 

}

void MainAlarm(){
  Serial.println("Main Alarm...");
  
  sim900.begin(9600);
  Serial.println("starting timesync");
  syncSIM900Clock();
  Serial.println("finished timesync");
  
  double temp = 59.0;
  double hum = 99.0;


   if (smsSampleCount<8) {
    Serial.println(smsSampleCount);
    finalDataArray[smsSampleCount].timeStamp = timestamp;
    finalDataArray[smsSampleCount].tempSample = 59.0+smsSampleCount;
    finalDataArray[smsSampleCount].humSample = 99.0+smsSampleCount;
    smsSampleCount++;
   } else {
    Serial.println("Sending data");
    sendData();
   }

}

void syncSIM900Clock(){
        //DEBUG ONLY
        sim900.println("AT");
        delay(5000);
        
        //SYNC CLK
        sim900.println("AT+QGSMLOC=4"); //ran 1st and worked (maybe syncd from now on)
        delay(5000);

        //PRINT TIME
        sim900.println("AT+CCLK?");
        delay(5000);
        printRead();
}

void printRead() {
  char datain;
  while(sim900.available()>0){
    datain=sim900.read();
    if(datain>0){
      //Serial.print(datain);
      timestamp = datain;
      Serial.print(timestamp);
    }
  }
}

void sendData(){
  Serial.println("Data is");
  Serial.println(finalDataArray[0].timeStamp);
  Serial.println(finalDataArray[1].timeStamp);
  Serial.println(finalDataArray[2].timeStamp);
  Serial.println(finalDataArray[3].timeStamp);
  Serial.println(finalDataArray[4].timeStamp);
  Serial.println(finalDataArray[5].timeStamp);
  Serial.println(finalDataArray[6].timeStamp);
  Serial.println(finalDataArray[7].timeStamp);
  Serial.println(finalDataArray[0].tempSample);
  Serial.println(finalDataArray[1].tempSample);
  Serial.println(finalDataArray[2].tempSample);
  Serial.println(finalDataArray[3].tempSample);
  Serial.println(finalDataArray[4].tempSample);
  Serial.println(finalDataArray[5].tempSample);
  Serial.println(finalDataArray[6].tempSample);
  Serial.println(finalDataArray[7].tempSample);
  Serial.println(finalDataArray[0].humSample);
  Serial.println(finalDataArray[1].humSample);
  Serial.println(finalDataArray[2].humSample);
  Serial.println(finalDataArray[3].humSample);
  Serial.println(finalDataArray[4].humSample);
  Serial.println(finalDataArray[5].humSample);
  Serial.println(finalDataArray[6].humSample);
  Serial.println(finalDataArray[7].humSample);
  // Now clear the array to start over
}
finalDataArray[smsSampleCount].timeStamp = timestamp;

timestamp out in the code is a char variable. 8 bits. Won't hold much of a timestamp. If the timestamp is coming from the sim network as a string then you'll need an array of char long enough to hold the whole string and you'll need to parse through it to get the timestamp part and then convert the ascii string into a real number with strtoul or something.

timestamp in the struct is a uint32_t. That's unsigned long. That look like something that will hold a timestamp. Once you've made a real number out of what's coming from the sim900, you'll be good to store it here.

  Serial.println(finalDataArray[0].timeStamp);
  Serial.println(finalDataArray[1].timeStamp);
  Serial.println(finalDataArray[2].timeStamp);
  Serial.println(finalDataArray[3].timeStamp);
  Serial.println(finalDataArray[4].timeStamp);
  Serial.println(finalDataArray[5].timeStamp);
  Serial.println(finalDataArray[6].timeStamp);
  Serial.println(finalDataArray[7].timeStamp);
  Serial.println(finalDataArray[0].tempSample);
  Serial.println(finalDataArray[1].tempSample);
  Serial.println(finalDataArray[2].tempSample);
  Serial.println(finalDataArray[3].tempSample);
  Serial.println(finalDataArray[4].tempSample);
  Serial.println(finalDataArray[5].tempSample);
  Serial.println(finalDataArray[6].tempSample);
  Serial.println(finalDataArray[7].tempSample);
  Serial.println(finalDataArray[0].humSample);
  Serial.println(finalDataArray[1].humSample);
  Serial.println(finalDataArray[2].humSample);
  Serial.println(finalDataArray[3].humSample);
  Serial.println(finalDataArray[4].humSample);
  Serial.println(finalDataArray[5].humSample);
  Serial.println(finalDataArray[6].humSample);
  Serial.println(finalDataArray[7].humSample);

Never heard of for loops?

Ok I got this:

#include <Time.h>
#include <TimeLib.h>
#include <TimeAlarms.h>
//>>timestamptestSimple
#include "SIM900z.h"
#include <SoftwareSerial.h>
//timestamptestSimple<<
int count = 0;
//>>timestamptestSimple
SoftwareSerial sim900(9,10);
String str;
//timestamptestSimple<<

int smsSampleCount=0;
typedef struct {
  String timeStamp;
  double tempSample;
  double humSample;
} samplePoint;

samplePoint finalDataArray[10];

void setup() {
  Serial.begin(9600);
  Serial.println("Setup");
  Alarm.timerRepeat(10, MainAlarm); //600/60=10s
}

void loop() {
  Alarm.delay(1000); // wait one second between clock display

}

void MainAlarm(){
  Serial.println("Main Alarm...");
  
  //>>timestamptestSimple
  sim900.begin(9600);
  Serial.println("starting timesync");
  syncSIM900Clock();
  Serial.println("finished timesync");
  //timestamptestSimple<<
  
  double temp = 59.0;
  double hum = 99.0;


   if (smsSampleCount<8) {
    Serial.println(smsSampleCount);
    finalDataArray[smsSampleCount].timeStamp = str;
    finalDataArray[smsSampleCount].tempSample = 59.0+smsSampleCount;
    finalDataArray[smsSampleCount].humSample = 99.0+smsSampleCount;
    smsSampleCount++;
   } else {
    Serial.println("Sending data");
    sendData();
   }

}

void syncSIM900Clock(){
        //DEBUG ONLY
        sim900.println("AT");
        delay(1000);
        printRead();
        
        //SYNC CLK
        sim900.println("AT+QGSMLOC=4"); 
        delay(1000);
        printRead();

        //PRINT TIME
        sim900.println("AT+CCLK?");
        delay(1000);
        printRead();
}

void printRead() {
  char datain;
  while(sim900.available()>0){
    datain=sim900.read();
    if(datain>0){
      str = String(datain);
      //Serial.print(str);
      //datain.toCharArray(timestamp, 50);
      //Serial.print(timestamp);
    }
  }
}

void sendData(){
  Serial.println("Data is");
  for (int x=0; x>8; x+1) {
    Serial.print(finalDataArray[x].timeStamp);
    Serial.print(finalDataArray[x].tempSample);
    Serial.print(finalDataArray[x].humSample);  
  }
}

But its not printing out the data at the end. I get the Data is log but no array values. It logs this:

Main Alarm…
starting timesync
finished timesync
5
Main Alarm…
starting timesync
finished timesync
6
Main Alarm…
starting timesync
finished timesync
7
Main Alarm…
starting timesync
finished timesync
Sending data
Data is
Main Alarm…
starting timesync
finished timesync
Sending data
Data is
Main Alarm…
starting timesync

void printRead() {
  char datain;
  while(sim900.available()>0){
    datain=sim900.read();
    if(datain>0){
      str = String(datain);
      //Serial.print(str);
      //datain.toCharArray(timestamp, 50);
      //Serial.print(timestamp);
    }
  }
}

You’re just reading one character and then creating a string from that one character and then read another character and overwrite the one character string you had with a new one character string.

Why don’t you go look at Robin2’s Serial Input Basics thread and study for a little while. You’ll see some really good methods for reading in the whole string you need and parsing out the part you need.

Ok, I almost have it. Here is my code:

#include <Time.h>
#include <TimeLib.h>
#include <TimeAlarms.h>
//>>timestamptestSimple
#include "SIM900z.h"
#include <SoftwareSerial.h>
//timestamptestSimple<<
int count = 0;
//>>timestamptestSimple
SoftwareSerial sim900(9,10);
String timestamp;
//timestamptestSimple<<

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data
boolean newData = false;

int smsSampleCount; //how many samples i want in the array
typedef struct {
  String timeStamp;
  double tempSample;
  double humSample;
} samplePoint;

samplePoint finalDataArray[10];

void setup() {
  Serial.begin(9600);
  Serial.println("Setup");
  Alarm.timerRepeat(10, MainAlarm); //600/60=10s
}

void loop() {
  Alarm.delay(1000); // wait one second between clock display

}

void MainAlarm(){  
  sim900.begin(9600);
  Serial.println("starting timesync");
  syncSIM900Clock();
  Serial.println("finished timesync");
  
  double temp = 59.0;
  double hum = 99.0;

   if (smsSampleCount<3) {
    Serial.println(smsSampleCount);
    finalDataArray[smsSampleCount].timeStamp = timestamp;
    finalDataArray[smsSampleCount].tempSample = 59.0+smsSampleCount;
    finalDataArray[smsSampleCount].humSample = 99.0+smsSampleCount;
    smsSampleCount++;
   } else {
    Serial.println("Sending data");
    //sendData();
    smsSampleCount = 0;
    showNewData();
   }

}

void syncSIM900Clock(){
    //DEBUG ONLY
    //sim900.println("AT");
    //delay(1000);
    //printRead();
    
    //SYNC CLK
    //sim900.println("AT+QGSMLOC=4"); //ran 1st and worked (maybe syncd from now on)
    //delay(1000);
    //printRead();

    //PRINT TIME
    sim900.println("AT+CCLK?");
    delay(1000);
    printRead();
}

void printRead() {
  static byte ndx = 0;
  char endMarker = '\n';
  char rc;
    
  while(sim900.available()>0 && newData == false){
    rc=sim900.read();
    if (rc != endMarker) {
      receivedChars[ndx] = rc;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
    } else {
        receivedChars[ndx] = '\0'; // terminate the string
        ndx = 0;
        newData = true;
    }//end of if rc != endMarker
      //if rc = "+CCLK:" then count the next 20-22 chars
    }//closes if ----  PARSE LOOKING FOR +CCLK: "17/01/27,16:32:54-24"
  }//closes while
} //closes function

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(receivedChars);
        newData = false;
    }
}

void sendData(){
  //Serial.print("This just in ... ");
  //Serial.println(receivedChars);
  Serial.println("Data is");
  int x = 0;
  while (x<3) {
    Serial.println(finalDataArray[x].timeStamp);
    Serial.println(finalDataArray[x].tempSample);
    Serial.println(finalDataArray[x].humSample);  
    x=x+1;
  }
}

and my results are:

Screen Shot 2017-01-28 at 7.42.13 PM.png

So I have the response in characters in an array. How do I print out the whole array without it going character by character? I tried this but it doesnt work:

#include <Time.h>
#include <TimeLib.h>
#include <TimeAlarms.h>
//>>timestamptestSimple
#include "SIM900z.h"
#include <SoftwareSerial.h>
//timestamptestSimple<<
int count = 0;
//>>timestamptestSimple
SoftwareSerial sim900(9,10);
String timestamp;
//timestamptestSimple<<

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data
boolean newData = false;

int smsSampleCount; //how many samples i want in the array
typedef struct {
  String timeStamp;
  double tempSample;
  double humSample;
} samplePoint;

samplePoint finalDataArray[10];

void setup() {
  Serial.begin(9600);
  Serial.println("Setup");
  Alarm.timerRepeat(10, MainAlarm); //600/60=10s
}

void loop() {
  Alarm.delay(1000); // wait one second between clock display

}

void MainAlarm(){  
  sim900.begin(9600);
  //Serial.println("starting timesync");
  syncSIM900Clock();
  //Serial.println("finished timesync");
  
  double temp = 59.0;
  double hum = 99.0;

//   if (smsSampleCount<3) {
//    Serial.println(smsSampleCount);
//    finalDataArray[smsSampleCount].timeStamp = timestamp;
//    finalDataArray[smsSampleCount].tempSample = 59.0+smsSampleCount;
//    finalDataArray[smsSampleCount].humSample = 99.0+smsSampleCount;
//    smsSampleCount++;
//   } else {
//    Serial.println("Sending data");
//  smsSampleCount = 0;
    showNewData();
//   }

}

void syncSIM900Clock(){
    //DEBUG ONLY
    //sim900.println("AT");
    //delay(1000);
    //printRead();
    
    //SYNC CLK
    //sim900.println("AT+QGSMLOC=4"); //ran 1st and worked (maybe syncd from now on)
    //delay(1000);
    //printRead();

    //PRINT TIME
    sim900.println("AT+CCLK?");
    delay(1000);
    printRead();
}

void printRead() {
  static byte ndx = 0;
  char endMarker = '\n';
  char rc;
    
  while(sim900.available()>0 && newData == false){
    rc=sim900.read();
    if (rc != endMarker) {
      receivedChars[ndx] = rc;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
    } else {
        receivedChars[ndx] = '\0'; // terminate the string
        ndx = 0;
        newData = true;
    }//end of if rc != endMarker
      //if rc = "+CCLK:" then count the next 20-22 chars
    }//closes if ----  PARSE LOOKING FOR +CCLK: "17/01/27,16:32:54-24"
  }//closes while
} //closes function

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        for (int i = 0; i < sizeof(receivedChars) - 1; i++){
          Serial.println(receivedChars[i]);
        }
        newData = false;
    }
}

void sendData(){
  //Serial.print("This just in ... ");
  //Serial.println(receivedChars);
  Serial.println("Data is");
  int x = 0;
  while (x<3) {
    Serial.println(finalDataArray[x].timeStamp);
    Serial.println(finalDataArray[x].tempSample);
    Serial.println(finalDataArray[x].humSample);  
    x=x+1;
  }
}
for (int i = 0; i < sizeof(receivedChars) - 1; i++){
          Serial.println(receivedChars[i]);
        }

Or just:

Serial.print(receivedChars);

You are using the Time/TimeLib library so why not use the time_t epoch value as your timestamp?
You can sync the time tracked by Time to any external timesource as that is also supported by the Time library.

Then convert the time_t timestamp back to a human readable local time whenever necessary.
This is the normal way of handling timestamps.

--- bill

Can I sync the time with the gsm provider? Because from what I see here:

http://playground.arduino.cc/Code/time

it can be set by:

-an RTC like DS1307
-NTP which requires internet access

  • and GPS

There is a function in the time library that you can redefine to get the time from wherever you want.

Thanks. Any chance of you pointing me in the direction of that function. I see the setTime functions, but that is for setting the time manually. Then there are the setSyncProvider which I don't fully understand, is that the one?

Then there are the setSyncProvider which I don't fully understand, is that the one?

Yes. setSynchProvider() takes an argument which returns a Unix time from the device you want to synch to the RTC.

cattledog:
Yes. setSynchProvider() takes an argument which returns a Unix time from the device you want to synch to the RTC.

Just for clarification, the function is called setSyncProvider() and the single argument is a pointer to the function to run.
See this page for some additional information: Time Library, Timekeeping and Time/Date Manipulation on Teensy

OK but I can't use the gsm antenna time as with AT+QGSMLOC?

I want to avoid GPRS and GPS and ds1307 time providers.

OK but I can't use the gsm antenna time as with AT+QGSMLOC?

Why not?

rtc.setSyncProvider(getTimeFromGSM);


time_t getTimeFromGSM()
{
   time_t now;
   // Get the time from the GSM

   return now;
}

You can also fetch the time from your time source in the background rather than do it in the sync provider.
It is a little more complex to do it that way since you have to keep track of when the time was obtained and then offset it to the current time, but it is pretty simple to do.
By doing it in the background you can minimize the realtime impact of the sync provider function since it wouldn't have to actually fetch the time, but simply add the offset to the last time fetched which is much faster.

It doesn't really make anything any faster, it simply shifts where the overhead of doing the time fetch is done.

--- bill