Context:
A small ATTINY1607 based project with an RTC, which can receive, over serial, the time data and set the time to RTC.
The uC wakes up on a button press and shows the set time and then goes to sleep. While awake it can receive the above mentioned serial data.
Additionally, I'm trying to send another value with the current time data (details below), which will determine, in next cycle for how long the uC should be awake for.
The serial data is coming from a webpage (using web-serial)
Problem explanation:
Note: before moving forward, I would like to state that, I will focus on parts of code base without overwhelming anyone. If any more parts from the code base is required, please state, I will try to be provide, if it exists.
The data sent from the js side is in this structure:
HH:MM:SS:WEEKDAY:DD:MM:YYYY:STAY_AWAKE_TIME.
For e.g: 02:18:19:6:25:06:2021:5
Main part on JS Side (using web-serial):
syncbtn.addEventListener("click", () => {
// -- Get the time
const now = new Date;
// Here the vaklue of "Delay" stands for how long the uC should be stay awake for.
// To set it dynamically, it is added to end of the rest of serial data set.
// ** Delay value comes from a HTML select object
var delay_selection = document.getElementById("delays");
var delay_in_ms = Number(delay_selection.value);
serialData = now.getHours()+":"+
now.getMinutes()+":"+
now.getSeconds()+":"+
now.getDay()+":"+
now.getDate()+":"+
now.getMonth()+":"+
now.getFullYear()+":"+
delay_in_ms;
// -- write the Serial Data
if(port !=null){
writeToStream(serialData);
}else{
console.log("Not writing to Serial Port as it wasn't created/selected!");
}
});
function writeToStream(...lines) {
const writer = outputStream.getWriter();
lines.forEach(line => {
console.log("[SEND]", line);
writer.write(line + "\n");
});
writer.releaseLock();
}
Now in the Parser side of the uC, it looks for a '\n' as the end of data stream and up until then it stores everything in a char array. Once end of stream is reached, it starts parsing the char array data structure with the help of the delimators and assigns the respectiove values to the variables to be used further (for example: setting time and uC's wakeup period).
Main part on Arduino Side:
void parseDataArray() {
if (newDataArrived) {
newDataArrived = false;
totalDelimators = 0;
// Count how many delimators (in our case that is ':' of byte value 10) are there
for (int i = 0; i < int(sizeof(dataArray)); i++) {
if (dataArray[i] == ':') {
totalDelimators++;
}
}
// Datastructure:
// 02:18:19:6:25:06:2021 (totalDelimators == 6)
// 02:18:19:6:25:06:2021:5 (totalDelimators == 7)
// Check received data's format & integrity
if (totalDelimators >= 6) { // or 6/7 based on the stream ends with year value or with additional delay value
char * strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(dataArray, ":"); // get the first part - the string
hrToBeSet = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ":"); // this continues where the previous call left off
minToBeSet = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ":");
secToBeSet = atoi(strtokIndx);
strtokIndx = strtok(NULL, ":");
weekdayToBeSet = atoi(strtokIndx);
strtokIndx = strtok(NULL, ":");
dateToBeSet = atoi(strtokIndx);
strtokIndx = strtok(NULL, ":");
monthToBeSet = atoi(strtokIndx);
strtokIndx = strtok(NULL, ":");
yearToBeSet = atoi(strtokIndx);
// [TBD / WIP bc not converting to int properly ]
strtokIndx = strtok(NULL, ":");
new_stayAwakeFor = (atoi(strtokIndx))*1000; // where x is in sec which needs to be converted in milli seconds.Hence *1000
setNewTime = true;
}
}
}
As you might have seen in the code part, I have highlighted, the last bit from the data structure (STAY_AWAKE_FOR) is creating the issue.
I'm not sure if it os JS side issue in the way it creates teh string or the uC's parsing method issue!
Things I have tried:
When in JS side, I remove the last bit of data and only send time data, i.e: when the data structure is HH:MM:SS:WEEKDAY:DD:MM:YYYY and on the Arduino side, I parse only upto the ...:YYYY part of the data structure, it works flawlessly.
JS side:
.
.
.
// serialData = now.getHours()+":"+
// now.getMinutes()+":"+
// now.getSeconds()+":"+
// now.getDay()+":"+
// now.getDate()+":"+
// now.getMonth()+":"+
// now.getFullYear()+":"+
// delay_in_ms;
serialData = now.getHours()+":"+
now.getMinutes()+":"+
now.getSeconds()+":"+
now.getDay()+":"+
now.getDate()+":"+
now.getMonth()+":"+
now.getFullYear();
.
.
.
uC side:
.
.
.
// Check received data's format & integrity
if (totalDelimators == 6) { // or 6/7 based on the stream ends with year value or with additional delay value
char * strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(dataArray, ":"); // get the first part - the string
hrToBeSet = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ":"); // this continues where the previous call left off
minToBeSet = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ":");
secToBeSet = atoi(strtokIndx);
strtokIndx = strtok(NULL, ":");
weekdayToBeSet = atoi(strtokIndx);
strtokIndx = strtok(NULL, ":");
dateToBeSet = atoi(strtokIndx);
strtokIndx = strtok(NULL, ":");
monthToBeSet = atoi(strtokIndx);
strtokIndx = strtok(NULL, ":");
yearToBeSet = atoi(strtokIndx);
setNewTime = true;
}
.
.
.
The parsing doesn't work when the last bit ( ...:STAY_AWAKE_TIME ) is added to the serial string!.
No idea what I'm doing wrong here!. Definitely missing something.
Any help would help :)
Thanks in Advance for guidance!