Принять значение температуры с контроллера на контроллер
- Войдите на сайт для отправки комментариев
Здравствуйте.
Имеется контроллер Arduino UNO. К нему (на нём) - крепится шилд TFT LCD 2.4". Так как TFT шилд занимает практически все пины на UNO, пришлось думать, как заиметь свободные пины для выполнения команд (замыкания/размыкания реле, считывание данных с датчиков температуры). В итоге - было принято решение подключить дополнительно второй контроллер Arduino nano, через пины RX и TX. В итоге эксперимент удался - простым примером удалось управлять светодиодом (пин 13) как с UNO на nano, так и наоборот. Далее - подключил датчик температуры DS18B20 к контроллеру nano. Значения температуры фиксируются. В порт посылаются. Это видно в IDE при просмотре порта.
Вопрос: как лучше принять это значение температуры на UNO и вывести на дисплее TFT?
Вот такой код сейчас загружен на контроллер nano (из стандартного примера попытался поубирать лишнее, но так и не знаю, как работает. Но работает.):
#include <OneWire.h> OneWire ds(2); // on pin 2 (a 4.7K resistor is necessary) void setup(void) { Serial.begin(9600); } void loop(void) { byte addr[8]; if ( !ds.search(addr)) { ds.reset_search(); delay(250); return; } if (OneWire::crc8(addr, 7) != addr[7]) { return; } if (addr[0]==0x28){ } else { Serial.println("Device is not a DS18B20."); return; } ds.reset(); ds.select(addr); ds.write(0x44); // start conversion, with parasite power on at the end delay(1000); // maybe 750ms is enough, maybe not ds.reset(); ds.select(addr); ds.write(0xBE); // Read Scratchpad byte i; byte data[9]; for ( i = 0; i < 9; i++) { data[i] = ds.read(); } if (OneWire::crc8(data, 8) != data[8]) { return; } int16_t raw = (data[1] << 8) | data[0]; if (0) { raw = raw << 3; // 9 bit resolution default if (data[7] == 0x10) { // "count remain" gives full 12 bit resolution raw = (raw & 0xFFF0) + 12 - data[6]; } } else { byte cfg = (data[4] & 0x60); // at lower res, the low bits are undefined, so let's zero them if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms //// default is 12 bit resolution, 750 ms conversion time } float celsius; celsius = (float)raw / 16.0; Serial.println(celsius); }
На приёмнике (UNO с TFT шилдом) пишу код типа:
tft.print(Serial.read());
в надежде получить значение температуры. Но ничего не получается. Не удаётся на экран TFT вывести значение температуры, которое принимает nano от датчика DS18B20.
Почитайте для начала, как на самом деле работает Serial.read(), и как правильно принять данные из Serial.
Имеется контроллер Arduino UNO. К нему (на нём) - крепится шилд TFT LCD 2.4". Так как TFT шилд занимает практически все пины на UNO, пришлось думать, как заиметь свободные пины для выполнения команд (замыкания/размыкания реле, считывание данных с датчиков температуры). В итоге - было принято решение подключить дополнительно второй контроллер Arduino nano, через пины RX и TX.
Отличный пример того, что использование шилдов ведет к атрофии мозга.
Сначала поставить шилд, а потом городить второй контроллер, потому что пинов больше нет :) - это удаление аппендицита через жопу.
Автор! О том, чтобы (о. боже!) снять TFT-шилд с Уно и подключить его несколькими проводами - вы не подумали?
b707, это неспортивно. Каждому даччику - по Ардуине!!!
b707, дело не в том, что сам шилд занимает место ("мамы" пинов на UNO), а в том, что электрически свободным остаётся всего один аналоговый вход/выход (некоторые его используют для регулировки яркости подсветки, но с вмешательством в плату TFT).
Я поискал информацию про "Serial.read()". Вроде данная функция читает байты (но с символами "H" и "L" работало, когда я управлял светодиодом) и вроде как - цифры считывать не может. Вот что прочитал: "Если обмены ведутся в виде текста, то все ОК. А вот если передаются именно байты, возникает проблема: -1 это 0xFF, т.е. 255. такой же байт, как и все остальные. поэтому нужно сперва вызывать available ()." - http://pashkevich.me/article/6.html
Там же на той страничке написано, что чтобы получить именно численное значение с плавающей точкой - можно воспользоваться стандартной функцией "Serial.parseFloat()". Буду пытаться по этому пути. Но нет никакого представления. Всё наугад.
Кстати, по поводу того, что TFT занимает UNO - мне уже пришлось подпаять дополнительные "папы" пинов RX, TX, GND, 5V, 5V - чтобы подключить одновременно датчик, UNO и nano от одного USB шнура.
про "Serial.read()", байты и цифры написан бред, простите. Цифры в компьютере хранятся в виде байтов.... если вы не знали.
замечание не по делу... заметки на полях.
я поражен. сколько пинов нужно для работы этого дурацкого экрана... судя по картинке, он действительно занимает почти все выводы Уно. Это какой-то бред, неужели нельзя данные по SPI передавать? нафига еще 8 пинов занимать?
b707, можно хоть по Serial, вопрос в скорости: при SPI 4 MHz - максимум 3 FPS по самым оптимистичным оценкам. При 1 MHz - соответственно менее 1 FPS.
Но в любом случае можно использовать A4 и A5 либо как I2C, либо как CS для двух SPI устройств. Все лучше чем Serial.
Добрый день.
Вчера вечером довольно долго возился с проектом. Получил некоторый результат. В контроллере nano (он у меня является получателем информации с датчика температуры и передатчиком этой информации на UNO) в итоге был прописан следующий код (скопировал у кого-то здесь же на форуме):
Контроллер nano посылает в порт значение температуры, умноженное на 10.
В "приёмнике" (UNO) я добавил следующую часть кода, относящуюся к выводу значения информации на дисплей (весь код нет смысла выкладывать, это только то, что влияет у меня на вывод температуры на дисплее):
В итоге - получен некоторый результат. Значение температуры выводится на дисплей и проверяется и обновляется каждые 3 секунды (синим в верхнем левом углу экрана):
Но выявилась большая проблема - переходы по меню очень сильно стали "тормозиться". Такое впечатление, будто UNO занята каким-то процессом. При этом - когда я обрываю связь TX и RX между контроллерами - переходы по менюшкам TFT дислея работают быстро.
Помогите мне понять, в чём причина такой сильной "заторможенности" дисплея при приёме данных по температуре. И как это исправить.
Я уже и так увеличил delay в передатчике и Serial.setTimeout в приёмнике до 3000 мс - но это не помогло.
Я уже и так увеличил delay в передатчике и Serial.setTimeout в приёмнике до 3000 мс - но это не помогло.
пипец логика. Поскольку все тормозит (из-за задержек и таймаутов) - поставим задержки побольше :)
Слабо посмотреть в мануале, как связаны функции Serial.setTimeout и Serial.ParseInt? При обработке входящих данных с сериала функция Serial.ParseInt ждет данных в течении времени, заданное Serial.setTimeout. В это время программа "висит" и ничего другого делать не может. Увеличив таймаут, вы только усугубили проблему.
Для ускорения обмена ввм надо совсем отказаться от ParseInt (поскольку даже при маленьком таймауте эта функция медленная) и обрабатывать входящие данные самостоятельно.
Спасибо за разъяснения.
Для ускорения обмена ввм надо совсем отказаться от ParseInt (поскольку даже при маленьком таймауте эта функция медленная) и обрабатывать входящие данные самостоятельно.
Правильно ли я понимаю, что речь идёт о том, чтобы передавать байты подобно этому коду:
?
Пробовал вчера... почему-то не получилось. Не видит у меня IDE "itoa" как некую команду.
b707, можно хоть по Serial, вопрос в скорости: при SPI 4 MHz - максимум 3 FPS по самым оптимистичным оценкам. При 1 MHz - соответственно менее 1 FPS.
Интересно, а 1-3 FPS - это мало? Данные-то сначала генерить надо. А у нас в качестве мозга - Уно. Сделайте ей канал в 10 FPS - ей передавать по нему нечего будет...
Правильно ли я понимаю, что речь идёт о том, чтобы передавать байты подобно этому коду:
неправильно.
Прочитайте внимательнее - я вам написал, что вам надо переписать прием. Передачу можете оставить как есть.
Дайте пожалуйста подсказку, через каких операторов выполнить приём информации. Как я вчера смог уяснить - передаются байты, байты трансформируются в символы, символы переводятся в число. Но мне не удалось найти понятного примера, как это записать кодом на "приёмнике". И, наверное, как-то надо учесть что в конечном виде проекта планируется принимать значения с трёх датчиков температуры (т.е. - как-то их различать при приёме).
Простейший случай - функция atoi()
Для более сложного почитайте соседнюю тему http://arduino.ru/forum/programmirovanie/poluchenie-dannykh-po-uart-0
Полазил по просторам интернета, поискал различные применения atoi().
Из того, что нашёл собрал код (касаемо приёма значения температуры):
Доберусь до контроллеров - попробую "залить" код, в надежде что заработает. Передатчик у меня посылает в порт значение температуры умноженное на 10, например температура "23.2" посылается в порт как 232. Но мне хоть бы так получить - потом, надеюсь, разберусь с плавающей точкой.
Интересно, а 1-3 FPS - это мало? Данные-то сначала генерить надо. А у нас в качестве мозга - Уно. Сделайте ей канал в 10 FPS - ей передавать по нему нечего будет...
10 FPS означает, что Уно будет заниматься только экраном, ни на что больше не реагируя, 100 мс, а 1 FPS - уже 1000 мс. О том, как выглядит обновление небольшого экранчика 1000 мс, я уже не говорю.
IMHO, если уж мы используем экран с глубиной цвета 16-18 бит, то отдать на него целиком все мощности Atmel-328 - не грех. Такая вот дешевенькая альтернатива Nextion. А если Уно при этом еще что-то должна делать, следует ограничиться однобитным, а то и вовсе текстовым экраном.
Ура!!! У меня всё заработало (с использованием кода двумя постами выше). Проблему с выводом значения температуры с плавающей точкой решил просто, по аналогии как в одном из примеров с этого форума:
Менюшки по экрану переключаются бодро, температура выводится каждую секунду. b707, большое спасибо за подсказки, разъяснения.
Единственное, что меня смущает - датчик имеет погрешность 0.5 градуса. Может, нет смысла выводить каждые 0.1 градуса. Хочу сделать округление до 0.5 градуса. Может, подскажите, как лучше реализовать? (но шаг в 1 градус - это многовато для меня)
Следующая моя задача - принимать одновременно значения температур на TFT LCD от трёх датчиков температур. Подскажите, код для "передатчика" в сообщении №8 можно ли как-то по простому модифицировать под передачу температуры с трёх датчиков?
Или же необходимо полностью изменить код, аналогично как в этом сообщении для "Вариант с 2-мя датчиками"?
Следующая моя задача - принимать одновременно значения температур на TFT LCD от трёх датчиков температур. Подскажите, код для "передатчика" в сообщении №8 можно ли как-то по простому модифицировать под передачу температуры с трёх датчиков?
Да можно особо не модифицировать. Добавьте перед цифрами букву, обозначающую каждый датчик - да и все. Например, пусть "А254" это будет 25.4 гр с первого датчика, а "В187" - 18.7 со второго...Ну и в приемник придется добавить код для извлечения букв
Думал-думал, искал-искал. Вот какой получается у меня код:
Возможности загрузить в контроллер и проверить код - пока что нет. Взгляните пожалуйста, на первый взгляд - нет ли "косяков", должно ли работать?
Также интересует, насколько рационально записан код, нет ли чего-то лишнего. Адрес каждого из трёх датчиков - планируется прописать вручную.
Посмотрел. 2/3 кода - лишние.
Посмотрел. 2/3 кода - лишние.
поддерживаю.
PPeterr, нафига отдельная процедура для каждого датчика? А если их будет 10? У вас в коде процедуры меняется только адрес - так передавайте его в виде параметра
Спасибо. Подскажите, что убрать. "1, 2, 3" относящиеся к номеру датчика, как-то через переменную задать, типа "i++"?
Спасибо. Подскажите, что убрать. "1, 2, 3" относящиеся к номеру датчика, как-то через переменную задать, типа "i++"?
Нет, вы меня не поняли. Датчики можете перебирать как хотите - по одному как сейчас или в цикле - это несущественно. Главное - вам надо избавится от трех дублирующих процедур TempProcess1 , 2 и 3. Процедура для каждого датчика должна вызываться одна и та же, а адрес конкретного датчика ей нужно передавать в виде параметра.
Пытаюсь сделать то, о чём говорите.
IDE выдаёт ошибки типа:
"warning: invalid conversion from 'byte* {aka unsigned char*}' to 'byte {aka unsigned char}' [-fpermissive]
note: initializing argument 2 of 'int tempProcess(boolean, byte)'"
Не знаю, что это означает. На ваш взгляд - код должен быть рабочим?
41-я строка наверное такая должна быть:
kalapanga, спасибо. Помогло. Ошибки в IDE исчезли. Вечером надеюсь "залить" код на контроллер.
kalapanga, спасибо. Помогло. Ошибки в IDE исчезли. Вечером надеюсь "залить" код на контроллер.
Далее ознакомьтесь с разделом "Multiple-device commands" на https://playground.arduino.cc/Learning/OneWire и запускайте конверсию одновременно на всех термометрах. Это и время выполнения сэкономит и объем кода (немного).
Единственное, что меня смущает - датчик имеет погрешность 0.5 градуса. Может, нет смысла выводить каждые 0.1 градуса. Хочу сделать округление до 0.5 градуса. Может, подскажите, как лучше реализовать? (но шаг в 1 градус - это многовато для меня)
Умножать на 2 и округлять до целого.
При выводе на экран - делить на 2, а если число нечетное (до деления), дописывать к нему ".5".
я бы не стал округлять. Погрешность в 0.5 гр вовсе не означает, что цифры после точки бесполезны. Как пример - часы могут отставать или спешить на несколько минут, но это не значит, что секундная стрелка на них не нужна...
Здравствуйте.
Вчера подключил ещё два датчика температуры (в итоге - получилось три штуки - именно столько мне достаточно для проекта).
С помощью стандартного примера из "OneWire" - просмотрел адрес каждого конкретного датчика. Переписал в код, составленный вчера здесь. Вот какой получился в итоге код для контроллера nano (он у меня принимает значения температур с датчиков и передаёт эти значения на UNO):
Далее возился с кодом на контроллере UNO (довольно долго). У меня получилось распознавать от какого датчика значение пришло - только когда буква "A, B, C" были в конце передаваемых по Serial значений температур. Вот что залито на UNO (касаемо приёма и вывода на LCD значения температуры):
Одно значение температуры (датчика №2) вывел с десятыми. Остальные - мне для проекта достаточно показаный целых значений градуса. Не знаю, есть ли смысл экономить память за счёт этого. Буду думать по окончании проекта - в зависимости от того, сколько останется свободной памяти на контроллерах.
На фото в начале сообщения - три значения температур выводятся в верху экранчика и меняются (обновляются) раз в секунду.
Прошу вас просмотреть выложенный в этом сообщении программный код и указать на грубые ошибки, если они есть.
неоптимально два раза читать, чтение - процедура долгая. ds.read() что отдает, не помню, char или int?
t = ds.read() | (ds.read()<<8);
надо бы
t = ds.read(); t = (t<<8) | (t & 0xFF);
Это ему не особо поможет. ScratchPad он читает не полностью, CRC не проверяет, разрешение датчика не устанавливает/проверяет, undefined low bits не сбрасывает в зависимости от разрешения и пр. и др.
Надеюсь, что это не какой-нибудь датчик газового котла будет... иначе абзац соседям.
Один из датчиков - должен мерить температуру воздуха на улице;
второй - температуру теплоносителя (воды) на входе в систему отопления;
третий - температуру воздуха в помещении.
Конечно же, я не знаю и не понимаю. Но я поэтому и обратился к помощи форума. Мне нужен некий минимальный набор кода (наиболее простой), но способный обеспечить вполне надёжную работу системы автоматического поддержания температуры в помещении. Основные исполнительные органы - котёл на дизельном топливе, насосы перекачивающие воду. У котла - своя автоматика защиты и контроля процесса горения (штатная, заводская). Я лишь планирую включать/выключать котёл с помощью реле.
Это ему не особо поможет. ScratchPad он читает не полностью, CRC не проверяет, разрешение датчика не устанавливает/проверяет, undefined low bits не сбрасывает в зависимости от разрешения и пр. и др.
из всего этого критично только CRC, да и ту можно заменить проверкой полученных значений на некие граничные условия. При ошибке обычно приходит либо ноль, либо какие-то совершенно нереальные цифры, которые легко отсеять.
из всего этого критично только CRC, да и ту можно заменить проверкой полученных значений на некие граничные условия. При ошибке обычно приходит либо ноль, либо какие-то совершенно нереальные цифры, которые легко отсеять.
Даже не знаю, как прокомментировать.
Т.е. 0 градусов на улице или датчик оторвался - вообще пофиг? Предлагаю тогда вообще не подключать термометры и сэкономить пин и второй контроллер. А значения на экран через rand() выводить.
из всего этого критично только CRC, да и ту можно заменить проверкой полученных значений на некие граничные условия. При ошибке обычно приходит либо ноль, либо какие-то совершенно нереальные цифры, которые легко отсеять.
Даже не знаю, как прокомментировать.
Т.е. 0 градусов на улице или датчик оторвался - вообще пофиг? Предлагаю тогда вообще не подключать термометры и сэкономить пин и второй контроллер. А значения на экран через rand() выводить.
Там типичные, либо -127, либо 85. Смысла в CRC особого нет, только если действительно линия засранная. В этот случае проверку легко добавить.
Для ТС: Посмотрите эту тему, есть на сторожевом таймере, есть функция на миллис.
Там типичные, либо -127, либо 85. Смысла в CRC особого нет, только если действительно линия засранная. В этот случае проверку легко добавить.
Там - это где? Давайте поищем в datasheet на 18x20 число -127.
-127 - это #define DEVICE_DISCONNECTED_C из библиотеки DallasTemperature. Я посмотрел, когда оно возвращается - по false == isConnected(deviceAddress, scratchPad). А isConnected(...) возвращает true если _wire->crc8(scratchPad, 8) == scratchPad[SCRATCHPAD_CRC].
Но я не наблюдаю того, что ТС где-то использует DallasTemperature, поэтому весьма сомнительно, что он от чистого OneWire получит при обрыве то число, которое вы привели.
Впрочем, конечно, дело ваше - CRC же придумали трусы ;)
Спасибо. Я именно из этой темы и брал примеры, чтобы составить код получения температуры с датчиков (сообщения от Pyotr и dimax).
Но, к сожалению, на данный момент я не знаю, что такое "сторожевой таймер" и "функция на миллис". И если для моего случая это не критично - то я бы и не хотел тратить силы на понимание (и так ясно - программистом мне не быть).
Просто, сейчас вообще не могу "переварить" полученную информацию о что такое некие проверки датчика и нужны ли они в моём случае. Какова вероятность, что датчик может прислать некорректное значение температуры. И почему могут возникнуть трудности с получением температуры 0 на улице.
Я могу себе представить некие грубые ограничения, для исключения совсем уж нелепых ошибок: например, задаться что диапазон температур на улице: -20...+40; в помещении: 0...+30; в системе: 0...+90. Это уже позволит отсеять большинство критических ошибок (которые могут повлиять на выход из строя оборудования, хотя это по-моему нереально. В худших случаях будет перерасход топлива либо заморозка системы отопления). И если значения получаемые от датчиков будут вне этого диапазона - просто, игнорировать их.
Просто, сейчас вообще не могу "переварить" полученную информацию о что такое некие проверки датчика и нужны ли они в моём случае. Какова вероятность, что датчик может прислать некорректное значение температуры. И почему могут возникнуть трудности с получением температуры 0 на улице.
В принципе, наиболее правильно добавить проверку CRC (у вас критичная система), тогда распознаем и обрыв и неверные значения. Для этой проверки надо будет считать не два байта, как сейчас, а все восемь и рассчитать CRC (примеры есть в библе OneWire).
Хотя мне несколько лет и без него хорошо (в овощехранилище и на ректификаторе), так что решать вам.
Я немного почитал этот OneWire.cpp. В битовых масках не силен, поэтому с ходу сообразить как включается подтяжка Input pin-а я не могу. Однако по комменту в OneWire::read_bit() можно заключить, что библиотека ожидает увидеть подтяжку на шине: "let pin float, pull up will raise".
Т.е. если я правильно понимаю, для передачи бита датчик тянет DQ на землю. Таким образом, конечно, при отрыве датчика, МК (у которого есть pull-up) будет читать все время HIGH, что, как я полагаю, трансформируется в byte[0]=255 и byte[1]=255. В случае с int t = byte[0] | (byte[1] << 8) мы будем иметь -32767, если я не ошибаюсь. Да, это невероятное для температуры число. Можно по нему отсеять. Однако, если на шине произойдет замыкание на землю, то мы получим byte[0]=0 и byte[1]=0. Т.е. t==0, при алгоритме, который используется в данном скетче. Т.е. датчик закоротило, а девайс считает, что в помещении дубак и поддает газу бесконечно.
Конечно, есть способ узнать про замыкание - DS18x20 не дураки проектировали. В OneWire даже есть подсказка: "uint8_t OneWire::reset(void) // Perform the onewire reset function. We will wait up to 250uS for the bus to come high, if it doesn't then it is broken or shorted and we return a 0". Нужно, как минимум, просто смотреть, что возвращает ds.reset(), чего в коде ТС нет.
Однако, и это не поможет распознать неверный результат, полученный, как правильно отмечено выше, от наводок на шину. Хоть это и невероятно, но можно представить, что в какой-нибудь из циклов опроса из-за битых байтов T окажется равной +60, автоматика инициирует отключение насоса (или чем там она будет заведовать), в следующий цикл в переменную придет +3, насос нужно будет включать (через секунду). Потом еще что-нибудь... и такая дребедень целый день. Но температура будет в пределах нормы. Мне кажется, что эта ситуация близка к той, в котором спасжилет надевать не надо, потому что за последние 10 лет на этом озере никто не утонул. Может и повезет...
Поэтому я даже и не знаю - стоит ли экономить на спичках и наворачивать какие-то проверки на вхождение в допустимый диапазон, отслеживание замыкания на линии или просто принять ScratchPad целиком и сравнить CRC. И скидывать неопределенные биты в зависимости от разрешения термометра.
Это мои соображения исключительно по использованию CRC в данном прожекте. Так, как напоследок ТС озвучил считывание отрицательных температур, то не могу не заметить, что простым сложением байт минусовую температуру в переменной не получить.
Т.е. если я правильно понимаю, для передачи бита датчик тянет DQ на землю. Таким образом, конечно, при отрыве датчика, МК (у которого есть pull-up) будет читать все время HIGH, что, как я полагаю, трансформируется в byte[0]=255 и byte[1]=255. В случае с int t = byte[0] | (byte[1] << 8) мы будем иметь -32767, если я не ошибаюсь. Да, это невероятное для температуры число. Можно по нему отсеять. Однако, если на шине произойдет замыкание на землю, то мы получим byte[0]=0 и byte[1]=0. Т.е. t==0, при алгоритме, который используется в данном скетче. Т.е. датчик закоротило, а девайс считает, что в помещении дубак и поддает газу бесконечно.
имхо, все вышеизложенное - не более чем ваши домыслы. Любой протокол, в том числе OneWire - основан в первую очередь на импульсах и их длительности, то есть на ИЗМЕНЕНИЯХ уровня с лоу на хай и обратно. При постоянном уровне в линии никаких изменений нет, фронты отсутствуют и никакие постоянные нули или единицы в регистры читаться не будут.
Подскажите мне пожалуйста, при использовании программного кода, который я выложил здесь выше - я не увижу на экране LCD дисплея отрицательных температур? Просто, сейчас проблемно выяснить это экспериментально. Не засуну же я макетик в морозилку... И что мне следует сделать, чтобы иметь возможность получать корректные данные температур при их отрицательных значениях.
имхо, все вышеизложенное - не более чем ваши домыслы. Любой протокол, в том числе OneWire - основан в первую очередь на импульсах и их длительности, то есть на ИЗМЕНЕНИЯХ уровня с лоу на хай и обратно. При постоянном уровне в линии никаких изменений нет, фронты отсутствуют и никакие постоянные нули или единицы в регистры читаться не будут.
Ну, хорошо, исключим меня и домыслы.
Вот код из OneWire.cpp:
По вашему мнению - что будет на выходе read() при отсутствии датчика, пульсирующего на шине , а так же при ее закорачивании на землю?
sadman41, мне сейчас некогда рыться в исходниках - но очевидно, что так, как вы это себе представляете - работать не может. Приемник не может просто тупо измерять уровень на линии, не сообразуясь с моментом начала и окончания передачи. иначе при незначительном расхождении тайминга между приемником и передатчиком принималась бы полная белиберда.
sadman41, мне сейчас некогда рыться в исходниках - но очевидно, что так, как вы это себе представляете - работать не может.
Зачем рыться? Ключевую функцию я вам привел - OneWire::read_bit(). Не думаю, что вам понадобится более минуты чтобы понять, как именно она возвращает значение бита. И еще 30 сек на мысленное формирование байта в случае с обрывом или замыканием.
Это исключит домыслы о работе библиотеки как с моей стороны, так и с вашей.
Зачем рыться? Ключевую функцию я вам привел - OneWire::read_bit(). Не думаю, что вам понадобится более минуты чтобы понять, как именно она возвращает значение бита. И еще 30 сек на мысленное формирование байта в случае с обрывом или замыканием.
Я посмотрел этот код - но это не более как самый нижний уровень протокола. Синхронизация должна происходить на более высоком уровне. Без синхронизации значения, полученные OneWire::read_bit(). - просто идут в помойку.
Я посмотрел этот код - но это не более как самый нижний уровень протокола. Синхронизация должна происходить на более высоком уровне. Без синхронизации значения, полученные OneWire::read_bit(). - просто идут в помойку.
Ну ОК, будем считать, что вы правы. Хотя мне все равно не понятно, как это может работать. Но лезть в исходники сейчас и правда совершенно некогда. может дома гляну.