andybeg
Jul 21 2010, 15:44
пытаюсь конвертировать модбас данные во флоут
Цитата
union { float fVal; unsigned char bytes[4]; } value;
value.bytes[0] = data[4];
value.bytes[1] = data[3];
value.bytes[2] = data[6];
value.bytes[3] = data[5];
printf("\n float = %f \n", value.fVal);
и на принтфе просто без ругани выкидывает из программы
Savrik
Jul 21 2010, 17:18
Странно.. Код на первый взгляд без ошибок.. Попробуйте вместо data[х] присвоит какое-то значение, скажем, запишите туда единицы. И запустите
andybeg
Jul 21 2010, 19:04
попробовал ещё один вариант перевда во флоут
Цитата
float Float(const unsigned char* p)
{
float val;
memcpy(&val,p,sizeof(val));
return val;
}
arr[0] = data[4];
arr[1] = data[3];
arr[2] = data[6];
arr[3] = data[5];
fl = Float(arr);
printf("\n float = %f \n", fl);//(unsigned int)value.fVal);
результат тот е, только теперь уж понятно что вылетет именно при выводе числа
Savrik
Jul 21 2010, 19:34
мм.. даже не знаю.. На большом брате все работает, значит, трабл в железе.. компилируется без варнингов? Памяти досаточно?
А вообще что-либо printf() выводит?
andybeg
Jul 22 2010, 01:56
варнинг то я и не заметил
Цитата
incompatible implicit declaration of built-in function ‘memcpy’
правда ворнинг появляется только во втором варианте кнвертации, в первом его естественно нет
принтф печатает
Цитата
float = />
sergeeff
Jul 22 2010, 05:55
А вы уверены, что в вашем варианте printf вообще активирована поддержка float? Попробуйте, для проверки:
Код
float vv = 123.567;
printf("float = %f\n", vv);
Работает?
1) Формирование строки сделайте с помощью sprintf, а выдачу строки - с помощью printf.
2) В вашем компиляторе float может оказаться 16-битным и правильнее написать double.
3) Полезно почитать книгу Керниган Б.В. и Ричи Д.М. -Язык C
andybeg
Jul 22 2010, 18:47
Цитата
активирована поддержка float?
вероятно не активирована, не работает, по итогу привёл к инту и пользовал эти флоуты так, в конце концов пока что дробная часть не актуальна
Цитата
2) В вашем компиляторе float может оказаться 16-битным и правильнее написать double.
дабл постигла та же участь
Цитата
1) Формирование строки сделайте с помощью sprintf, а выдачу строки - с помощью printf.
3) Полезно почитать книгу Керниган Б.В. и Ричи Д.М. -Язык C
попробую
При таком заполнении flоat-переменной
Код
union { float fVal; unsigned char bytes[4]; } value;
value.bytes[0] = data[4];
value.bytes[1] = data[3];
value.bytes[2] = data[6];
value.bytes[3] = data[5];
может оказаться, что вы записали в него "нечисло". Т.к. далеко не любая комбинация битов является валидным значением float.
А бедняга printf начинает конверировать инвалидное число в десятичное и сходит с ума

.
Мой совет: ... потренируйтесь на нулях
andybeg
Jul 23 2010, 01:58
Цитата
может оказаться, что вы записали в него "нечисло". Т.к. далеко не любая комбинация битов является валидным значением float.
А бедняга printf начинает конверировать инвалидное число в десятичное и сходит с ума smile.gif.
Мой совет: ... потренируйтесь на нулях smile.gif
не сцать - записываю число, ибо после приведения к инту получаю правильное число без дробной части
forever failure
Jul 23 2010, 04:25
1. Каким образом первоначально формируются эти четыре байта ?
2. Порядок следования байт (little/big) endian, не ?
3. Тема целевой платформы, на которой происходит выполнение не раскрыта.
andybeg
Jul 23 2010, 04:49
Цитата
1. Каким образом первоначально формируются эти четыре байта ?
MODBUS и ещё раз повторюсь - разбираю я их верно
Цитата
3. Тема целевой платформы, на которой происходит выполнение не раскрыта.
а тема нет? никак не названа?
forever failure
Jul 23 2010, 05:06
Про тему пардон, в шары долблюсь.
Верно - это как ? Они из каких данных составляются, в коде покажите. Ну и опять же на АРМе порядок следования байт может быть любым. Он одинаков на обоих сторонах модбаса ?
andybeg
Jul 23 2010, 05:34
верно это так что с ttyS имею протокол модбас и входящую посылку <01><03><04><D1><C7><47><81><81><62> где болдом обозначены байты данных, они запихиваются в массив data c которым проводятся выше опсанные манипуляции и по итогу печатаем printf("\n float = %d \n", (unsigned int)fl); получая на выходе верное число без дробной части, а при чистом флоуте printf("\n float = %lf \n",fl); программа вылетает
sasamy
Jul 23 2010, 06:38
Цитата(andybeg @ Jul 21 2010, 18:44)

value.bytes[0] = data[4];
value.bytes[1] = data[3];
value.bytes[2] = data[6];
value.bytes[3] = data[5];
Как-то приходилось работать с одним тепловычислителем, так там честно говорили что протокол modbus-подобный и float передавались с порядком байт little-endian друг за другом:
value.bytes[0] = data[3];
value.bytes[1] = data[4];
value.bytes[2] = data[5];
value.bytes[3] = data[6];
forever failure
Jul 23 2010, 06:49
Ну а на другом конце модбаса эти отмеченные болдом байты из чего берутся ?
И: верность числа в чём заключается ?
А так, в качестве опыта, - подставьте ваши болдом выделенные баты в любой хекс-эдитор, и посмотите, какому значению четырёхбайтной плавучки эти байты соответствуют.
andybeg
Jul 23 2010, 06:58
Цитата
value.bytes[0] = data[3];
value.bytes[1] = data[4];
value.bytes[2] = data[5];
value.bytes[3] = data[6];
с модбасом вапще часто творят что хотят, канонически быйты идут в том порядке в котором сделано у меня
forever failure
Jul 23 2010, 07:01
Пробую телепатировать: должно получится 66467.6, нет, не так ?
Если так, то ваш линукс и иполняемое приложение должно исползовать little endian порядок байт. Иначе пробуйте заполнять выше обозначенный унион в обратном порядке:
value.bytes[3] = data[4];
value.bytes[2] = data[3];
value.bytes[1] = data[6];
value.bytes[0] = data[5];
andybeg
Jul 23 2010, 07:08
Цитата
И: верность числа в чём заключается ?
предлагаю закрыть тему
неверного фрмирования флоута, провёл эксперимент
Цитата
vv=123.456;
printf("\n int %d ",(unsigned int)(10*vv));
и на выходе получил 1234, думаю можно сделать вывод о том что проблемы именно с принтфом
Цитата
Пробую телепатировать: должно получится 66467.6, нет, не так ?
именно так
forever failure
Jul 23 2010, 07:28
Да именно так, похоже неверным оказывается printf
sasamy
Jul 23 2010, 07:55
Цитата(andybeg @ Jul 22 2010, 22:47)

вероятно не активирована, не работает, по итогу привёл к инту и пользовал эти флоуты так, в конце концов пока что дробная часть не актуальна
Хе - сначала не заметил этот момент, там похоже какой-то лихой тулчейн используется, принципиально новый ;-)
sergeeff
Jul 23 2010, 18:04
Цитата(forever failure @ Jul 23 2010, 10:28)

Да именно так, похоже неверным оказывается printf
Возьмите printf из любой библиотеки (например DietLib), переименуйте printf из этого модуля и подключите к своему проекту. Сразу все увидите. Удивительно сколько времени тратится на изучение "black box'a" в виде непонятно кем сделанной библиотеки.
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.