int16 получить битовую маску значений
- Войдите на сайт для отправки комментариев
Пт, 05/08/2016 - 17:38
Всем привет!
Использую библиотеку Modbus RTU. Опрашиваю прибор МВ 110. Там 16 входов. Сосчитать их состояние можно одной командой. В ответ получаю значения int16.
Вот так я получаю почти то что мне нужно:
char A[17]; itoa(regs[0],A,2);
т.е. при замыкании контактов 2 и 6, я получаю ответ в виде A = 100010
Вот так только 8 контакт: 10000000
Всего 16 входов. Я хочу в print посылать значения, приведенные к нормальным, в виде:
A = 10100010 K1 = 0 K2 = 1 K3 = 0 K4 = 0 K5 = 0 K6 = 1 K7 = 0 K8 = 1 K9 = 0 K10 = 0 K11 = 0 K12 = 0 K13 = 0 K14 = 0 K15 = 0 K16 = 0
Опытным путем сделал вот так, но все равно не совсем как надо:
void loop() { modbus_update(); mySerial.print(" regs0: "); char A[17]; itoa(regs[0],A,2); mySerial.print(A); for (byte i = 0; i < 16; i++){ mySerial.print(" K"); int i2 = 16-i; mySerial.print(i2); mySerial.print(": "); mySerial.print(A[i]); } mySerial.println(); }
При работе кода что выше я получаю строку при замкнутом 7 контакте. regs0 = показывает что замкнут только 7 контакт, а как добавить недостающие нули? чтобы мой код правильно начал работать?
regs0: 1000000 K16: 1 K15: 0 K14: 0 K13: 0 K12: 0 K11: 0 K10: 0 K9: K8: 0 K7: K6: K5: K4: K3: K2: K1:
Ответ банальный. Не пользоваться функцией itoa.
Ответ банальный. Не пользоваться функцией itoa.
Подскажите как правильно написать?
Скорее всего подобно этому.
Но скорее в цикле A[i]=(regs[0] & (1<<i))>> i где i от 0 до 16, а regs[0] ваше число которое надо преобразовывать.
ПС: надо проверять.
Вы про битовые операции знаете? Вот их и надо использовать, как-то так, навскидку:
Сам скетч:
Тупо быстро набросал, мог где-то ошибиться, на ардуину закачивать не стал - все свободные щас заняты :(
Что-то не один из вариантов не работает :(
Что-то не один из вариантов не работает :(
Сорри, я там обшибся, щас поправлю. Вот поправленный:
Поправил и сверху, на всякий. Совсем забыл про CHAR_BIT, голова садовая.
Проверил на http://cpp.sh/, вот код, на котором проверял всё работает как надо:
Только определиться с big endian и little endian надо. Если надо в обратном порядке биты выводить, то:
Если Вы будете нумеровать их не с 1, а, как все нормальные люди, с нуля (т.е. на 1, 2, ..., 16), а (0, 1, 2, ..., 15), то можете воспользоваться простым, рабоче-крестьянским макросом bitRead. Просто, как мычание нулевой бит переменной а - bitRead(a, 0), первый - bitRead(a,1) и т.п. И не надо городить никакого огорода с самогонными функциями. Макрос простой как валенок, определён в arduino.h вот так
Спасибо всем за помощь и советы :)
Очень помогли!