serial.println(String) prints "#" instead of the string - c

i'm just trying to recieve a string using a serial and to send this string back. So when i send a string to an arduino over a serial the arduino should automaticly send this string back.
i created this code:
String test;
void setup(){
Serial.begin(9600);
Serial.setTimeout(2);
test = "null";
}
void loop(){
if(Serial.available()){
test = Serial.readString();
}
Serial.println(test);
}
I guess it is not that difficult to understand. However now the arduino will always print a "#" instead of the variable test. My connected serial device is a bluetooth modul. (hc-06)
What did i do wrong?
Thank you!
(i also ran this code in the arduino emulator 123D Circuits. There it worked just fine)

You need change your code. Move println into if statement.
Try increase timeout interval, 2ms is not enough, good value (at 9600) lies above 10ms. Theoretically timeout should be at least 3.5 characters long and for current speed this equals ~0,4 ms. But in practice higher values are used.
String test;
void setup(){
Serial.begin(9600);
Serial.setTimeout(10);// or more
test = "null";
}
void loop(){
if(Serial.available()){
test = Serial.readString();
Serial.println(test);// moved into if
}
}
Update: Another simple solution to return characters back looks like:
void loop(){
if(Serial.available()) Serial.write(Serial.read());
}
Update 2: Had similar issue with BLE module HM10 (clone, not official). It was sending about 15 dummy bytes prior to any array. And i didn't solve it. But if weired bytes always the same you can make a simple trick using String.remove():
if(Serial.available()){
test = Serial.readString();
test.remove(0,5);
// test.remove - add code to remove last character
Serial.println(test);
}
Also try another terminal.

Related

How to generate string from variable in a function and show it by serial port (ESP8266)

I use to program different microcontrollers, but at low level. I mean, I program them to control power converters and so.
However, I am interested in working with the nodemcu (ESP8266) due to the fact that messages can be send via MQTT protocol.
I did a very easy program generating the messages by concatenating strings. Now I am trying to do the same thing but in a more elegant way i.e. with functions. Due to my poor skills, I sweating like a pig trying to figure out what I am doing wrong. Hope you can help me! :D
Here is the code. As you can see, I have a float variable that increases with a counter, just to change its value, you know. Then, I call a function to generate the message and send it to the serial port (later it would be MQTT).
#include <string.h> // Libreria para trabajar con caracteres
int contador=1;
float Vbat=2.1; // tension de la bateria
char *Vbat_en_string;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
// This function generates the message. Turns float into string.
void generamensaje(float valor, char* destino)
{
//I need to do this. Otherwise, dtostrf doesn't work
destino ="";
//Saving float "valor" in string "destino"
dtostrf(valor,6,3,destino);
}
void loop() {
generamensaje(Vbat,Vbat_en_string);
Serial.print("Message:");
Serial.println(Vbat_en_string);
contador++;
Vbat = Vbat + contador*1.0024;
delay(2000);
}
This should generate something like:
Message: 3926.496
Message: 4015.709
Message: 4105.925
But what I read in the serial port is:
Message:
3926.496Message:
4015.709Message:
4105.925
Could you help me a little? I thought Serial.println automatically changed the line.
Thank you so much, community.
Once we have this solved, I have more questions :D
The line:
//I need to do this. Otherwise, dtostrf doesn't work
destino ="";
Is quite definitely incorrect, since it makes destino point to a zero length string constant, then dtostrf then writes to that location, which is both constant and too short. The consequent behaviour is undefined. You do need to change the code to make it work, but that is not the correct solution.
Instead Vbat_en_string should point to a buffer of sufficient length before generamensaje() is called. It also need not be global - you should avoid globals where possible and it is possible in all cases - unfortunately most Arduino sketch examples are poor in this respect and as a "teaching" platform set a bad example:
include <string.h> // Libreria para trabajar con caracteres
void setup()
{
// put your setup code here, to run once:
Serial.begin(9600);
}
// This function generates the message. Turns float into string.
void generamensaje(float valor, char* destino)
{
//Saving float "valor" in string "destino"
dtostrf(valor,6,3,destino);
}
void loop()
{
static int contador=1;
static float Vbat=2.1; // tension de la bateria
char Vbat_en_string[32] ;
generamensaje(Vbat,Vbat_en_string);
Serial.print("Message:");
Serial.println(Vbat_en_string);
contador++;
Vbat = Vbat + contador*1.0024;
delay(2000);
}

Arduino Socket.io shows disconnected when delay() is used

I am new to Arduino and facing an issue. I am implementing socket in Arduino for ESP8266 . It works as expected when I am not using delay() or not using someFunction(). As soon as i use delay or do some processing than i am getting connection disconnected one server socket.
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ArduinoJson.h>
#include <WebSocketsClient.h>
#include <SocketIOclient.h>
#include <Hash.h>
ESP8266WiFiMulti WiFiMulti;
SocketIOclient socketIO;
#define USE_SERIAL Serial1
void socketIOEvent(socketIOmessageType_t type, uint8_t * payload, size_t length) {
switch(type) {
case sIOtype_DISCONNECT:
USE_SERIAL.printf("[IOc] Disconnected!\n");
break;
case sIOtype_CONNECT:
USE_SERIAL.printf("[IOc] Connected to url: %s\n", payload);
break;
case sIOtype_EVENT:
USE_SERIAL.printf("[IOc] get event: %s\n", payload);
break;
case sIOtype_ACK:
USE_SERIAL.printf("[IOc] get ack: %u\n", length);
hexdump(payload, length);
break;
case sIOtype_ERROR:
USE_SERIAL.printf("[IOc] get error: %u\n", length);
hexdump(payload, length);
break;
case sIOtype_BINARY_EVENT:
USE_SERIAL.printf("[IOc] get binary: %u\n", length);
hexdump(payload, length);
break;
case sIOtype_BINARY_ACK:
USE_SERIAL.printf("[IOc] get binary ack: %u\n", length);
hexdump(payload, length);
break;
}
}
void setup() {
// USE_SERIAL.begin(921600);
USE_SERIAL.begin(115200);
//Serial.setDebugOutput(true);
USE_SERIAL.setDebugOutput(true);
USE_SERIAL.println();
USE_SERIAL.println();
USE_SERIAL.println();
for(uint8_t t = 4; t > 0; t--) {
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t);
USE_SERIAL.flush();
delay(1000);
}
// disable AP
if(WiFi.getMode() & WIFI_AP) {
WiFi.softAPdisconnect(true);
}
WiFiMulti.addAP("SSID", "passpasspass");
//WiFi.disconnect();
while(WiFiMulti.run() != WL_CONNECTED) {
delay(100);
}
String ip = WiFi.localIP().toString();
USE_SERIAL.printf("[SETUP] WiFi Connected %s\n", ip.c_str());
// server address, port and URL
socketIO.begin("10.11.100.100", 8880);
// event handler
socketIO.onEvent(socketIOEvent);
}
unsigned long messageTimestamp = 0;
void loop() {
socketIO.loop();
uint64_t now = millis();
if(now - messageTimestamp > 2000) {
messageTimestamp = now;
// creat JSON message for Socket.IO (event)
DynamicJsonDocument doc(1024);
JsonArray array = doc.to<JsonArray>();
// add evnet name
// Hint: socket.on('event_name', ....
array.add("event_name");
// add payload (parameters) for the event
JsonObject param1 = array.createNestedObject();
param1["now"] = now;
// JSON to String (serializion)
String output;
serializeJson(doc, output);
// Send event
socketIO.sendEVENT(output);
// Print JSON for debugging
USE_SERIAL.println(output);
}
//NEED TO DO SOME PROCESSIONG
delay(2000);
someFuntion();
}
void someFunction(){
//some processing that consume the time
}
You are getting timeout on server side.
When you are making delay(10000) esp8266 is just hanging on some loop (as a delay implementation) - any other code is not executed due this time. So when the server is not getting any data it disconnects client.
The solution (easy way) is to make a new connection every time you want to send data. In pseudocode it will look like this:
void loop(){
connectToServer();
sendData();
Disconnect();
delay(1000);
SomeFunction();
}
Then it should work.
The more complicated method is to familiarize yourself with the concept of Events and callbacks and get rid of delay() function. Or try to use esp_rtos_sdk witch is asynchronous tasks concepts RTOS framework.
Have fun!
Edited:
After refreshed the code I'm able to tell more about it, so I'm editing the previous post.
The quickest way to make it work(partly) is to remove the delay(2000) statement - because this If() statement is handling sending messages in 2 seconds interval. As I see you may wan't to put this void someFunction() to this if() statement too. This will make "some processing" in 2 seconds interval.
socketIO.loop() is handling maintaining connection with server and sending event's to server so it has to be call as quick as plausible. In case with delay you are getting socket timeout and disconnection.
void loop() function must be shortest as plausible to maintain the connection. Probably it is 500ms or so - regarding to you experiments. So any delay's is not plausible. If you need more processing try to familiarize with event processing. The easiest way is to declare flags as Boolean and timers counting time intervals. When timer is lunched it's sets the flag as true and you may process function.
Websockets on ESP(or other embedded microprocessors) are hard for beginners because they are time dependent. You need to have short processing loop or some of asynchronous methods used.
I hope, that I help.

Sound Sensor RGB LED coding

So we connected a sound sensor to our board to light up our LED light when sound is heard, it kinda works but there some hiccups.
We tried messing with the code for a while but no matter what we do the senor will only react to loud even when we put in a threshold. If you see in the picture, it it only displaying "loud" noise to the display and cant seem be able to go to the other condition we set in our threshold. We configure the sensor with our screw driver but nothing seem to work. Our code is below & before we continue on, we wanted to know if there a problem with it that can fix out the issue,thanks you
ALSO the sound sensor is a "ko9A01"
PS: we use "energia" to code this.
#include <msp430.h>
#include <Wire.h>
int soundsensor = 2;
int led = 3;
void setup()
{
Serial.begin(9600);
Serial.println("Begin Test");
pinMode(soundsensor,OUTPUT);
pinMode(led,OUTPUT);
}
void loop()
{
int sensorValue = digitalRead(soundsensor);
Serial.println(sensorValue);
delay(250);
if (sensorValue == 1)
{
Serial.print("LOUD");
digitalWrite(led,HIGH);
}
else
{
Serial.print("QUIET");
digitalWrite(led,LOW);
}
}
EDIT: NOW With the help of Brydon we change the output to input and change it to this we change it to this and now we get this new error voi
void setup()
{
Serial.begin(9600);
Serial.println("Begin Testing");
pinMode(soundsensor,INPUT);
}
and it only show
"begin test":
0 and wont move from there
You have the sound sensor configured as an OUTPUT in the setup.
I assume you want it to be an input? That would be the case if you're reading values from it.
I can't tell what sensor you have - but with more information on the sensor, we can read the documentation and help you configure the inputs appropriately (ie a threshold)

Receiving a fixed length string on Arduino serial and storing it in a structure

I am currently receiving a fixed length string means it's length cant exceed more than 50 but can be less then that.i am using following code.
void loop()
{
char *datareceived;
int number;
char sword[] ="times";
uint8_t x;
digitalWrite(ledPin,LOW);
number = BTSerial.available();
// Keep reading from HC-05 and send to Arduino Serial Monitor
if (number){
datareceived = (char *)malloc(sizeof(char)*number);
if(datareceived == 0){
Serial.print("Error: Out of Memmory");
}
if(number>0){
for(x=0;x<number;x++){
datareceived[x]=BTSerial.read();
if(datareceived[x] == '\n')
//datareceived[x]='\0';
break;
}
strcpy(dataReceivedfromBluetooth,datareceived);
Serial.println(dataReceivedfromBluetooth);
}
if((strstr(dataReceivedfromBluetooth,sword))){
Serial.println("Yes");
digitalWrite(ledPin,HIGH);
delay(30);
}
else{
digitalWrite(ledPin,LOW);
}
}
free(datareceived);
}
Now with this code, it is not printing any thing at all.I think my code of dynamic memory allocation is all right.
whereas a simple code like this
void loop(){
if (BTSerial.available())
Serial.write(BTSerial.read());
if (Serial.available())
BTSerial.write(Serial.read());
}
is working perfect ally fine and writing everything on serial port, so what i am trying in my main code is what ever is being received by BTSerail.read() is stored in a array/string and then i use that array for some of string operations like strstsr to find out whether that incoming string has a particular word or not.
Yes, it's very likely to be a problem in your code: you're not terminating the string.
A C string is just an array of characters, with a character with the value '\0' marking the end of the string. Unless you know that the sender includes the terminator, you're not writing one so the string just "runs off" into la-la-land.

Arduino Serial.println() outputs a blank line if not in loop()

I'm attempting to write a function that will pull text from different sources (Ethernet client/Serial/etc.) into a single line, then compare them and run other functions based on them. Simple..
And while this works, I am having issues when trying to call a simple Serial.println() from a function OTHER than loop().
So far, I have around 140 lines of code, but here's a trimmed down version of the portion that's causing me problems:
boolean fileTerm;
setup() {
fileTerm = false;
}
loop() {
char character;
String content="";
while (Serial.available()) {
character = Serial.read();
content.concat(character);
delay(1);
}
if (content != "") {
Serial.println("> " + content);
/** Error from Serial command string.
* 0 = No error
* 1 = Invalid command
*/
int err = testInput(content);
}
int testInput(String content) {
if (content == "term") {
fileTerm = true;
Serial.println("Starting Terminal Mode");
return 0;
}
if (content == "exit" && fileTerm == true) {
fileTerm = false;
Serial.println("Exiting Terminal Mode");
return 0;
}
return 1;
}
(full source at http://pastebin.com/prEuBaRJ)
So the point is to catch the "term" command and enter some sort of filesystem terminal mode (eventually to access and manipulate files on the SD card). The "exit" command will leave the terminal mode.
However, whenever I actually compile and type these commands with others into the Serial monitor, I see:
> hello
> term
> test for index.html
> exit
> test
> foo
> etc...
I figure the function is catching those reserved terms and actually processing them properly, but for whatever reason, is not sending the desired responses over the Serial bus.
Just for the sake of proper syntax, I am also declaring the testInput() function in a separate header, though I would doubt this has any bearing on whether or not this particular error would occur.
Any explainable reason for this?
Thanks.
Model: Arduino Uno R3, IDE version: 1.0.4, though this behavior also happened on v1.0.5 in some instances..
It is kinda guessable how you ended up putting delay(1) in your code, that was a workaround for a bug in your code. But you didn't solve it properly. What you probably saw was that your code was too eager to process the command, before you were done typing it. So you slowed it down.
But that wasn't the right fix, what you really want to do is wait for the entire command to be typed. Until you press the Enter key on your keyboard.
Which is the bug in your code right now, the content variable doesn't just contain "term", it also contains the character that was generated by your terminal's Enter key. Which is why you don't get a match.
So fix your code, add a test to check that you got the Enter key character. And then process the command.

Resources