Как сгенерировать строку из переменной в функции и отобразить ее через последовательный порт (ESP8266)

#c #arduino #esp8266 #nodemcu #arduino-esp8266

#c #arduino #esp8266 #nodemcu #arduino-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

Ответ №1:

Строка:

   //I need to do this. Otherwise, dtostrf doesn't work
  destino ="";
  

Совершенно определенно неверно, поскольку оно destino указывает на строковую константу нулевой длины, dtostrf а затем записывает в это местоположение, которое является постоянным и слишком коротким. Последующее поведение не определено. Вам нужно изменить код, чтобы он работал, но это неправильное решение.

Вместо Vbat_en_string этого следует указывать на буфер достаточной длины перед generamensaje() вызовом. Это также не обязательно должно быть глобальным — вам следует избегать глобальных значений, где это возможно, и это возможно во всех случаях — к сожалению, большинство примеров Arduino sketch в этом отношении плохи и в качестве «обучающей» платформы подают плохой пример:

 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);
}
  

Комментарии:

1. Я попробую то, что вы говорите. Спасибо Клиффорду 🙂

2. Дорогой Клиффорд, спасибо, что показал мне, я понятия не имею… Ваш код работает отлично. Надеюсь, вы будете рядом, когда я подготовлю свой следующий пост в stack overflow . Приветствую и желаю хорошего дня.

3. Обратите внимание, что единственное изменение, необходимое для работы вашего кода, — это удалить присвоение Vbat_en_string in generamensaje и изменить его тип с указателя на массив. Устранение глобальных значений — это просто совет , и потому, что я не мог заставить себя публиковать код с ненужными глобальными значениями, как вопрос профессиональной честности 😉 Стоит прочитать: embedded.com/a-pox-on-globals