Передача float

SO_OOF

✩✩✩✩✩✩✩
7 Июн 2021
14
1
Добрый вечер. Я получаю показатели температуры и влажности с датчика DHT22 и потом хочу их передать на ESP-01 при помощи serial. Но команда Serial.write не передает тип float. Хотел бы узнать, как мне передать Эти данные. И Какой код, я должен написать на стороне SEP-01?
 

SO_OOF

✩✩✩✩✩✩✩
7 Июн 2021
14
1
Я сделал вот так.

float humidity = dht.readHumidity();
byte* ptr - это переменная указатель
ptr = &temperature - указатель ptr хранит адрес переменной temperature
Serial.write(ptr,4)

Мне выдало ошибку
exit status 1
no matching function for call to 'HardwareSerial::write(float*&, int)'
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,159
1,267
Москва
Можно как массив байт, а можно по другому:
тип флоат использует 4 байта. можно передать как цело32 битное. Ниже код (который точно можно сократить как то, но я что то туплю с этими ссылочными типами) который переводит float в uint32_t и потом обратно
C++:
void setup() {
 
  Serial.begin(115200);
 
  float f1 = 123.456;
  Serial.println(f1);

  void * u1;
  u1=&f1;   
  uint32_t * ud;
  ud=u1;
  uint32_t d1;
  d1 = *ud;
  Serial.println(d1);

  void * u2;
  u2=&d1;
  float * uf;
  uf=u2;
  float f2;
  f2=*uf;
  Serial.println(f2);

}

void loop() {
 
}
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,159
1,267
Москва
Да, наверное. Была цель еще показать и помучить преобразования типов. Сначала думал можно как то проще, но не заработало сразу
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,159
1,267
Москва
Я тоже не понимаю, но ведь работает :D
Учиться никогда не поздно.
Суть такая флоат занимает 4 байта в памяти. uint32_t тоже. значит у них ест что то общее. Я перегнал 4 байта из флоат на место 4-х байт целого чилса. А потом обратно
union же для того и другого числа использует общие 4 байта.
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,159
1,267
Москва
Тогда жопа, Но это один из конкретных случае.
Для 128 бит будут другие типы данных,
Данные как число Пи. в военное время может достигать 6
 

bort707

★★★★★★✩
21 Сен 2020
2,864
850
Я сделал вот так.
Код:
float humidity = dht.readHumidity();
byte* ptr - это переменная указатель
ptr = &temperature - указатель ptr хранит адрес переменной temperature
Serial.write(ptr,4)
третью строчку вот так перепишите и все заработает
C++:
ptr = (uint8_t*) &temperature ;
 

SO_OOF

✩✩✩✩✩✩✩
7 Июн 2021
14
1
@bort707,Сделал как вы сказали. В ком порте выводится обратный знак вопроса и буква А настроил на 9600 бод и в консоли стоит 9600 бод

Вот мой код

C++:
#include "DHT.h"
#define DHTPIN 2
#define DHTTYPE DHT22
unsigned long last_time;
float humidity;
float temperature;

DHT dht(DHTPIN, DHTTYPE); //Инициация датчика
Adafruit_CCS811 ccs; //Инициация датчика

void setup() {
  Serial.begin(9600);
  dht.begin();
}

void loop() {
  if (millis() - last_time >= 2000) {
    last_time = millis();
    get_dht_metrics();
    //sending_data(temperature)
    byte* ptr; //- переменная указатель
    ptr = (uint8_t*) &temperature; //- указатель ptr хранит адрес переменной temperature
    Serial.write(ptr,4);
    Serial.read();
  }
}

void get_dht_metrics() {
  humidity = dht.readHumidity(); //Измеряем влажность
  temperature = dht.readTemperature(); //Измеряем температуру
  if (isnan(humidity) || isnan(temperature)) {  // Проверка. Если не удается считать показания, выводится «Ошибка считывания», и программа завершает работу
    Serial.println("Failed to read from DHT sensor!");
    return 0;
  }
}

/*void sending_data(float param1) {
  Serial.write(param1);
  //Serial.write((String)(param2));
}*/
 

bort707

★★★★★★✩
21 Сен 2020
2,864
850
А как мне тогда читать?
А это не так просто, как кажется. Нужно читать 4 байта в цикле и потом собирать из них тип флоат.
А почему "не просто" - потому что как только вы читаете не один байт, появляется проблема определить, какой байт в передаче первый, а какой последний.
Вот эта картинка хорошо показывает проблему начального и конечного символа - как определить, какое слово тут по кругу - "МАТЬ" или "ТЬМА" ?

так что, кроме отсылаемых 4х байт, хорошо бы пересылать еще метку "начало пакета" и метку конца пакета.


url картинки, у кого не видно
C++:
http://artdesign21.narod.ru/image/8190--1236004-m750x740.jpg
 
Изменено:

Старик Похабыч

★★★★★★★
14 Авг 2019
4,159
1,267
Москва
Бывает любовь между мужчиной и женщиной...
Слайды! Слайды!
Бывает любовь между женщиной и женщиной...
Слайды! Слайды!
А бывает любовь к Родине, и теперь будут слайды!

Вот поэтому то я и предложил передавать через целое 32битное число.
 

rGlory

★✩✩✩✩✩✩
11 Май 2021
200
20
Я тоже не понимаю, но ведь работает
На самом деле не работает. Такие приведения нелегальны и "работают" до поры до времени.

Автору: имхо проще всего умножить на 100 и привести к целому и передавать целые. Вам же не нужна температура или влажность точнее 0.01 ? Это и реализовать проще, и отлаживать - значения читаемы, в отличие от хаков с передачей float
 

bort707

★★★★★★✩
21 Сен 2020
2,864
850
Вот поэтому то я и предложил передавать через целое 32битное число.
в смысле через print(d1) - то есть перевод в строку? А на приемнике конвертировать обратно ?Так тогда проще сразу флоат печатать

А если передавать "целое 32битное" через write - разницы с 4 байтами никакой
 

rGlory

★✩✩✩✩✩✩
11 Май 2021
200
20
Можно пример , когда это не сработает ?
Зачем вам пример? Это нелегально с точки зрения языка, а это значит, что рано или поздно вам попадется компилятор, который выдаст код, который не будет работать так, как вы ожидаете.