Уважаемые гуру пожалуйста подскажите. Я с ардуино знаком на весьма любительском уровне. Я взял скетч из примеров из библиотеки Modbus-Master-Slave-for-Arduino-master. В этом примере данные из регистров мдбас слейв устройств считываются в массив uint16_t au16data[]; В Модбас слейв в двух регистрах по 16 бит лежит одно значение float размером 32 бит то есть в двух ячейках uint16_t массива у меня сохраняться одно значение float размером 32 бит. Я планировал в скетче из двух uint16_t побитово перенести в переменную float 32 бита. Примерно так: Код (C++): uint16_t au16data[16] ; float volts ; bitWrite(volts, 0, bitRead(au16data [1], 0)); bitWrite(volts, 1, bitRead(au16data [1], 1)); bitWrite(volts, 2, bitRead(au16data [1], 2)); bitWrite(volts, 3, bitRead(au16data [1], 3)); bitWrite(volts, 4, bitRead(au16data [2], 0)); bitWrite(volts, 5, bitRead(au16data [2], 1)); bitWrite(volts, 6, bitRead(au16data [2], 2)); bitWrite(volts, 7, bitRead(au16data [2], 3)); Но компилятор ругается. Код (C++): C:\Users\Vitaly\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\cores\arduino/Arduino.h:112:37: error: in evaluation of 'operator|=(float, long unsigned int)' #define bitSet(value, bit) ((value) |= (1UL << (bit))) C:\Users\Vitaly\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\cores\arduino/Arduino.h:114:52: note: in expansion of macro 'bitSet' #define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) C:\Users\Vitaly\AppData\Local\Temp\arduino_modified_sketch_712994\sketch_jun25c.ino:121:5: note: in expansion of macro 'bitWrite' bitWrite(volts, 0, bitRead(au16data [1], 0)); C:\Users\Vitaly\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\cores\arduino/Arduino.h:113:39: error: invalid operands of types 'float' and 'long unsigned int' to binary 'operator&' #define bitClear(value, bit) ((value) &= ~(1UL << (bit))) C:\Users\Vitaly\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\cores\arduino/Arduino.h:114:73: note: in expansion of macro 'bitClear' #define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) C:\Users\Vitaly\AppData\Local\Temp\arduino_modified_sketch_712994\sketch_jun25c.ino:121:5: note: in expansion of macro 'bitWrite' bitWrite(volts, 0, bitRead(au16data [1], 0)); C:\Users\Vitaly\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\cores\arduino/Arduino.h:113:39: error: in evaluation of 'operator&=(float, long unsigned int)' #define bitClear(value, bit) ((value) &= ~(1UL << (bit))) C:\Users\Vitaly\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.21\cores\arduino/Arduino.h:114:73: note: in expansion of macro 'bitClear' #define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit)) C:\Users\Vitaly\AppData\Local\Temp\arduino_modified_sketch_712994\sketch_jun25c.ino:121:5: note: in expansion of macro 'bitWrite' bitWrite(volts, 0, bitRead(au16data [1], 0)); Встречал в инете обьяснение этому, но моих знаний не хватило понять это, там все была на СИ++. Пожалуйста подскажите, как в моем случае должен выглядеть код. Просьба сильно не пинать.
bitwrite не работает с плавающей точкой. тебе надо использовать union сначала, чтоб конвертировать float в 2 int-а. Код (C++): union IntConvert { int IntValues[2]; float FloatValue; } и потом засовывать int-ы в массив, а забирать оттуда float целиком. И наоборот. И массив и float физически находятся по одному и тому же адресу памяти, разное только обращение к ней. Прочитай за union чонить.
Не, а Здесь ТС не понимает, что он хочет сделать и что получить на выходе. union здесь не поможет, т.к. взвод бита для float это бред... Как он будет вытаскивать float на выходе??? 2-TC: Вы опишите, что вы хотите, может Вам и дадут правильный совет
Про union уже сказали. Ещё один путь - прямое копирование памяти: Код (C++): uint16_t from[2]; float to; uint8_t* fromRead = (uint8_t*) from; uint8_t* toWrite = (uint8_t*) &to; memcpy(toWrite,fromRead,4); // копируем 4 байта Но! Это не всегда корректно, хотя бы из-за порядка следования байт. И вообще - желание из двух целых скопировать во float - кмк, сигнализирует о том, что ТС не совсем понимает, что нужно. На примере: допустим, в одном uint16_t содержится значение температуры в целых, во втором - в десятитысячных долях. Тогда конвертируется это во float довольно просто: Код (C++): uint16_t tempWhole = 12; uint16_t tempFract = 1234; float result = tempWhole; result *= 10000.0; result += tempFract; result /= 10000.0;
Вот, для демонстрации безумства первого подхода (прямое копирование) и корректности работы второго - набросал тут: http://cpp.sh/ - небольшую программку: Код (C++): // Example program #include <iostream> #include <string> #include <cstring> int main() { uint16_t from[2] = {56,1234}; float to; uint8_t* fromRead = (uint8_t*) from; uint8_t* toWrite = (uint8_t*) &to; memcpy(toWrite,fromRead,4); // копируем 4 байта std::cout << to << "\n"; uint16_t tempWhole = 56; uint16_t tempFract = 1234; float result = tempWhole; result *= 10000.0; result += tempFract; result /= 10000.0; std::cout << result << "\n"; } Вывод программы:
а нельзя ли так: Код (C++): uint16_t a,b; //2 половинки числа uint32_t x; //временная переменная float32_t y; //результат x=a; x=x<<16; x=x+b; y=(float32_t)x; Чую, я не понял задачу.
Вот код: Код (C++): // Example program #include <iostream> #include <string> int main() { uint16_t a = 56,b=1234; //2 половинки числа uint32_t x; //временная переменная float y; //результат x=a; x=x<<16; x=x+b; y=(float)x; std::cout << y; } Тестировал здесь: http://cpp.sh/ Вывод: Не очень похоже на 56.1234, не находите?
В каком месте такое нельзя сделать на восьмибитке? Вывод в поток - дык это не основа алгоритма, это просто демонстрация результатов, не более того. Остальное - вполне валидный код на С++, который ОБЯЗАН компилироваться любым современным компилятором.
Огромное спасибо всем откликнувшимся за подсказки, кажется победил: Код (C++): int16_t au16data[]={17260, 0, 17259, 52429 };// 236.00 and 235.8 float* ptr_recData; uint8_t numPar =0; // номер параметра из массива float volts =0 ; int16_t temp[2]; void setup() { Serial.begin(9600); ptr_recData = (float*)(&temp[0]) ; // получаем адрес переменной } void loop() { temp [1] = au16data[(numPar*2)]; temp [0] = au16data[(numPar*2)+1]; volts =*ptr_recData; Serial.println(temp [0]); Serial.println(temp [1]); Serial.println(volts,8); Serial.println("_"); ++numPar*2; temp [1] = au16data[(numPar*2)]; temp [0] = au16data[(numPar*2)+1]; volts =*ptr_recData; Serial.println(temp [0]); Serial.println(temp [1]); Serial.println(volts,8); Serial.println("__________"); delay(2000); }
плавающая запятая для чего? Вывод на дисплей? Можно отдельно выводить целую и отдельно дробную. АЛУ АВР-ок и так убогое, а вы ему ещё и плавающую запятую....
Ну он же у него одни флоаты, да ещё и глобальные зачем-то. Ну ты прав - конкурентов не надо растить - без работы останешься. Ыыыы с такими горе программистами конкуренции не будет НИКОГДА. Так что я спокоен)))