ESP8266- Buffer storage capacity from the UART - c

I have an issue while transferring the values of string from UART to buffer. I am using ESP8266 to receive strings on serial from STM32 device. I have total 600 string and i have CSV file that is being transmitted from the STM32 device. I have used proper filtering for every row on the NodeMCU side... I am having no clue why after 300 string the value transmitted to the buffer gets changed as well as the string read on UART also changes exactly after 300/305 string being transmitted. please let me know if there's any mistake in the code.
int i,j,k,l=0;
int httpCode=0;
String fields[24] = {"","month","year","hours","minutes","seconds","rimin","riavg","rimax","yimin","yiavg","yimax","bimin","biavg","bimax","nimin","niavg","nimax","eimin","eiavg","eimax","simin","siavg","simax"};
String element = "API_key=123&mac=0fa&day=";
String postApi1[300];
String postApi2[300];
String str= "";
String str_tx = "";
char char_array[128];
char* token;
char* rest = char_array;
WiFiClient client;
HTTPClient http;
void setup()
{
Serial.begin(230400);
s.begin(9600);
pinMode(13, INPUT);
pinMode(15, OUTPUT);
}
void loop()
{
if (s.available() >0)
{
for(j=0;j<300;j++)
{
i=0;
str = s.readStringUntil('\n');
Serial.println(str);
Serial.println("j");
postApi1[j]= str;
Serial.println(postApi1[j]);
str = "";
}
for(k=0;k<300;k++)
{
i=0;
str = s.readStringUntil('\n');
Serial.println(str);
Serial.println("k");
postApi2[k]= str;
Serial.println(postApi2[k]);
str = "";
}
}
}
Here is the code i am using and following is the Serial output of the code.

I think that the readStringUntil function waits for the terminator char. Is the '\n' sent also after 300th character? Also, try to avoid Serial.println in the read function, since the print function is quite slow, you might miss some characters. I would also avoid two for loops, instead, declare a variable, count number of received bytes and according to this save the "str" into "postApi1" or "postApi2".
Also, what is the purpose of "i" variable?

Hey #Andrej I tried your suggestion but it worked as follows
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <SoftwareSerial.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <stdio.h>
#include <string.h>
using namespace std;
ESP8266WiFiMulti WiFiMulti;
SoftwareSerial s(13,15); //RX TX
double buff[24]; //Initialized variable to store recieved data
double val;
char c;
int i,j,k,l=0;
int httpCode=0;
String fields[24] = {"","month","year","hours","minutes","seconds","rimin","riavg","rimax","yimin","yiavg","yimax","bimin","biavg","bimax","nimin","niavg","nimax","eimin","eiavg","eimax","simin","siavg","simax"};
String element = "API_key=123&mac=0fa&day=";
String postApi[616];
String str= "";
String str_tx = "";
char char_array[128];
char* token;
char* rest = char_array;
WiFiClient client;
HTTPClient http;
void setup()
{
Serial.begin(230400);
s.begin(9600);
pinMode(13, INPUT);
pinMode(15, OUTPUT);
//Serial.setDebugOutput(true);
//ESP.wdtDisable();
//Serial.begin(115200);
// Serial.setDebugOutput(true);
Serial.println();
Serial.println();
Serial.println();
for (uint8_t t = 4; t > 0; t--) {
Serial.printf("[SETUP] WAIT %d...\n", t);
Serial.flush();
delay(1000);
}
WiFi.mode(WIFI_STA);
WiFiMulti.addAP("ECLP", "p##$w0rD");
if ((WiFiMulti.run() == WL_CONNECTED))
{
Serial.print("WIFI connected");
}
}
void loop()
{
if (s.available() >0)
{
for(j=0;j<616;j++)
{
i++;
str = s.readStringUntil('\n');
//Serial.println(str);
//Serial.println(j);
postApi[j]= str;
//Serial.println(postApi[j]);
str = "";
}
}
if(i == 616)
{
i=0;
for(k=0;k<616;k++)
{
Serial.println(k);
Serial.print(" : ");
Serial.print(postApi[k]);
}
}
}
And receive on the output the following thing
Just for the ref i printed "k" value with output to know at which string the data loss occurs in buffer

Related

Array Data Reading Failed

I am reading the data from a "Torque Wrench" using "USB Host Shield2.0" and Arduino UNO. I am receiving correct data from my "Torque Wrench" Data is receiving in a array.
But when I started reading data after "for" loop inside Void loop() I am receiving incorrect data. I attached Both output pictures correct and incorrect data.
Basically I am read data from Torque Wrench and send to receiver using Nrf24l01. I am receiving incorrect data.
My question is :- Why I am reading Incorrect data outside "for" loop.
Correct Data inside "for" loop :- enter image description here
Incorrect Data outside "for" loop :- enter image description here
#include <SPI.h> // for SPI communication
#include <nRF24L01.h>
#include <RF24.h>
#include <cdcacm.h>
#include <usbhub.h>
//#include "pgmstrings.h"
// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.h>
RF24 radio(7, 8); // CE, CSN
const byte address[6] = {'R','x','A','A','A','B'}; // the address the the module
class ACMAsyncOper : public CDCAsyncOper
{
public:
uint8_t OnInit(ACM *pacm);
};
uint8_t ACMAsyncOper::OnInit(ACM *pacm)
{
uint8_t rcode;
// Set DTR = 1 RTS=1
rcode = pacm->SetControlLineState(3);
if (rcode)
{
ErrorMessage<uint8_t>(PSTR("SetControlLineState"), rcode);
return rcode;
}
LINE_CODING lc;
lc.dwDTERate = 9600;
lc.bCharFormat = 0;
lc.bParityType = 0;
lc.bDataBits = 8;
rcode = pacm->SetLineCoding(&lc);
if (rcode)
ErrorMessage<uint8_t>(PSTR("SetLineCoding"), rcode);
return rcode;
}
USB Usb;
//USBHub Hub(&Usb);
ACMAsyncOper AsyncOper;
ACM Acm(&Usb, &AsyncOper);
void setup() {
Serial.begin(9600);
radio.begin();
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_MAX);
radio.stopListening();
#if !defined(__MIPSEL__)
while (!Serial);
#endif
Serial.println("Start");
if (Usb.Init() == -1)
Serial.println("USB Not Connected");
delay( 200 );
}
void loop() {
Usb.Task();
if( Acm.isReady()) {
uint8_t rcode;
/* reading the keyboard */
if(Serial.available()) {
uint8_t data= Serial.read();
/* sending to the phone */
rcode = Acm.SndData(1, &data);
if (rcode)
ErrorMessage<uint8_t>(PSTR("SndData"), rcode);
}
delay(10);
uint8_t buf[64];
uint16_t rcvd = 64;
char text[64];
rcode = Acm.RcvData(&rcvd, buf);
if (rcode && rcode != hrNAK)
ErrorMessage<uint8_t>(PSTR("Ret"), rcode);
if ( rcvd ) {
for(uint16_t i=0; i < rcvd; i++ )
{
// Serial.print((char)buf[i]); // correct Data read from torque wrench
text[i] = (char)buf[i];
}
Serial.println(text); // reading wrong data here
//radio.write(&text, sizeof(text));
//Serial.println(text);
}
delay(10);
}
}
Character arrays must be null-terminated to count as C strings.
After the for loop, add text[rcvd] = '\0';
Also, your rcvd is fixed at 64. It needs to be one less than the array size for the null terminator to fit.

My string has hidden characters and is longer than what I can visually see?

Problem
I have a function which assigns data from reading a Bluetooth connection to a char array QualArray[4][30], although it appears that the length of each char array is 1 char greater than the number of characters that visually appear in the array, suggesting a hidden character?
Furthermore, I add these strings to another string called 'resource' using strcpy(), and the length of the string resource is 5 chars more than what it should be (so the 4 additional hidden characters from QualArray makes sense but there is apparently another hidden char added??) I have printed a "_" at the start and end of the string to see if there are any empty chars at either side but there aren't.
Somehow there are hidden chars in my strings but I don't know why, any help would greatly be appreciated!
Code
char resource[160] = "/macros/s/AKfycbzTAkuhTqJfi-EofdpOjBxKNlDe18fdTkOPHMOuOwvl9zbDqfPHwbb1/exec?"; //must be pre-defined buffer
char staticresource[160] = "/macros/s/AKfycbzTAkuhTqJfi-EofdpOjBxKNlDe18fdTkOPHMOuOwvl9zbDqfPHwbb1/exec?Cooker=RiceCooker&Meal=Rice&Portion=3&Method=Boil";
char QualArray[5][30]; // [Qparam][charnum]
char CookerQuery[20] = "&Cooker=";
char MealQuery[15] = "&Meal=";
char PortionQuery[15] = "&Portion=";
char MethodQuery[15] = "&Method=";
void CollectQualitativeData() {
int Qparam=0;
int charnum = 0;
while(Qparam < 4) { // While Qualitative data has not been collectedQualDataCollected = 0
if (SerialBT.available()) {
char incomingChar = SerialBT.read();
if (QualArray[Qparam] !="" && incomingChar == '\n') { // If the message isnt empty and the recieved char is nothing (ie if at end of word) if (message !=""
Serial.print(QualArray[Qparam]);
Serial.print("_");
Serial.print(" length = ");
Serial.println(strlen(QualArray[Qparam]));
Qparam++;
charnum = 0;
}
if (incomingChar != '\n'){ // If the incomingChar is different than \n, concatenate that char character to QualArray.
if (charnum <30) { // if greater than maximum specified array val then ignore
QualArray[Qparam][charnum] = incomingChar;
charnum++;
}
} else {
}
}
delay(20);
}
}
void setup() {
Serial.begin(115200);
SerialBT.begin("ESP32test"); //Bluetooth device name
//Serial.println("The device started, now you can pair it with bluetooth!");
CollectQualitativeData();
Serial.println("Complete");
Serial.println(QualArray[0]);
Serial.println(QualArray[1]);
Serial.println(QualArray[2]);
Serial.println(QualArray[3]);
Serial.println(QualArray[4]);
strcat(resource,CookerQuery); // resource + Resource_variables
strcat(resource,QualArray[0]);
strcat(resource,MealQuery); // resource + Resource_variables
strcat(resource,QualArray[1]);
strcat(resource,PortionQuery); // resource + Resource_variables
strcat(resource,QualArray[2]);
strcat(resource,MethodQuery); // resource + Resource_variables
strcat(resource,QualArray[3]);
Serial.print("resource=_");
Serial.print(resource);
Serial.println("_");
Serial.print("staticresource=_");
Serial.print(staticresource);
Serial.println("_");
Serial.print("length static=");
Serial.println(strlen(staticresource));
Serial.print("length resource=");
Serial.println(strlen(resource));
}
https://github.com/Conwon99/4th-Year-Project/blob/main/StringLengthIssue
Serial Monitor Debugging
RiceCooker_ length = 11
Rice_ length = 5
3_ length = 2
Boil_ length = 5
Complete
RiceCooker
Rice
3
Boil
resource=_/macros/s/AKfycbzTAkuhTqJfi-EofdpOjBxKNlDe18fdTkOPHMOuOwvl9zbDqfPHwbb1/exec&Cooker=RiceCooker&Meal=Ric&Portion=3&Method=Boil_
staticresource=_/macros/s/AKfycbzTAkuhTqJfi-EofdpOjBxKNlDe18fdTkOPHMOuOwvl9zbDqfPHwbb1/exec?Cooker=RiceCooker&Meal=Rice&Portion=3&Method=Boil_
length static=125
length resource=130
char[] has null-terminator value \0 and it is counted as the length of the array. Just use std::vector and String. Anyway, your code is uncompilable. I'll rewrite for you:
#include <BluetoothSerial.h>
#include <vector>
const char resource[] PROGMEM = "/macros/s/AKfycbzTAkuhTqJfi-EofdpOjBxKNlDe18fdTkOPHMOuOwvl9zbDqfPHwbb1/exec?"; //must be pre-defined buffer
const char staticresource[] PROGMEM = "/macros/s/AKfycbzTAkuhTqJfi-EofdpOjBxKNlDe18fdTkOPHMOuOwvl9zbDqfPHwbb1/exec?Cooker=RiceCooker&Meal=Rice&Portion=3&Method=Boil";
const char cookerQuery[] PROGMEM = "&Cooker=";
const char mealQuery[] PROGMEM = "&Meal=";
const char portionQuery[] PROGMEM = "&Portion=";
const char methodQuery[] PROGMEM = "&Method=";
std::vector<String> qualArray;
BluetoothSerial SerialBT;
void CollectQualitativeData() {
while (qualArray.size() < 4 ) {
if (SerialBT.available()) {
String incomingChar = SerialBT.readStringUntil('\n');
qualArray.push_back(incomingChar);
}
delay(20);
}
}
void setup() {
Serial.begin(115200);
SerialBT.begin("ESP32test");
CollectQualitativeData();
Serial.println("Complete");
for (int i = 0; i < qualArray.size(); i++) {
Serial.println(qualArray[i]);
}
String res(resource);
res += cookerQuery + qualArray[0];
res += mealQuery + qualArray[1];
res += portionQuery + qualArray[2];
res += methodQuery + qualArray[3];
Serial.println(res);
}
void loop() {}

C: variables retain the value from previous operation instead of resetting

I am fairly new to C and have been trying my hand with some arduino projects on Proteus. I recently tried implementing a keypad and LCD interface with Peter Fleury's libraries, so far the characters I input are displayed fine, but I run into a problem when trying to print to the serial port. It's like the value of the keys keeps on being concatenated with every iteration so the ouput has extra characters like this:
The value before the comma is from the 'key' variable, the value after it the 'buf' variable:
151
(The 5 I input in the second iteration was added to the 1 from the first iteration and then put into the variable I print)
I figure it may be due to my lack/incorrect use of pointers, heres is my code:
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <stdio.h>
#include "lcd.h"
#include "mat_kbrd.h"
#include "funciones.h"
#include "menu.h"
char buf[256];
char* coma = ",";
int main(void)
{
pin_init();
serial_begin();
lcd_init(LCD_DISP_ON);
kbrd_init();
bienvenida();
while (1) {
int i = 0;
char key = 0;
//char *peso;
//int pesoSize = 1;
char peso[100];
//peso = calloc(pesoSize,sizeof(char));
int salida = 0;
lcd_clrscr();
desechos();
key = kbrd_read();
if (key != 0) {
lcd_gotoxy(0,3);
lcd_putc(key);
_delay_ms(2000);
lcd_clrscr();
cantidad();
while (salida != 1) {
char keypeso = 0;
keypeso = kbrd_read();
//pesoSize = i;
//peso = realloc(peso,pesoSize*sizeof(char));
if (keypeso != 0) {
if (keypeso == '+') {
salida = 1;
keypeso = *("");
lcd_clrscr();
calcularTotal(key,peso);
_delay_ms(2000);
} else {
lcd_gotoxy(i,1);
lcd_putc(keypeso);
snprintf(peso, sizeof peso, "%s%s",peso, &keypeso);
//strcat(peso,&keypeso);
i++;
_delay_ms(2000);
}
}
}
snprintf(buf, sizeof buf, "%s%s%s", &key,coma,peso);
serial_println_str(buf);
}
}
}
&key and &keypeso point to a single char, but you are using the %s format specifier, so trying to read a string into a single char. Use %c rather then %s for single characters, and pass the char not the address-of-char..

I want to get string using RX_interrupt in MBED

I’m trying to write code using MBED, but there are some problems.
The thing is that I want to get "character array".
If I send "abcde" to the MBED board, the board will get "abcde" and do something.
This is my code.
#include <mbed.h>
char message[200];
void Rx_interrupt();
int i;
Serial pc(PA_2, PA_3);
int main() {
pc.baud(115200);
pc.attach(&Rx_interrupt, Serial::RxIrq);
while (1) {
}
return 0;
}
void Rx_interrupt() {
char a1[6] = "abcde";
memset(message, 0, sizeof(message));
i = 0;
while (pc.readable()) {
message[i] = pc.getc();
i++;
}
if (!strcmp(a1, message)) {
pc.printf(message);
}
else {
pc.printf("FAIL");
}
}
If I send "abcde", the board should print "abcde". This is my purpose.
But the board prints "FAIL" only one time. What should I do?
I think that there are some problems with pc.getc().

Receiving AT commands

I'm using a microcontroller to communicate with a SIM808 module and I want to send and receive AT commands.
The problem right now is that for some commands I receive only some portions of the answers I should receive, but for some others I receive what I should. For example, if I shut down the module I receive "NORMAL POWER DOWN", as expected.
I believe I'm receiving everything, I'm just not being capable of seeing it. I receive the beginning and the end of the response, so the problem should be on the way I parse and buffer. I'm using a FIFO buffered RXC interrupt.
For example, for the command "AT+CBC" I should receive something like:
"
+CBC: 1,96,4175
OK
"
But I receive "+CBC1,4130OK"
(I replaced the unreadable characters with a dot)
bool USART_RXBufferData_Available(USART_data_t * usart_data)
{
/* Make copies to make sure that volatile access is specified. */
uint8_t tempHead = usart_data->buffer.RX_Head;
uint8_t tempTail = usart_data->buffer.RX_Tail;
/* There are data left in the buffer unless Head and Tail are equal. */
return (tempHead != tempTail);
}
uint8_t USART_receive_array (USART_data_t * usart_data, uint8_t * arraybuffer)
{
uint8_t i = 0;
while (USART_RXBufferData_Available(usart_data))
{
arraybuffer[i] = USART_RXBuffer_GetByte(usart_data);
++i;
}
return i;
}
void USART_send_array (USART_data_t * usart_data, uint8_t * arraybuffer, uint8_t buffersize)
{
uint8_t i = 0;
/* Wait until it is possible to put data into TX data register.
* NOTE: If TXDataRegister never becomes empty this will be a DEADLOCK. */
while (i < buffersize)
{
bool byteToBuffer;
byteToBuffer = USART_TXBuffer_PutByte(usart_data, arraybuffer[i]);
if(byteToBuffer)
{
++i;
}
}
}
void send_AT(char * command){
uint8_t TXbuff_size = strlen((const char*)command);
USART_send_array(&expa_USART_data, (uint8_t *)command, TXbuff_size);
fprintf(PRINT_DEBUG, "Sent: %s\n\n", command);
}
void receive_AT(uint8_t *RXbuff){
memset (RXbuff, 0, 100);
uint8_t bytes = 0;
bytes = USART_receive_array(&expa_USART_data, RXbuff);
int n;
if (bytes>0)
{
RXbuff[bytes]=0;
for (n=0;n<bytes;n++)
{
if (RXbuff[n]<32)
{
RXbuff[n]='.';
}
}
}
fprintf(PRINT_DEBUG, "Received: %s\n\n", RXbuff);
}
int main(){
unsigned char RXbuff[2000];
send_AT("ATE0\r\n");
receive_AT(RXbuff);
send_AT("AT\r\n");
receive_AT(RXbuff);
send_AT("AT+IPR=9600\r\n");
receive_AT(RXbuff);
send_AT("AT+ECHARGE=1\r\n");
receive_AT(RXbuff);
send_AT("AT+CBC\r\n");
_delay_ms(2000);
receive_AT(RXbuff);
send_AT("AT+CSQ\r\n");
_delay_ms(2000);
receive_AT(RXbuff);
}
So, the problem didn't have to do with this part of the code. I am using an emulated serial port to print stuff from the micro-controller to the PC. The issue was that the rate with which I was printing a char to the PC was much faster than what the PC was receiving, that's why some parts didn't appear.

Resources