Нужна помощь добрых людей-программистов
- Войдите на сайт для отправки комментариев
Сб, 22/10/2016 - 18:00
Доброго времени суток, уважаемые программисты.
Решил я вначале создать элементарный I2C термометр, который при достижении опеределлной температуры включает вентилятор, потом захотелось усложнить проект и поставить на это всё еще и сигнализацию. Подключил к arduino обычный геркон и звуковой динамик и при открытии двери должен был идти звук и надпись на дисплее менялась на Alert, а при закрытии двери, опять бы показывалась температура. Но, к сожалению всё выглядит немного не так и чуточку обидненько.
А вот собственно и сам код
#include <LiquidCrystal.h> //библиотека работы с экраном #include <OneWire.h> //библиотека работы с устройством 1-wire #include <Wire.h> //библиотека работы с устройством I2C #include <DallasTemperature.h> //библиотека работы с датчиком температуры dallas DS18b20 LiquidCrystal lcd (2,3,4,5,6,7); //задаем имя и входы/выходы для управления LCD-экраном #define ONE_WIRE_BUS 13 // датчику температуры задаем пин на плате arduino OneWire oneWire(ONE_WIRE_BUS); //даем имя устройству 1-WIRE DallasTemperature sensors(&oneWire);// задаем переменную, которая будет понимать программа, что оно является устройством oneWire DeviceAddress sensor1 = {0x28, 0xFF, 0xBF, 0xE8, 0x62, 0x16, 0x04, 0xF0}; //адрес датчика температуры Dallas DS18B20 float temp1; //переменная для хранения значения температуры с плавающей точкой //задаем значок для температуры byte degree [8]={ B00110, B01001, B01001, B00110, B00000, B00000, B00000, B00000, }; //задаем значок для режима "вентилятор включен" byte fan_on [8] = { B00100, B10101, B01110, B11111, B01110, B10101, B00100, B00000, }; //задаем значок для режима "вентилятор выключен" byte fan_off [8]={ B00100, B00100, B00100, B11111, B00100, B00100, B00100, B00000, }; int FAN=11; //вентилятор на 11 пин float set_temp=27; //устанавливаем значение температуры, равной 27 градусам int SPEAKER = 8; int SENSOR_DOOR = 9; void setup() { pinMode (SENSOR_DOOR,INPUT);//задаем датчик открытия двери ка вход pinMode (SPEAKER, OUTPUT);// задаем значени я динамика как выход pinMode (FAN, OUTPUT); //задаем пин FAN как выход Wire.begin(); //запускаем шину 1-WIRE sensors.begin(); //активируем датчик температуры sensors.setResolution(sensor1, 12); //задаем разрядность для датчика температуры lcd.begin (16,2); //активируем lcd экран //задаем режимы отображения символом на экране lcd.createChar (0, degree); // значок температуры lcd.createChar (1, fan_off); //значок "вентилятор отключен" lcd.createChar (2, fan_on); // значок "вентилятор включен" lcd.setCursor(0, 0); //задаем начальное значение отображения надписей (первая строка, первый столбец) lcd.print("KAZBEK INC'"); // сама надпись приветствия delay (2000);//Задержка приветствия lcd.clear(); // очищаем экран lcd.setCursor (0,0); //задаем начальное значение отображения надписей (первая строка, первый столбец) lcd.print ("Current:"); //отображаем надпись "температура" lcd.setCursor (13,0); // задаем место отображения значка температуры lcd.write ((byte)0); // отображаем его lcd.setCursor (14,0);// задаем место отображения значка температуры буквы С lcd.print ("C"); // отображаем его lcd.setCursor (0,1); //отображаем надпись "установлено" lcd.print ("Set:"); // отображаем его lcd.setCursor (8,1);// задаем место отображения установленной температуры lcd.print (set_temp); // отображаем его lcd.setCursor (13,1);// задаем место отображения значка температуры lcd.write ((byte)0);// отображаем его lcd.setCursor (14,1);// задаем место отображения значка температуры буквы С lcd.print ("C");// отображаем его lcd.setCursor (5,1);// задаем место отображения значка "вентилятор отключен" lcd.write (1);// отображаем его } void printTemperature(DeviceAddress deviceAdress) //функция отображения температуры с датчика, адрес которого указан { temp1 = sensors.getTempC(deviceAdress); // получаем температуру lcd.setCursor(8, 0);// задаем место отображения значка температуры, считанной с датчика lcd.print(temp1); // отображение температуры } void loop() { if (temp1>set_temp) //если температуры в комнате превысила установленную { digitalWrite (FAN,LOW); //включиь вентилятор lcd.setCursor (5,1); //задаем место отображения значка "вентилятор включен" lcd.write (2); //записываем его } else //иначе, т.е. если в комнате нормальная тепература, не превышающая установленную температуру { digitalWrite (FAN, HIGH); //отключить вентилятор lcd.setCursor (5,1); //задаем место отображения значка "вентилятор отлючен" lcd.write (1); //записываем его } sensors.requestTemperatures();//Посылаем команду, чтобы получить температуру printTemperature(sensor1); //выводим температуру на экран { if (digitalRead (SENSOR_DOOR)==LOW) { lcd.clear(); lcd.setCursor (6,0); lcd.print ("ALERT!"); tone (SPEAKER, 100); delay (500); } else { noTone (SPEAKER); } } };Усложнили проект. Вот вам результат. Поймите чем сложнее код , тем сложнее вылавливать ошибки. То есть ваше умение программировать должно перейти от количественного в качественное, или ... погрязнуть под слоем кода и ошибок в нем.
Просто нужно в одном устройстве много всего))
Я всегда использую такую структуру, что в сложных, что в простых конструкциях. Простые почему-то усложняются.
/* #1 #2 #3 */ //#1 //#2 //#3 void setup() { //#1 //#2 //#3 } void loop() { static uint32_t MILLIS ; MILLIS = millis() ; //#1 1000 миллисекунд вычислит. поток 1 static uint32_t future1 = 0 ; if (MILLIS>=future1) { future1 = MILLIS + 1000 ; // сам код MILLIS = millis() ; } //#2 200 миллисекунд вычислит. поток 2 static uint32_t future2 = 0 ; if (MILLIS>=future2) { future2 = MILLIS + 200 ; // сам код MILLIS = millis() ; } //#3 100 миллисекунд вычислит. поток 3 static uint32_t future3 = 0 ; if (MILLIS>=future3) { future3 = MILLIS + 100 ; // сам код } }ПС: А там в конце как будут выглядить программы в этом стиле.http://arduino.ru/forum/programmirovanie/takhometr-na-arduino-pro-mini-ot-datchika-kholla-na-lcd1602i2c
qwone, в твоем коде в строках 21, 28, 35 заложены ошибки, и ты их с завидной регулярностью всем новичкам предлагаешь. Может тебе сначала подучить матчасть.....
И в чем ошибки?
Почитай про переполнение, много раз обсуждалось, вот например:
http://arduino.ru/forum/programmirovanie/arduino-perepolnenie-millis-i-m...
Это из бредовых фантазий "теоретиков программистов". Коллапс 2000 наблюдал? Переход в новое тысячелетие. Где крушение человечества, конец света и прочее. Много вони и все. Так вот у меня раз в 48дней длительностью в 1000(200,100) когда в future1,future2,future3 переполнится и станет почти нулем цикл loop() будет работать без сдержки , пока millis() не станет тоже 0. А дальше все нормализуется и ничего страшного не произойдет. Но это такая малость, если можно засунуть в ардуину кучу функций и подключить кучу устройств практически без конфликтно.
Ты к себе здесь на Вы обращаешься, да?
Коллапс 2000 наблюдал?
Не напоминай. Больше года работы отдела и все равно ряд клиентов огреб проблемы, хоть и по собственной невнимательности. Особый кайф был в новогоднюю ночь отвечать на звонки с Дальнего Востока.
Я с тех пор COBOL возненавидел и сейчас залажу в него только в обмен на отгулы.
Не напоминай.
А многие тогда столько бабла на лоховских страхах подняли.
Может к моему вопросу немного вернемся?))
Может к моему вопросу немного вернемся?))
А чего к нему возвращаться? Ответ не нужен даже Вам самому, а нам-то он зачем?
Если бы Вам нужен был ответ, то вместо "всё выглядит немного не так и чуточку обидненько" Вы бы написали толком в чём Ваша проблема. Смотреть кучу картинок и видео и догадываться по картинкам и видео о Вашей проблеме мне лень.
Вам нужна помощь - объясните в чём проблема. Не хотите объяснять - значит помощь не нужна.
Может к моему вопросу немного вернемся?))
Ну минимум я могу переписать ваш код под себя , а потом всовывать дополнительные устройства. Но вам же не это надо.
Когда открывается дверь необходимо снять сигнализацию и чтобы опять начала показываться температура.
Помогите с программным кодом уж...
Лови. Погоняй его.
/* #1 температура -> 12 (temperature_pin) вентилятор -> 11 (Fan_pin) #2 сенсор двери -> 9 (Sensor_door_pin) динамик -> 8 (Speaker_pin) #3 LCD дисплей -> 2,3,4,5,6,7 */ //#1 температура #include <OneWire.h> const int One_wire_bas_pin = 12 ; // пин на шину OneWire OneWire oneWire(One_wire_bas_pin); #include <DallasTemperature.h> DallasTemperature sensors(&oneWire); // подключаем датчик DS18B20 на шину OneWire float Get_Temperature() { //получить температуру float t = sensors.getTempCByIndex(0); // получить температуру с 1 датчика(0) sensors.requestTemperatures(); // послать команду измерить новую температуру return t; } float Temperature_value;//обьявляем переменную текущей температуры //вентилятор const int Fan_pin = 11; // пин ветилятора uint8_t Fan; // состояние вентилятора 1 работает/ 0 нет float switching_temperature = 27; //устанавливаем значение температуры, равной 27 градусам //#2 сенсор двери и динамик const int Sensor_door_pin = 9; // пин сенсор двери uint8_t Sensor_door; // состояние сенсора двери 0 открыта/ 1 нет const int Speaker_pin = 8; // пин динамика const int frequency = 1000; // частота звука сигнализации Гц const int duration = 500; // длительность посылок миллисекундах //#3 дисплей #include <LiquidCrystal.h> //библиотека работы с экраном LiquidCrystal lcd (2, 3, 4, 5, 6, 7); //задаем имя и входы/выходы для управления LCD-экраном byte Sign_degree [8] = { //задаем значок для температуры B00110, B01001, B01001, B00110, B00000, B00000, B00000, B00000, }; byte Sign_fan_on [8] = { //задаем значок для режима "вентилятор включен" B00100, B10101, B01110, B11111, B01110, B10101, B00100, B00000, }; byte Sign_fan_off [8] = { //задаем значок для режима "вентилятор выключен" B00100, B00100, B00100, B11111, B00100, B00100, B00100, B00000, }; void setup() { //#1 температура sensors.begin(); Temperature_value = Get_Temperature(); // измерить температуру pinMode (Fan_pin, OUTPUT); //задаем пин ветилятора как выход digitalWrite(Fan_pin, Fan = 0); // выключить ветилятор //#2 сенсор двери и динамик pinMode (Sensor_door_pin, INPUT); //задаем датчик открытия двери ка вход pinMode (Speaker_pin, OUTPUT);// задаем значени я динамика как выход //#5 дисплей lcd.begin (16, 2); //активируем lcd экран lcd.createChar (0, Sign_degree); // значок температуры lcd.createChar (1, Sign_fan_off); //значок "вентилятор отключен" lcd.createChar (2, Sign_fan_on); // значок "вентилятор включен" } void loop() { static uint32_t MILLIS ; MILLIS = millis() ; //#1 1.000 сек измерение температуры и вкл вентилятора если надо static uint32_t future1 = 0 ; if (MILLIS >= future1) { future1 = MILLIS + 1000 ; Temperature_value = Get_Temperature(); // измерить температуру digitalWrite(Fan_pin, Fan = (Temperature_value > switching_temperature)); // если больше нужного включить вентилятор } //#2 1.000 сек сенсор двери и динамик static uint32_t future2 = 0 ; if (MILLIS >= future2) { future2 = MILLIS + 1000 ; Sensor_door = digitalRead (Sensor_door_pin); if (! Sensor_door) tone(Speaker_pin, frequency, duration); } //#3 1.000 сек дисплей static uint32_t future3 = 0 ; if (MILLIS >= future3) { future3 = MILLIS + 1000 ; lcd.clear(); if (! Sensor_door) { lcd.setCursor (6, 0); lcd.print ("ALERT!"); } else { lcd.print ("Current: "); //отображаем надпись "температура" lcd.print (Temperature_value); lcd.write ((byte)0); lcd.print ("C"); lcd.setCursor (0, 1); //отображаем надпись "установлено" lcd.print ("Set: "); lcd.print (switching_temperature); // отображаем его lcd.write ((byte)0);// отображаем его lcd.print ("C");// отображаем его lcd.setCursor (5, 1); //задаем место отображения значка if (Fan) lcd.write (2); // "вентилятор включен" else lcd.write (1); // "вентилятор отлючен" } } }qwone, учи матчасть, прежде чем раздавать новичкам код с багами. Они же потом придут с вопросом "Почему работает х..во?"
qwone, учи матчасть, прежде чем раздавать новичкам код с багами. Они же потом придут с вопросом "Почему работает х..во?"
Что каждому Моцарту по Сольери. А вы не набивайтесь мне в Сольери. Я все же не Моцарт. А если вы считаете себя правым, то нарисуйте ТС свой код. А то получается , мертвые не потеют ... (простите) бездельники не ошибаются, потому что ничего не делают. Но советов от бездельников можно получить море.
Ошибка в 110 строке((
ПС: Вам нужна кнопка отключения сигнализации. Дверь открылась, включилась сигнализация, нажали на кнопку, сигнализация отключилась. А то в этом варианте дверь открылась - сигнализация дверь закрылась сигнализация отключилась.
Конечно не Моцарт, и даже не дилетант, дилетанты хотя бы прислушиваются к советам, ты лошара.
Тебе же русским языком сказали так нельзя:
Это ведет к неминуемой ошибке, пусть через 50 дней, но к ошибке.
Но ты ведь даже не способен этого понять.
А если так:
//библиотека работы с экраном. #include <LiquidCrystal.h> //библиотека работы с устройством 1-wire #include <OneWire.h> //библиотека работы с устройством I2C #include <Wire.h> //библиотека работы с датчиком температуры dallas DS18b20 #include <DallasTemperature.h> // датчику температуры задаем пин на плате arduino #define ONE_WIRE_BUS 13 //задаем имя и входы/выходы для управления LCD-экраном LiquidCrystal lcd ( 2, 3, 4, 5, 6, 7 ); //даем имя устройству 1-WIRE OneWire oneWire( ONE_WIRE_BUS ); // задаем переменную, которая будет понимать программа, что оно является устройством oneWire DallasTemperature sensors( & oneWire ); //адрес датчика температуры Dallas DS18B20 DeviceAddress sensor1 = { 0x28, 0xFF, 0xBF, 0xE8, 0x62, 0x16, 0x04, 0xF0 }; //переменная для хранения значения температуры с плавающей точкой float temp1; //вентилятор на 11 пин int FAN = 11; //устанавливаем значение температуры, равной 27 градусам float set_temp = 27; int SPEAKER = 8; int SENSOR_DOOR = 9; int sensorLastState = HIGH; int sensorState = HIGH; unsigned long time; //задаем значок для температуры byte degree [8]={ B00110, B01001, B01001, B00110, B00000, B00000, B00000, B00000, }; //задаем значок для режима "вентилятор включен" byte fan_on [8] = { B00100, B10101, B01110, B11111, B01110, B10101, B00100, B00000, }; //задаем значок для режима "вентилятор выключен" byte fan_off [8]={ B00100, B00100, B00100, B11111, B00100, B00100, B00100, B00000, }; void setup() { //задаем датчик открытия двери ка вход pinMode( SENSOR_DOOR, INPUT ); // задаем значени я динамика как выход pinMode( SPEAKER, OUTPUT ); //задаем пин FAN как выход pinMode( FAN, OUTPUT ); //запускаем шину 1-WIRE Wire.begin(); //активируем датчик температуры sensors.begin(); //задаем разрядность для датчика температуры sensors.setResolution( sensor1, 12 ); //активируем lcd экран lcd.begin( 16, 2 ); //задаем режимы отображения символом на экране lcd.createChar( 0, degree ); // значок температуры lcd.createChar( 1, fan_off ); //значок "вентилятор отключен" lcd.createChar( 2, fan_on ); // значок "вентилятор включен" //задаем начальное значение отображения надписей (первая строка, первый столбец) lcd.setCursor( 0, 0 ); // сама надпись приветствия lcd.print( F( "KAZBEK INC'" ) ); //Задержка приветствия delay( 2000 ); lcd.clear(); // очищаем экран lcd.setCursor( 0, 0 ); //задаем начальное значение отображения надписей (первая строка, первый столбец) lcd.print( F( "Current:" ) ); //отображаем надпись "температура" lcd.setCursor( 13, 0 ); // задаем место отображения значка температуры lcd.write( ( byte ) 0 ); // отображаем его lcd.setCursor( 14, 0 );// задаем место отображения значка температуры буквы С lcd.print( 'C' ); // отображаем его lcd.setCursor( 0, 1 ); //отображаем надпись "установлено" lcd.print( F( "Set:" ) ); // отображаем его lcd.setCursor( 8, 1 );// задаем место отображения установленной температуры lcd.print( set_temp ); // отображаем его lcd.setCursor( 13, 1 );// задаем место отображения значка температуры lcd.write( ( byte ) 0 );// отображаем его lcd.setCursor( 14, 1 );// задаем место отображения значка температуры буквы С lcd.print( 'C' );// отображаем его lcd.setCursor( 5, 1 );// задаем место отображения значка "вентилятор отключен" lcd.write(1);// отображаем его } //функция отображения температуры с датчика, адрес которого указан void printTemperature( DeviceAddress deviceAdress ) { // получаем температуру temp1 = sensors.getTempC( deviceAdress ); // задаем место отображения значка температуры, считанной с датчика lcd.setCursor( 8, 0 ); // отображение температуры lcd.print( temp1 ); } void loop() { // Включить/выключить вентилятор. digitalWrite( FAN, ( temp1 > set_temp ? LOW : HIGH ) ); //задаем место отображения значка "вентилятор включен" lcd.setCursor( 5, 1 ); lcd.write( temp1 > set_temp ? 2 : 1 ); // Посылаем команду, чтобы получить температуру. sensors.requestTemperatures(); sensorState = digitalRead( SENSOR_DOOR ); if ( ( sensorLastState == HIGH ) && ( sensorState == LOW ) ) { time = millis(); lcd.clear(); lcd.setCursor( 6, 0 ); lcd.print( F( "ALERT!" ) ); } else if ( ( sensorLastState == LOW ) && ( sensorState == LOW ) ) { unsigned long tmp = millis(); if ( tmp - time > 1500 ) { time = millis(); tone( SPEAKER, 1000, 500 ); } } else if ( ( sensorLastState == LOW ) && ( sensorState == HIGH ) ) { noTone( SPEAKER ); lcd.clear(); // очищаем экран lcd.setCursor( 0, 0 ); //задаем начальное значение отображения надписей (первая строка, первый столбец) lcd.print( F( "Current:" ) ); //отображаем надпись "температура" } else { //выводим температуру на экран printTemperature( sensor1 ); } sensorLastState = sensorState; }Не напоминай.
А многие тогда столько бабла на лоховских страхах подняли.
Там реально проблемы были. Код, который писался еще на древних EC-ках, начиная с 60-х годов прошлого века. Сплошняком по одну байту на год в двоично-десятичном формате. Сам то формат хранения мы передлывали только в редких случаях. Например, когда должен храниться год ввода основного средства в эксплуатацию. ЛЭП могли и в 20-х годах в эксплуатацию ввести и до сих пор только ремонтировать и модернизировать. Раньше 1917 только не встречалось. Остальные правки были только для сравнения дат и их сортировки, чтобы 00 было больше 99.
А, кто мешает сделать Serial и тестировать программу.
Там реально проблемы были.
Сколько было реальных проблем, и сколько напуганных лохов? Несравнимо.
Это ведет к неминуемой ошибке, пусть через 50 дней, но к ошибке.
Чоэта? А тип future1 указан же unsigned long. Значит в нем есть переполнение, так же как в millis(), значит можно складывать-умножать сколько влезет. Не? Чем тогда лучше код
?
Не ну так. если вы настаиваете что мат. операции над меткой времени из миллиса это ошибка.
А почитать по ссылке выше или поискать на форуме про переполнение....? Религия не позволяет или интеллект?
bboykazbek
Вы надпись "ALERT" выводите с 6 позиции, а значение температуры с 8 позиции. Вот у Вас одно на другое и наползает. При выводе "ALERT" Вы экран очищаете, по этому надписи
которые выводятся один раз в setup() пропадают.Фигурные скобки в строках 106 и 119 ни к чему не привязаны, их можно убрать.