Преобразование char to float
- Войдите на сайт для отправки комментариев
Здравствуйте, уважаемые форумчане! Возникла проблема с преобразованием массива char во float.
Использую atmega328p, к которой подключен GPS-приемник (код пишу на Atmel Studio 7.0). Через прерывание приемник-антенна передает микроконтроллеру NMEA-данные вот такие:
$GNRMC,173754.00,A,4314.25363,N,07649.87564,E,0.271,,00820,,,A*63
$GNVTG,,T,,,0.271,N,0.52,K,A*3E
$GGGA,173754.0,4314.25363,,07649.87564E,1,08,2.51,09.9,M,-48.0M,,*61
$GNGA,A,3,04,26,1,09,,,,,,,,3.52,2.51,2.7*14
$GNGSAA,3,66,76,6775,,,,,,,,,352,2.51,2.471D
$GPGSV,21,08,04,60,32,41,06,08,38,,07,03,250,09,23,301,2*72
$GPGSV2,2,08,16,52154,,26,55,07,27,29,05,06,24,31,24,01,25*79
$GLSV,2,1,08,6516,144,23,6682,134,23,6740,324,33,7524,038,28*62$GLGSV,2,2,8,76,76,021,1,77,44,226,83,00,319,,8,05,011,*63
$GNGLL,4314.5363,N,0764987564,E,17374.00,A,A*73
Я беру только одну строку $GNRMC:
$GNRMC,173754.00,A,4314.25363,N,07649.87564,E,0.271,,00820,,,A*63
Далее из этой строки мне нужно взять только значение 0.271 (это скорость в узлах).
И вот здесь возникает проблема
вот небольшой код
char speed[10]; float a; float b; int main() { USARTInit(MYUBRR); _delay_ms(2000); sei(); while(1) { cli(); for(int i=0;i<ind;i++) send_Uart(buf[i]); // это для проверки, приходит ли строка. ind=0; if(stringReceived == 1) { for(int i=7;i<13;i++) // из строки GNRMC вытаскиваем значение скорости в узлах { speed[i]=buf[i]; } a = atof(speed); b = a*1,852; // чтобы получить скорость в км/ч нужно домножить на коэффициент send_Uart(b); } } return 0; }
В итоге результат. Вместо значения скорости рисует кракозябру.
В чем может быть проблема? Программу для вывода использую Terminal v1.9b
http://arduino.ru/forum/obshchii/kak-postich-nepostizhimoe#comment-388080
Да я вытащить скорость могу, у меня не получается преобразовать ее в float чтобы потом произвести математические действия.
Не понимаю, что происходит в небольшом примере, однако строки в Си называются ASCIIZ именно потому, что в конце они затерминированны нулем. Без такой терминации любая строковая функция будет работать как бог на душу положит.
atof()
Код Вы привели неполностью (в таком виде он не то что не работает, а даже не компилируется), поэтому понять что Вы там вытаскиваете из строки невозможно.
Данные из строки Вы вытаскиваете скорее всего неправильно. Точнее сказать не могу, т.к. код неполный, но по тому, что я вижу, скорее всего результат должен быть случайным.
Какая именно религия мешает Вам напечатать переменную speed перед строкой №26, чтобы хоть видеть что Вы там собрались преобразовывать?
Да код не полный, там просто много чего он делает, попытался сократить чтобы понятнее было. Вот еще
там где цикл for вот такое значение for(int i=46;i<51;i++)
А зачем ее снова объявлять переменную speed, тем более перед ним записываются данные в это массив?
Я дико извиняюсь за такой код. Сейчас сделаю его понятнее вам.
Клоунада очередная???
Там ещё строка #54 доставляет, но, видимо, в Студии свои законы физики и логики.
Клоунада очередная???
В смысле?
Клоунада очередная???
Кажется я догадываюсь)
А что не так с 54 строкой?
А, там ещё и cli приделано. Когда в буфер нормальные байты успевают попадать - не понимаю.
А зачем ее снова объявлять переменную speed, тем более перед ним записываются данные в это массив?
А я разве говорил "объявлять"? Я говорил
Напечатайте и посмотрите что в ней.
1. Вы неправильно готовите строку для atof (напечатайте её и убедитесь)
2. Вы уверены, что функции send_Uart можно передавать float и она адекватно переведёт Ваш float обратно в строку для печати?
3. Где, когда и при каких обстоятельствах ind получает начальное значение?
Т.е. сначала Вы неправильно формируете строку для перевода во float, а птом Вы этот float неправильно печатаете.
А зачем ее снова объявлять переменную speed, тем более перед ним записываются данные в это массив?
А я разве говорил "объявлять"? Я говорил
Напечатайте и посмотрите что в ней.
1. Вы неправильно готовите строку для atof (напечатайте её и убедитесь)
2. Вы уверены, что функции send_Uart можно передавать float и она адекватно переведёт Ваш float обратно в строку для печати?
3. Где, когда и при каких обстоятельствах ind получает начальное значение?
Т.е. сначала Вы неправильно формируете строку для перевода во float, а птом Вы этот float неправильно печатаете.
Ну вот смотрите я поставлю два вывода для speed (один в цикле, другой после)
вот так:
Результат на программе Terminal:
А зачем ее снова объявлять переменную speed, тем более перед ним записываются данные в это массив?
А я разве говорил "объявлять"? Я говорил
Напечатайте и посмотрите что в ней.
1. Вы неправильно готовите строку для atof (напечатайте её и убедитесь)
2. Вы уверены, что функции send_Uart можно передавать float и она адекватно переведёт Ваш float обратно в строку для печати?
3. Где, когда и при каких обстоятельствах ind получает начальное значение?
Т.е. сначала Вы неправильно формируете строку для перевода во float, а птом Вы этот float неправильно печатаете.
2. По поводу float и send_Uart. Да я понял теперь что нужно сделать отдельный вывод для float, спасибо.
3. По поводу ind. А он здесь причем? Интересует то совсем другое. Я его обнуляю. Потому что потом снова пойдет счет по прерыванию, где снова будет ловится строка GNRMC.
Вы нам специально мозги канифолите? В send_Uart_str() что передаёте? А буквы свои куда пишете?
Я сделал два вывода, один внутри цикла, другой вне цикла, для проверки, как просил Евгений П. Вывожу значение скорости
Чем отличается *speed от speed[46] ?
Одна берется из массива char speed, другая из массива char buf
Одна берется из массива char speed, другая из массива char buf
там не speed[46], там диапазон с 46 до 51 ячейки массива buf[100]
Отличаются чем эти две записи? Суть их какова? Пока этого не выясните - нет никакого смысла разбирать строку.
Вы опять привели код не полностью! Избавьтесь от этой дебильной привычки! Ну, трудно же работать!
Вот Вы написали
А speed как объявлен? Также, как и раньше?
char
speed[10];
(если бы Вы привели код полностью - вопроса бы не было!)
Т.е. Вы в переменную у которой всего 10 элементов (с 0-го по 9-ый), пишете в позиции 46 и далее, а потом печатаете её с 0-ой позиции? И Вас удивляет, что там что-то не то печатается? А почему там должно быть "то"?
Вы опять привели код не полностью! Избавьтесь от этой дебильной привычки! Ну, трудно же работать!
Вот Вы написали
А speed как объявлен? Также, как и раньше?
char
speed[10];
(если бы Вы привели код полностью - вопроса бы не было!)
Т.е. Вы в переменную у которой всего 10 элементов (с 0-го по 9-ый), пишете в позиции 46 и далее, а потом печатаете её с 0-ой позиции? И Вас удивляет, что там что-то не то печатается? А почему там должно быть "то"?
Да, все верно. Я учел все замечания, теперь вроде что-то получается. Хотя все равно придется допиливать)
Господа-программисты, спасибо вам всем за помощь. Не зря есть пословица что "в споре рождается истина". Я учел все ваши замечания и что-то уже исправляется,и это очень радует. До идеала конечно далеко, но буду доделывать)).
"в споре рождается истина".
А что, был какой-то спор? Не заметил.
что-то уже исправляется
Не думаю.
Вы изначально чрезмерно усложнили код, а теперь геройски пытаетесь его исправить.
Вот, допустим, что Вы поняли что не так с формирование переменной speed. Давайте пойдём чуть дальше.
Скажите мне, а вот вообще нафига
попу гармоньВам эта переменная speed? Вот просто на-фи-га?Если Вы уже нашли начала интересующего Вас числа в массиве buf, кто Вам мешает преобразовать его прямо оттуда? Зачем его копировать в какой-то speed? Функции atof глубоко плевать, что идёт в строке после числа - она выбирает только число, а на остальное кладёт.
Чтобы убедиться в этом, достаточно запустить простой проверочный скетч (обратите внимание, я привожу полный скетч. который Вы можете легко скопировать к себе и запустить без лишних телодвижений. Поступайте всегда также - это просто уважение к собеседнику)
результат
Я надеюсь, что "учел все замечания, теперь вроде что-то получается", это как минимум:
Или нет? Или я тут вообще как пятое колесо?
6-ю строку из цикла вынести можно. Ну, и понять, что скорость не всегда начинается с 46-й позиции. И вообще - в atof передать адрес позиции в буфере.
Не дочитал, но моя версия кода ТС подойдет для "копирования части строки".
А еще ТС и всем остальным кто еще не пользуется (или не знает): компилятор игнорирует пробелы, не стесняйтесь и используйте их в коде - так код становится на много более читабельным.
[/quote]
Не думаю.
Вы изначально чрезмерно усложнили код, а теперь геройски пытаетесь его исправить.
Вот, допустим, что Вы поняли что не так с формирование переменной speed. Давайте пойдём чуть дальше.
Скажите мне, а вот вообще нафига
попу гармоньВам эта переменная speed? Вот просто на-фи-га?Если Вы уже нашли начала интересующего Вас числа в массиве buf, кто Вам мешает преобразовать его прямо оттуда? Зачем его копировать в какой-то speed? Функции atof глубоко плевать, что идёт в строке после числа - она выбирает только число, а на остальное кладёт.
[/quote]
так мне же нужно с ним проделать дофига математических операций. Сначала домножить на коэффициент 1.852, а после еще и округлить, а затем передать через uart
Чтобы убедиться в этом, достаточно запустить простой проверочный скетч (обратите внимание, я привожу полный скетч. который Вы можете легко скопировать к себе и запустить без лишних телодвижений. Поступайте всегда также - это просто уважение к собеседнику)
результат
Спасибо, нужно будет попробовать.
Я надеюсь, что "учел все замечания, теперь вроде что-то получается", это как минимум:
Или нет? Или я тут вообще как пятое колесо?
Нет, все верно. Я примерно так сделал, только чуть по-другому.
так мне же нужно с ним проделать дофига математических операций. Сначала домножить на коэффициент 1.852, а после еще и округлить, а затем передать через uart
Вы невнимательно читаете, для программиста это неприемлемо.
Я Вам говорил, "нафига
попу гармоньВам эта переменная speed? Вот просто на-фи-га?". Вам нужно делать операции, а при чём тут промежуточная строковая переменная speed? Вы с ней собрались операции проделывать? Или таки с уже преобразованным во float значением? А если с преобразованным, так и преобразовывайте его прямо из буфера безо всякой промежуточной строки - нафига она Вам? Чтобы всё усложнить, и расходовать лишнюю память и время исполнения? Больше она не нужна ни для чего.Да он уже сделал, сойдёт. Но так то да - зачем и так малую память использовать для непонятных манипуляций? Сразу в растудыть ее и жарить на углях уже шомпол с мясом, а не отдельные куски )))
так мне же нужно с ним проделать дофига математических операций. Сначала домножить на коэффициент 1.852, а после еще и округлить, а затем передать через uart
Вы невнимательно читаете, для программиста это неприемлемо.
Я Вам говорил, "нафига
попу гармоньВам эта переменная speed? Вот просто на-фи-га?". Вам нужно делать операции, а при чём тут промежуточная строковая переменная speed? Вы с ней собрались операции проделывать? Или таки с уже преобразованным во float значением? А если с преобразованным, так и преобразовывайте его прямо из буфера безо всякой промежуточной строки - нафига она Вам? Чтобы всё усложнить, и расходовать лишнюю память и время исполнения? Больше она не нужна ни для чего.Я вас понял, вы имеете ввиду сразу миновать переменную speed, создав переменную float и сразу закинуть туда преобразованное значение с массива buf. Да, это хорошая идея, скорее всего так и сделаю. Но чтобы не запутаться пока сделал так.