temp1 = DS18B20(addr1); - то есть эта строка это "чтение" функции которая называется DS18B20? float DS18B20(byte *adres) - а здесь указатель byte что бы контроллер преобразовал адрес из массива в байты и записал их в adres? оператор * - как я понял это "косвенное обращение"?
Только не чтение, а вызов. Функция - это подпрограмма. Да, функция принимает адрес первого элемента массива с адресом датчика и считывает из массива нужное количество байт.
Всем привет, гуру подскажите что я делаю не так? Суть - необходимо отслеживать неполадки с DS18B20 (обрыв питания или обрыв шины данных) Вот что написал: Код (PHP): byte error85[9] = {0x50, 0x05, 0x4B, 0x46, 0x7F, 0xFF, 0x0C, 0x10, 0x1C}; // эти данные в массиве data при обрыве положительного питания (при этом значении T=85) //================================================================================== // Считывание температуры //================================================================================== float DS18B20(byte *adres){ ds.reset(); ds.select(adres); ds.write(0x44,0); // start conversion, with parasite power on at the end ds.reset(); ds.select(adres); ds.write(0xBE); // Read Scratchpad for (byte i = 0; i < 9; i++) { // we need 9 bytes data[i] = ds.read (); // ***********ОШИБКИ с датчиков DS18b20******************* если обрыв линии или питания if (data[i]==error85[i] || data[i]==0xFF) {e++;} //сравниваем одинаковые байты else {e=0; } } if (e>8) {podtv++; e=0;} // если все байты в массиве совпали, увеличиваем счетчик ошибок if (podtv>5) error=1; //если счетчик ошибое перевалил за 5 - выводим ошибку //************ПРОДОЛЖИМ вычисление температуры************ raw = (data[1] << 8) | data[0];//=======Пересчитываем в температуру float celsius = (float)raw / 16.0; return celsius; } переменная error как была 0 так и остается(
сам спросил - сам ответил) в общем запись, где байт записан в HEX: data==0xFF - не работает. Хотя когда сравниваю массив data с массивом error85 (где, кстати, байты записаны в HEX формате) - все работает. Исправил на data==0 - все заработало
Здравствуйте. Спасибо за скетч - повторил, все устраивает по быстрдействию (и клавиатура опрашивается и реле щелкают и еще много чего параллельно считает). Но есть одно неудобство - температура отображается с шагом 0.5 градуса. Да, япомню про точность18В20 как раз в 0.5 градуса, однако подскажите, как сменить отображение на 0.1 градуса?
Думаю, зависит от настройки разрешения, в библиотеке даллас есть пример. У меня сейчас показывают 3 датчика с сотыми градуса
Да, верно, в библиотеке Dallas это сделать довольно очевидно Код (C++): //Инициализируем термодатчик и установим разрешающую способность 12 бит (обычно она установлена по умолчанию, так что последнюю строчку можно опустить) void setup() { sensors.begin(); sensors.getAddress(tempDeviceAddress, 0); sensors.setResolution(12); // 12 бит } Только ради этого снова переходить на "тормознутую" библиотеку, решать каждому Сам не игрался с этим, точность меня вполне устраивала 0.5*С, но полагаю, что в функции Код (C++): float DS18B20(byte *adres){ ds.reset(); ds.select(adres); ds.write(0x44,0); // start conversion, with parasite power on at the end ds.reset(); ds.select(adres); ds.write(0xBE); // Read Scratchpad for (byte i = 0; i < 9; i++) { // we need 9 bytes - разрешение датчика data[i] = ds.read (); можно изменить строчку Код (C++): for (byte i = 0; i < 9; i++) // разрешение датчика на Код (C++): for (byte i = 0; i < 12; i++) // т.е. повысить разрешение с 9 до 12 бит Будет здорово, если проверите и отпишитесь о результате
Попробую, но по ощущениям точность можно задать в даллосовской библиотеке, затем уже пользоваться этим разрешением в варе...но проверю и отпишусь...
Подскажите как узнать адрес датчика? в проекте важно чтобы ардуина не переставила датчики местами после отключения питания.
Добрый день! Сделал свой вариант Спойлер: на базе этого кода. Но использую 8-ми разрядный ЛЕД на MAX7219, поэтому немного переделал код под себя: Код (C++): #include <OneWire.h> #include <LedControl.h> LedControl lc=LedControl(11,10,9,2); OneWire ds (8); byte data[12]; byte addr1[8] = {0x28, 0xFF, 0x8A, 0xF8, 0xA3, 0x15, 0x03, 0xB0}; unsigned int raw; float temp1; int T1; // переменная текущей температуры int ones, tens, hundreds, thousand; void setup() { Serial.begin(9600); lc.clearDisplay(0);// clear screen lc.shutdown(0,false);// turn off power saving, enables display lc.setIntensity(0,5);// sets brightness (0~15 possible values) lc.setScanLimit(0, 4); } void loop() { temp1 = DS18B20(addr1); Serial.println(temp1); T1 = temp1*100; thousand = T1/1000; hundreds = (T1-thousand*1000)/100; tens = (T1-(thousand*1000+hundreds*100))/10; ones = T1-(thousand*1000+hundreds*100+tens*10); lc.setDigit(0,0,ones,false); lc.setDigit(0,1,tens,false); lc.setDigit(0,2,hundreds,true); lc.setDigit(0,3,thousand,false); delay(5000); } //================================================================================== // Считывание температуры //================================================================================== float DS18B20(byte *adres) { ds.reset(); ds.select(adres); ds.write(0x44, 1); // start conversion, with parasite power on at the end ds.reset(); ds.select(adres); ds.write(0xBE); // Read Scratchpad for (byte i = 0; i < 9; i++) // можно увеличить точность измерения до 0.0625 *С (от 9 до 12 бит) { // we need 9 bytes data[i] = ds.read (); } raw = (data[1] << 8) | data[0];//=======Пересчитываем в температуру float celsius = (float)raw / 16.0; return celsius; } При этом ЛЕД ведёт себя поразному: может несколько циклов показывать правильную температуру, потом срывается и разные разряды показывают всякую хрень, точки могут сами включаться/выключаться, потом загораются все сегменты и до перезагрузки ничего не меняется. А могут все сегменты погаснуть но через несколько циклов опять работают кое-как. При этом вывод температуры в сериал идёт нормально. По отдельности DS18B20 и ЛЕД работают нормально: датчик работает и по 1варе и по далассу, ЛЕД нормально отображает тестовые скетчи. Что тут можно ещё поправить? Короче говоря, решил отвлечься и запихнуть Уно в стандартный прозрачный корпус. Собрал, запустил и о чудо! Работает. Толи наводки какие были, толи неправильно собирал до этого (хотя сто раз всё проверял), толи просто ей хотелось жить в своём собственном доме. Спасибо за рабочий пример.
Добрый день, я тут новичок, да и вообще только начал изучение ардуино. Пытаюсь вытянуть температуру с двух датчиков DS1820, по некоторым библиотекам определяется как DS18S20, что в общем то одно и тоже. Суть проблеммы, подключил датчики к Нано, тремя проводами, с сопративлением, скетчем из Даллосовской библиотеки(мультипл) проверяю адреса датчиков, всё показывает, и адреса и корректную температуру, затем делаю другой скетч, по примерам из темы, показания отправляю на LCD и в сериалпорт. Показания идут с обоих датчиков, но не корректные, занижены в десятки раз, и даже не понятно на сколько именно. Пробылвал смотреть показания с отключенным датчиком, на даллосовской библиотеке начинает показывать -127 градусов, это я так понимаю всё правильно. А на моём скетче показывает 4095,94 при отключенном датчике. Прошу помощи рабобраться что не так, два вечера уже убил на поиск температуры, освоение прерываний както проще далось. Скет прилагаю. Код (C++): #include <OneWire.h> #include <Wire.h> // I2C #include <LiquidCrystal_I2C.h> // LCD OneWire ds (10); byte data[12]; byte addr1[8] = {0x10, 0x40, 0xDF, 0xD7, 0x01, 0x08, 0x00, 0xE5}; // ID индивидуально для каждого датчика byte addr2[8] = {0x10, 0x3F, 0xD3, 0xD7, 0x01, 0x08, 0x00, 0x78}; unsigned int raw; float temp1, temp2; LiquidCrystal_I2C lcd(0x27, 16, 2); void setup() { Wire.begin(); lcd.init(); lcd.backlight(); // вкл. подсветку LCD (noBack-выкл) lcd.clear(); Serial.begin(9600); } void loop() { temp1 = DS18B20(addr1); temp2 = DS18B20(addr2); Serial.println(temp1); Serial.println(temp2); lcd.setCursor(6, 0); lcd.print(temp1); // отображение температуры lcd.setCursor(6, 1); lcd.print(temp2); // отображение температуры } //================================================================================== // Считывание температуры //================================================================================== float DS18B20(byte *adres){ { ds.reset(); ds.select(adres); ds.write(0x44); // start conversion, with parasite power on at the end ds.reset(); ds.select(adres); ds.write(0xBE); // Read Scratchpad for (byte s = 0; s < 9; s++) // можно увеличить точность измерения до 0.0625 *С (от 9 до 12 бит) data[s] = ds.read (); raw = (data[1] << 8) | data[0];//=======Пересчитываем в температуру float celsius = (float)raw / 16.0; return celsius; }}
Отказался от Даллас, как у ТС, температура реле стало щелкать без задержек, но жутко тормозит считывание с IR. Надо долго тиснуть пока сработает, что не так??? Плиз. Код (C++): #include <LiquidCrystal.h> //подключаем библиотеку работы с ЖКИ #include <OneWire.h> //подключаем библиотеку работы с 1-wire #include <IRremote.h> #include <Wire.h> OneWire ds(8); LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2); int buz=6; int RECEIVE_PIN = 7; int VALVE_PIN=9; int y; float x; float Temp1; byte addr1[8] = { 0x28, 0xFF, 0x34, 0x61, 0x61, 0x15, 0x01, 0x8F }; byte data[12]; unsigned int raw; IRrecv irrecv(RECEIVE_PIN); decode_results results; //================================================================================== // Считывание температуры //================================================================================== float DS18B20(byte *adres) { ds.reset(); ds.select(adres); ds.write(0x44, 1); // start conversion, with parasite power on at the end ds.reset(); ds.select(adres); ds.write(0xBE); // Read Scratchpad for (byte i = 0; i < 9; i++) // можно увеличить точность измерения до 0.0625 *С (от 9 до 12 бит) { // we need 9 bytes data[i] = ds.read (); } raw = (data[1] << 8) | data[0];//=======Пересчитываем в температуру float celsius = (float)raw / 16.0; return celsius; } void setup() { y=0; x=40; pinMode(buz, OUTPUT); pinMode(VALVE_PIN, OUTPUT); pinMode(A0, INPUT); irrecv.enableIRIn(); lcd.begin(16, 2); lcd.clear(); Wire.begin(); } void loop() { Temp1 = DS18B20(addr1); if (irrecv.decode(&results)) { switch (results.value) { case 0xFF9867: x+=10; break; case 0xFF6897: x-=10; break; case 0xFF18E7: x+=1; break; case 0xFF30CF: x-=1; break; case 0xFF38C7: x+=0.1;break; case 0xFF10EF: x-=0.1;break; case 0xFF4AB5: x+=0.01;break; case 0xFF42BD: x-=0.01;break; case 0xFF629D: y+=1; break; case 0xFFA857: y-=1; break; } irrecv.resume(); } lcd.setCursor(0, 0); // устанавливаем курсор во вторую строку (нумерация с 0) в 0 столбец lcd.print("T1="); // выводим "Т=" на экран lcd.print(Temp1); // в следующей позиции будет печататься температура lcd.setCursor(10, 0); lcd.print("*"); lcd.print(x); lcd.setCursor(10, 1); lcd.print("y"); lcd.print(y); if (Temp1>x){ digitalWrite(buz, HIGH);} else digitalWrite(buz, LOW); /* switch (y) { case 0: digitalWrite(VALVE_PIN, LOW); break; case 1: {digitalWrite(VALVE_PIN, HIGH); delay(10); digitalWrite(VALVE_PIN, LOW); delay(50);} break; case 2: {digitalWrite(VALVE_PIN, HIGH); delay(20); digitalWrite(VALVE_PIN, LOW); delay(50);} break; case 3: {digitalWrite(VALVE_PIN, HIGH); delay(30); digitalWrite(VALVE_PIN, LOW); delay(50);} break; case 4: {digitalWrite(VALVE_PIN, HIGH); delay(35); digitalWrite(VALVE_PIN, LOW); delay(50);} break; case 5: {digitalWrite(VALVE_PIN, HIGH); delay(50); digitalWrite(VALVE_PIN, LOW); delay(50);} break; case 6: {digitalWrite(VALVE_PIN, HIGH);} break; }*/ }
Я просто балдею от этого кусочка кода. Он бродит от одного ардуинщика к другому уже лет сто и никто не задаётся вопросом зачем он нужен и для чего жрёт память массив, куда читаются данные.
1. Замените Код (C++): for (byte i = 0; i < 9; i++) // можно увеличить точность измерения до 0.0625 *С (от 9 до 12 бит) { // we need 9 bytes data[i] = ds.read (); } На Код (C++): data[0] = ds.read (); data[1] = ds.read (); Так будет быстрее. 2. Надо понимать, что DS18b20 на вычисление температуры требуется некоторое время. При паразитном питании ок 700 мс., при обычном - тоже сколько-то надо. Дергать его чаще чем раз в секунду не стоит, хотя и не запрещено. В любом случае, если датчик не осуществил вычисление температуры и занесение результатов в регистры - шина 1wire останавливает выполнение кода для ожидания.
Игорь, спасибо. И вместе с тем почему перестает воспринимать Ir?. Если закрментировать // Temp1 = DS18B20(addr1); то все становится нормально. Тормозит в функции. Спасибо