├── .gitattributes ├── .github └── workflows │ └── tg-send.yml ├── LICENSE ├── README.md ├── README_EN.md ├── doc └── scheme.png ├── examples ├── address_read │ └── address_read.ino ├── async_read │ └── async_read.ino ├── async_read_many │ └── async_read_many.ino ├── async_read_many_bus │ └── async_read_many_bus.ino ├── async_read_many_bus_pgm │ └── async_read_many_bus_pgm.ino ├── flash_reduction │ └── flash_reduction.ino ├── one_pin_many_sensors │ └── one_pin_many_sensors.ino ├── one_pin_one_sensor │ └── one_pin_one_sensor.ino └── raw_and_calc │ └── raw_and_calc.ino ├── keywords.txt ├── library.properties └── src ├── DS_raw.cpp ├── DS_raw.h ├── microDS18B20.h ├── microOneWire.cpp └── microOneWire.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/workflows/tg-send.yml: -------------------------------------------------------------------------------- 1 | 2 | name: Telegram Message 3 | on: 4 | release: 5 | types: [published] 6 | jobs: 7 | build: 8 | name: Send Message 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: send telegram message on push 12 | uses: appleboy/telegram-action@master 13 | with: 14 | to: ${{ secrets.TELEGRAM_TO }} 15 | token: ${{ secrets.TELEGRAM_TOKEN }} 16 | disable_web_page_preview: true 17 | message: | 18 | ${{ github.event.repository.name }} v${{ github.event.release.tag_name }} 19 | ${{ github.event.release.body }} 20 | https://github.com/${{ github.repository }} 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Alex 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | |⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️

**ВНИМАНИЕ, БИБЛИОТЕКА УСТАРЕЛА! ИСПОЛЬЗУЙ БИБЛИОТЕКУ [GyverDS18](https://github.com/GyverLibs/GyverDS18), ОНА ИМЕЕТ БОЛЬШЕ ВОЗМОЖНОСТЕЙ И РАБОТАЕТ НА ESP32**

⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️| 2 | | --- | 3 | 4 | [![latest](https://img.shields.io/github/v/release/GyverLibs/microDS18B20.svg?color=brightgreen)](https://github.com/GyverLibs/microDS18B20/releases/latest/download/microDS18B20.zip) 5 | [![PIO](https://badges.registry.platformio.org/packages/gyverlibs/library/microDS18B20.svg)](https://registry.platformio.org/libraries/gyverlibs/microDS18B20) 6 | [![arduino-library](https://www.ardu-badge.com/badge/microDS18B20.svg?)](https://www.ardu-badge.com/microDS18B20) 7 | [![Foo](https://img.shields.io/badge/Website-AlexGyver.ru-blue.svg?style=flat-square)](https://alexgyver.ru/) 8 | [![Foo](https://img.shields.io/badge/%E2%82%BD$%E2%82%AC%20%D0%9D%D0%B0%20%D0%BF%D0%B8%D0%B2%D0%BE-%D1%81%20%D1%80%D1%8B%D0%B1%D0%BA%D0%BE%D0%B9-orange.svg?style=flat-square)](https://alexgyver.ru/support_alex/) 9 | [![Foo](https://img.shields.io/badge/README-ENGLISH-blueviolet.svg?style=flat-square)](https://github-com.translate.goog/GyverLibs/microDS18B20?_x_tr_sl=ru&_x_tr_tl=en) 10 | 11 | [![Foo](https://img.shields.io/badge/ПОДПИСАТЬСЯ-НА%20ОБНОВЛЕНИЯ-brightgreen.svg?style=social&logo=telegram&color=blue)](https://t.me/GyverLibs) 12 | 13 | # microDS18B20 14 | Легкая библиотека для работы с 1-Wire (OneWire) термометрами Dallas DS18B20 15 | - Асинхронная работа (без ожидания конвертации) 16 | - Работа с несколькими датчиками на одном пине (режим адресации) 17 | - Хранение массива адресов в PROGMEM памяти 18 | - Работа с одним датчиком на пине (без использования адресации) 19 | - Расчет температуры в целых числах и с плавающей точкой 20 | - Чтение сырых данных для случаев сильной экономии памяти 21 | - Проверка корректности полученной температуры 22 | - Настраиваемое разрешение преобразования 23 | - Проверка подлинности данных 24 | - Проверка корректности работы датчика 25 | 26 | ### Совместимость 27 | Совместима со всеми Arduino платформами (используются Arduino-функции) 28 | - Не работает на свежих версиях sdk esp32 29 | - Не работает на Digispark, какой то конфликт с компилятором. Используй ядро [ATTInyCore Universal](https://github.com/SpenceKonde/ATTinyCore) с настройкой ATtiny85 + Micronucleous (Digispark) вместо стандартного Digi-ядра 30 | 31 | ## Содержание 32 | - [Установка](#install) 33 | - [Инициализация](#init) 34 | - [Использование](#usage) 35 | - [Подключение](#wiring) 36 | - [Примеры](#examples) 37 | - [Версии](#versions) 38 | - [Баги и обратная связь](#feedback) 39 | 40 | 41 | ## Установка 42 | - Библиотеку можно найти по названию **microDS18B20** и установить через менеджер библиотек в: 43 | - Arduino IDE 44 | - Arduino IDE v2 45 | - PlatformIO 46 | - [Скачать библиотеку](https://github.com/GyverLibs/microDS18B20/archive/refs/heads/main.zip) .zip архивом для ручной установки: 47 | - Распаковать и положить в *C:\Program Files (x86)\Arduino\libraries* (Windows x64) 48 | - Распаковать и положить в *C:\Program Files\Arduino\libraries* (Windows x32) 49 | - Распаковать и положить в *Документы/Arduino/libraries/* 50 | - (Arduino IDE) автоматическая установка из .zip: *Скетч/Подключить библиотеку/Добавить .ZIP библиотеку…* и указать скачанный архив 51 | - Читай более подробную инструкцию по установке библиотек [здесь](https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA) 52 | ### Обновление 53 | - Рекомендую всегда обновлять библиотеку: в новых версиях исправляются ошибки и баги, а также проводится оптимизация и добавляются новые фичи 54 | - Через менеджер библиотек IDE: найти библиотеку как при установке и нажать "Обновить" 55 | - Вручную: **удалить папку со старой версией**, а затем положить на её место новую. "Замену" делать нельзя: иногда в новых версиях удаляются файлы, которые останутся при замене и могут привести к ошибкам! 56 | 57 | 58 | 59 | ## Инициализация 60 | ```cpp 61 | // один датчик на пине без адресации 62 | MicroDS18B20 ds; 63 | 64 | // несколько датчиков на пине с адресацией, указываем адрес (адрес - массив uint8_t) 65 | MicroDS18B20 ds; 66 | 67 | // указываем, что будем работать с адресацией. Сам адрес передадим позже (в setAddress()) 68 | MicroDS18B20; 69 | 70 | // указываем, что будем работать с адресацией, и на линии будет несколько (amount) датчиков 71 | // см. пример async_read_many_bus 72 | MicroDS18B20; 73 | 74 | // указываем, что будем работать с адресацией, на линии будет несколько (amount) датчиков, а адреса будем хранить в PROGMEM 75 | // см. пример async_read_many_bus_pgm 76 | MicroDS18B20; 77 | ``` 78 | 79 | 80 | ## Использование 81 | ```cpp 82 | // ============= МЕТОДЫ КЛАССА ============= 83 | bool readAddress(uint8_t *addressArray); // Прочитать уникальный адрес термометра в массив. [true, если успешно] 84 | void setAddress(uint8_t *addr); // установить (сменить) адрес 85 | void setResolution(uint8_t resolution); // Установить разрешение 9-12 бит 86 | bool online(); // проверить связь с датчиком (true - датчик онлайн). Шина должна быть подтянута 87 | 88 | void requestTemp(); // Запросить новое преобразование температуры 89 | bool readTemp(); // прочитать температуру с датчика. [true если успешно] 90 | 91 | float getTemp(); // получить значение температуры в float 92 | int16_t getTempInt(); // получить значение температуры в int 93 | int16_t getRaw(); // получить "сырое" значение температуры (в 16 раз больше, чем реальная температура) 94 | 95 | // ======= МЕТОДЫ ДЛЯ ШИНЫ ДАТЧИКОВ ======= 96 | // см. примеры async_read_many_bus и async_read_many_bus_pgm 97 | void setResolutionAll(uint8_t res); // Установить разрешение 9-12 бит у всех датчиков на линии 98 | void setResolution(uint8_t resolution, uint8_t idx); // Установить разрешение 9-12 бит (датчик под номером idx) 99 | bool online(uint8_t idx); // проверить связь (датчик под номером idx) 100 | 101 | void requestTempAll(); // запрос температуры у всех датчиков на линии 102 | void requestTemp(uint8_t idx); // Запросить новое преобразование температуры (датчик под номером idx) 103 | bool readTemp(uint8_t idx); // прочитать температуру с датчика (датчик под номером idx) 104 | 105 | float getTemp(uint8_t idx); // получить значение температуры в float (датчик под номером idx) 106 | int16_t getTempInt(uint8_t idx); // получить значение температуры в int (датчик под номером idx) 107 | int16_t getRaw(uint8_t idx); // получить "сырое" значение температуры (датчик под номером idx) 108 | 109 | // =========== ФУНКЦИИ ВНЕ КЛАССА =========== 110 | int DS_rawToInt(int data); // преобразовать raw данные в температуру int 111 | float DS_rawToFloat(int data); // преобразовать raw данные в температуру float 112 | 113 | // ============ ДЕФАЙНЫ НАСТРОЕК ============ 114 | // прописывать перед подключением библиотеки 115 | #define DS_CHECK_CRC [true / false] // Проверка подлинности данных. При отключении будет выдавать некорректное значение при сбое передачи (умолч. true) 116 | #define DS_CRC_USE_TABLE [true / false] // Использовать таблицу для CRC. Быстрее, но +256 байт flash (<1мкс VS ~6мкс) (умолч. false) 117 | 118 | // ================== ИНФО ================== 119 | // Время преобразования от точности 120 | точность | время 121 | 12 бит | 750 мс 122 | 11 бит | 375 мс 123 | 10 бит | 187 мс 124 | 9 бит | 93 мс 125 | ``` 126 | 127 | ### Работа с датчиком 128 | #### Без адресации 129 | В этом режиме на один пин МК подключается один датчик, для работы с ним не требуется предварительного чтения адреса и записи его в программу. 130 | Можно подключить несколько датчиков, каждому указать свой пин, см. пример *one_pin_one_sensor*. 131 | ```cpp 132 | MicroDS18B20<пин1> sensor1; 133 | MicroDS18B20<пин2> sensor2; 134 | // ... и так далее 135 | ``` 136 | 137 | #### С адресацией 138 | В этом режиме можно подключить сколько угодно датчиков на один пин МК, но для работы с ними понадобится занести в программу уникальные адреса датчиков. 139 | В момент чтения адреса к пину должен быть подключен только один датчик! Пример - *address_read*. 140 | Для дальнейшей работы адреса хранятся в массивах на стороне программы и передаются датчикам при инициализации, пин указывается один и тот же: 141 | ```cpp 142 | uint8_t addr1[] = {0x28, 0xFF, 0xCD, 0x59, 0x51, 0x17, 0x4, 0xFE}; 143 | uint8_t addr2[] = {0x28, 0xFF, 0x36, 0x94, 0x65, 0x15, 0x2, 0x80}; 144 | 145 | MicroDS18B20<пин, addr1> sensor1; 146 | MicroDS18B20<пин, addr2> sensor2; 147 | // ... и так далее 148 | ``` 149 | Также адрес можно сменить во время работы программы, см. документацию выше. 150 | 151 | #### Чтение температуры 152 | Чтение температуры делится на два этапа - запрос и получение данных. Запрос делается функцией `requestTemp()`. После получения запроса 153 | датчик начинает измерение температуры, которое длится от 90 до 750 мс в зависимости от настроенной точности *(по умолчанию точность максимальная, 154 | преобразование длится 750 мс)*. Если прочитать температуру до окончания преобразования - датчик вернёт результат предыдущего измерения, 155 | поэтому в примерах используется задержка или опрос по таймеру на 1 секунду. Получить температуру можно при помощи `getTemp()` [float] или `getTempInt()` [int]. 156 | Если принятые данные повреждены или датчик отсутствует на линии - функция вернёт предыдущее успешно прочитанное значение температуры. 157 | **Примечание:** при повторных вызовах `getTemp()` не запрашивает с датчика новую температуру (долгое выполнение функции), 158 | вместо этого она просто возвращает предыдущий результат до тех пор, пока не будет сделан новый запрос `requestTemp()`. 159 | 160 | В версии библиотеки 3.5 появилась возможность отдельно запросить температуру и определить корректность полученных данных, чтобы только после этого их прочитать 161 | и применить в программе - функция `readTemp()`. Также это позволяет определить состояние подключения и всё ли в порядке с датчиком. 162 | Для чтения температуры рекомендуется использовать конструкцию вида: 163 | ```cpp 164 | if (sensor.readTemp()) value = sensor.getTemp(); 165 | // else отработка ошибки 166 | ``` 167 | где `readTemp()` запрашивает данные с датчика и возвращает `true`, если они прочитаны корректно. После этого можно забрать текущую температуру из `getTemp()`, 168 | которая уже не запрашивает температуру с датчика, а отдаёт прочитанный в `readTemp()` результат. 169 | 170 | #### Подключаем много датчиков на один объект 171 | В версии библиотеки 3.9 появилась возможность подключить сколько угодно датчиков на один объект MicroDS18B20, не создавая массива объектов (как в старых версиях). 172 | Нужно создать двумерный массив адресов и передать его в библиотеку, также указав количество датчиков на линии (можно максимальное, если оно будет меняться в процессе работы программы). 173 | Это позволяет сэкономить немного памяти, но можно пойти дальше - засунуть массив адресов датчиков в PROGMEM, чтобы они не висели в оперативной памяти. 174 | Инициализация в этом случае выглядит так: `MicroDS18B20<пин, DS_ADDR_MODE, колич-во>;` или `MicroDS18B20<пин, DS_ADDR_MODE, колич-во, DS_PROGMEM>;` для PROGMEM режима. 175 | Адреса передаются в `setAddress()`, а для опроса просто передаём индекс датчика в те же функции что и раньше. Смотри примеры *async_read_many_bus*, *async_read_many_bus_pgm* и раздел документации *МЕТОДЫ ДЛЯ ШИНЫ ДАТЧИКОВ*. 176 | 177 | 178 | ## Подключение 179 | ![scheme](/doc/scheme.png) 180 | P.S. Вместо резистора на 4.7к можно использовать параллельно два по 10к =) 181 | 182 | 183 | Остальные примеры смотри в **examples**! 184 | ## Один датчик без адресации 185 | ```cpp 186 | // один датчик лучше читать без адресации, это сильно экономит память 187 | #include 188 | MicroDS18B20<2> sensor; 189 | 190 | void setup() { 191 | Serial.begin(9600); 192 | } 193 | 194 | void loop() { 195 | // запрос температуры 196 | sensor.requestTemp(); 197 | 198 | // вместо delay используй таймер на millis(), пример async_read 199 | delay(1000); 200 | 201 | // проверяем успешность чтения и выводим 202 | if (sensor.readTemp()) Serial.println(sensor.getTemp()); 203 | else Serial.println("error"); 204 | } 205 | ``` 206 | 207 | ## Несколько датчиков без адресации 208 | ```cpp 209 | // 2 и более датчиков НЕВЫГОДНО использовать в таком режиме! Но можно 210 | 211 | #include 212 | // Датчики на D2 и D3 213 | MicroDS18B20<2> sensor1; 214 | MicroDS18B20<3> sensor2; 215 | 216 | void setup() { 217 | Serial.begin(9600); 218 | } 219 | 220 | void loop() { 221 | // запрос температуры 222 | sensor1.requestTemp(); 223 | sensor2.requestTemp(); 224 | 225 | // вместо delay используй таймер на millis(), пример async_read 226 | delay(1000); 227 | 228 | // ПЕРВЫЙ ДАТЧИК 229 | Serial.print("t1: "); 230 | 231 | // просто выводим температуру первого датчика 232 | Serial.print(sensor1.getTemp()); 233 | 234 | // ВТОРОЙ ДАТЧИК 235 | Serial.print(", t2: "); 236 | 237 | // проверяем успешность чтения и выводим 238 | if (sensor2.readTemp()) Serial.println(sensor2.getTemp()); 239 | else Serial.println("error"); 240 | } 241 | ``` 242 | 243 | ## Чтение адреса 244 | ```cpp 245 | #include 246 | 247 | // на пин подключен только один датчик! 248 | MicroDS18B20 <2> sensor; // Создаем термометр без адреса на пине D2 249 | uint8_t address[8]; // Создаем массив для адреса 250 | 251 | void setup() { 252 | Serial.begin(9600); 253 | } 254 | 255 | void loop() { 256 | // читаем адрес термометра в указанный массив 257 | if (sensor.readAddress(address)) { // если успешно, выводим 258 | Serial.print('{'); 259 | for (uint8_t i = 0; i < 8; i++) { 260 | Serial.print("0x"); 261 | Serial.print(address[i], HEX); // Выводим адрес 262 | if (i < 7) Serial.print(", "); 263 | } 264 | Serial.println('}'); 265 | 266 | } else Serial.println("Not connected"); 267 | delay(1000); 268 | } 269 | ``` 270 | 271 | ## Несколько датчиков с адресацией 272 | ```cpp 273 | // 2 и более датчиков выгоднее использовать с адресацией на одном пине 274 | #include 275 | #define DS_PIN 2 // пин для термометров 276 | 277 | // Уникальные адреса датчиков - считать можно в примере address_read 278 | uint8_t s1_addr[] = {0x28, 0xFF, 0xCD, 0x59, 0x51, 0x17, 0x4, 0xFE}; 279 | uint8_t s2_addr[] = {0x28, 0xFF, 0x36, 0x94, 0x65, 0x15, 0x2, 0x80}; 280 | 281 | MicroDS18B20 sensor1; // Создаем термометр с адресацией 282 | MicroDS18B20 sensor2; // Создаем термометр с адресацией 283 | 284 | void setup() { 285 | Serial.begin(9600); 286 | } 287 | 288 | void loop() { 289 | // асинхронное чтение нескольких датчиков смотри в примере async_read_many 290 | sensor1.requestTemp(); // Запрашиваем преобразование температуры 291 | sensor2.requestTemp(); 292 | 293 | delay(1000); // ожидаем результат 294 | 295 | Serial.print("t1: "); 296 | if (sensor1.readTemp()) Serial.println(sensor1.getTemp()); 297 | else Serial.println("error"); 298 | 299 | Serial.print("t2: "); 300 | if (sensor2.readTemp()) Serial.println(sensor2.getTemp()); 301 | else Serial.println("error"); 302 | } 303 | ``` 304 | 305 | ## Асинхронный опрос пачки датчиков 306 | ```cpp 307 | // пример компактного асинхронного опроса датчиков на программном таймере 308 | // https://alexgyver.ru/lessons/time/ 309 | 310 | // количество датчиков для удобства 311 | #define DS_SENSOR_AMOUNT 5 312 | 313 | // создаём двухмерный массив с адресами 314 | uint8_t addr[][8] = { 315 | {0x28, 0xFF, 0x78, 0x5B, 0x50, 0x17, 0x4, 0xCF}, 316 | {0x28, 0xFF, 0x99, 0x80, 0x50, 0x17, 0x4, 0x4D}, 317 | {0x28, 0xFF, 0x53, 0xE5, 0x50, 0x17, 0x4, 0xC3}, 318 | {0x28, 0xFF, 0x42, 0x5A, 0x51, 0x17, 0x4, 0xD2}, 319 | {0x28, 0xFF, 0xCD, 0x59, 0x51, 0x17, 0x4, 0xFE}, 320 | }; 321 | 322 | #include 323 | // указываем DS_ADDR_MODE для подключения блока адресации 324 | // и создаём массив датчиков на пине D2 325 | MicroDS18B20<2, DS_ADDR_MODE> sensor[DS_SENSOR_AMOUNT]; 326 | 327 | void setup() { 328 | Serial.begin(9600); 329 | // устанавливаем адреса 330 | for (int i = 0; i < DS_SENSOR_AMOUNT; i++) { 331 | sensor[i].setAddress(addr[i]); 332 | } 333 | } 334 | 335 | void loop() { 336 | // конструкция программного таймера на 1c 337 | static uint32_t tmr; 338 | if (millis() - tmr >= 1000) { 339 | tmr = millis(); 340 | 341 | // выводим показания в порт 342 | for (int i = 0; i < DS_SENSOR_AMOUNT; i++) { 343 | Serial.print(sensor[i].getTemp()); 344 | Serial.print(','); 345 | } 346 | Serial.println(); 347 | 348 | // запрашиваем новые 349 | for (int i = 0; i < DS_SENSOR_AMOUNT; i++) { 350 | sensor[i].requestTemp(); 351 | } 352 | } 353 | } 354 | ``` 355 | 356 | 357 | ## Версии 358 | - v3.0 - Библиотека переехала на шаблон! Старые примеры НЕСОВМЕСТИМЫ. Оптимизация, новые трюки. 359 | - v3.0.1 - добавлен пример 360 | - v3.1 - добавлена возможность смены адреса на лету 361 | - v3.1.1 - microOneWire разбит на .h и .cpp 362 | - v3.2 - исправлены отрицательные температуры 363 | - v3.3 - разбил на файлы 364 | - v3.4 - добавлена проверка онлайна датчика и буфер, при ошибке чтения возвращается последнее прочитанное значение 365 | - v3.5 - оптимизация, повышение стабильности, проверка правильности чтения, online() работает с адресацией, добавлен метод getTempInt() и readTemp(), упразднён DS_TEMP_TYPE 366 | - v3.6 - исправлена ошибка компиляции, добавлена поддержка GyverCore (спасибо ArtemiyKolobov) 367 | - v3.7 - исправлена ошибка readTemp() при 0 градусов 368 | - v3.8 - небольшая оптимизация. Совместимость с ESP32 369 | - v3.9 - добавил расширенный режим адресации и хранение адресов в PROGMEM 370 | - v3.10 - оптимизация, увеличена стабильность 371 | 372 | 373 | ## Баги и обратная связь 374 | При нахождении багов создавайте **Issue**, а лучше сразу пишите на почту [alex@alexgyver.ru](mailto:alex@alexgyver.ru) 375 | Библиотека открыта для доработки и ваших **Pull Request**'ов! 376 | 377 | 378 | При сообщении о багах или некорректной работе библиотеки нужно обязательно указывать: 379 | - Версия библиотеки 380 | - Какой используется МК 381 | - Версия SDK (для ESP) 382 | - Версия Arduino IDE 383 | - Корректно ли работают ли встроенные примеры, в которых используются функции и конструкции, приводящие к багу в вашем коде 384 | - Какой код загружался, какая работа от него ожидалась и как он работает в реальности 385 | - В идеале приложить минимальный код, в котором наблюдается баг. Не полотно из тысячи строк, а минимальный код 386 | -------------------------------------------------------------------------------- /README_EN.md: -------------------------------------------------------------------------------- 1 | This is an automatic translation, may be incorrect in some places. See sources and examples! 2 | 3 | # Microds18b20 4 | Light library for working with 1-Wire (Onewire) thermometers Dallas DS18B20 5 | - asynchronous work (without expectation of conversion) 6 | - Work with several sensors on one pin (addressing mode) 7 | - storage of an array of addresses in ProGMEM memory 8 | - Work with one sensor on pin (without using addressing) 9 | - calculation of temperature in integers and with a floating point 10 | - reading raw data for cases of strong memory savings 11 | - checking the correctness of the resulting temperature 12 | - customized resolution of transformation 13 | - Data authenticity check 14 | - checking the correctness of the sensor 15 | 16 | ## compatibility 17 | Compatible with all arduino platforms (used arduino functions) 18 | - does not work on fresh versions of SDK ESP32 19 | - It does not work on Digispark, some kind of conflict with a compiler.Use the nucleus [Attinycore Universal] (https://github.com/spencekonde/atTinycore) with the setting of Attiny85 + Micronucleous (Digispark) instead 20 | 21 | ## Content 22 | - [installation] (# Install) 23 | - [initialization] (#init) 24 | - [use] (#usage) 25 | - [connection] (#wiring) 26 | - [Examples] (# ExamPles) 27 | - [versions] (#varsions) 28 | - [bugs and feedback] (#fedback) 29 | 30 | 31 | ## Installation 32 | - The library can be found by the name ** Microds18b20 ** and installed through the library manager in: 33 | - Arduino ide 34 | - Arduino ide v2 35 | - Platformio 36 | - [download the library] (https://github.com/gyverlibs/microds18b20/archive/refs/heads/main.zip). Zip archive for manual installation: 37 | - unpack and put in * C: \ Program Files (X86) \ Arduino \ Libraries * (Windows X64) 38 | - unpack and put in * C: \ Program Files \ Arduino \ Libraries * (Windows X32) 39 | - unpack and put in *documents/arduino/libraries/ * 40 | - (Arduino id) Automatic installation from. Zip: * sketch/connect the library/add .Zip library ... * and specify downloaded archive 41 | - Read more detailed instructions for installing libraries [here] (https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%BD%D0%BE%BE%BE%BED0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA) 42 | ### Update 43 | - I recommend always updating the library: errors and bugs are corrected in the new versions, as well as optimization and new features are added 44 | - through the IDE library manager: find the library how to install and click "update" 45 | - Manually: ** remove the folder with the old version **, and then put a new one in its place.“Replacement” cannot be done: sometimes in new versions, files that remain when replacing are deleted and can lead to errors! 46 | 47 | 48 | 49 | ## initialization 50 | `` `CPP 51 | // One sensor on pin without addressing 52 | Microds18b20 ds; 53 | 54 | // Several sensors on the pin with addressing, indicate the address (address - array Uint8_T) 55 | Microds18b20 ds; 56 | 57 | // We indicate that we will work with addressing.We will transmit the address itself later (in Setaddress ()) 58 | Microds18b20 ; 59 | 60 | // indicate that we will work with addressing, and there will be several (amount) sensors on the line 61 | // See example async_read_many_bus 62 | Microds18b20 ; 63 | 64 | // We indicate that we will work with addressing, there will be several sensors on the line, and we will store the addresses in Progmem 65 | // see pr.Imer async_read_many_bus_pgm 66 | Microds18b20 ; 67 | `` ` 68 | 69 | 70 | ## Usage 71 | `` `CPP 72 | // ============= Methods of class ======================== 73 | Bool Readaddress (Uint8_t *Addressarry);// Read the unique address of the thermometer in the array.[True, if successful] 74 | VOID Setaddress (Uint8_T *Addr);// Set (change) address 75 | VOID Setresolution (Uint8_T Resolution);// Set a resolution 9-12 bits 76 | Bool online ();// Check the connection with the sensor (True - online sensor).The tire should be fitted 77 | 78 | VOID RequestTemp ();// Request a new temperature transformation 79 | Bool Readtemp ();// Read the temperature from the sensor.[true if successfully] 80 | 81 | Float gettemp ();// get the temperature value in Float 82 | int16_t gettempint ();// get the temperature value in int 83 | Int16_T GETRAW ();// get a "raw" temperature value (16 times more than real temperature) 84 | 85 | // ======= Methods for the tire of sensors ========= 86 | // See examples async_read_many_bus and async_read_many_bus_pgm 87 | VOID Setresolutionall (Uint8_T Res);// Set a resolution of 9-12 bits for all sensors on the line 88 | VOID Setresolution (Uint8_T Resolution, Uint8_T IDX);// Set a resolution 9-12 bits (sensor under the IDX number) 89 | Bool Online (Uint8_T IDX);// Check the connection (sensor under the IDX number) 90 | 91 | VOID RequestTempall ();// Temperature request for all sensors on the line 92 | VOID REQUESTEMP (Uint8_T IDX);// Request a new temperature conversion (sensor under the IDX number) 93 | Bool Readtemp (Uint8_T IDX);// Read the temperature from the sensor (sensor under the IDX number) 94 | 95 | Float Gettemp (Uint8_T IDX);// get the temperature value in Float (sensor under the IDX number) 96 | Int16_T Gettempint (Uint8_T IDX);// get the temperature value in int (sensor under the IDX number) 97 | Int16_T Getraw (Uint8_T IDX);// Get a "raw" temperature value (sensor under the IDX number) 98 | 99 | // =========== Functions outside the class ============ 100 | int DS_RAWTOINT (inta);// Transform RAW data into temperature int 101 | Float DS_RAWTOFLOAT (Inta);// Transform RAW data to Float temperature 102 | 103 | // ========ward 104 | // write down before connecting the library 105 | #define ds_check_crc [True / False] // Checking of data authenticity.When disconnecting, it will give out incorrect value when gear failure (def. True) 106 | #define ds_crc_use_table [True / False] // Use a table for CRC.Faster, but +256 bytes Flash (<1mx vs ~ 6mx) (silence. False) 107 | 108 | // ====ward 109 | // Time of transformation from accuracy 110 | accuracy |time 111 | 12 bits |750 ms 112 | 11 bit |375 ms 113 | 10 bits |187 ms 114 | 9 bits |93 ms 115 | `` ` 116 | 117 | ### Work with a sensor 118 | #### without addressing 119 | In this mode, one sensor is connected to one PIN MK, it does not require a preliminary reading of the address and write it to the program to work with it. 120 | You can connect several sensors, indicate each PIN, see example *One_pin_one_Sensor *. 121 | `` `CPP 122 | Microds18b20 Sensor1; 123 | Microds18b20 Sensor2; 124 | // ... and so on 125 | `` ` 126 | 127 | ### with addressing 128 | In this mode, you can connect as many sensors to one PIN MK, but to work with them you will need to bring unique sensors addresses into the program. 129 | At the time of reading the address to Pin, only one sensor must be connected!Example - *Address_read *. 130 | For further work, the addresses are stored in arrays on the side of the program and transmitted to the sensors during initialization, the PIN is indicated the same: 131 | `` `CPP 132 | uint8_t addr1 [{0x28, 0xff, 0xcd, 0x59, 0x51, 0x17, 0x4, 0xfe}; 133 | uint8_t addr2 [] = {0x28, 0xff, 0x36, 0x94, 0x65, 0x15, 0x2, 0x80}; 134 | 135 | Microds18b20 Sensor1; 136 | Microds18b20 SensoR2; 137 | // ... and so on 138 | `` ` 139 | Also, the address can be changed during the program, see the documentation above. 140 | 141 | #### Reading Temperature 142 | Reading the temperature is divided into two stages - a request and obtaining data.The request is made by the `REQUESTEMP ()` function.After receiving the request 143 | The sensor begins a temperature measurement, which lasts from 90 to 750 ms, depending on the configured accuracy *(by default, the accuracy is maximum, 144 | The transformation lasts 750 ms)*.If you read the temperature before the end of the transformation, the sensor will return the result of the previous measurement, 145 | Therefore, the examples use a delay or a survey by a timer for 1 second.You can get the temperature using `gettemp ()` [float] or `gettempint ()` [int]. 146 | If the accepted data is damaged or the sensor is absent on the line, the function will return the previous successfully read temperature value. 147 | ** Note: ** During repeated calls, `gettemp ()` does not request a new temperature from the sensor (long execution of the function), 148 | Instead, she simply returns the previous result until a new request is made `RequestTemp ()`. 149 | 150 | In the version of Library 3.5, it became possible to separately request the temperature and determine the correctness of the data obtained, so that only after that read them 151 | And apply in the program - the function `Readtemp ()`.This also allows you to determine the condition of the connection and whether everything is in order with the sensor. 152 | To read temperature, it is recommended to use the design of the type: 153 | `` `CPP 154 | if (Sensor.Readtemp ()) value = sensor.gettemp (); 155 | // Else error development 156 | `` ` 157 | Where `Readtemp ()` Causes the data from the sensor and returns `true` if they are read correctly.After that, you can pick up the current temperature from `gettemp ()`, 158 | Which no longer requests the temperature from the sensor, but gives the result read in `readtemp ()` result. 159 | 160 | ### We connect a lot of sensors to one object 161 | In the version of Library 3.9, it became possible to connect as many sensors to one object Microds18b20, without creating an array of objects (as in old versions). 162 | It is necessary to create a two -dimensional array of addresses and transfer it to the library, also indicating the number of sensors on the line (you can maximum if it changes in the process of the program). 163 | This allows you to save a little memory, but you can go further - put an array of sensors in the Progmem so that they do not hang in RAM. 164 | In this case, the initialization looks like this: `Microds18b20 ;` or `Microds18b20 ;` for Progmem mode. 165 | The addresses are transmitted to `setaddress ()`, and for the survey we simply transmit the sensor index to the same functions as before.See examples *async_read_many_bus *, *async_read_Many_bus_pgm *and documentation section *Methods for the sensors tire *. 166 | 167 | 168 | ## connection 169 | ! [Scheme] (/doc/scheme.png) 170 | P.S.Instead of a resistor at 4.7k, you can use two in parallel by 10k =) 171 | 172 | 202 | // sensors for d2 and d3 203 | Microds18b20 <2> Sensor1; 204 | Microds18b20 <3> Sensor2; 205 | 206 | VOID setup () { 207 | Serial.Begin (9600); 208 | } 209 | 210 | VOID loop () { 211 | // Temperature request 212 | Sensor1.requesttemp (); 213 | Sensor2.requesttemp (); 214 | 215 | // Instead of DELAY, use a timer on Millis (), an example async_read 216 | DELAY (1000); 217 | 218 | // The first sensor 219 | Serial.print ("t1:"); 220 | 221 | // just display the temperature of the first sensor 222 | Serial.print (Sensor1.gettemp ()); 223 | 224 | // Second sensationK. 225 | Serial.print (", t2:"); 226 | 227 | // Check the success of reading and display 228 | if (Sensor2.Readtemp ()) serial.println (Sensor2.gettemp ()); 229 | Else serial.println ("error"); 230 | } 231 | `` ` 232 | 233 | ## Reading the address 234 | `` `CPP 235 | #include 236 | 237 | // only one sensor is connected to the pin! 238 | Microds18b20 <2> Sensor;// Create a thermometer without address on pin D2 239 | uint8_t address [8];// Create an array for the address 240 | 241 | VOID setup () { 242 | Serial.Begin (9600); 243 | } 244 | 245 | VOID loop () { 246 | // read the thermometer address in the specified array 247 | if (Sensor.Readaddress (Address)) {// If successfully, we display 248 | Serial.print ('{'); 249 | for (uint8_t i = 0; i <8; i ++) { 250 | Serial.print ("0x"); 251 | Serial.print (address [i], hex);// display the address 252 | if (i <7) serial.print (","); 253 | } 254 | Serial.println ('}'); 255 | 256 | } Else serial.println ("Not Connected"); 257 | DELAY (1000); 258 | } 259 | `` ` 260 | 261 | ## a few sensors with addressing 262 | `` `CPP 263 | // 2 or more sensors is more profitable to use with addressing on one pin 264 | #include 265 | #define ds_pin 2 // PIN for thermometers 266 | 267 | // Unique sensors - you can count in the example of Address_read 268 | uint8_t s1_addr [] = {0x28, 0xff, 0xcd, 0x59, 0x51, 0x17, 0x4, 0xfe}; 269 | uint8_t s2_addr [] = {0x28, 0xff, 0x36, 0x94, 0x65, 0x15, 0x2, 0x80}; 270 | 271 | Microds18b20 sensor1;// Create a thermometer with addressing 272 | Microds18b20 sensor2;// Create a thermometer with addressing 273 | 274 | VOID setup () { 275 | Serial.Begin (9600); 276 | } 277 | 278 | VOID loop () { 279 | // Asynchronous reading of several sensors see async_read_many 280 | Sensor1.requesttemp ();// Request temperature transformation 281 | Sensor2.requesttemp (); 282 | 283 | DELAY (1000);// We expect the result 284 | 285 | Serial.print ("t1:"); 286 | if (Sensor1.Redtemp ()) serial.println (Sensor1.gettemp ()); 287 | Else serial.println ("error"); 288 | 289 | Serial.print ("t2:"); 290 | if (Sensor2.Readtemp ()) serial.println (Sensor2.gettemp ()); 291 | Else serial.println ("error"); 292 | } 293 | `` ` 294 | 295 | ## asynchronous survey packs of sensors 296 | `` `CPP 297 | // An example of a compact asynchronous survey of sensors on a software timer 298 | // https://alexgyver.ru/lessons/time/ 299 | 300 | // number of sensors for convenience 301 | #define ds_sensor_amount 5 302 | 303 | // Create a two -dimensional array with addresses 304 | uint8_t addr [] [8] = {{ 305 | {0x28, 0xff, 0x78, 0x5b, 0x50, 0x17, 0x4, 0xcf}, 306 | {0x28, 0xff, 0x99, 0x80, 0x50, 0x17, 0x4, 0x4d}, 307 | {0x28, 0xff, 0x53, 0xe5, 0x50, 0x17, 0x4, 0xc3}, 308 | {0x28, 0xff, 0x42, 0x5a, 0x51, 0x17, 0x4, 0xd2}, 309 | {0x28, 0xff, 0xcd, 0x59, 0x51, 0x17, 0x4, 0xfe}, 310 | }; 311 | 312 | #include 313 | // specify ds_addr_mode to connect an addressing unit 314 | // and create an array of sensors on pin D2 315 | Microds18b20 <2, ds_addr_mode> sensor [ds_sensor_amount]; 316 | 317 | VOID setup () { 318 | Serial.Begin (9600); 319 | // Install the addresses 320 | for (int i = 0; i = 1000) { 329 | TMR = Millis (); 330 | 331 | // We display the readings to the port 332 | for (int i = 0; i 347 | ## versions 348 | - V3.0 - The library moved to the template!Old examples are incompatible.Optimization, new tricks. 349 | - v3.0.1 - Added example 350 | - v3.1 - added the possibility of changing the address on the fly 351 | - V3.1.1 - Microonewire is divided into .h and .cpp 352 | - v3.2 - negative temperatures are fixed 353 | - v3.3 - divided into files 354 | - v3.4 - added the sensor online and buffer, with an error of reading, the last value read is returned 355 | - V3.5 - optimization, increasing stability, checking the correctness of reading, online () works with addressing, added Gettempint () and Readtemp (), abolished ds_temp_type 356 | - V3.6 - Fixed compilation error, added support Gyvercore (thanks Artemiykolobov) 357 | - v3.7 - ReadTemp () error is fixed at 0 degrees 358 | - V3.8 - slight optimization.Compatibility with ESP32 359 | - v3.9 - added an extended addressing mode and storage of addresses in Progmem 360 | - v3.10 - optimization, stability increased 361 | 362 | 363 | ## bugs and feedback 364 | Create ** Issue ** when you find the bugs, and better immediately write to the mail [alex@alexgyver.ru] (mailto: alex@alexgyver.ru) 365 | The library is open for refinement and your ** pull Request ** 'ow! 366 | 367 | 368 | When reporting about bugs or incorrect work of the library, it is necessary to indicate: 369 | - The version of the library 370 | - What is MK used 371 | - SDK version (for ESP) 372 | - version of Arduino ide 373 | - whether the built -in examples work correctly, in which the functions and designs are used, leading to a bug in your code 374 | - what code has been loaded, what work was expected from it and how it works in reality 375 | - Ideally, attach the minimum code in which the bug is observed.Not a canvas of a thousand lines, but a minimum code -------------------------------------------------------------------------------- /doc/scheme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GyverLibs/microDS18B20/db585e5843cfb4357d32bff863269813abe88a8e/doc/scheme.png -------------------------------------------------------------------------------- /examples/address_read/address_read.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Чтение уникального адреса термометра для последующего использования 3 | ВНИМАНИЕ! Устанавливать не более одного датчика на линию (пин) 4 | */ 5 | #include 6 | 7 | MicroDS18B20 <2> sensor; // Создаем термометр без адреса на пине D2 8 | uint8_t address[8]; // Создаем массив для адреса 9 | 10 | void setup() { 11 | Serial.begin(9600); 12 | } 13 | 14 | void loop() { 15 | // читаем адрес термометра в указанный массив 16 | if (sensor.readAddress(address)) { // если успешно, выводим 17 | Serial.print('{'); 18 | for (uint8_t i = 0; i < 8; i++) { 19 | Serial.print("0x"); 20 | Serial.print(address[i], HEX); // Выводим адрес 21 | if (i < 7) Serial.print(", "); 22 | } 23 | Serial.println('}'); 24 | 25 | } else Serial.println("Not connected"); 26 | delay(1000); 27 | } 28 | -------------------------------------------------------------------------------- /examples/async_read/async_read.ino: -------------------------------------------------------------------------------- 1 | // пример асинхронного опроса датчика на программном таймере 2 | // https://alexgyver.ru/lessons/time/ 3 | // один датчик - один пин 4 | 5 | #include 6 | MicroDS18B20<2> sensor; // датчик на D2 7 | 8 | void setup() { 9 | Serial.begin(9600); 10 | } 11 | 12 | void loop() { 13 | // конструкция программного таймера на 800 мс 14 | static uint32_t tmr; 15 | if (millis() - tmr >= 800) { 16 | tmr = millis(); 17 | 18 | // читаем прошлое значение 19 | if (sensor.readTemp()) Serial.println(sensor.getTemp()); 20 | else Serial.println("error"); 21 | 22 | // запрашиваем новое измерение 23 | sensor.requestTemp(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/async_read_many/async_read_many.ino: -------------------------------------------------------------------------------- 1 | // пример компактного асинхронного опроса датчиков на программном таймере 2 | // https://alexgyver.ru/lessons/time/ 3 | 4 | // количество датчиков для удобства 5 | #define DS_SENSOR_AMOUNT 5 6 | 7 | // создаём двухмерный массив с адресами 8 | uint8_t addr[][8] = { 9 | {0x28, 0xFF, 0x78, 0x5B, 0x50, 0x17, 0x4, 0xCF}, 10 | {0x28, 0xFF, 0x99, 0x80, 0x50, 0x17, 0x4, 0x4D}, 11 | {0x28, 0xFF, 0x53, 0xE5, 0x50, 0x17, 0x4, 0xC3}, 12 | {0x28, 0xFF, 0x42, 0x5A, 0x51, 0x17, 0x4, 0xD2}, 13 | {0x28, 0xFF, 0xCD, 0x59, 0x51, 0x17, 0x4, 0xFE}, 14 | }; 15 | 16 | #include 17 | // указываем DS_ADDR_MODE для подключения блока адресации 18 | // и создаём массив датчиков на пине D2 19 | MicroDS18B20<2, DS_ADDR_MODE> sensor[DS_SENSOR_AMOUNT]; 20 | 21 | void setup() { 22 | Serial.begin(9600); 23 | // устанавливаем адреса 24 | for (int i = 0; i < DS_SENSOR_AMOUNT; i++) { 25 | sensor[i].setAddress(addr[i]); 26 | } 27 | } 28 | 29 | void loop() { 30 | // конструкция программного таймера на 1c 31 | static uint32_t tmr; 32 | if (millis() - tmr >= 1000) { 33 | tmr = millis(); 34 | 35 | // выводим показания в порт 36 | for (int i = 0; i < DS_SENSOR_AMOUNT; i++) { 37 | Serial.print(sensor[i].getTemp()); 38 | Serial.print(','); 39 | } 40 | Serial.println(); 41 | 42 | // запрашиваем новые 43 | for (int i = 0; i < DS_SENSOR_AMOUNT; i++) { 44 | sensor[i].requestTemp(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /examples/async_read_many_bus/async_read_many_bus.ino: -------------------------------------------------------------------------------- 1 | // работа в режиме шины - несколько датчиков на линии, один объект 2 | // количество датчиков для удобства 3 | #define SENS_AMOUNT 5 4 | 5 | // создаём двухмерный массив с адресами 6 | uint8_t addr[][8] = { 7 | {0x28, 0xFF, 0x78, 0x5B, 0x50, 0x17, 0x4, 0xCF}, 8 | {0x28, 0xFF, 0x99, 0x80, 0x50, 0x17, 0x4, 0x4D}, 9 | {0x28, 0xFF, 0x53, 0xE5, 0x50, 0x17, 0x4, 0xC3}, 10 | {0x28, 0xFF, 0x42, 0x5A, 0x51, 0x17, 0x4, 0xD2}, 11 | {0x28, 0xFF, 0xCD, 0x59, 0x51, 0x17, 0x4, 0xFE}, 12 | }; 13 | 14 | #include 15 | MicroDS18B20 sensors; 16 | 17 | void setup() { 18 | Serial.begin(9600); 19 | // устанавливаем адреса 20 | sensors.setAddress((uint8_t*)addr); 21 | 22 | // Установить разрешение 9-12 бит у всех датчиков на линии 23 | //sensors.setResolutionAll(10); 24 | } 25 | 26 | void loop() { 27 | // конструкция программного таймера на 1c 28 | static uint32_t tmr; 29 | if (millis() - tmr >= 1000) { 30 | tmr = millis(); 31 | 32 | // выводим показания в порт 33 | for (int i = 0; i < SENS_AMOUNT; i++) { 34 | Serial.print(sensors.getTemp(i)); 35 | Serial.print(','); 36 | } 37 | Serial.println(); 38 | 39 | // запрашиваем новые 40 | sensors.requestTempAll(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /examples/async_read_many_bus_pgm/async_read_many_bus_pgm.ino: -------------------------------------------------------------------------------- 1 | // работа в режиме шины - несколько датчиков на линии, один объект 2 | // количество датчиков для удобства 3 | #define SENS_AMOUNT 5 4 | 5 | // создаём двухмерный массив с адресами 6 | const uint8_t addr[][8] PROGMEM = { 7 | {0x28, 0xFF, 0x78, 0x5B, 0x50, 0x17, 0x4, 0xCF}, 8 | {0x28, 0xFF, 0x99, 0x80, 0x50, 0x17, 0x4, 0x4D}, 9 | {0x28, 0xFF, 0x53, 0xE5, 0x50, 0x17, 0x4, 0xC3}, 10 | {0x28, 0xFF, 0x42, 0x5A, 0x51, 0x17, 0x4, 0xD2}, 11 | {0x28, 0xFF, 0xCD, 0x59, 0x51, 0x17, 0x4, 0xFE}, 12 | }; 13 | 14 | #include 15 | MicroDS18B20 sensors; 16 | 17 | void setup() { 18 | Serial.begin(9600); 19 | // устанавливаем адреса 20 | sensors.setAddress((uint8_t*)addr); 21 | 22 | // Установить разрешение 9-12 бит у всех датчиков на линии 23 | //sensors.setResolutionAll(10); 24 | } 25 | 26 | void loop() { 27 | // конструкция программного таймера на 1c 28 | static uint32_t tmr; 29 | if (millis() - tmr >= 1000) { 30 | tmr = millis(); 31 | 32 | // выводим показания в порт 33 | for (int i = 0; i < SENS_AMOUNT; i++) { 34 | Serial.print(sensors.getTemp(i)); 35 | Serial.print(','); 36 | } 37 | Serial.println(); 38 | 39 | // запрашиваем новые 40 | sensors.requestTempAll(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /examples/flash_reduction/flash_reduction.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Пример с максимальной экономией flash при использовании библиотеки 3 | Если датчик один - не используйте адресацию 4 | Если датчиков несколько - рекомендуется использование адресации и ОДНОЙ линии для экономии flash 5 | */ 6 | 7 | #define DS_CHECK_CRC false // отключить проверку подлинности принятых данных (может привести к выдаче некорректных измерений) 8 | #include 9 | 10 | // Датчик один - не используем адресацию 11 | #define DS_PIN 2 12 | MicroDS18B20 sensor; 13 | 14 | void setup() { 15 | Serial.begin(9600); 16 | } 17 | 18 | void loop() { 19 | sensor.requestTemp(); 20 | delay(1000); 21 | Serial.print("t: "); 22 | Serial.print(sensor.getTempInt()); 23 | Serial.println(" *C"); 24 | } 25 | -------------------------------------------------------------------------------- /examples/one_pin_many_sensors/one_pin_many_sensors.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Пример нескольких термометров на одном пине с использованием адресации 3 | Использование адресации для нескольких датчиков значительно экономит память 4 | */ 5 | 6 | #include 7 | #define DS_PIN 2 // пин для термометров 8 | 9 | // Уникальные адреса датчиков - считать можно в примере address_read 10 | uint8_t s1_addr[] = {0x28, 0xFF, 0xCD, 0x59, 0x51, 0x17, 0x4, 0xFE}; 11 | uint8_t s2_addr[] = {0x28, 0xFF, 0x36, 0x94, 0x65, 0x15, 0x2, 0x80}; 12 | 13 | MicroDS18B20 sensor1; // Создаем термометр с адресацией 14 | MicroDS18B20 sensor2; // Создаем термометр с адресацией 15 | 16 | void setup() { 17 | Serial.begin(9600); 18 | } 19 | 20 | void loop() { 21 | // асинхронное чтение нескольких датчиков смотри в примере async_read_many 22 | sensor1.requestTemp(); // Запрашиваем преобразование температуры 23 | sensor2.requestTemp(); 24 | 25 | delay(1000); // ожидаем результат 26 | 27 | Serial.print("t1: "); 28 | if (sensor1.readTemp()) Serial.println(sensor1.getTemp()); 29 | else Serial.println("error"); 30 | 31 | Serial.print("t2: "); 32 | if (sensor2.readTemp()) Serial.println(sensor2.getTemp()); 33 | else Serial.println("error"); 34 | } 35 | -------------------------------------------------------------------------------- /examples/one_pin_one_sensor/one_pin_one_sensor.ino: -------------------------------------------------------------------------------- 1 | // пример работы с двумя датчиками без адресации 2 | // один датчик - один пин 3 | 4 | #include 5 | // Датчики на D2 и D3 6 | MicroDS18B20<2> sensor1; 7 | MicroDS18B20<3> sensor2; 8 | 9 | void setup() { 10 | Serial.begin(9600); 11 | } 12 | 13 | void loop() { 14 | // запрос температуры 15 | sensor1.requestTemp(); 16 | sensor2.requestTemp(); 17 | 18 | // вместо delay используй таймер на millis(), пример async_read 19 | delay(1000); 20 | 21 | // ПЕРВЫЙ ДАТЧИК 22 | Serial.print("t1: "); 23 | 24 | // просто выводим температуру первого датчика 25 | Serial.print(sensor1.getTemp()); 26 | 27 | // ВТОРОЙ ДАТЧИК 28 | Serial.print(", t2: "); 29 | 30 | // проверяем успешность чтения и выводим 31 | if (sensor2.readTemp()) Serial.println(sensor2.getTemp()); 32 | else Serial.println("error"); 33 | } 34 | -------------------------------------------------------------------------------- /examples/raw_and_calc/raw_and_calc.ino: -------------------------------------------------------------------------------- 1 | // пример с чтением сырого 16 бит значения 2 | // и расшифровкой его в температуру 3 | // может быть использовано для чтения и передачи 4 | 5 | #include 6 | // Датчик на D2 7 | MicroDS18B20<2> sensor; 8 | 9 | void setup() { 10 | Serial.begin(9600); 11 | //sensor.setResolution(12); // разрешение [9-12] бит. По умолч. 12 12 | } 13 | 14 | void loop() { 15 | sensor.requestTemp(); 16 | delay(1000); 17 | // прпочитали сырое значение 18 | uint16_t rawVal = sensor.getRaw(); 19 | Serial.print(rawVal); 20 | Serial.print(" "); 21 | 22 | // преобразовали 23 | Serial.println(DS_rawToFloat(rawVal)); 24 | } 25 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For microDS18B20 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | MicroDS18B20 KEYWORD1 9 | microDS18B20 KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | setResolution KEYWORD2 15 | readAddress KEYWORD2 16 | setAddress KEYWORD2 17 | requestTemp KEYWORD2 18 | readTemp KEYWORD2 19 | getTemp KEYWORD2 20 | getTempInt KEYWORD2 21 | getRaw KEYWORD2 22 | online KEYWORD2 23 | requestTempAll KEYWORD2 24 | setResolutionAll KEYWORD2 25 | 26 | DS_rawToInt KEYWORD2 27 | DS_rawToFloat KEYWORD2 28 | 29 | ####################################### 30 | # Constants (LITERAL1) 31 | ####################################### 32 | DS_CHECK_CRC LITERAL1 33 | DS_CRC_USE_TABLE LITERAL1 34 | DS_ADDR_MODE LITERAL1 35 | DS_PROGMEM LITERAL1 -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=microDS18B20 2 | version=3.10 3 | author=AlexGyver 4 | maintainer=AlexGyver 5 | sentence=Light library for DS18b20 sensor 6 | paragraph=Light library for DS18b20 sensor 7 | category=Sensors 8 | url=https://github.com/GyverLibs/microDS18B20 9 | architectures=* -------------------------------------------------------------------------------- /src/DS_raw.cpp: -------------------------------------------------------------------------------- 1 | #include "DS_raw.h" 2 | 3 | int DS_rawToInt(int16_t data) { 4 | return (data / 16); 5 | } 6 | float DS_rawToFloat(int16_t data) { 7 | return (data / 16.0); 8 | } -------------------------------------------------------------------------------- /src/DS_raw.h: -------------------------------------------------------------------------------- 1 | #ifndef _DS_raw_h 2 | #define _DS_raw_h 3 | #include 4 | int DS_rawToInt(int16_t data); // преобразовать raw данные в температуру int 5 | float DS_rawToFloat(int16_t data); // преобразовать raw данные в температуру float 6 | 7 | #endif -------------------------------------------------------------------------------- /src/microDS18B20.h: -------------------------------------------------------------------------------- 1 | /* 2 | Легкая библиотека для работы с 1-Wire (OneWire) термометрами Dallas DS18B20 3 | Документация: 4 | GitHub: https://github.com/GyverLibs/microDS18B20 5 | Возможности: 6 | - Работа с несколькими датчиками на одном пине (режим адресации) 7 | - Хранение массива адресов в PROGMEM памяти 8 | - Работа с одним датчиком на пине (без использования адресации) 9 | - Расчет температуры в целых числах и с плавающей точкой 10 | - Чтение сырых данных для случаев сильной экономии памяти 11 | - Проверка корректности полученной температуры 12 | - Настраиваемое разрешение преобразования 13 | - Проверка подлинности данных 14 | - Проверка корректности работы датчика 15 | 16 | Egor 'Nich1con' Zakharov & AlexGyver, alex@alexgyver.ru 17 | https://alexgyver.ru/ 18 | MIT License 19 | 20 | Версии: 21 | v3.0 - Библиотека переехала на шаблон! Старые примеры НЕСОВМЕСТИМЫ. Оптимизация, новые трюки. 22 | v3.1 - добавлена возможность смены адреса на лету 23 | v3.1.1 - microOneWire разбит на .h и .cpp 24 | v3.2 - исправлены отрицательные температуры 25 | v3.3 - разбил на файлы 26 | v3.4 - добавлена проверка онлайна датчика и буфер, при ошибке чтения возвращается последнее прочитанное значение 27 | v3.5 - оптимизация, повышение стабильности, проверка правильности чтения, online() работает с адресацией, добавлен метод getTempInt() и readTemp(), упразднён DS_TEMP_TYPE 28 | v3.6 - исправлена ошибка компиляции, добавлена поддержка GyverCore (спасибо ArtemiyKolobov) 29 | v3.7 - исправлена ошибка readTemp() при 0 градусов 30 | v3.8 - небольшая оптимизация. Совместимость с ESP32 31 | v3.9 - добавил расширенный режим адресации и хранение адресов в PROGMEM 32 | v3.10 - оптимизация, увеличена стабильность 33 | */ 34 | 35 | #ifndef _microDS18B20_h 36 | #define _microDS18B20_h 37 | #include 38 | #include "microOneWire.h" 39 | #include "DS_raw.h" 40 | 41 | #define DS_PROGMEM 1 42 | 43 | #ifndef DS_CHECK_CRC 44 | #define DS_CHECK_CRC true // true/false - проверка контрольной суммы принятых данных - надежнее, но тратит немного больше flash 45 | #endif 46 | 47 | #ifndef DS_CRC_USE_TABLE 48 | #define DS_CRC_USE_TABLE false // true/false - использовать готовую таблицу контрольной суммы - значительно быстрее, +256 байт flash 49 | #endif 50 | 51 | /* 52 | Время исполнения функций для работы с датчиком (частота ядра - 16 МГц): 53 | _________________________________________________________________________________ 54 | | Датчик без адресации (один на линии) | Датчик с адресацией (несколько на линии) | 55 | |______________________________________|__________________________________________| 56 | | .setResolution(...) ~ 3591.125 мкс | .setResolution(...) ~ 8276.0625 мкс | 57 | | .requestTemp() ~ 1839.9375 мкс | .requestTemp() ~ 6522.1875 мкс | 58 | |______________________________________|__________________________________________| 59 | | С использованием CRC8 | 60 | |_________________________________________________________________________________| 61 | | .readAddress(...) ~ 6467.3125 мкс | float .getTemp() ~ 12250.25 мкс | 62 | | float .getTemp() ~ 7620.25 мкс | int .getTemp() ~ 12250.2500 мкс | 63 | | int .getTemp() ~ 7574.0625 мкс | | 64 | |______________________________________|__________________________________________| 65 | | Без использования CRC8 | 66 | |_________________________________________________________________________________| 67 | | .readAddress(...) ~ 6394.3125 мкс | float .getTemp() ~ 7809.1250 мкс | 68 | | float .getTemp() ~ 3132.9375 мкс | int .getTemp() ~ 7809.1250 мкс | 69 | | int .getTemp() ~ 3132.9375 мкс | | 70 | |______________________________________|__________________________________________| 71 | */ 72 | 73 | // ====================== CRC TABLE ====================== 74 | #if (DS_CRC_USE_TABLE == true) 75 | static const uint8_t PROGMEM _ds_crc8_table[] = { 76 | 0x00, 0x5e, 0xbc, 0xe2, 0x61, 0x3f, 0xdd, 0x83, 0xc2, 0x9c, 0x7e, 0x20, 0xa3, 0xfd, 0x1f, 0x41, 77 | 0x9d, 0xc3, 0x21, 0x7f, 0xfc, 0xa2, 0x40, 0x1e, 0x5f, 0x01, 0xe3, 0xbd, 0x3e, 0x60, 0x82, 0xdc, 78 | 0x23, 0x7d, 0x9f, 0xc1, 0x42, 0x1c, 0xfe, 0xa0, 0xe1, 0xbf, 0x5d, 0x03, 0x80, 0xde, 0x3c, 0x62, 79 | 0xbe, 0xe0, 0x02, 0x5c, 0xdf, 0x81, 0x63, 0x3d, 0x7c, 0x22, 0xc0, 0x9e, 0x1d, 0x43, 0xa1, 0xff, 80 | 0x46, 0x18, 0xfa, 0xa4, 0x27, 0x79, 0x9b, 0xc5, 0x84, 0xda, 0x38, 0x66, 0xe5, 0xbb, 0x59, 0x07, 81 | 0xdb, 0x85, 0x67, 0x39, 0xba, 0xe4, 0x06, 0x58, 0x19, 0x47, 0xa5, 0xfb, 0x78, 0x26, 0xc4, 0x9a, 82 | 0x65, 0x3b, 0xd9, 0x87, 0x04, 0x5a, 0xb8, 0xe6, 0xa7, 0xf9, 0x1b, 0x45, 0xc6, 0x98, 0x7a, 0x24, 83 | 0xf8, 0xa6, 0x44, 0x1a, 0x99, 0xc7, 0x25, 0x7b, 0x3a, 0x64, 0x86, 0xd8, 0x5b, 0x05, 0xe7, 0xb9, 84 | 0x8c, 0xd2, 0x30, 0x6e, 0xed, 0xb3, 0x51, 0x0f, 0x4e, 0x10, 0xf2, 0xac, 0x2f, 0x71, 0x93, 0xcd, 85 | 0x11, 0x4f, 0xad, 0xf3, 0x70, 0x2e, 0xcc, 0x92, 0xd3, 0x8d, 0x6f, 0x31, 0xb2, 0xec, 0x0e, 0x50, 86 | 0xaf, 0xf1, 0x13, 0x4d, 0xce, 0x90, 0x72, 0x2c, 0x6d, 0x33, 0xd1, 0x8f, 0x0c, 0x52, 0xb0, 0xee, 87 | 0x32, 0x6c, 0x8e, 0xd0, 0x53, 0x0d, 0xef, 0xb1, 0xf0, 0xae, 0x4c, 0x12, 0x91, 0xcf, 0x2d, 0x73, 88 | 0xca, 0x94, 0x76, 0x28, 0xab, 0xf5, 0x17, 0x49, 0x08, 0x56, 0xb4, 0xea, 0x69, 0x37, 0xd5, 0x8b, 89 | 0x57, 0x09, 0xeb, 0xb5, 0x36, 0x68, 0x8a, 0xd4, 0x95, 0xcb, 0x29, 0x77, 0xf4, 0xaa, 0x48, 0x16, 90 | 0xe9, 0xb7, 0x55, 0x0b, 0x88, 0xd6, 0x34, 0x6a, 0x2b, 0x75, 0x97, 0xc9, 0x4a, 0x14, 0xf6, 0xa8, 91 | 0x74, 0x2a, 0xc8, 0x96, 0x15, 0x4b, 0xa9, 0xf7, 0xb6, 0xe8, 0x0a, 0x54, 0xd7, 0x89, 0x6b, 0x35 92 | }; 93 | #endif 94 | 95 | #pragma GCC diagnostic push 96 | #pragma GCC diagnostic ignored "-Wunused-variable" 97 | uint8_t _empDsAddr[1] = {1}; 98 | #pragma GCC diagnostic pop 99 | #define DS_ADDR_MODE _empDsAddr 100 | 101 | // ====================== CLASS ====================== 102 | template 103 | class MicroDS18B20 { 104 | public: 105 | MicroDS18B20() { 106 | pinMode(DS_PIN, INPUT); 107 | digitalWrite(DS_PIN, LOW); 108 | } 109 | 110 | // Установить разрешение термометра 9-12 бит 111 | void setResolution(uint8_t res, uint8_t idx = 0) { 112 | if (!oneWire_reset(DS_PIN)) return; // Проверка присутствия 113 | addressRoutine(idx); // Процедура адресации 114 | oneWire_write(0x4E, DS_PIN); // Запись RAM 115 | oneWire_write(0xFF, DS_PIN); // Максимум в верхний регистр тревоги 116 | oneWire_write(0x00, DS_PIN); // Минимум в верхний регистр тревоги 117 | oneWire_write(((constrain(res, 9, 12) - 9) << 5) | 0x1F, DS_PIN); // Запись конфигурации разрешения 118 | } 119 | 120 | // Установить разрешение термометра 9-12 бит у всех датчиков на линии 121 | void setResolutionAll(uint8_t res) { 122 | for (int i = 0; i < DS_AM; i++) setResolution(res, i); 123 | } 124 | 125 | // установить адрес 126 | void setAddress(uint8_t *addr) { 127 | _addr = addr; 128 | } 129 | 130 | // Прочитать уникальный адрес термометра в массив 131 | bool readAddress(uint8_t *addr) { 132 | if (!oneWire_reset(DS_PIN)) return 0; // Проверка присутствия 133 | oneWire_write(0x33, DS_PIN); // Запрос адреса 134 | uint16_t sum = 0; // контрольная сумма 135 | uint8_t crc = 0; // обнуляем crc 136 | for (uint8_t i = 0; i < 8; i++) { // Прочитать 8 байт адреса 137 | addr[i] = oneWire_read(DS_PIN); // Записать в массив 138 | sum += addr[i]; // контрольная сумма 139 | #if (DS_CHECK_CRC == true) 140 | _ds_crc8_upd(crc, addr[i]); // Обновить значение CRC8 141 | #endif 142 | } 143 | return !(sum == 0x8F7 || !sum || crc); // CRC не сошелся или адрес нулевой - ошибка 144 | } 145 | 146 | // запрос температуры 147 | void requestTemp(uint8_t idx = 0) { 148 | state[idx] = 0; // запрошена новая температура 149 | if (!oneWire_reset(DS_PIN)) return; // Проверка присутствия 150 | addressRoutine(idx); // Процедура адресации 151 | oneWire_write(0x44, DS_PIN); // Запросить преобразование 152 | } 153 | 154 | // запрос температуры у всех датчиков на линии 155 | void requestTempAll() { 156 | for (int i = 0; i < DS_AM; i++) requestTemp(i); 157 | } 158 | 159 | // получить температуру float 160 | float getTemp(uint8_t idx = 0) { 161 | if (!state[idx]) readTemp(idx); 162 | return (_buf[idx] / 16.0); 163 | } 164 | 165 | // получить температуру int 166 | int16_t getTempInt(uint8_t idx = 0) { 167 | if (!state[idx]) readTemp(idx); 168 | return (_buf[idx] >> 4); 169 | } 170 | 171 | // получить "сырое" значение температуры 172 | int16_t getRaw(uint8_t idx = 0) { 173 | if (!state[idx]) readTemp(idx); 174 | return _buf[idx]; 175 | } 176 | 177 | // прочитать температуру с датчика. true если успешно 178 | bool readTemp(uint8_t idx = 0) { 179 | state[idx] = 1; 180 | if (!oneWire_reset(DS_PIN)) return 0; // датчик оффлайн 181 | addressRoutine(idx); // Процедура адресации 182 | oneWire_write(0xBE, DS_PIN); // Запросить температуру 183 | uint8_t crc = 0; // обнуляем crc 184 | int16_t temp; // переменная для расчёта температуры 185 | uint16_t sum = 0; // контрольная сумма 186 | for (uint8_t i = 0; i < 9; i++) { // Считать RAM 187 | uint8_t data = oneWire_read(DS_PIN); // Прочитать данные 188 | sum += data; 189 | #if (DS_CHECK_CRC == true) 190 | _ds_crc8_upd(crc, data); // Обновить значение CRC8 191 | #endif 192 | if (i == 0) temp = data; 193 | else if (i == 1) temp |= (data << 8); 194 | } 195 | if (sum == 0x8F7 || !sum || crc) return 0; // датчик оффлайн или данные повреждены 196 | if (temp != 0x0550) _buf[idx] = temp; // пропускаем первое чтение (85 градусов) 197 | return 1; 198 | } 199 | 200 | // проверить связь с датчиком (true - датчик на линии). ЛИНИЯ ДОЛЖНА БЫТЬ ПОДТЯНУТА 201 | bool online(uint8_t idx = 0) { 202 | if (DS_ADDR != nullptr) { 203 | if (!oneWire_reset(DS_PIN)) return 0; 204 | addressRoutine(idx); 205 | oneWire_write(0xBE, DS_PIN); 206 | uint16_t sum = 0; 207 | for (uint8_t i = 0; i < 5; i++) sum += oneWire_read(DS_PIN); 208 | return (sum != 0x4FB); 209 | } else return oneWire_reset(DS_PIN); 210 | } 211 | 212 | private: 213 | bool state[DS_AM]; 214 | int16_t _buf[DS_AM]; 215 | uint8_t *_addr = DS_ADDR; 216 | 217 | void addressRoutine(uint8_t idx) { // Процедура адресации 218 | if (DS_ADDR != nullptr) { // Адрес определен? 219 | oneWire_write(0x55, DS_PIN); // Говорим термометрам слушать адрес 220 | for (uint8_t i = 0; i < 8; i++) { 221 | if (DS_PGM) oneWire_write(pgm_read_byte(&_addr[i + idx * 8]), DS_PIN); 222 | else oneWire_write(_addr[i + idx * 8], DS_PIN); 223 | } 224 | } else oneWire_write(0xCC, DS_PIN); // Адреса нет - пропускаем адресацию на линии 225 | } 226 | 227 | void _ds_crc8_upd(uint8_t &crc, uint8_t data) { 228 | #if (DS_CRC_USE_TABLE == true) // Используем таблицу? 229 | crc = pgm_read_byte(&_ds_crc8_table[crc ^ data]); // Тогда берем готовое значение 230 | #else // считаем вручную 231 | #ifdef __AVR__ 232 | // резкий алгоритм для AVR 233 | uint8_t counter; 234 | uint8_t buffer; 235 | asm volatile ( 236 | "EOR %[crc_out], %[data_in] \n\t" 237 | "LDI %[counter], 8 \n\t" 238 | "LDI %[buffer], 0x8C \n\t" 239 | "_loop_start_%=: \n\t" 240 | "LSR %[crc_out] \n\t" 241 | "BRCC _loop_end_%= \n\t" 242 | "EOR %[crc_out], %[buffer] \n\t" 243 | "_loop_end_%=: \n\t" 244 | "DEC %[counter] \n\t" 245 | "BRNE _loop_start_%=" 246 | : [crc_out]"=r" (crc), [counter]"=d" (counter), [buffer]"=d" (buffer) 247 | : [crc_in]"0" (crc), [data_in]"r" (data) 248 | ); 249 | #else 250 | // обычный для всех остальных 251 | uint8_t i = 8; 252 | while (i--) { 253 | crc = ((crc ^ data) & 1) ? (crc >> 1) ^ 0x8C : (crc >> 1); 254 | data >>= 1; 255 | } 256 | #endif 257 | #endif 258 | } 259 | }; 260 | #endif -------------------------------------------------------------------------------- /src/microOneWire.cpp: -------------------------------------------------------------------------------- 1 | #include "microOneWire.h" 2 | #ifdef __AVR__ 3 | #define MOW_CLI() uint8_t oldSreg = SREG; cli(); 4 | #define MOW_SEI() SREG = oldSreg 5 | #else 6 | #define MOW_CLI() 7 | #define MOW_SEI() 8 | #endif 9 | 10 | bool oneWire_reset(uint8_t pin) { 11 | pinMode(pin, OUTPUT); 12 | delayMicroseconds(600); 13 | pinMode(pin, INPUT); 14 | MOW_CLI(); 15 | delayMicroseconds(60); 16 | bool pulse = digitalRead(pin); 17 | MOW_SEI(); 18 | delayMicroseconds(600); 19 | return !pulse; 20 | } 21 | 22 | void oneWire_write(uint8_t data, uint8_t pin) { 23 | for (uint8_t i = 8; i; i--) { 24 | pinMode(pin, OUTPUT); 25 | MOW_CLI(); 26 | if (data & 1) { 27 | delayMicroseconds(5); 28 | pinMode(pin, INPUT); 29 | delayMicroseconds(60); 30 | } else { 31 | delayMicroseconds(60); 32 | pinMode(pin, INPUT); 33 | delayMicroseconds(5); 34 | } 35 | MOW_SEI(); 36 | data >>= 1; 37 | } 38 | } 39 | 40 | uint8_t oneWire_read(uint8_t pin) { 41 | uint8_t data = 0; 42 | for (uint8_t i = 8; i; i--) { 43 | data >>= 1; 44 | MOW_CLI(); 45 | pinMode(pin, OUTPUT); 46 | delayMicroseconds(2); 47 | pinMode(pin, INPUT); 48 | delayMicroseconds(8); 49 | if (digitalRead(pin)) data |= (1 << 7); 50 | delayMicroseconds(60); 51 | MOW_SEI(); 52 | } 53 | return data; 54 | } -------------------------------------------------------------------------------- /src/microOneWire.h: -------------------------------------------------------------------------------- 1 | // v1.2 от 26.04.2020 - Повышена стабильность 2 | // v1.3 от 08.09.2021 - Разбил на .h и .cpp 3 | // v1.4 от 07.01.2022 - Чуть сократил код, поддержка GyverCore 4 | // v1.5 от 18.02.2022 - оптимизация, поддержка esp32 5 | 6 | #ifndef _microOneWire_h 7 | #define _microOneWire_h 8 | #include 9 | 10 | bool oneWire_reset(uint8_t pin); 11 | void oneWire_write(uint8_t data, uint8_t pin); 12 | uint8_t oneWire_read(uint8_t pin); 13 | #endif --------------------------------------------------------------------------------