如何从函数中的变量生成字符串并通过串口显示(ESP8266)
How to generate string from variable in a function and show it by serial port (ESP8266)
我曾经对不同的微控制器进行编程,但水平较低。我的意思是,我对它们进行编程以控制电源转换器等。
但是,我对使用 nodemcu (ESP8266) 很感兴趣,因为可以通过 MQTT 协议发送消息。
我做了一个非常简单的程序,通过连接字符串来生成消息。现在我正在尝试做同样的事情,但以更优雅的方式,即使用函数。由于我的技术不好,我像猪一样大汗淋漓地想弄清楚自己做错了什么。希望你能帮我! :D
这是代码。如您所见,我有一个随计数器增加的浮点变量,只是为了改变它的值,您知道。然后调用函数生成消息发送到串口(以后就是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);
}
这应该生成如下内容:
Message: 3926.496
Message: 4015.709
Message: 4105.925
但是我在串口读取的是:
Message:
3926.496Message:
4015.709Message:
4105.925
你能帮我一点忙吗?我以为Serial.println自动换行了
非常感谢,社区。
一旦我们解决了这个问题,我还有更多问题:D
行:
//I need to do this. Otherwise, dtostrf doesn't work
destino ="";
绝对是不正确的,因为它使 destino
指向零长度字符串 constant,然后 dtostrf
写入该位置,即恒定和太短。后续行为是未定义的。您确实需要更改代码才能使其正常工作,但这不是正确的解决方案。
相反,Vbat_en_string
应该指向足够长度的缓冲区 ,然后 generamensaje()
被调用。它也不必是全局的——你应该尽可能避免全局变量,它在所有情况下都是 possible——不幸的是,大多数 Arduino 草图示例在这方面都很差,作为一个“教学”平台设置了一个坏例子:
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);
}
我曾经对不同的微控制器进行编程,但水平较低。我的意思是,我对它们进行编程以控制电源转换器等。
但是,我对使用 nodemcu (ESP8266) 很感兴趣,因为可以通过 MQTT 协议发送消息。
我做了一个非常简单的程序,通过连接字符串来生成消息。现在我正在尝试做同样的事情,但以更优雅的方式,即使用函数。由于我的技术不好,我像猪一样大汗淋漓地想弄清楚自己做错了什么。希望你能帮我! :D
这是代码。如您所见,我有一个随计数器增加的浮点变量,只是为了改变它的值,您知道。然后调用函数生成消息发送到串口(以后就是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);
}
这应该生成如下内容:
Message: 3926.496
Message: 4015.709
Message: 4105.925
但是我在串口读取的是:
Message:
3926.496Message:
4015.709Message:
4105.925
你能帮我一点忙吗?我以为Serial.println自动换行了
非常感谢,社区。
一旦我们解决了这个问题,我还有更多问题:D
行:
//I need to do this. Otherwise, dtostrf doesn't work
destino ="";
绝对是不正确的,因为它使 destino
指向零长度字符串 constant,然后 dtostrf
写入该位置,即恒定和太短。后续行为是未定义的。您确实需要更改代码才能使其正常工作,但这不是正确的解决方案。
相反,Vbat_en_string
应该指向足够长度的缓冲区 ,然后 generamensaje()
被调用。它也不必是全局的——你应该尽可能避免全局变量,它在所有情况下都是 possible——不幸的是,大多数 Arduino 草图示例在这方面都很差,作为一个“教学”平台设置了一个坏例子:
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);
}