Closed Joaomarques1994 closed 4 years ago
try to move the line
JsonArray array =doc.to<JsonArray>();
inside the loop() {}
You are adding values to the array in the loop, and each iteration tries to add new set of values, but the old ones aren't being removed. Given that you created the document only for 4 array entries, it adds values only on the first iteration of the loop() and then just runs out of memory. So you need to clear your document before adding new set of values. doc.to<JsonArray>();
should do that for you.
Hi dyarkovoy,
Thank you for your contribution. Now my array add new data. However, I am unable to associate my variables (data1, data2, data3, data4) with the entries of the array. I need to associate this to send data to a database
Hi, @Joaomarques1994, deserializeJson() returns status, check what it is. Your input may not be parseable.
Thank you once more dyarkovoy. However, I don't think that would be the case since in the serial monitor I manage to see the deserialized data as shown below. The zeros only appear when I try to associate the different data to my data variables (data1, data2, data3, data4). The zeros only appear when I "serial.print" those variables.
64.10,26.00,409,425 [26,64.1,409,425]26.00 64.10 409.00 425.00 0 0 0 0
My issue is to write the following part of the code in a way that I could associate the entries of the array with my variables (data1, data2, data 3, data4)
JsonArray json_list =doc.as
Are you writing to and reading from the same document? In your code, there are 2 doc
variables defined, one is global and one is inside the loop(){}
, which seems confusing. If you intend to use 2 different documents, maybe name them differently and define in the same place? Then, you retrieve JsonArray json_list
from the inner doc
, but when printing your data you iterate over array
, which belongs to the outer doc
. I'm not exactly sure if this is your intention, but seems confusing to me. Maybe clean up your code a little.
Thank you once more. My intention is to create a single doc and past the different array entries to my variables
Then you shoud create a single doc. Right now you create 2 different ones.
Hi again. Thank you once again for helping me with my problem. However, I was not able to correct my issue. I will put my code here and the serial monitor response to show that my problem is not fixed yet. I apologize in advance if the problem occurred due to my stupidity.
Code
//Constants
DHT dht (DHTPIN, DHTTYPE); int sensorValue_1, sensorValue_2; int data1, data2, data3, data4;
void setup() { // put your setup code here, to run once:
Serial.begin(9600); dht.begin(); pinMode(A1, INPUT); pinMode(A2,INPUT); }
//StaticJsonDocument<5000> doc;
// const size_t CAPACITY =JSON_ARRAY_SIZE(4);
// StaticJsonDocument
//JsonArray array =doc.to
void loop() { // put your main code here, to run repeatedly: float h = dht.readHumidity(); // Read temperature as Celsius (the default) float t = dht.readTemperature(); sensorValue_1= analogRead(A1); sensorValue_2=analogRead(A2); Serial.print(h); Serial.print(","); Serial.print(t); Serial.print(","); Serial.print(sensorValue_1); Serial.print(","); Serial.println(sensorValue_2);
const size_t CAPACITY =JSON_ARRAY_SIZE(4);
StaticJsonDocument<CAPACITY> doc;
JsonArray array =doc.to
serializeJson(doc, Serial);
// doc["temp"] = t; // doc["hum"] = h; // doc["acel1"]=sensorValue_1; // doc["acel2"]=sensorValue_2;
// if(Serial.available()>0) // { // serializeJson(doc, Serial); // } delay(3000); // 30 detik //StaticJsonDocument<5000> doc;
//deserializeJson(doc,Serial);
//const size_t CAPACITY =JSON_ARRAY_SIZE(4);
// StaticJsonDocument
} delay(1000);
data1= json_list[0]; data2= json_list[1]; data3= json_list[2]; data4= json_list[3];
//data1=doc["temp"]; //data2=doc["hum"]; //data3=doc["acel1"]; //data4=doc["acel2"]; // Serial.println(data1); Serial.println(data2); Serial.println(data3); Serial.println(data4);
delay(3000); }
Serial Monitor 63.20,25.80,405,421 [25.8,63.2,405,421]25.80 63.20 405.00 421.00 0 0 0 0
If I understand your logic correctly, you serialize JSON to Serial
port and then want to deserialize it by reading from the same Serial
port on the same device that wrote it? This isn't possible, Serial is not a buffer where you can send data and retrieve later. Serial is a means of communication between TWO enpoints. Endpoint A writes to serial port and Endpoint B receives it at the same moment. Endpoint B writes to serial port and Endpoint A receives it at the same moment.
But it is not possible that Endpoint A writes some data to Serial
, and some moments later Endpoint A reads what it wrote, it doesn't work that way.
To make your code work the way you want to, you need to connect Serial port on your Arduino (or whatever hardware you use), let's call it Endpoint A, not to the PC with the serial monitor, but to another Arduino ( let's call it Endpoint B). Now Endpoint A should do serializeJson(doc, Serial);
with intervals in the loop, and Endpoint B should check in the loop if there's data available on the Serial ( if(Serial.available()>0) ...
) and if it is, call deserializeJson(doc, Serial);
.
This is only a rough draft, not the exact recipe, because there are other pitfalls. For example, Endpoint B needs to understand where is the start if the data, because you may turn it on at the moment when Endpoint A is in the middle of writing, so what should Endpoint B do? It should somehow understand that what it just read is only a part of the packet, and the other part was lost because it started reading few moments after Endpoint A started writing, so it should discard this partial packet and wait for the new one. Usually this problem is solved by writing some special character or sequence of characters that would indicate the start of the packet, and ending the packet with another special character(s).
There are other things to consider. If you want to go this way, read about Point-To-Point protocol (PPP), it is designed for these kind of tasks.
Thank you so much for the explanation. Firstly I would like to apologize since my main goal is to have two endpoints (one is an arduino Mega and the other one is an esp 8266) (it is an arduino mega wifi). I tested the two endpoints but only zeros appeared in my database. With this in mind, I only tested in the same endpoint because I did not want to fill my database with nonsense data (only zeros). So I thought that I could test the serialize concept on one endpoint. However, with your explanation, I know now that it is not possible. I will try to use both at the same time. Sorry once if I made you waste time with me regarding this question. Once more thank you for the explanation and patience that you had. If I manage to do it right, I will let you know.
One quick question, if I only put deserialize (doc, Serial) in the other code it will give me the error that doc was not declared in the scope. I would like to ask how can I declare doc without creating a different doc. Thank you in advance
You should read about scope rules in C, and also about declaring and defining variables. The simple answer is that you need to do StaticJsonDocument<5000> doc;
only once, and not many times. If your code complains that doc was not declared, and you already have that line in your code, it may be misplaced.
Hi, once more thank you for answering my question. I understand that I only can write StaticJsonDocument<5000> doc;. However, in the other endpoint I need to declare doc again. Do you know should declare doc? thanks in advance
To be honest, I don't understand your question.
You just write StaticJsonDocument<5000> doc;
in the software for Endpoint A.
Then, you write StaticJsonDocument<5000> doc;
in the software for Endpoint B.
And now you have doc
declared and defined both in your software for for Endpoint A and in your software for Endpoint B.
Are you worried about double definition? There is none, because you have 2 separate endpoints and 2 separate softwares. So you declare one doc in the software for Endpoint A and one doc in the software for Endpoint B.
When I said before that you should use a single definition, it means single definition per scope, not single definition per all the software you ever write.
Thank you again and so sorry for my stupidity. I will try and let you know. Once again thank you
Hi once again Firstly I would like to apologize for taking so time to solve my problem. I tried to perform as you said but only manage to receive 0 at my database. I am using an arduino mega wifi. I have to different codes one for the mega and other for the esp8266 I will put here both codes. The communication to my database is working since I put some random values in my esp 8266 and they appeared at my database. Thank you in adavance
Mega
//Constants
DHT dht (DHTPIN, DHTTYPE); int sensorValue_1, sensorValue_2; int data1, data2, data3, data4;
void setup() { // put your setup code here, to run once:
Serial.begin(9600); dht.begin(); pinMode(A1, INPUT); pinMode(A2,INPUT); }
void loop() { // put your main code here, to run repeatedly: float h = dht.readHumidity(); // Read temperature as Celsius (the default) float t = dht.readTemperature(); sensorValue_1= analogRead(A1); sensorValue_2=analogRead(A2); Serial.print(h); Serial.print(","); Serial.print(t); Serial.print(","); Serial.print(sensorValue_1); Serial.print(","); Serial.println(sensorValue_2);
const size_t CAPACITY =JSON_ARRAY_SIZE(4);
StaticJsonDocument<CAPACITY> doc;
doc["temp"] = t; doc["hum"] = h; doc["acel1"]=sensorValue_1; doc["acel2"]=sensorValue_2;
serializeJson(doc, Serial);
delay(3000); // 30 detik }
Esp 8266
// DECLARAÇÃO DE VARIÁVEIS PARA WIFI const char ssid = ; // name of your wifi network!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! const char password = ; // wifi pasword
// DECLARAÇÃO DE VARIÁVEIS PARA MySQL IPAddress server_addr(); // IP of the MySQL server here char user = ; // MySQL user login username char password_sql = ; // MySQL user login password
char INSERT_SQL[] = ; char query[128]; WiFiClient client; MySQL_Connection conn((Client *)&client);
// DECLARAÇÃO DE FUNÇÕES //void conectaWifi(); //void enviaDados();
int data1, data2, data3, data4; void setup() { // put your setup code here, to run once: Serial.begin(9600); conectaWifi();
while (!conn.connect(server_addr, 3306, user, password_sql)) { Serial.println("Conexão SQL falhou."); conn.close(); delay(1000); Serial.println("Conectando SQL novamente.");
if (conn.connect(server_addr, 3306, user, password_sql)){ Serial.println("Conectado ao servidor SQL."); } } } void loop() { // put your main code here, to run repeatedly:
const size_t CAPACITY =JSON_ARRAY_SIZE(4);
StaticJsonDocument
data1=doc["temp"]; data2=doc["hum"]; data3=doc["acel1"]; data4=doc["acel2"];
//
//data1=30; //data2=50; //data3=400; //data4=400; Serial.println(data1); Serial.println(data2); Serial.println(data3); Serial.println(data4);
enviaDados(); }
void conectaWifi(){ WiFi.mode(WIFI_STA); WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) { delay(500); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } void enviaDados(){ sprintf(query, INSERT_SQL, data1, data2, data3, data4); // Initiate the query class instance MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn); // Execute the query cur_mem->execute(query); // Note: since there are no results, we do not need to read any data // Deleting the cursor also frees up memory used delete cur_mem; Serial.println("Informações Enviadas"); delay(3000); }
Serial.print(h);
Serial.print(",");
Serial.print(t);
Serial.print(",");
Serial.print(sensorValue_1);
Serial.print(",");
Serial.println(sensorValue_2);
[1,2,3,4]
, or an object, i.e {"temp":1,"hum":2,"acel1":3,"acel2":4}
. In the former case, you should compute capacity of the document as const size_t CAPACITY = JSON_ARRAY_SIZE(4);
, in the latter case you should compute capacity of the document as const size_t CAPACITY = JSON_OBJECT_SIZE(4);
. deserializeJson(doc, Serial);
, you should define a String input
and read one character from Serial in the loop until you hit the starting character of your data packet, either '[' or '{'. Once you get that starting character, you continue reading in the loop character-by-character and append them to the input
until you hit ending character (either ']' or '}'). Once that happens, you are ready to call deserializeJson(doc, input);
and now you should have valid data in your doc. Another approach would be to serialize to string on the sending endpoint and use Serial.println(serialized string)
, then on the receiving endpoint do Serial.readStringUntil('\n')
and then deserialize your document from the string. Both approaches suffer from deficiencies, but they have an advantage of being simple. If you want ultimate and reliable solution to transfer packets between endpoints via serial interface, you should look into Point-To-Point protocol (PPP)Finally, this discussion is moving further and further away from ArduinoJson and into the very basics of C. You may want to find forum/thread for general C questions and ask your questions there.
Finally, this discussion is moving further and further away from ArduinoJson and into the very basics of C. You may want to find forum/thread for general C questions and ask your questions there.
Agreed! This is not the right place for this type of discussion. @dyarkovoy was kind enough to answers all your lengthy questions for the last ten days. Please stop abusing his (her) generosity.
@Joaomarques1994, I don't think you realize how much time it takes to write detailed answers as he (she) did. Maybe if you spent more time working on your questions, you'd find the answer yourself, or at least, give all the information to the people who are trying to help you.
Hi, Firstly I would like to thank bblanchon for the work that he is done regarding ArduinoJson Secondly, I am having issues retrieving the data from the JsonArray. With my current code (shown below) I can see in the Serial Monitor however I cannot associate each array entry to a specific variable. Bare in mind that I serialize and deserialize in the same code only to test those concepts since the main goal is to promote the communication between an esp 8266 and an arduino mega.
Thank you in advance for your time
Code: