Подскажите по преобразованию данных
- Войдите на сайт для отправки комментариев
Ср, 21/12/2016 - 13:37
Собственно проблема такая -
читаюсообщение с CANBUS, к примеру 01 FF 00 00 00 00 00 00 необходимо получить результат вида 01FF и перевести в десятичную систему т.е. 511, если во втором числе всё, что угодно кроме FF, то преобразуется правильно, как только FF - затык. Код ниже, что я делаю не так?
#include <mcp_can.h> #include <SPI.h> long unsigned rxId; long previousMillis = 0; unsigned char len = 0; unsigned char rxBuf[8]; int value = LOW; long freq = 0; long b; long input; MCP_CAN CAN(10); void setup() { CAN.begin(CAN_500KBPS); } void loop() { canread(); if (rxId == 0x37E && (len == 5 || len == 6 || len == 7)) { goto a39; } a39: canread(); if (rxId == 0x37E) { input = uint16_t(rxBuf[0] << 7 | rxBuf[1] ); } blink(input); goto a39; } void blink (long input) { if (b != input) { b = input; } if (input > 0) { freq = 65535 / b; if (millis() - previousMillis > freq) { previousMillis = millis(); if (value == LOW) value = HIGH; else value = LOW; digitalWrite(3, value); } } else if (input == 0) { digitalWrite(3, HIGH); } } void canread() { CAN.readMsgBuf(&len, rxBuf); rxId = CAN.getCanId(); }
Используйте для беззнаковых величин unsigned int, unsigned long, uint16_t и т.п.
Иначе при обработке значений больше 0x80, 0x8000, 0x80000000 получим неверный результат.
В приведенном фрагменте кода, знаковые переменые не требуются, заменяйте все int на unsigned, а long на unsigned long.
после замены ровно тот же результат - 01FF=00FF
Интересно, что Вы хотели здесь сделать?
Интересно, что Вы хотели здесь сделать?
1. Определить авто по уникальному ID (код сильно кастрирован ибо идентификаторы - военная тайна)
2. Прочитать 2 бита из 8
3. Моргнуть светодиодом через функцию blink
4. Вернуться в цикл а39.
Оказалось что надо так -
input = uint16_t(rxBuf[0] << 8 | rxBuf[1] );
В общем немного переписал, но грабли остались, поможите люди добрые бьюсь как лбом об стену - не преобразуется из 16 в 10ку input хоть лопни.
1. Определить авто по уникальному ID (код сильно кастрирован ибо идентификаторы - военная тайна)
2. Прочитать 2 бита из 8
3. Моргнуть светодиодом через функцию blink
4. Вернуться в цикл а39.
1 - понятно.
2 - понятно, только наверное 2 байта
3 - не понятно, носудя по коду моргнуть светодиодом на время 65535 минус то что прочитали 0x01FF (511) миллисек, то есть на 65024 миллисек (65 сек = чуть больше минуты), так ?
4 - код ужасный, это не надо.
более развернуто опишите.
а по поводу ваших мытарств с input, вот попробуйте, пытался по шагам
1. Определить авто по уникальному ID (код сильно кастрирован ибо идентификаторы - военная тайна)
2. Прочитать 2 бита из 8
3. Моргнуть светодиодом через функцию blink
4. Вернуться в цикл а39.
1 - понятно.
2 - понятно, только наверное 2 байта
3 - не понятно, носудя по коду моргнуть светодиодом на время 65535 минус то что прочитали 0x01FF (511) миллисек, то есть на 65024 миллисек (65 сек = чуть больше минуты), так ?
4 - код ужасный, это не надо.
более развернуто опишите.
а по поводу ваших мытарств с input, вот попробуйте, пытался по шагам
По 4му пункту - прошу пардона, ну не кодер я, немного на PHP пишу...... не суть. Плюс здесь просто кусок из контекста - циклов типа "а39" в полной версии около 200.
Попробую более развернуто - надо на выхлопе получить меандр с D3 что то примерно около 600 импульов в минуту, частота меандра естественно должна повышаться по увеличению первых 2х байт сообщения с CAN шины.
Как то так.
посмотрите вот это http://arduino.ru/forum/proekty/generator-s-reguliruemoei-chastotoi-na-arduino
нодо только установить нужную частоту и менять ее не от энкодера, а от принятых байт с CAN шины.
Спасибо, посмотрел.... чужой код хуже татарина, аж мозг вскипел.....