Подредактировать скетч
- Войдите на сайт для отправки комментариев
Чт, 19/04/2012 - 12:28
Дорый всем день!
Имеется скетч
// подключаем библиотеки // ... они должны лежать в папке libraries с установленной ардионо-иде #include <LiquidCrystalRus.h> // для общения с LCD по русски #include <OneWire.h> // для обмена по 1-wire #include <EEPROM.h> // для работы с EEPROM byte butPin = 0; // пин входа кнопок int val; // знач. АЦП при нажатой кнопке byte butPush = 0; // код нажатой кнопки boolean butRel=1; // отпущена ли сейчас кнопка int butval[8]={0,1023,817,602,407,203,0,0}; // АЦП кнопок // ... просьба не обращать внимание на то, что массив объявлен на // ... восемь переменных, это просто пережиток прошлого // ... также значения не обязательны такие, можно просто вбить нули // ... впоследствии в этот массив мы считаем данные из памяти byte butsens=20; // чувствительность кнопок byte buzzer = 5; // выход динамика byte menu=0; // переменная хранящая номер текущего экрана byte i; // просто счетчик byte n; // просто счетчик byte m=0; // просто счетчик byte t=0; // просто счетчик float T[]={0,0,0,0}; // переменная для хранения температуры float Tp[]={0,0,0,0}; // переменная для хранения температуры с прошлого замера // ... нужно для устранения некоторых ошибок byte data[9]; // массив для хранения данных принятых от датчика byte TotalDS=0; // число найденых датчиков на линии byte addr[4][8] = { // двумерный массив адресов датчиков {0,0,0,0,0,0,0,0}, // 4 адреса по 8 байт {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, }; OneWire ds(31); // на этот пин подключена линия DQ 1-wire LiquidCrystalRus lcd(8,9,4,5,6,7); //инициализация LCD // ... соответственно на эти пины ардуины он и подключен void setup() { lcd.begin(2, 16); // включаем дисплей Serial.begin(9600); // последовательный порт для отладки if (analogRead(butPin) > 100) { // если в момент загрузки значение АЦП // ... клавиатуры больше 100 (нажата какая-то кнопка) то запускаем процедуру калибровки lcd.print("Kaлибpoвкa"); // На дисплей выводим слово "Калибровка" lcd.setCursor(0,1); // устанавливаем курсор во вторую строку delay(3000); // пауза 3 сек, за это время надо отпустить кнопку for ( i = 1; i < 6; i++) { // цикл от 1 до 5 lcd.clear(); // очищаем дисплей lcd.print("Haжмитe "); // выводим слово "Нажмите" с пробелом в конце в первую строку lcd.print(i, DEC); // выводим номер кнопки, теперь на экране написано "Нажмите 1" while (analogRead(butPin) < 100) {}; //ничего не делаем (пустой цикл) пока не нажата кнопка button (); // процедура опроса кнопки, по окончанию в val будет значение АЦП butval[i]=val; // записываем это значение в массив lcd.clear(); // очищаем дисплей lcd.setCursor(0,1); // и во вторую строку ... lcd.print(i, DEC); // ... выводим номер кнопки ... lcd.print(" "); // ... и через пробел... lcd.print(butval[i], DEC); // значение АЦРП ей соответствующее EEPROM.write(224+i*2,butval[i]/4); // записиваем в EEPROM по 2 байта на значение начиная с адреса 224 // в первый адрес старшие 8 бит EEPROM.write(225+i*2,butval[i]%4); // во второй - остаток. (всего у нас было 10 бит) delay(1000); // пауза 1 сек (просто так... чтоб сильно не шокировать) } } // конец калибровки else { // читаем АЦП кнопок // если условие запуска калибровки не выполнилось читаем то, что было записано ранее for ( i = 0; i < 8; i++) { // цикл на 8 байт. опять же пережиток butval[i] = EEPROM.read(224+i*2)*4+EEPROM.read(225+i*2); //процедура обратная записию берем старшие 8 бит, // ... сдвигаем на 2 разряда (умножаем на 4) и прибавляем младшие биты. } // конец цикла } // конец if read_DS(); //считываем адреса датчиков из памяти, подпрограмма ниже } // конец setup void loop() // главный цикл. Когда программа доходит до конца, выполнение переходит к этой строке { ds.reset(); // самое интересное - опрос датчиков. Начинается со сброса линии ds.write(0xCC,1); // пропуск ROM - этим мы говорим "Внимание всем!" Следующую команду // ... выполняют все устройства (если конечно их тип это позволяет) ds.write(0x44,1); // запускаем конвертацию температуры for( n = 1; n < 90; n++) { //ждем 900 мс... (время необходимое датчикам чтобы преобразовать температуру) delay(10); if (analogRead(butPin) > 100 && butRel) { Menu(button ()); } // ... периодически проверяя не нажата ли кнопка // и если нажата - выполнить подпрограмму "Menu" (показываем меню) if (analogRead(butPin) < 100) {butRel=1;} } for( n = 0; n < 4; n++) { // Цикл от 0 до 3 - по числу датчиков (4 шт) ds.reset(); // начинаем считывать температуры, обмен начинается со сброса ds.select(addr[n]); // выбираем нужный (по порядку) адрес датчика, после этой команды до след. сброса // ... отвечать нам будет только выбранный датчик ds.write(0xBE); // команда на считывание ОЗУ датчика for ( i = 0; i < 9; i++) {data[i] = ds.read();} // читаем с линии 9 байт Tp[n] = float((data[1] << 8) + data[0])/16; // значение температуры в первых 2-х байтах. Высчитываем температуру // ... команда float приводит тип byte (полученный от датчика) к типу с плавающей точкой if (Tp[n] == 85) {} else {T[n]=Tp[n];} // это для того, чтобы при глюке датчика (обычно при переключениях // ... выдача температуры 85 град не приводила к переходу на другой шаг программы. Мы просто возьмем предыдущее значение // ... (вот для чего мы его и хранили, ну впрочем можно еще дельту посчитать, вполне можно найти применение) } // Ну вот, температуру прочитали // Тут может быть Ваша рекл... тьфу, Ваш код. Например сравнение температур с уставками и реализация каких-то действий Menu(0); // собственно больше делать нечего. показываем юзеру картинку (меню) (ниже) } int button () { // подпрограмма считывания кнопок int exitMenu = 1; // если exitMenu истина то выходим из меню butPush = 0; // код нажатой кнопки delay(15); // задержка для устранения дребезга контактов val = analogRead(butPin); // читаем АЦП порта кнопок (значение от 0 до 1023) if (val > (butval[5]-butsens) && val < (butval[5]+butsens)) {butPush = 5;} // если считанное значение около (на величину butsens) // значения соответствующего кнопке 5 то считаем что она и нажата if (val > (butval[4]-butsens) && val < (butval[4]+butsens)) {butPush = 4;} // аналогично для остальных if (val > (butval[3]-butsens) && val < (butval[3]+butsens)) {butPush = 3;} if (val > (butval[2]-butsens) && val < (butval[2]+butsens)) {butPush = 2;} if (val > (butval[1]-butsens)) {butPush = 1;} // коды кнопок: 1 - вверх, 2 - влево, 3 - ок, 4 - вправо, 5 вниз butRel=0; // эта переменная нужна для проверки в главной программе return butPush; // возвращаем значение нажатой кнопки } byte write_DS() { // программа записывает адреса датчиков в память for (i=0; i<8; i++) { // всего 8 байт. В переменной m - номер датчика который надо записать if (m==0) {EEPROM.write(128+t*8+i,0);} // записывать будем начиная с адреса 128. Если номер датчика равен нулю - то значит он отсутствует. else {EEPROM.write(128+t*8+i,addr[m-1][i]);} } return 0; } byte read_DS() { // программа считывает адреса датчиков из памяти for (n=0; n<4; n++) { // у нас она "заточена" на 4 адреса, потому и цикл до 4 for (i=0; i<8; i++) { // в адресе 8 байт addr[n][i] = EEPROM.read(128+n*8+i); // читаем байт со смещения 128 + 8 * номер датчика + номер байта } } return 0; } void Menu(int butPush) { // самая мутная но и самая интересная часть. Фунцция показа меню lcd.clear(); // очищаем дисплей switch (menu) { // оператор switch переключает на нужную секцию в зависимости от значения menu case 0: // показываем все температуры lcd.print("1:"); // Печатаем "1:" lcd.print(T[0]); // выводим температуру первого датчика lcd.setCursor(8,0); // ставим курсор посередине первой строки lcd.print("2:"); // Печатаем "2:" lcd.print(T[1]); // выводим температуру второго датчика lcd.setCursor(0,1); // далее аналогично lcd.print("3:"); lcd.print(T[2]); lcd.setCursor(8,1); lcd.print("4:"); lcd.print(T[3]); if (butPush == 1) {menu=1; Menu(0);} // обработка кнопок. Если нажата кнопка "вверх" то возвращаемся в конец подменю if (butPush == 5) {menu++; Menu(0);} // если нажата кнопка вниз - идем к следующему экрану. Далее эти кнопки не комментирую break; case 1: // меню настроек lcd.print("Настройки"); lcd.setCursor(0,1); lcd.print("Haжмитe OK"); if (butPush == 1) {menu--; Menu(0);} if (butPush == 3) {menu=40; Menu(0);} // если нажать "ОК" в этом экране то пойдем к меню номер 40 if (butPush == 5) {menu=0; Menu(0);} break; ////////////////////////////////////////////////////////////////////////////////////// case 40: // поиск датчиков i = 0; n=0; while (i != 1 ) // ищем датчики { if ( ds.search(addr[n]) != 1) { // функция поиска специальным образом выискивает первый датчик и записывает его адрес // возвращет 1 если он найден. в случае, если вернет что-то не равное 1 (см. пред. строку) то поиск останавливается ds.reset_search(); i = 1; } else { // если что-то найдено то... n++; // увеличиваем счетчик и ... TotalDS = n; // говорим, что всего у нас теперь n датчиков } } lcd.print("Поиск датчиков"); // Заголовок в первой ... lcd.setCursor(0,1); // а результат будем печатать во второй строке lcd.print(n, DEC); lcd.print(" найдено"); if (butPush == 1) {menu=0; Menu(0);} // нажатие "вверх", ... if (butPush == 2) {menu=0; Menu(0);} // ... "влево" ... if (butPush == 5) {menu=0; Menu(0);} // ... и "вниз" возвращает нас в главное меню if (butPush == 3) {menu=100; Menu(0);} // нажатие " ОК" ... if (butPush == 4) {menu=100; Menu(0);} // ... или "вправо" переносит в меню детальной настройки датчиков break; ////////////////////////////////////////////////////////////////////////////////////// case 100: // меню настроек датчиков DS1820 lcd.print("T"); // выводим "Т" и lcd.print(t+1,DEC); // ... номер датчика lcd.setCursor(0,1); if (m==0) {lcd.print("Отсутствует");} // если номер равен 0 то считаем что датчик отсутствует else {lcd.print(T[m-1],DEC);} // иначе показываем текущую температуру if (butPush == 1) {if (t==0) {menu=101;} else {t--;} Menu(0);} // кнопки "вверх" и "вниз" меняют номер датчика. если дошли до конца, то переходим к меню 101 if (butPush == 2) {if (m==0) {} else {m--;} Menu(0);} // кнопки "вправо" и "влево" изменяют физический датчик сопоставленный данному номеру. if (butPush == 3) {write_DS(); lcd.setCursor(0,1); lcd.print("Записано в EEPROM"); tone(buzzer, 1000); delay(1000); noTone(buzzer); menu=100; Menu(0);} // нажатие "ОК" вызывает запись текущего датчика в память. Записать необходимо все датчики поочередно // ПОСЛЕ ЭТОЙ ПРОЦЕДУРЫ НЕОБХОДИМО ПЕРЕЗАГРУЗИТЬ УСТРОЙСТВО if (butPush == 4) {m++; if (m > TotalDS) { m = TotalDS;} Menu(0);} if (butPush == 5) {if (t==3) {menu=101;} else {t++;} Menu(0);} break; case 101: // Выход из меню. Комментировать не буду - надоело. lcd.print("Выйти из меню"); lcd.setCursor(0,1); lcd.print("OK для выхода"); if (butPush == 1) {t=3; menu=100; Menu(0);} if (butPush == 3) {menu=0; Menu(0);} if (butPush == 5) {t=0; menu=100; Menu(0);} break; } // end switch }
Скеч не мой. Я только учюсь.
Прога сама ищет температурные датчики и выводит на дисплей показания.
Имеется ЛЦД шильд 16х2 и мега2560 с 4мя датчиками.
Датчики не находит. Что и где править?
Вот схемка включения кнопок
А что за шилд? датчики куда подключаются? В вашем коде датчики должны быть подключены к 31 выводу, у вас на шилде также?
Датчики подключены(средние ноги) на вывод31 самой меги
А какой способ питания датчиков используете паразитный(2 провода) или обычный(3 провода)?
Попробуйте упростить схему. Отключите все кнопки, LCD.
Подключите только датчики. Возмите библиотеку dallastemperaturecontrol, отложите ваш скетч в сторону, возмите примеры идущие с библиотекой. Укажите адреса датчиков в явном виде. Убедитесь что они у вас вообще работают и подключены правильно.
Потом, раз есть желание детектить адреса автоматом, возмите пример из библиотеки OneWire, убедитесь что "поиск" тоже работает нормально.
И только после этого, когда будете уверены что с датчиками "все в порядке" - начинайте разбиратся с собственным комплексным примером. Имея уверенность что "с датчиками все хорошо".
P.S. Надеюсь вы обратили внимание, что ваш скетч при "просто включении" - датчики не обнаружит. Он попробует прочитать их адреса из EEROM, а там будут "нули или мусор". Нужно, через меню, запустить их "обнаружение", записать найденные адреса, через меню, в EEROM, и перегрузить контроллер.
Датчики по трём проводам.
leshak прав. Так и делал.
После долгих мучений(предварительно изменив скетч в нескольких местах) зашёл в меню, нашёл датчики и прописал в еепром.
Теперь хотелось бы управлять пару релюшками.
Поможите?
Алгоритм выложу на днях.
Не ну делать ваш проект за вас - никто не будет. Попробуйте, вначале, тут поискать как народ релюхами, моторами, насосами управляет (вверху есть поиск).
Да и гугл на вопрос "арудино управление нагрузкой" думаю не оставит вас в неведениии.
Все-таки задача совершенно не экзотика. Нужно просто потратить время и разобратся, почитать, посмотреть.
Ну хотя-бы вот тут
http://easyelectronics.ru/upravlenie-moshhnoj-nagruzkoj-postoyannogo-tok...
http://easyelectronics.ru/upravlenie-moshhnoj-nagruzkoj-postoyannogo-tok...
Там вообще куча "нубских вопросов" освещена. Советую потратить время и основательно изучить этот сайт.
Не ну делать свой проэкт буду сам.Спасибо.