that read and save reading on it's ram on a global variable of char, i'm at a point wher i have donee the code for reading the data in another sketch that is ready and work, now i've done a pc "test machine" where i've made a similar version that with modifications it will be th final one; I'm at a point where in the loop() i ask to give a number between 1 and 4 with a switch and there is the problem that the switch works only with the 1 case, when i give the others it will not follow the case and i've tried to put only Serial.println in the case 2,3,4 and it print the message in them but nothing to do with the previous.
I've used MemoryUsage library to get the global space reading to know how much space i'm occuping
Here is the code:
#include <MemoryUsage.h>
char *sReadings[820]; //global char array for storing readings value
word cRPointer = 0; //global pointer for number of readings inserted
void setup() {
Serial.begin(9600);
while (!Serial) {}
}
void loop() {
Serial.println(F("Starting state of the memory:"));
Serial.println();
FREERAM_PRINT;
Serial.println("Please type a number to choose and press 'Enter'");
Serial.println("Select 1 for inserting new data");
Serial.println("Select 2 for retrieving a particular data");
Serial.println("Select 3 for retrieving all data");
Serial.println("Select 4 for flushing all data");
while (!Serial.available()) {
Serial.print('.');
delay(500);
}
int value = Serial.parseInt();
if (value == 0) {
Serial.println("Choice NOT Valid");
return;
}
Serial.println("Ok");
Serial.println(value);
switch (value) {
case 1:
//data entry
Serial.println("Requested inserting new data");
long time = getLong();
float volt = getFloat();
if ((time == 0) || (volt == 0.00)) {
Serial.println("Data Not Valid");
break;
}
//data elaboration
char *cReading = elaborateData(time, volt);
//data storing
if (!(saveData(cReading))) {
Serial.println("Value not entered correctly");
break;
}
break;
case 2:
Serial.println("Requested Reading a particular data");
Serial.println("Please insert a index to retrieve the data");
while (!Serial.available()) {
Serial.print('.');
delay(500);
}
int i = Serial.parseInt();
Serial.println("Ok");
Serial.println(i);
getOneData(i);
break;
case 3:
Serial.println("Requested Reading all data");
getAllData();
break;
case 4:
Serial.println("Requested flushing all data");
flushData();
break;
default:
Serial.println("Unrecognized choice");
break;
}
Serial.println();
Serial.println(F("Ending state of the memory:"));
Serial.println();
FREERAM_PRINT;
}
long getLong() {
//long for the millis
Serial.print("Insert a long ");
while (!Serial.available()) {
Serial.print('.');
delay(500);
}
long time = Serial.parseInt();
Serial.print(time);
Serial.println();
return time;
}
float getFloat() {
//float for the voltage in volt
Serial.print("Insert a float ");
while (!Serial.available()) {
Serial.print('.');
delay(500);
}
float volt = Serial.parseFloat();
Serial.print(volt);
Serial.println();
return volt;
}
char *elaborateData(long time, float volt) {
char *reading; //local char array
char ltime[8];
ltoa(time, ltime, 10);
Serial.print("long value ");
Serial.println(ltime);
char lvolt[9];
dtostrf(volt, 0, 3, lvolt);
Serial.print("float value ");
Serial.println(lvolt);
Serial.print("first cReading value: ");
reading = ltime; //First part of the reading
Serial.println(reading);
strcat(reading, "-"); //Reading part separator
strcat(reading, lvolt); //Second part of the reading
Serial.print("final cReading value: ");
Serial.println(reading);
// example of reading value 86400000-50.000
return reading; //return final value
}
bool saveData(char *reading) {
if (cRPointer < 820) {
sReadings[cRPointer] = reading;
cRPointer++;
return true;
}
return false;
}
void getOneData(word i) {
//searching the particular data with all its informations
for (int j = 0; j < 15; j++) {
Serial.print(sReadings[i][j]);
}
}
void getAllData() {
//reading all data from the ram
Serial.println("Full reading started");
int i;
Serial.println("Starting Reading data");
for (i = 0; i < cRPointer; i++) {
for (int j = 0; j < 15; j++) {
Serial.print(sReadings[i][j]);
}
Serial.println();
}
Serial.println("Ending Reading data");
Serial.print("Total entries: ");
Serial.println(i);
}
void flushData() {
//deleting all data on ram
for (int i = 0; i < cRPointer; i++) {
sReadings[i] = ((char *)"NULL");
}
}
and here is the serial monitor result
23:56:44.609 -> Starting state of the memory:
23:56:44.609 ->
23:56:44.640 -> Free Ram Size: 1435
23:56:44.640 -> Please type a number to choose and press 'Enter'
23:56:44.709 -> Select 1 for inserting new data
23:56:44.742 -> Select 2 for retrieving a particular data
23:56:44.776 -> Select 3 for retrieving all data
23:56:44.813 -> Select 4 for flushing all data
23:56:44.813 -> ..............Ok
23:56:52.798 -> 1
23:56:52.798 -> Requested inserting new data
23:56:52.798 -> Insert a long ......100
23:56:56.787 -> Insert a float ..12.00
23:56:58.791 -> long value 100
23:56:58.791 -> float value 12.000
23:56:58.830 -> first cReading value: 100
23:56:58.863 -> final cReading value: 100-12.000
23:56:58.896 ->
23:56:58.896 -> Ending state of the memory:
23:56:58.929 ->
23:56:58.929 -> Free Ram Size: 1435
23:56:58.929 -> Starting state of the memory:
23:56:58.962 ->
23:56:58.962 -> Free Ram Size: 1435
23:56:58.996 -> Please type a number to choose and press 'Enter'
23:56:59.062 -> Select 1 for inserting new data
23:56:59.096 -> Select 2 for retrieving a particular data
23:56:59.129 -> Select 3 for retrieving all data
23:56:59.163 -> Select 4 for flushing all data
23:56:59.163 -> ......Ok
23:57:03.143 -> 2
23:57:03.143 ->
23:57:03.143 -> Ending state of the memory:
23:57:03.182 ->
23:57:03.182 -> Free Ram Size: 1435
23:57:03.182 -> Starting state of the memory:
23:57:03.215 ->
23:57:03.215 -> Free Ram Size: 1435
23:57:03.249 -> Please type a number to choose and press 'Enter'
23:57:03.315 -> Select 1 for inserting new data
23:57:03.348 -> Select 2 for retrieving a particular data
23:57:03.381 -> Select 3 for retrieving all data
23:57:03.420 -> Select 4 for flushing all data
23:57:03.420 -> ...Ok
23:57:05.899 -> 3
23:57:05.899 ->
23:57:05.899 -> Ending state of the memory:
23:57:05.932 ->
23:57:05.932 -> Free Ram Size: 1435
23:57:05.932 -> Starting state of the memory:
23:57:05.967 ->
23:57:05.967 -> Free Ram Size: 1435
23:57:05.999 -> Please type a number to choose and press 'Enter'
23:57:06.066 -> Select 1 for inserting new data
23:57:06.099 -> Select 2 for retrieving a particular data
23:57:06.132 -> Select 3 for retrieving all data
23:57:06.170 -> Select 4 for flushing all data
23:57:06.170 -> ..Ok
23:57:08.152 -> 4
23:57:08.152 ->
23:57:08.152 -> Ending state of the memory:
23:57:08.185 ->
23:57:08.185 -> Free Ram Size: 1435
23:57:08.185 -> Starting state of the memory:
23:57:08.219 ->
23:57:08.219 -> Free Ram Size: 1435
23:57:08.252 -> Please type a number to choose and press 'Enter'
23:57:08.318 -> Select 1 for inserting new data
23:57:08.351 -> Select 2 for retrieving a particular data
23:57:08.385 -> Select 3 for retrieving all data
23:57:08.428 -> Select 4 for flushing all data
23:57:08.428 -> ..Ok
23:57:10.386 -> 5
23:57:10.386 ->
23:57:10.386 -> Ending state of the memory:
23:57:10.433 ->
23:57:10.433 -> Free Ram Size: 1435
23:57:10.433 -> Starting state of the memory:
23:57:10.470 ->
23:57:10.470 -> Free Ram Size: 1435
23:57:10.503 -> Please type a number to choose and press 'Enter'
23:57:10.572 -> Select 1 for inserting new data
23:57:10.603 -> Select 2 for retrieving a particular data
23:57:10.636 -> Select 3 for retrieving all data
23:57:10.679 -> Select 4 for flushing all data
Thanks for the idea but i need to store the time in milliseconds when the reading is taken and the reading itself, so i need a long and a float, in a int there is no space for all that, but that is not my problem, my need is to know why i can't enter in the other cases out of the 1 in the switch onto the loop().
The analog voltage readings are integers. There is no need to convert to float, and it would be a waste of RAM memory to do so (4 bytes for a float, 2 bytes for an int).
Here is how to store the time
int readings[100]={0};
unsigned long times[100]={0};
for (int i=0; i<100; i++) {
times[i]=millis();
readings[i]=analogRead(A0);
}
for (int i=0; i<100; i++) {
Serial.print(times[i]);
Serial.print(", ");
Serial.println(readings[i]);
}
case 1:
//data entry
Serial.println("Requested inserting new data");
long time = getLong();
float volt = getFloat();
if ((time == 0) || (volt == 0.00)) {
Serial.println("Data Not Valid");
break;
}
//data elaboration
char *cReading = elaborateData(time, volt);
//data storing
if (!(saveData(cReading))) {
Serial.println("Value not entered correctly");
break;
}
break;
You need to enclose the entire case within brackets braces, otherwise you are not allowed to declare a variable with an initializer inside a case. The scope of the variable is from the point of declaration till the end of the switch statement, and the compiler sees each subsequent case as having an uninitialized variable and will never allow you to reach those cases.
You will have more ram to work with if you use the F() macro for all the printed text literals.
A function should not return a pointer to a local char array, that array no longer exists after the function ends, and can be overwritten at any time.
Storing the data as characters is extremely wasteful of memory, an array of struct would be my preference.
char *elaborateData(long time, float volt) {
char *reading; //local char array
char ltime[8];
ltoa(time, ltime, 10);
Serial.print("long value ");
Serial.println(ltime);
char lvolt[9];
dtostrf(volt, 0, 3, lvolt);
Serial.print("float value ");
Serial.println(lvolt);
Serial.print(F("first cReading value: "));
reading = ltime; //First part of the reading
Serial.println(reading);
strcat(reading, "-"); //Reading part separator
strcat(reading, lvolt); //Second part of the reading
Serial.print(F("final cReading value: "));
Serial.println(reading);
// example of reading value 86400000-50.000
return reading; //return final value
}
You are going to have serious problems with storing a potential reading of "86400000-50.000" in a char array that can hold only seven characters plus the terminating null. The pointer will points to memory that you have not allocated.
It takes six bytes to store a time in milliseconds and an analog voltage reading as binary data, in contrast to the 16 bytes required by this character array: "86400000-50.000".
Having looked over the code while trying to actually get it to compile, the whole concept you are using is wrong. Just the array of 820 character pointers is going to take 1640 bytes, where do you expect to store the actual data being pointed to? All of your pointers are meaningless anyway, because they point to local data from a function. Even it you made the array in the function static, the pointers would all point to the exact same location, which would only contain the last data stored there.
Ok, i need to change the core storage for the data, the type and how it's stored, if you can tell me more about this i will apreciate it, so an array of struct will be better? ;
and even if i need to change that the changes i've done with the F in print is getting me something different now
#include <MemoryUsage.h>
char *sReadings[820]; //global char array for storing readings value
word cRPointer = 0; //global pointer for number of readings inserted
void setup() {
Serial.begin(9600);
while (!Serial) {}
}
void loop() {
Serial.println(F("Starting state of the memory:"));
Serial.println();
FREERAM_PRINT;
Serial.println(F("Please type a number to choose and press 'Enter'"));
Serial.println(F("Select 1 for inserting new data"));
Serial.println(F("Select 2 for retrieving a particular data"));
Serial.println(F("Select 3 for retrieving all data"));
Serial.println(F("Select 4 for flushing all data"));
while (!Serial.available()) {
Serial.print('.');
delay(500);
}
int value = Serial.parseInt();
if (value == 0) {
Serial.println(F("Choice NOT Valid"));
return;
}
Serial.println(F("Ok"));
Serial.println(value);
switch (value) {
case 1:
//data entry
{
Serial.println(F("Requested inserting new data"));
long time = getLong();
float volt = getFloat();
if ((time == 0) || (volt == 0.00)) {
Serial.println(F("Data Not Valid"));
break;
}
//data elaboration
char *cReading = elaborateData(time, volt);
//data storing
if (!(saveData(cReading))) {
Serial.println(F("Value not entered correctly"));
break;
}
}
break;
case 2:
{
Serial.println(F("Requested Reading a particular data"));
Serial.println(F("Please insert a index to retrieve the data"));
while (!Serial.available()) {
Serial.print('.');
delay(500);
}
int i = Serial.parseInt();
Serial.println(F("Ok"));
Serial.println(i);
getOneData(i);
}
break;
case 3:
{Serial.println(F("Requested Reading all data"));
getAllData();}
break;
case 4:
{Serial.println(F("Requested flushing all data"));
flushData();}
break;
default:
{Serial.println(F("Unrecognized choice"));}
break;
}
Serial.println();
Serial.println(F("Ending state of the memory:"));
Serial.println();
FREERAM_PRINT;
}
long getLong() {
//long for the millis
Serial.print(F("Insert a long "));
while (!Serial.available()) {}
long time = Serial.parseInt();
Serial.print(time);
Serial.println();
return time;
}
float getFloat() {
//float for the voltage in volt
Serial.print(F("Insert a float "));
while (!Serial.available()) {}
float volt = Serial.parseFloat();
Serial.print(volt);
Serial.println();
return volt;
}
char *elaborateData(long time, float volt) {
char *reading; //local char array
char ltime[8];
ltoa(time, ltime, 10);
Serial.print(F("long value "));
Serial.println(ltime);
char lvolt[9];
dtostrf(volt, 0, 3, lvolt);
Serial.print(F("float value "));
Serial.println(lvolt);
Serial.print(F("first cReading value: "));
reading = ltime; //First part of the reading
Serial.println(reading);
strcat(reading, "-"); //Reading part separator
strcat(reading, lvolt); //Second part of the reading
Serial.print(F("final cReading value: "));
Serial.println(reading);
// example of reading value 86400000-50.000
return reading; //return final value
}
bool saveData(char *reading) {
if (cRPointer < 820) {
sReadings[cRPointer] = reading;
cRPointer++;
return true;
}
return false;
}
void getOneData(word i) {
//searching the particular data with all its informations
for (int j = 0; j < 15; j++) {
Serial.print(sReadings[i][j]);
}
}
void getAllData() {
//reading all data from the ram
Serial.println(F("Full reading started"));
int i;
Serial.println(F("Starting Reading data"));
for (i = 0; i < cRPointer; i++) {
for (int j = 0; j < 15; j++) {
Serial.print(sReadings[i][j]);
}
Serial.println();
}
Serial.println(F("Ending Reading data"));
Serial.print(F("Total entries: "));
Serial.println(i);
}
void flushData() {
//deleting all data on ram
for (int i = 0; i < cRPointer; i++) {
sReadings[i] = ((char *)"NULL");
}
}
``` 01:19:23.715 -> Free Ram Size: 169 01:19:23.748 -> Starting state of the memory:
**01:19:23.780 -> ** 01:19:23.780 -> Free Ram Size: 169 01:19:23.814 -> Please type a number to choose and press 'Enter' 01:19:23.849 -> Select 1 for inserting new data 01:19:23.882 -> Select 2 for retrieving a particular data 01:19:23.914 -> Select 3 for retrieving all data 01:19:23.984 -> Select 4 for flushing all data 01:19:24.948 -> Choice NOT Valid 01:19:24.948 -> Starting state of the memory:
**01:19:24.981 -> ** 01:19:24.981 -> Free Ram Size: 169 01:19:25.014 -> Please type a number to choose and press 'Enter' 01:19:25.047 -> Select 1 for inserting new data 01:19:25.079 -> Select 2 for retrieving a particular data 01:19:25.147 -> Select 3 for retrieving all data 01:19:25.187 -> Select 4 for flushing all data 01:19:25.187 -> ................Ok 01:19:33.168 -> 4 01:19:33.168 -> Requested flushing all data
**01:19:33.200 -> ** 01:19:33.200 -> Ending state of the memory:
**01:19:33.234 -> ** 01:19:33.234 -> Free Ram Size: 169 01:19:33.234 -> Starting state of the memory:
**01:19:33.267 -> ** 01:19:33.267 -> Free Ram Size: 169 01:19:33.300 -> Please type a number to choose and press 'Enter' 01:19:33.367 -> Select 1 for inserting new data 01:19:33.400 -> Select 2 for retrieving a particular data 01:19:33.431 -> Select 3 for retrieving all data 01:19:33.478 -> Select 4 for flushing all data 01:19:34.423 -> Choice NOT Valid 01:19:34.423 -> Starting state of the memory:
**01:19:34.467 -> ** 01:19:34.467 -> Free Ram Size: 169 01:19:34.500 -> Please type a number to choose and press 'Enter' 01:19:34.546 -> Select 1 for inserting new data 01:19:34.579 -> Select 2 for retrieving a particular data 01:19:34.646 -> Select 3 for retrieving all data 01:19:34.686 -> Select 4 for flushing all data 01:19:34.686 -> ..Ok 01:19:35.621 -> 5 01:19:35.621 -> Unrecognized choice
**01:19:35.621 -> ** 01:19:35.621 -> Ending state of the memory:
**01:19:35.686 -> ** 01:19:35.686 -> Free Ram Size: 169 01:19:35.719 -> Starting state of the memory:
**01:19:35.752 -> ** 01:19:35.752 -> Free Ram Size: 169 01:19:35.786 -> Please type a number to choose and press 'Enter' 01:19:35.819 -> Select 1 for inserting new data 01:19:35.852 -> Select 2 for retrieving a particular data 01:19:35.919 -> Select 3 for retrieving all data 01:19:35.963 -> Select 4 for flushing all data 01:19:36.909 -> Choice NOT Valid 01:19:36.909 -> Starting state of the memory:
**01:19:36.954 -> ** 01:19:36.954 -> Free Ram Size: 169 01:19:36.989 -> Please type a number to choose and press 'Enter' 01:19:37.022 -> Select 1 for inserting new data 01:19:37.055 -> Select 2 for retrieving a particular data 01:19:37.121 -> Select 3 for retrieving all data 01:19:37.153 -> Select 4 for flushing all data 01:19:37.153 -> ............................................................
How many readings do you need to store? Even at six bytes per reading (four for time, two for voltage), storing 250 readings is starting to get risky on an UNO.
i have to monitor voltage to for 12h or 24h, and i wanted to sav only the mayor spikes of voltage i don't need to get 250 readings of the same 12 volts (for example), i need to see if the voltage through a day or half a day goes from 12 to 15 or lower, so I have to store only when there is a difference between the normal voltage (that i will set) and the read voltage, that's why i've don the "flushData" so when i will check on that i can save the data caught on a txt file and i will have new space available (also i need to rework also the function to this in the new format and now it will put only "null" in the array to just mak sure it modify it, it's only an example).
i've modified the way of storage, i'm not sure on the flush data but on the others i think is better than before
#include <MemoryUsage.h>
data sAReadings[220]; //global char array for storing readings value
word cRPointer = 0; //global pointer for number of readings inserted
struct data //struct to define the data layout
{
long time; //time
float volt; //volt
};
void setup() {
Serial.begin(9600);
while (!Serial) {}
}
void loop() {
Serial.println(F("Starting state of the memory:"));
FREERAM_PRINT;
Serial.println(F("Please type a number to choose and press 'Enter'"));
Serial.println(F("Select 1 for inserting new data"));
Serial.println(F("Select 2 for retrieving a particular data"));
Serial.println(F("Select 3 for retrieving all data"));
Serial.println(F("Select 4 for flushing all data"));
while (!Serial.available()) {
Serial.print(F("."));
delay(500);
}
int value = Serial.parseInt();
if (value == 0) {
Serial.println(F("Choice NOT Valid"));
return;
}
Serial.println(F("Ok"));
Serial.println(value);
switch (value) {
case 1:
//data entry
{
Serial.println(F("Requested inserting new data"));
long time = getLong();
float volt = getFloat();
if ((time == 0) || (volt == 0.00)) {
Serial.println(F("Data Not Valid"));
break;
}
//data elaboration
data cReading = elaborateData(time, volt);
//data storing
if (!(saveData(cReading))) {
Serial.println(F("Value not entered correctly"));
break;
}
}
break;
case 2:
{
Serial.println(F("Requested Reading a particular data"));
Serial.println(F("Please insert a index to retrieve the data"));
while (!Serial.available()) {
Serial.print(F("."));
delay(500);
}
int i = Serial.parseInt();
Serial.println(F("Ok"));
Serial.println(i);
getOneData(i);
}
break;
case 3:
{
Serial.println(F("Requested Reading all data"));
getAllData();
}
break;
case 4:
{
Serial.println(F("Requested flushing all data"));
flushData();
}
break;
default:
{
Serial.println(F("Unrecognized choice"));
}
break;
}
Serial.println(F("Ending state of the memory:"));
FREERAM_PRINT;
}
long getLong() {
//long for the millis
Serial.print(F("Insert a long "));
while (!Serial.available()) {}
long time = Serial.parseInt();
Serial.print(time);
Serial.println();
return time;
}
float getFloat() {
//float for the voltage in volt
Serial.print(F("Insert a float "));
while (!Serial.available()) {}
float volt = Serial.parseFloat();
Serial.print(volt);
Serial.println();
return volt;
}
data elaborateData(long time, float volt) {
data reading = { time, volt };
// example of reading value 86400000-50.000
return reading; //return final value
}
bool saveData(data reading) {
if (cRPointer < 820) {
sAReadings[cRPointer] = reading;
cRPointer++;
return true;
}
return false;
}
void getOneData(word i) {
//searching the particular data with all its informations
Serial.print(sAReadings[i].time);
Serial.print(F("-"));
Serial.println(sAReadings[i].volt);
}
void getAllData() {
//reading all data from the ram
Serial.println(F("Full reading started"));
int i;
Serial.println(F("Starting Reading data"));
for (i = 0; i < cRPointer; i++) {
Serial.print(sAReadings[i].time);
Serial.print(F("-"));
Serial.print(sAReadings[i].volt);
Serial.println();
}
Serial.println(F("Ending Reading data"));
Serial.print(F("Total entries: "));
Serial.println(i);
}
void flushData() {
//deleting all data on ram
sAReadings[220] = {};
}