#1 2025-03-14 14:49:31

Primaangel88
Учасник
Зареєстрований: 2025-03-13
Повідомлень: 15

Допомога з конвертацією float в HEX

Доброго дня, спільното!
попереджаю, я не програміст. керувати  реле, діодом, міряти температуру та інше по дрібноті вмію робити, але складні проекти ніколи не робив. Тому на перед прошу вибачення, якщо якусь нісенітницю напишу.

Тепер до справи.
задача: треба міряти температуру, потім це значення передавати на дисплей по serial у вигляді 5A A5 05 82 50 01 00 00

Підкажіть як конвертувати значеня float в HEX і внести в останні 2 значення масиву. взагалі не розумію які операції треба виконати.


#include <microDS18B20.h>
#define DS_PIN 2 // пин для термометров
// Уникальные адреса датчиков - считать можно в примере address_read
uint8_t s1_addr[] = {0x28, 0xFF, 0x6D, 0x56, 0x1E, 0xE1, 0xF8, 0xDD};
MicroDS18B20<DS_PIN, s1_addr> sensor1;  // Создаем термометр с адресацией
  // Создаем термометр с адресацией
byte Send_ar[8] = {0x5A, 0xA5, 0x05, 0x82, 0x50, 0x02, 0x00, 0x00}; //массив с командой на дисплей
// в номера 6-7 будем записывать значение температуры float в Hex формате
float temp1; //переменная для хранения температуры
void setup() {
  Serial.begin(115200); //общение с дисплеем по сериал
}
void loop() {
  
  sensor1.requestTemp();      // Запрашиваем преобразование температуры
  delay(1000);           // ожидаем результат 
 
  temp1 = sensor1.getTemp(); //запись температуры в переменную

  

delay(1000);
Send_ar[7] = 22;//меняем значение и смотрим на реакцию дисплея
Serial.write(Send_ar,8);  // это команда отправки массива
delay(1000);
Send_ar[7] = 01;//меняем значение и смотрим на реакцию дисплея
Serial.write(Send_ar,8);  // это команда отправки массива
        

  }
 

Остання редакція Primaangel88 (2025-03-14 14:50:42)

Неактивний

#2 2025-03-14 15:13:47

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 316

Re: Допомога з конвертацією float в HEX

Primaangel88 пише:

Підкажіть як конвертувати значеня float в HEX і внести в останні 2 значення масиву. взагалі не розумію які операції треба виконати.

Тип float в C++ - це 4 байта (в більшості реалізацій це IEEE 754). В 2 байта без втрати точності вони не влізуть. В якому конкретно форматі потрібно представити значення float? Який порядок байт, little endian чи big endian?

Є здогадка, що ви хочете відображати температуру у вигляді двозначного десяткового числа. Якщо так, то для цього ніякого конвертування float в HEX не потрібно. Що за дисплей? В якому форматі він очікує дані, ASCII-коди символів?

Неактивний

#3 2025-03-14 16:22:28

Primaangel88
Учасник
Зареєстрований: 2025-03-13
Повідомлень: 15

Re: Допомога з конвертацією float в HEX

Вибачаюсь. Уточнюю тип данних int 2 байта.
Дисплей DWIN DMT80600L104_02wtz6F
має отримувати данні в вигляді ASCII. останні два байти це данні які треба записати
я пробував записати 0x00 0x22 на виході маю значення 0.22, якщо записати 0x22 0x00 на дисплеї 56.32

Остання редакція Primaangel88 (2025-03-14 16:28:03)

Неактивний

#4 2025-03-14 17:21:49

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 316

Re: Допомога з конвертацією float в HEX

Primaangel88 пише:

Вибачаюсь. Уточнюю тип данних int 2 байта.
Дисплей DWIN DMT80600L104L104_02wtz6F
має отримувати данні в вигляді ASCII. останні два байти це данні які треба записати

Так в якому форматі мають бути дані? Припустимо, значення temp1 = 42.7315. Які значення у тих двох байтах будуть відповідати цьому значенню temp?

Якщо потрібно записати цілу частину float'а як 2-байтовий int, тоді в разі big endian:

uint16_t t = temp1;
Send_ar[6] = t >> 8;
Send_ar[7] = t & 0xff;

В разі little endian:

uint16_t t = temp1;
Send_ar[6] = t & 0xff;
Send_ar[7] = t >> 8;

(Для знакових int це працюватиме тільки в системі з доповненням до 2-х).

А що записувати, якщо значення float не вміщається в 2-байтовий int?

Якщо ж потрібно записати ASCII-коди десяткового представлення цілої частини float, тоді можна щось типу

if (temp >= 0 && temp < 100) {
    uint16_t t = temp1;
    Send_ar[6] = t / 10 + '0';
    Send_ar[7] = t % 10 + '0';
} else {
    Send_ar[7] = Send_ar[6] = '-';
}

Звідки ви взяли цю адресу 0x5002 для запису командою 0x82? Там же має бути описаний і формат даних. Наприклад, згідно з цим мануалом, 0x5002 - це взагалі якийсь байт статуса чи то відтворення відео, чи то якоїсь анімації. Навряд чи те, що вам потрібно. Наскільки розумію, ті дисплеї мають купу різних варіантів прошивок, у яких одні й ті ж адреси мають різні призначення.
Уточніть в документації на конкретно вашу версію прошивки, за якою адресою і в якому точно форматі потрібно писати дані для відображення.

Неактивний

#5 2025-03-14 17:29:22

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 316

Re: Допомога з конвертацією float в HEX

Primaangel88 пише:

я пробував записати 0x00 0x22 на виході маю значення 0.22, якщо записати 0x22 0x00 на дисплеї 56.32

О, це вже щось. Для 0x00 0x22 я би сказав, що це BCD, але тоді для 0x22 0x00 було би 22.00. Гіпотеза про BCD не підтверджується. Які значення на дисплеї відповідають наступним записаним значенням:
0x01 0x00
0x00 0x01
0x80 0x00
0x00 0x80
0x55 0x55
?

Неактивний

#6 2025-03-14 17:43:41

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 316

Re: Допомога з конвертацією float в HEX

5632₁₀ = 1600₁₆, 16₁₆ = 22₁₀
Таки схоже на якесь недо-BCD.

Неактивний

#7 2025-03-14 19:44:15

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 316

Re: Допомога з конвертацією float в HEX

Можна припустити, що відображається число (N*256+M)/100, де N - перший байт двічі в BCD, M - другий байт один раз в BCD. Але це якесь збочення. Там же в цих дисплеях наче програмується формат даних для відображення. Може варто перепрограмувати сам дисплей, щоб сприймав дані у нормальному форматі, аніж підганяти дані під такий дивний формат?

Неактивний

#8 2025-03-14 20:14:01

jokeer
Гість

Re: Допомога з конвертацією float в HEX

Якщо хочеться зайнятися хакерством, спробуйте міняти окремі біти в команді і дивитися до чого це приводить.

#9 2025-03-15 12:19:08

Primaangel88
Учасник
Зареєстрований: 2025-03-13
Повідомлень: 15

Re: Допомога з конвертацією float в HEX

dimich пише:
Primaangel88 пише:

я пробував записати 0x00 0x22 на виході маю значення 0.22, якщо записати 0x22 0x00 на дисплеї 56.32

О, це вже щось. Для 0x00 0x22 я би сказав, що це BCD, але тоді для 0x22 0x00 було би 22.00. Гіпотеза про BCD не підтверджується. Які значення на дисплеї відповідають наступним записаним значенням:
0x01 0x00
0x00 0x01
0x80 0x00
0x00 0x80
0x55 0x55
?

0x01 0x00 -> 2.56
0x00 0x01 -> 0.01
0x80 0x00 -> 20.48
0x00 0x80 -> 1.28
0x55 0x55 -> 18.45

налаштуванням відображення вказаних вище
variable type (int 2 bytes)
integer digits 2
decimal digits 2

змінив налаштування:
variable type (int 2 bytes)
integer digits 2
decimal digits 1

отримані результати:
0x01 0x00 -> 25.6
0x00 0x01 -> 0.1
0x80 0x00 -> 04.8
0x00 0x80 -> 12.8
0x55 0x55 -> 84.5


таке враження що він отримує число без коми, а потім розтавляє кому так я вказано в налаштуваннях скільки чисел вказувати до та після коми, починаючи з останньої. Тобто якщо отримане число 21845(HEX 0x55 0x55), а вказано що після коми одна цифра, до коми 2 цифри, то він ставить кому так 2184.5  а першу та другу цифру не відображує бо вказано лише 2 відображати.




dimich пише:

Звідки ви взяли цю адресу 0x5002 для запису командою 0x82? Там же має бути описаний і формат даних. Наприклад, згідно з цим мануалом, 0x5002 - це взагалі якийсь байт статуса чи то відтворення відео, чи то якоїсь анімації. Навряд чи те, що вам потрібно. Наскільки розумію, ті дисплеї мають купу різних варіантів прошивок, у яких одні й ті ж адреси мають різні призначення.
Уточніть в документації на конкретно вашу версію прошивки, за якою адресою і в якому точно форматі потрібно писати дані для відображення.

процессор T5 версія оболонки T5UIC3.

адреси взяв з китайських відеоуроків по програмуванню(створенню інтерфейса) дисплеїв DWIN
кнопки змінюють по 1 біт за адресою 5001 від 0 до 15(тобта в одній адресі може вмістититись керування 16 кнопок)
в мене наприклад 3
при натисканні кнопки дисплей видає в серіал наступне: 5A A5 06 83 50 01 01 00 01 (натиснута кнопка 1)
приведу список як змінюється дата в залежності від натиснутих кнопок:
1-off 2-off 3-off ->0000
1-on 2-off 3-off ->0001
1-on 2-on 3-off ->0002
1-on 2-on 3-off ->0003
1-off 2-off 3-on ->0004
1-on 2-off 3-on ->0005
1-off 2-on 3-on ->0006
1-on 2-on 3-on ->0007



за документаціє на дисплей


Структура кадру даних
Має наступний формат:
<Frame Header H> <Frame Header L> <Byte Count> <Command> [<Data>] [<CRC H> <CRC L>]
Скорочений запис:
<FHH> <FHL> <BC> <CMD> [<DATA>] [<CRCH> <CRCL>]

• Frame Header/FH - заголовок кадру: визначає початок кадру. Може використовуватись для унікальної ідентифікації кількох LCM на шинах зв'язку.
Значення за промовчанням = 0x5AA5.
• Byte Count/BC - кількість байт: кількість байтів у кадрі! виключаючи заголовок кадру(2байта) і цей байт.
Тобто кількість байт, що розпочинаються з командного байта.
Разом реальна довжина кадру: ByteCount + 3 байти.
• CMD – Команда: визначає команду, яка має бути виконана.
• Data - Дані: корисне навантаження кадру, складається з: адреси, довжини та значень. (0x50 0x00 [адреса] 0х01[довжина] 0хFF 0xFF[значення])
• CRC-16: хеш із 2 байт для виявлення пошкодження цілісності кадрів. Активується через файл CFG.(в моєму випадку вимкнено)

Остання редакція Primaangel88 (2025-03-15 13:37:50)

Неактивний

#10 2025-03-15 13:34:41

jokeer
Гість

Re: Допомога з конвертацією float в HEX

Ну, документація у вас є. Вам треба передати правильну команду і правильні дані, я правильно зрозумів?

#11 2025-03-15 13:40:16

Primaangel88
Учасник
Зареєстрований: 2025-03-13
Повідомлень: 15

Re: Допомога з конвертацією float в HEX

jokeer пише:

Ну, документація у вас є. Вам треба передати правильну команду і правильні дані, я правильно зрозумів?

так, я просто не розумію як перетворити десяткове число наприклад 26.4212 в ціле без коми 264212, обрізати до 4 чисел та перетворити в hex 0xFF 0xFF, щоб записати в масив.

Остання редакція Primaangel88 (2025-03-15 13:43:27)

Неактивний

#12 2025-03-15 13:56:42

jokeer
Гість

Re: Допомога з конвертацією float в HEX

> як перетворити десяткове число наприклад 26.4212 в ціле без коми 264212

int(26.4212 * 10000)

> обрізати до 4 чисел

треба отримати 2642?  int(26.4212 * 100)


> перетворити в hex

поясніть.  Треба отримати 0A52, 520А, 2642, 4226? яке кодування потрібно?

#13 2025-03-15 15:39:17

Honey
Учасник
З Київ
Зареєстрований: 2020-09-26
Повідомлень: 442

Re: Допомога з конвертацією float в HEX

float floatval = 26.4212;
int intval = floatval * 100 + 0.5;
Send_ar[6] = intval >> 8;
Send_ar[7] = intval & 0xff;

Неактивний

#14 2025-03-15 18:26:07

Primaangel88
Учасник
Зареєстрований: 2025-03-13
Повідомлень: 15

Re: Допомога з конвертацією float в HEX

Honey пише:

float floatval = 26.4212;
int intval = floatval * 100 + 0.5;
Send_ar[6] = intval >> 8;
Send_ar[7] = intval & 0xff;

спрацювало!!
не зразумів тільки як працює цей оператор. Якщо можна як це правильно називається?
intval >> 8;
апдейт: знайшов бітовий зсув)))

Дуже дякую dimich. Ваші питання вивели мене в правильне русло і дали поштовх для подальшого вивченя в правильному напрямку.
Також велике дякую Honey за кодінг!!!

Трохи пізніше допишу скетч з нормальними таймерами без delay,  та додам код керування реле.
Готовий скетч викладу тут.

Ще раз велика подяка!

Остання редакція Primaangel88 (2025-03-15 18:31:44)

Неактивний

#15 2025-03-15 20:10:51

jokeer
Гість

Re: Допомога з конвертацією float в HEX

Можна і без зсувів і масок

union myUnion {
    uint32_t  myint;
    struct {
        uint8_t b1;
        uint8_t b2;
        uint8_t b3;
        uint8_t b4; // or number them in reverse order
    } myBytes;

myUnion x;
x.myint = 2642;
Send_ar[7] =x.myBytes.b0;

#16 2025-03-15 20:23:12

Primaangel88
Учасник
Зареєстрований: 2025-03-13
Повідомлень: 15

Re: Допомога з конвертацією float в HEX

Jokeer вам теж дуже дякую!
Теж дали поштовх щоб разібразітисьв кодуваннях!!
Мені більш зрозуміла конструкція з зсувом. Можливо простотою використання з обмеженими, поки що, знаннями.
Ваш приклад кодінгу теж збережу, потроху і з ним розберусь як працює конструкція.

Остання редакція Primaangel88 (2025-03-15 20:25:56)

Неактивний

#17 2025-03-15 20:38:36

jokeer
Гість

Re: Допомога з конвертацією float в HEX

В вашому випадку union масива і структури буде працювати наглядніше.
В структуру з іменованими полями записуєте дані, масив передаєте в Serial. Ніякої магії типу send_ar[7] - таке складно читати

Також
Arduino has two helper functions (highByte() and lowByte()) for beginners or those not familiar with bit manipulation.

#18 2025-03-15 22:51:03

Primaangel88
Учасник
Зареєстрований: 2025-03-13
Повідомлень: 15

Re: Допомога з конвертацією float в HEX

Jokeer, дякую за пояснення.

тим часом зібрав код в купу, але є ньюанс.

нижче мій скетч.
при запускі программи керує реле, але температура не оновлюється, а лише при натисканні кнопки на дисплеї

код не мій, я просто підлаштував його під себе.

#include <microDS18B20.h>
#define DS_PIN 2 // пин для термометров
// Уникальные адреса датчиков - считать можно в примере address_read
uint8_t s1_addr[] = {0x28, 0xFF, 0x6D, 0x56, 0x1E, 0xE1, 0xF8, 0xDD};
MicroDS18B20<DS_PIN, s1_addr> sensor1;  // Создаем термометр с адресацией
  // Создаем термометр с адресацией
byte Send_ar[8] = {0x5A, 0xA5, 0x05, 0x82, 0x50, 0x02, 0x00, 0x00}; //массив с командой на дисплей
byte Send_ar1[8] = {0x5A, 0xA5, 0x05, 0x82, 0x50, 0x03, 0x00, 0x00}; //массив с командой на дисплей
// в номера 6-9 будем записывать значение температуры float в Hex формате
float temp1; //переменная1 для хранения температуры
float temp2; //переменная2 для хранения температуры
float temp3; //переменная3 для хранения температуры
float floatval;
int intval;
bool flag1 = false;
uint32_t tmr1=0;
uint32_t tmr2=0;
uint32_t tmr3=0;
// настройка работы с реле// 
const bool level = 0;         // 1 - реле высокого уровня 0 - реле низкого уровня
const byte relays_num = 3;    // Количество реле
byte relays[relays_num] = {4, 5, 6}; // Пины подключения реле
//не трогать //
byte Buffer[20];     //Создать буфер
byte Buffer_Len = 0;
bool flag = false;   // флаг чтения данных с монитора

void setup() {
  Serial.begin(115200); //общение с дисплеем по сериал

  for (byte i = 0; i < relays_num; i++)
  {
    pinMode(relays[i], OUTPUT);
    if (!level)
      digitalWrite(relays[i], HIGH);
  }

}
void loop() {
  
 ReadSerial();
 
  if (millis()-tmr1 >= 1000){//таймер на запрос температуры
  sensor1.requestTemp();      // Запрашиваем преобразование температуры
  tmr1=millis(); // сброс таймера
  flag1=!flag1; // подымаем флаг, формируется значение температуры
  }
  if(millis()-tmr2 >=1000 & flag){ //ждем время и флаг готовности
  temp1 = sensor1.getTemp(); //запись температуры в переменную
  tmr2 = millis(); //сброс таймера
  flag1=!flag1;//опускаем флаг, температура прочитана, ожидаем следуйщий цикл
  }
  if (millis()-tmr3 >= 1000){ //таймер на отправку данных на дисплей 
float floatval = temp1;
int intval = floatval * 100 + 0.5; //конвертируем значение температуры из float в HEX и записываем значения в массив
Send_ar[6] = intval >> 8;
Send_ar[7] = intval & 0xff;
Serial.write(Send_ar,8);

floatval = temp1;
intval = floatval * 100 + 0.5; //конвертируем значение температуры из float в HEX и записываем значения в массив
Send_ar1[6] = intval >> 8;
Send_ar1[7] = intval & 0xff;
Serial.write(Send_ar1,8);
tmr3=millis(); // сброс таймера
 }
 
  }

і другий файл

// читаем монитор порта
void ReadSerial()
{
  if (Serial.available())
  {
    Buffer[Buffer_Len] = Serial.read();
    Buffer_Len++;
    flag = true;
  }
  else
  {
    if (flag)
    {
      if (Buffer[0] == 0X5A & Buffer[3] == 0X83) {
        
          if (Buffer[4] == 0X50) {           
            for (byte i = 0; i < relays_num; i++)
           {
              digitalWrite(relays[i], level == 0 ? !bitRead(Buffer[8], i) : bitRead(Buffer[8], i));
           }
         
        
        }
      }
      Buffer_Len = 0; // сброс номера элемента в массиве
      flag = false;      
    }
  }
}

я підозрюю що я щось не врахував при роботі з буфером...
але що не бачу....

Остання редакція Primaangel88 (2025-03-15 22:52:40)

Неактивний

#19 2025-03-15 22:58:03

jokeer
Гість

Re: Допомога з конвертацією float в HEX

я думаю що у дисплея повинна бути окрема команда для відображення даних.

#20 2025-03-15 23:10:18

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 316

Re: Допомога з конвертацією float в HEX

jokeer пише:

Можна і без зсувів і масок

union myUnion {

Можна і без union:

uint16_t myint;
...
Send_ar[6] = (reinterpret_cast<uint8_t *>(&myint))[1];
Send_ar[7] = (reinterpret_cast<uint8_t *>(&myint))[0];

або по-C-шному:

Send_ar[6] = ((uint8_t *)&myint)[1];
Send_ar[7] = ((uint8_t *)&myint)[0];

Але що цей варіант, що варіант з union даватимуть різні результати на little endian та big endian процесорах. А варіант зі зсувами і масками портабельний, результат не залежить від архітектури процесора.

Неактивний

#21 2025-03-15 23:11:39

Primaangel88
Учасник
Зареєстрований: 2025-03-13
Повідомлень: 15

Re: Допомога з конвертацією float в HEX

команда на запис 0X82
дисплей відповідає 0X83

Остання редакція Primaangel88 (2025-03-15 23:13:15)

Неактивний

#22 2025-03-15 23:20:33

jokeer
Гість

Re: Допомога з конвертацією float в HEX

Ну, якщо складно з командами дисплея, можна паралельно кнопці припаяти ключ і нажимати автоматично  wink
До речі, може є десь ліба для вашого дисплея? Чи приклад готового коду?

#23 2025-03-15 23:39:07

Primaangel88
Учасник
Зареєстрований: 2025-03-13
Повідомлень: 15

Re: Допомога з конвертацією float в HEX

дивно якось, окремо скетчі працюють без питань, але кол склав в один то частина коду що відповідає за передачу данних на дисплей спрацьовує тільки коли скетч відпрацьовує команду натискання кнопки, і далі це значення зависає і постійно повторюється в серіал.
і не можу увімкнути відладку в серіал бо інакше дисплей сприймає ці данні і все ламається. завтра спробую посадити дисплей на софт серіал і спробую зрозуміти що не так.

Остання редакція Primaangel88 (2025-03-15 23:43:09)

Неактивний

#24 2025-03-15 23:55:16

jokeer
Гість

Re: Допомога з конвертацією float в HEX

ReadSerial виглядає по наркоманськи wink складно врюхати що там повинно відбуватися. Не люблю вкладені if з купою дужок.
може це якось пов'язане з тим, що ви передаєте 2 команди, а читаєте 1 відповідь?

#25 2025-03-15 23:57:29

jokeer
Гість

Re: Допомога з конвертацією float в HEX

ReadSerial виглядає по наркоманськи wink складно врюхати що там повинно відбуватися. Не люблю вкладені if з купою дужок.
може це якось пов'язане з тим, що ви передаєте 2 команди, а читаєте 1 відповідь?

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

Підвал форуму