i have a small code issue with converting the strings.
My goal is to use "number1" and give it's value into the function "sendATCommand", along with other String parts.
So the end goal is to send [AT+CPBW=1, "1234",145,"Number1"] to my SIM module.
Unfortunately it doesn't compile, due to the following error:
"Cannot convert 'StringSumHelper' to 'const char*'"
After researching it seems like i have to transform the String into Char array, but the more i read about it, the more confused i get.
Do you know a working (and comprehensible) fix for my problem?
c_str() is the answer, but here's another approach. Add this
void sendATCommand(String& cmd, unsigned long timeout) {
sendATCommand(cmd.c_str(), timeout);
}
This is function overloading. You've probably used it already, with Serial.println. It takes many different types, like int and const char *.
In your sketch, you have just one sendATCommand. So the compiler will try to convert what you have -- the result of + with a String: a StringSumHelper -- to what you asked for: const char* cmd. There is no way to do this automatically, so you get the error.
StringSumHelperis a subclass of String (the exact implementation can vary by board). By declaring this same-name function with a different set of arguments -- along with the return type, it's the function signature -- the compiler can find a match. And for this function variant, you call c_str() to return a const char*, which is what the first function is expecting.
The argument is a String&, which means the argument is passed by reference, to avoid making a copy, which is unnecessary and at least temporarily consumes memory.
Now with two variants, you can call sendATCommand with a plain literal string in quotes, a char buffer, a String, or the result of adding a String to other things.
Sorry, i have to follow up with something.
When i send the standalone command to the module, everything works fine and i get an "OK" back.
But when i'm trying to send it out of my main code, the arduino only sends gibberish to the serial port.
I'm basically sending an SMS to the module and want to save a given number.
if(SIM7670Serial.available()) {
response.reserve(50);
while(SIM7670Serial.available()){
char c = SIM7670Serial.read(); //gets one byte from serial buffer
response += c; //makes the String readString
delay(2); //slow looping to allow buffer to fill with next character
}
Serial.println(response);
if(response.indexOf("RING") != -1) { // Ringing
callStatus = 1;
}
if(response.indexOf("BEGIN") != -1) { // Call connected
callStatus = 2;
}
if(response.indexOf("END") != -1) { // Call ended
callStatus = 0;
}
if(response.indexOf("##1#") != -1){
location1 = response.indexOf("##1#");
location2 = location1 + 4;
number1 = response.substring(location2);
commandString="AT+CPBW=1,\"";
commandString +=number1;
commandString +="\",145,\"Number1\"";
sendATCommand(commandString.c_str(),1000);
Serial.println("Saved Tel.1: "+number1);
}
What i'm getting on the Monitor:
EDIT: After some debugging i found out that the following line is the problem. If i comment it, the command works fine. What's the issue here?
Sorry, but i still don't get it.
From what i understand from that blog post, is that one thing i did wrong for sure is to try to save the read chars into a String directly, instead of into a char array like in example 2.
So i tried to create an adapted new function for the serial read like that:
My thought was to save everything into a char array and then convert it to a String, since i will the String class later on (for the function .substring()).
Unfortunately the code will not compile:
Compilation error: expected primary-expression before '.' token
you can use a String to accumulate the incoming bytes, it's just a buffer at the end of the day (and your use of reserve protects somewhat against undesirable effect of memory fragmentation issues in the heap in some cases) but the challenge is in the way you try to second guess the timing of an asynchronous communication protocol
You do
while(SIM7670Serial.available()){
char c = SIM7670Serial.read(); //gets one byte from serial buffer
response += c; //makes the String readString
delay(2); //slow looping to allow buffer to fill with next character
}
The use of the delay can be an issue.
At 9600 bauds you get ~1 character per ms so by waiting 2ms, if the flow is continuous on the other side you accumulate 2 characters in the buffer and the while loop only unstacks one.
At each turn of the loop you add one byte into the buffer that you don't deal with until later.
If the message is short enough, you won't fill up the 64 byte buffer and all will be fine, you'll get your message but if it's a longer message, then by second guessing the timing you'll have overflown the Rx buffer and lost incoming bytes.
Best is to receive the bytes when they come and detect the end of the transmission (with AT commands it's usually a end of line or "OK\r\n" or something similar) and then deal with the message. That's what the tutorial talks about.
The problem i have at the moment is that i'm getting perfect answers in normal operation (sending commands and receiving the answers).
But the gibberish command only happens as soon as i use this line:
number1 = response.substring(location2);
and only in the corresponding AT command.
If i put a defined number (e.g. "1234") in there, it works fine.
So i don't think the bad way to read data from Serial is the issue, but something else i haven't figured out yet...
By declaring ndx as static, it is never reset to zero and keeps growing forever. If responseChar is an array, that's bad.
Because response is global, there may not be a need to repeatedly re-reserve the capacity, unless the capacity is reduced elsewhere; and in that case, why fiddle with capacity? Set it at the desired max size once.
char c is copied into responseChar in the loop, but is never NUL-terminated to indicate the end of the string. In that case, the string is could have garbage at the end
String.valueOf works in Java for example, but not here
Arduino String does not have valueOf
Can't use . to call static methods; need to use ::. That's why you got that error.
You're better off
reserve the space you need once
in the function, assign "" to clear it
in the loop, use plain += c to append the character
After again several hours of frustration and tinkering around with the Serial Objects, i have the feeling the String class is doing me more harm than good.
So i switched my code to char arrays only.
I got it to compile, but it's again outputting (this time different) garbage.
I'm on vacation for 2 weeks now and i will continue again after i return.
But i'll will probably open a new Topic, since this is kind of getting Off-Topic here.
Thank you so far for the help, maybe we will talk again in a few weeks.