Arduino + сенсор DHT11 + шаговый двигатель (биполярный)
- Войдите на сайт для отправки комментариев
Сб, 14/04/2012 - 22:34
- Доброго времени суток! Есть Arduino + сенсор DHT11 (температура и влажность) + шаговый двигатель (биполярный). Хочу сделать конролируемое по температуре открытие/закрытие форточки в доме. Например, при достижении t > 24 C, форточка открылась и не закрывалась. При t < 24 C форточка закрылась. При работе моего кода ШД, если t>24 или t<24, постоянно срабатывает. Знаю, чо где-то что-то делаю не правильно при цеплянии ШД. Помогите пожалуйста...
- P.S. да, ламер и чайник
#include <Stepper.h> #define DHT11_PIN 0 // цепляю сенсор #define STEPS 200 Stepper stepper(STEPS, 8, 9, 10, 11); byte read_dht11_dat() { byte i = 0; byte result=0; for(i=0; i< 8; i++){ while(!(PINC & _BV(DHT11_PIN))); delayMicroseconds(30); if(PINC & _BV(DHT11_PIN)) result |=(1<<(7-i)); while((PINC & _BV(DHT11_PIN))); } return result; } void setup() { DDRC |= _BV(DHT11_PIN); PORTC |= _BV(DHT11_PIN); Serial.begin(9600); stepper.setSpeed(10); Serial.println("Ready"); } void loop() { byte dht11_dat[5]; byte dht11_in; byte i; PORTC &= ~_BV(DHT11_PIN); delay(18); PORTC |= _BV(DHT11_PIN); delayMicroseconds(40); DDRC &= ~_BV(DHT11_PIN); delayMicroseconds(40); dht11_in = PINC & _BV(DHT11_PIN); if(dht11_in){ Serial.println("dht11 start condition 1 not met"); return; } delayMicroseconds(80); dht11_in = PINC & _BV(DHT11_PIN); if(!dht11_in){ Serial.println("dht11 start condition 2 not met"); return; } delayMicroseconds(80); for (i=0; i<5; i++) dht11_dat[i] = read_dht11_dat(); DDRC |= _BV(DHT11_PIN); PORTC |= _BV(DHT11_PIN); byte dht11_check_sum = dht11_dat[0]+dht11_dat[1]+dht11_dat[2]+dht11_dat[3]; if(dht11_dat[4]!= dht11_check_sum) { Serial.println("DHT11 checksum error"); } Serial.print("Current humdity = "); Serial.print(dht11_dat[0], DEC); Serial.print("."); Serial.print(dht11_dat[1], DEC); Serial.print("% "); Serial.print("temperature = "); Serial.print(dht11_dat[2], DEC); Serial.print("."); Serial.print(dht11_dat[3], DEC); Serial.println("C "); delay(2000); if (dht11_dat[2] > 24) // начало работы ШД { stepper.step(100); } if (dht11_dat[2] < 22) { stepper.step(-100); } }
спасибо
Решение называется RTFM - Read The Fucking Manual.
Если открыть даташит и посмотреть раздел тех. характеристик, то можно выяснить, что
"Temperature Accuracy ±2℃"
то есть, при одном считывании вы можете получить 20 градусов Цельсиуса, а при следующем за ним - 24. Или лучше так - при одном 25 (и срочно откроете свою форточку), а при следующем - 21 (и "побежите" задраивать все щели).
Пути решения? Их есть у меня:
либо расширяйте гистерезис, скажем с ">24 откр, <22 закр" перейдите на ">25 откр, <21 закр"
либо находите среднее арифметическое по последни 5-6-10-100 замерам.
ЗЫ: И еще: вот вы чексум проверяете и даже истошное сообщение в случае чего выводите.
Оч. хор.
Только, выполнив эту проверку, почему-то успокаиваитесь и бесстрашно используете полученные неправильные данные в своем алгоритме. Правильнее было бы заключить все инструкции, стоящие ниже проверки контрольной суммы, в конструкцию "else {...}" и выполнять их ТОЛЬКО в том случае, если проверка успешна.
Спасибо step962. значения температуры поменял.. однако остается следующая проблема - при t>25 двигатель срабатывает постоянно (т.е форточка открывается, затем еще и еще). <21 происходит закрытие, +закрытие, + закрытие и т.д.
Как сделать так, чтоб открытие/закрытие осуществлялось однократно (т.е. 24, 25, 26(открытие),27 (форточка продолжает оставаться открытой, а не "открывается еще разок")?
P.S. как посчитать "среднее арифметическое по последни 5-6-10-100 замерам"
Как сделать так, чтоб открытие/закрытие осуществлялось однократно (т.е. 24, 25, 26(открытие),27 (форточка продолжает оставаться открытой, а не "открывается еще разок")?
Ну, это можно реализовать разными способами.
Например, ввести константы
и переменную состояния (обозвав ее, например, State)
В setup():
В loop():
Проверка на закрывание - в том же духе.
P.S. как посчитать "среднее арифметическое по последни 5-6-10-100 замерам"
Это уже разбиралось в одной из тем, посвященных борьбе с дребезгом кнопок или чему-то там еще:
При расчете среднего не следует забывать об особенностях целочисленной математики, иначе очень легко накопить непереносимо большую погрешность. (например, в выражении, в котором участвуют исключительно целочисленные переменные результат действия 4/5 и даже 99/100 равен нулю)
Step962 спасибо вам ОГРОМНОЕ! Все работает! Думаю, тема закрыта)