Здравствуйте всем. Никак не могу найти пример подсоединения двух датчиков к 1 пину на Ардино. Во всех статьях только написано о том, что у каждого свой индивидуальный ROM и чтобы считать температуру с определенного датчика нужно искать соответствие. Но где это соответствие искать я врубиться не могу. В готовом примере на 1 датчик не могу разобраться, где этот самый ROM. не подскажете где найти готовый пример, либо в какой части скетча мне искать соответствие? Сразу прошу меня простить за столь элементарный вопрос. Я чайник, который всего-то дня 3 изучал программирование абсолютно с 0, а контроллер нужен уже довольно срочно... Нужно контролировать температуру сразу в 8 разных местах.
Пример из библиотеки. Скетч вначале ищет первый попавшийся датчик на шине а затем опрашивает именно его. Обратите внимание на массив addr - в нем хранится серийный номер найденного датчика. Код (C++): #include <OneWireSTM.h> // OneWire DS18S20, DS18B20, DS1822 Temperature Example // // Based on version by PJRC // // The DallasTemperature library can do all this work for you! // http://milesburton.com/Dallas_Temperature_Control_Library OneWire ds(10); // пин к которому подключаем датчики void setup(void) { Serial.begin(9600); } void loop(void) { byte i; byte present = 0; byte type_s; byte data[12]; byte addr[8]; // серийный номер или адрес датчика float celsius, fahrenheit; if ( !ds.search(addr)) { Serial.println("No more addresses."); Serial.println(); ds.reset_search(); delay(250); return; } Serial.print("ROM ="); // выводим в терминал найденный адрес for( i = 0; i < 8; i++) { Serial.write(' '); Serial.print(addr[i], HEX); } if (OneWire::crc8(addr, 7) != addr[7]) { Serial.println("CRC is not valid!"); return; } Serial.println(); // по первому байту в адресе определяем семейство датчика switch (addr[0]) { case 0x10: Serial.println(" Chip = DS18S20"); // or old DS1820 type_s = 1; break; case 0x28: Serial.println(" Chip = DS18B20"); type_s = 0; break; case 0x22: Serial.println(" Chip = DS1822"); type_s = 0; break; default: Serial.println("Device is not a DS18x20 family device."); return; } ds.reset(); ds.select(addr); // запрашиваем работу с конкретным датчиком ds.write(0x44, 1); // запуск преобразования температуры с паразитным питанием delay(1000); // maybe 750ms is enough, maybe not // we might do a ds.depower() here, but the reset will take care of it. present = ds.reset(); ds.select(addr); // опять выбираем этот датчк после сброса шины ds.write(0xBE); // читаем Scratchpad Serial.print(" Data = "); Serial.print(present, HEX); Serial.print(" "); for ( i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read(); Serial.print(data[i], HEX); Serial.print(" "); } Serial.print(" CRC="); Serial.print(OneWire::crc8(data, 8), HEX); Serial.println(); // Convert the data to actual temperature // because the result is a 16 bit signed integer, it should // be stored to an "int16_t" type, which is always 16 bits // even when compiled on a 32 bit processor. int16_t raw = (data[1] << 8) | data[0]; if (type_s) { 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 } celsius = (float)raw / 16.0; fahrenheit = celsius * 1.8 + 32.0; Serial.print(" Temperature = "); Serial.print(celsius); Serial.print(" Celsius, "); Serial.print(fahrenheit); Serial.println(" Fahrenheit"); }
Спасибо большое всем ответившим! Поняла, буду сочинять дальше! Так и знела, что addr мне и нужен. А в библиотеке, которую я скачала (OneWire) пример с температурой только один, и с одним датчиком. Потому не могла найти...
В принципе, адрес датчика не обязателен. Команда 0xcc отправляет запрос сразу на все присоединенные датчики, а потом точно так же со всех считывает результаты. Но без адресов будет трудно разобраться, какая температура с какого датчика пришла.
Мне обязательно знать с какого датчиа температура, т.к. это будет не просто градусник, а контроллер, который будет в зависимости от показаний включать и выключать обогрев/охлаждение. "Умный зоопарк" типа)
Я с этим датчиком температуры раньше не работал, характеристики заманчивы, но одно настораживает: протокол, по которому он возвращает данные, очень уж неспешный (нельзя было его на I2C сделать? ) Опрашивать не чаще чем раз в 1 сек - это ок, ладно. Допустим я его спросил - сколько примерно времени МК будет занят получением ответа?
На стандартной скорости - 15 кбит/с, на повышенной - 111 кбит/с, емнип. Цитата с сайта максимок: Ну а время чтения скратчпада - высчитывается, как понимаете И зависит, ессно, от размера скратчпада, т.к. девайсов на 1-Wire - вагончик. Применительно к DS18B20 - надо вычитать 9 байт, помимо записи команд, конечно. Если вот прям конкретно точно-точно надо - можно тестовым скетчем измерить скорость чтения.
Строго говоря, это не совсем так - можно опрашивать и чаще, зависит от установленного в датчик разрешения. Ну и команду конвертации можно выдавать нечасто, раз в 10 секунд, скажем - тогда и читать можно сколь угодно часто, просто отдаваться будут старые данные, до тех пор, пока не запросите у датчика конвертацию.
Работает протокол достаточно просто, в техническом описании DS18B20 не рекомендуют измерять температуру чаще, чем 1 раз в секунду, потому что датчик сам себя разогревает. Если нужно I2C то можно, например, применить LM75A, но точность +/- 2 градуса. Конечно, ограничение по длине линии I2C - платный протокол.
Были бы у меня эти датчики на руках, я бы так и сделал. Но они только через 3 дня приедут. А в сумме? мне не надо прям совсем-совсем точно. с точностью до +/- 50мс устроит.
Ну давайте прикинем: скорость примем в 15000 бит/с, т.е. 1875 байт/с. Нам надо отправить около пяти байт, и принять - около 10, т.е. 15 байт прогнать по шине. Для простоты увеличим это число до 30, чтоб уж точно, чтоб уж наверняка. Делим: 30/1875 = получаем 16 миллисекунд, это МАКСИМУМ, на практике будет в пару-тройку раз меньше: скажем, у меня пакет по 1-Wire - как раз 30 байт гоняется, после нажатия кнопочки в конфигураторе визуально отклик с данными мгновенный, никакой задержки нет, т.е. время заведомо меньше ста миллисекунд.
Здравствуйте! Подскажите, в чем может быть проблема. Подключаю DS18B20 по 1-Wire. Библиотекой Даллас не пользуюсь. Проблема в следующем: если отсылаю команду 0x44 по конкретному адресу датчика ( addrThermo5 ) - всё работает. oneWire.reset(); //сбрасываем шину 1-Wire oneWire.select (addrThermo5); //выбираем нужный термодатчик по его адресу oneWire.write (0x44); //пишем температуру в датчик А если пропускаю адрес (0xCC), то температура в датчик не пишется и не обновляется: oneWire.reset(); //сбрасываем шину 1-Wire oneWire.select (0xCC); //выбираем все термодатчики (Skip ROM) oneWire.write (0x44); //пишем температуру в датчик
Да непонятно. Вот даже тестовый скетч набросал: https://pastebin.com/uQNdQYZf Со строкой 16 работает, а с 17 не работает. Может, с датчиком чего? )
Попробуйте сделать по инструкции с Библиотекой Даллас. Если не заработает то может датчик вышел из строя. Зима-холода-статика. Очень чувствительны они к статике. http://wiki.amperka.ru/продукты:ds18b20
Смотрите, какая шляпа: 0xCC - это не адрес, это команда на пропуск адреса. Т.е. надо не select, а просто write: Код (Text): // запускаем конвертацию у всех датчиков на шине oneWire.reset(); oneWire.write(0xCC); oneWire.write(0x44);