#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <EEPROM.h>
#include <Adafruit_BMP085.h>
#include "DHT.h"
#define D0 16 //TDS
#define D1 5 //SCL
#define D2 4 //SDA
#define D3 0
#define D4 2 //LED помпа
#define D5 14 // Земля
#define D6 12 // 2 реле
#define D7 13 // 1 реле
#define D8 15
#define TX 1
#define RX 3
const char* ssid = "Home";
const char* password = "11111111";
String response = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
String response_klimat = "0000000000000000000000000000000000000000000000000000000000000000000000000000000000";
String delimiter = "|";
String delimiter_2 = "@";
String argument = "000000000000000000000000000000000000000";
String argument_name = "000000000000000000000000000000000000000";
String a = "0000000000000000000000";
ESP8266WebServer server(80);
float PERIOD = 10.0;
const float MINIMAL_PERIOD = 0.5;
int power_rate_1 = 0;
int power_rate_2 = 0;
float duration_on_1 = 0;
float duration_on_2 = 0;
float duration_off_1 = 0;
float duration_off_2 = 0;
unsigned long time_on_1;
unsigned long time_on_last_time_1 = 0;
unsigned long time_off_last_time_1 = 0;
unsigned long time_on_2;
unsigned long time_on_last_time_2 = 0;
unsigned long time_off_last_time_2 = 0;
unsigned long timer_1;
unsigned long timer_2;
unsigned long timer_start_1;
unsigned long timer_start_2;
boolean timer_enable_1 = false;
boolean timer_enable_2 = false;
boolean power_on_1 = false;
boolean power_on_2 = false;
boolean enable_1 = false;
boolean enable_2 = false;
//***********HISTORY************************************
const int SIZE_HISTORY = 100;
long HISTORY_PERIOD = 600000;
unsigned long array_millis[SIZE_HISTORY];
float history_temp[SIZE_HISTORY];
float history_temp_dht[SIZE_HISTORY];
float history_baro[SIZE_HISTORY];
float history_hum[SIZE_HISTORY];
unsigned long history_last_time=0;
int history_counter = 0;
//******DHT-21*******************************************
#define DHTPIN 2
#define DHTTYPE DHT21
DHT dht(DHTPIN, DHTTYPE);
float t; //Мгновенная температура
float h; //Мгновенная влажность
float average_t; //Средняя температура
float average_h; //Средняя влажность
float t_array [10] ; //Массив для температуры
float h_array [10] ; //Массив для влажности
int array_counter = 0; //Счетчик переполнения массива
boolean dht_first_flag = 1;
unsigned long dht_last_time =0;
//***********BMP085***************************************
Adafruit_BMP085 bmp;
float baro_temperature;
float baro_pressure;
float average_bar_pressure; //Среднее давление
float average_bar_temperature; //Средняя температура
float bar_temperature_array [10] ; //Массив для температуры
float bar_pressure_array [10] ; //Массив для давления
int bar_array_counter = 0; //Счетчик переполнения массива
boolean bar_first_flag = 1;
unsigned long bmp_last_time;
//--------------------EEPROM----------------------------
#define EE_period 0
#define EE_freq_1 10
#define EE_freq_2 2
//****************************************************************************************
void handleRoot() {
Create_info_response();
server.send(200, "text/html", response_klimat);
}
void handleNotFound(){
String message = "404. Not Found\n\n";
server.send(404, "text/plain", message);
}
void handleSet() {
argument = server.arg(0);
a = server.arg(0);
if(server.argName(0) == "info") {
Create_info_response();
Serial.println(response_klimat);
server.send ( 200, "text/plain", response_klimat );
}
if(server.argName(0) == "power_1") {
int old = power_rate_1;
power_rate_1 = a.toInt();
if(old == 0 && power_rate_1 > 0)time_on_1 = millis();
if(power_rate_1 > 0) enable_1 = true;
else {
enable_1 = false;
power_on_1 = false;
timer_enable_1 = false;
digitalWrite(D7, LOW);
}
Create_info_response();
server.send ( 200, "text/plain", response_klimat );
}
if(server.argName(0) == "power_2") {
int old = power_rate_2;
power_rate_2 = a.toInt();
if(old == 0 && power_rate_2 > 0)time_on_2 = millis();
if(power_rate_2 > 0) {
enable_2 = true;
}
else {
enable_2 = false;
power_on_2 = false;
timer_enable_2 = false;
digitalWrite(D6, LOW);
}
Create_info_response();
server.send ( 200, "text/plain", response_klimat );
}
if(server.argName(0) == "timer_1") {
int value = a.toInt();
if(value > 0) {
timer_1 = value * 60000L;
timer_enable_1 = true;
timer_start_1 = millis();
}else{
timer_enable_1 = false;
}
Create_info_response();
server.send ( 200, "text/plain", response_klimat );
}
if(server.argName(0) == "timer_2") {
int value = a.toInt();
if(value > 0) {
timer_2 = value * 60000L;
timer_enable_2 = true;
timer_start_2 = millis();
}else{
timer_enable_2 = false;
}
Create_info_response();
server.send ( 200, "text/plain", response_klimat );
}
if(server.argName(0) == "klimat") {
response_klimat = "";
response_klimat += average_bar_pressure;
response_klimat += delimiter;
response_klimat += average_bar_temperature;
response_klimat += delimiter;
response_klimat += average_h;
response_klimat += delimiter;
response_klimat += average_t;
server.send ( 200, "text/plain", response_klimat);
}
if(server.argName(0) == "history") {
Create_history_response();
server.send ( 200, "text/plain", response);
}
if(server.argName(0) == "freq") {
int value = a.toInt();
HISTORY_PERIOD = value * 1000L;
EEPROM.begin(10);
int first_byte = value/256;
int second_byte = value%256;
EEPROM.write(EE_freq_1, first_byte);
EEPROM.commit();
EEPROM.write(EE_freq_2, second_byte);
EEPROM.commit();
EEPROM.end();
response_klimat = value;
server.send ( 200, "text/plain", response_klimat);
}
if(server.argName(0) == "period") {
int value = a.toInt();
PERIOD = (float)value;
EEPROM.write(EE_period, (byte)value);
EEPROM.commit();
response_klimat = value;
server.send ( 200, "text/plain", response_klimat);
}
/*
response_klimat = "Get response: ";
response_klimat += server.argName(0);
response_klimat += " Value: ";
response_klimat += a.toInt();
response_klimat += " time:";
response_klimat += millis();
Serial.println(response_klimat);
*/
}
//****************************************************************************************
//****************************************************************************************
void setup(void){
pinMode(D6, OUTPUT);
pinMode(D7, OUTPUT);
pinMode(D5, OUTPUT);
digitalWrite(D5, LOW);
digitalWrite(D6, LOW);
digitalWrite(D7, LOW);
Serial.begin(115200);
Wire.begin();
dht.begin();
bmp.begin();
EEPROM.begin(10);
PERIOD = (float)EEPROM.read(EE_period);
int first_byte = EEPROM.read(EE_freq_1);
int second_byte = EEPROM.read(EE_freq_2);
HISTORY_PERIOD = (first_byte*256+second_byte) * 1000L;
EEPROM.end();
WiFi.begin(ssid, password);
Serial.println("");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
server.on("/", handleRoot);
server.on("/set", handleSet);
server.onNotFound(handleNotFound);
server.begin();
Serial.println("HTTP server started");
}
//**********************LOOP**************************************************************
//****************************************************************************************
void loop(void){
server.handleClient();
Calc_duration();
Pechka();
Baro(1000);
DHT_21(2000);
History(HISTORY_PERIOD);
Timer();
}
//****************************************************************************************
//****************************************************************************************
void History(long freq){
if((millis()-history_last_time)>freq){
history_temp_dht[history_counter] = average_t;
history_temp[history_counter] = average_bar_temperature;
history_baro[history_counter] = average_bar_pressure;
history_hum[history_counter] = average_h;
array_millis[history_counter] = millis();
history_counter ++;
if(history_counter >= SIZE_HISTORY) history_counter = 0;
history_last_time = millis();
}
}
void Create_history_response(){
response = "";
for(int i = 0; i < SIZE_HISTORY; i++){
response_klimat = "";
response_klimat += history_baro[i];
response_klimat += delimiter;
response_klimat += history_temp[i];
response_klimat += delimiter;
response_klimat += history_hum[i];
response_klimat += delimiter;
response_klimat += history_temp_dht[i];
response_klimat += delimiter;
long m = millis() - array_millis[i];
response_klimat += m;
response_klimat += delimiter_2;
response += response_klimat;
}
}
void Create_info_response(){
response_klimat = "";
response_klimat += power_rate_1;
response_klimat += delimiter;
response_klimat += power_on_1;
response_klimat += delimiter;
if(power_rate_1 > 0) response_klimat += millis() - time_on_1;
else response_klimat += 0;
response_klimat += delimiter;
if(timer_enable_1) response_klimat += timer_start_1 + timer_1 - millis();
else response_klimat += 0;
response_klimat += delimiter;
response_klimat += power_rate_2;
response_klimat += delimiter;
response_klimat += power_on_2;
response_klimat += delimiter;
if(power_rate_2 > 0) response_klimat += millis() - time_on_2;
else response_klimat += 0;
response_klimat += delimiter;
if(timer_enable_2) response_klimat += timer_start_2 + timer_2 - millis();
else response_klimat += 0;
response_klimat += delimiter;
response_klimat += HISTORY_PERIOD;
response_klimat += delimiter;
response_klimat += PERIOD;
}
//---------Барометр-----------------------------------------------------
void Baro(int freq){
if((millis()-bmp_last_time)>freq){
baro_pressure = bmp.readPressure()/133.322;
baro_temperature = bmp.readTemperature();
if(bar_first_flag){
for (int m = 0; m < 10; m++){
bar_temperature_array[m] = baro_temperature;
bar_pressure_array[m] = baro_pressure;
bar_first_flag = 0;
}
}
bar_temperature_array[bar_array_counter] = baro_temperature;
bar_pressure_array[bar_array_counter] = baro_pressure;
bar_array_counter++;
if(bar_array_counter>9){bar_array_counter=0;}
float m1 = 0;
float m2 = 0;
for (int m = 0; m < 10; m++){
m1 = m1 + bar_temperature_array[m];
m2 = m2 + bar_pressure_array[m];}
average_bar_pressure = m2/10.00;
average_bar_temperature = m1/10.00;
bmp_last_time = millis();
}
}
//---------------DHT--------------------------------------------
void DHT_21(int freq){
if ((millis()-dht_last_time)>freq){
t = dht.readTemperature();
h = dht.readHumidity();
if(dht_first_flag){
for (int m = 0; m < 10; m++){
t_array[m] = t;
h_array[m] = h;}
dht_first_flag = 0;
}
t_array[array_counter] = t;
h_array[array_counter] = h;
array_counter++;
if(array_counter>9)array_counter=0;
float summa_t = 0;
float summa_h = 0;
for (int m = 0; m < 10; m++){
summa_t += t_array[m];
summa_h += h_array[m];
}
average_t = summa_t/10.00;
average_h = summa_h/10.00;
dht_last_time = millis();}
}
//---------Pechka-------------------------------------------------------
void Pechka(){
if(enable_1){
if(power_on_1){
if(millis() - time_on_last_time_1 > duration_on_1 * 1000.0){
power_on_1 = false;
time_off_last_time_1 = millis();
digitalWrite(D7, LOW);
//Serial.println("1 off");
}
}
if(!power_on_1){
if(millis() - time_off_last_time_1 > duration_off_1* 1000.0){
power_on_1 = true;
time_on_last_time_1 = millis();
digitalWrite(D7, HIGH);
//Serial.println("1 on");
}
}
}else{
digitalWrite(D7,0);
}
if(enable_2){
if(power_on_2){
if(millis() - time_on_last_time_2 > duration_on_2 * 1000.0){
power_on_2 = false;
time_off_last_time_2 = millis();
digitalWrite(D6, LOW);
//Serial.println("2 off");
}
}
if(!power_on_2){
if(millis() - time_off_last_time_2 > duration_off_2* 1000.0){
power_on_2 = true;
time_on_last_time_2 = millis();
digitalWrite(D6, HIGH);
//Serial.println("1 onn");
}
}
}else{
digitalWrite(D6,0);
}
}
void Calc_duration(){
if(power_rate_1 == 100){
duration_on_1 = 600;
duration_off_1 = 0;
}
if(power_rate_1 == 0){
duration_on_1 = 0;
duration_off_1 = 100000;
}
if(power_rate_1 < 100 && power_rate_1 > 0){
duration_on_1 = power_rate_1/100.0 * PERIOD;
duration_off_1 = PERIOD - duration_on_1;
}
if(power_rate_2 == 100){
duration_on_2 = 600;
duration_off_2 = 0;
}
if(power_rate_2 == 0){
duration_on_2 = 0;
duration_off_2 = 100000;
}
if(power_rate_2 < 100 && power_rate_2 > 0){
duration_on_2 = power_rate_2/100.0 * PERIOD;
duration_off_2 = PERIOD - duration_on_2;
}
}
void Timer(){
if(timer_enable_1){
if(millis() - timer_start_1 > timer_1){
timer_enable_1 = false;
digitalWrite(D7, LOW);
power_rate_1 = 0;
enable_1 = false;
}
}
if(timer_enable_2){
if(millis() - timer_start_2 > timer_2){
timer_enable_2 = false;
digitalWrite(D6, LOW);
power_rate_2 = 0;
enable_2 = false;
}
}
}
+278 |
36169
160
|
+23 |
1888
52
|
+47 |
2506
89
|
+165 |
3870
48
|
как-же закон ома?
перегорание всех электронагревательных приборов происходит в момент пуска, пока температура мала, сопротивление меньше, ток бахает большой…
Нихромовая проволока камфорок про это не знает.
* перегрев -> изгиб ТЭНа/спирали -> касание корпуса нитью -> перегорание нити с/без прогоранием корпуса.
* отгорание провода от контакта нагревателя вследствие некачественной опрессовки/клеммы.
* выгорание описанного пунктом выше контакта из-за ослабления пружинного клемника.
* брак нагревателя в точке соединения контакта и нихромовой нити -> обрыв
* простой обрыв нити спирали. утверждать что спираль оборвалась из-за частых включений нельзя, это были не самые старые ТЭНы, да и их количество было ниже погрешности статистики.
И при чем здесь витамины?
Если ты видел что-то, то это означает только то, что ты увидел то, что хотел увидеть.
Но это не означает, что это могло быть на самом деле.
Если ты не видел просто перегоревшую конфорку или тэн, это не означает что они не перегорают так, как ты не видел.
Так и с витаминами, их никто не видел, а они существуют. ;-))))
в прочем писать ответ я больше не буду, вы мои ответы не читаете в принципе.
правка:
не тому написал
А вот сопротивление вольфрамовой спирали лампы накаливания при нагреве увеличивается на порядок.
Школьная физика.
Можно сделать и лампочки накаливания с нихромовыми спиралями. Они не будут перегорать в момент включения, но свет будет включаться ооочень медленно — примерно, как раскаляется спираль в инфракрасном обогревателе UFO.
Поэтому в лампочках вольфрам (у него: 1. Нужный температурный коэффициент сопротивления — свет загорится быстро. 2. Большая стойкость к высокой температуре — спираль прослужит дольше).
Вообщем, на порядок.
Нихром Х20Н80 — Cr 20 %, Ni 80 %. Удельное сопротивление 1,13 Ом·мм²/м при 20 °C, 1,167 Ом·мм²/м при 1100 °C; максимальная рабочая температура 1200 °C, температура плавления 1400 °C.
Отличная реализация, для кросс платформенности и управления извне можно использовать Blynk. Тогда по запросу из дома, вы хоть с пляжа в Турции сможете включить конфорку.
-это не я!!!
-тьфубл@, плиту взломали.
))))))
это я в шутку, конечно.
Давно в доме плита и духовка на емкостных кнопках
Иначе любой сбой с Wi-Fi оставит вашу семью голодными.
И, да, вы счастливо прошли мимо хитро расположенных граблей: на Али есть фотеки, которые от 3,3 вольт только зажигают свой светодиод, а уверенно включаться начинают лишь от 9 вольт. Это для тех, кто решит повторить самоделку и будет искать причину холодных конфорок при внешне работающей конструкции и весело мигающих индикаторах на фотеке.
PS: Чёт подумалось… Чем дальше цивилизация, тем сложнее становятся элементарные задачи.
Ведь исходный пример: наши деды, чтобы сделать термостат, ставили биметаллический переключатель и ващще не парились. И ведь, по большому счёту, работает же до сих пор, кое-где по полвека аптайм.
Наши отцы, чтобы сделать термостат, паяли кучку транзисторов и резисторов к терморезистору, и получали работоспособность на десятки и десятки лет.
А теперь, прочитал этот фундаментальный обзор и вот на философию потянуло… Вайфайные модули с датчиками атмосферного давления скрещивать. С мобильников/из браузеров обращаться, чтобы плиту включить… ЁмаЁ ©.
Нет, статья познавательная, безусловно. Честный заслуженный плюс поставил.
Но что же будет ещё через пяток лет — даже подумать боязно. Как в «Ералаше», чтобы время на часах посмотреть, два чемодана с собой носить постоянно? :)
Как в девятом элементе.
А линк сделать прямой от esp к мобилке, тогда можно и роутер тушить :)
Не увидел ни одной реальной фотографии реализации. Управление только с телефона? То ещё решение…
Сразу напрашиваются энкодер, дисплей вместо родного…
И прогоняйте текст через spell checker, хоть «конкакты» и «длинной» уберёт...Пока писал пост — сам додумался это «параллельный» стабилизатор тока для разного управляющего входного напряжения…
Никакой сувид будет не нужен :)
Надо развивать идею дальше. MAX6675 с выносным термометром прикрутить, пуш-уведомления на мобилку добавить, рецепты (термопрофили) запилить…
Конечно же неплохо еще поставить термодатчик на конфорку и контроль превышения температуры.
И термодатчики в конфорку встроены по умолчанию, в этом плане порядок.
Думаю, вкупе с твердотельным реле, имеет смысл установить малогабаритный контактор, чтоб он механически отключал питание конфорок.
Если поставить датчики температуры конфорок, то можно организовать ПИД регулятор, будет весьма удобная штука. Конфорка будет разогреваться на максимальной мощности, а потом сама регулировать мощность в зависимости от «теплоотвода».
да и с конфоркой вместо шим удобнее bang-bang алгоритм.
На кухне часто руки бывают не очень чистыми, а нужно срочно отключить/включить/изменить режим комфорки. Как минимум нужно помыть и вытереть руки.
Опять же, смартфон на кухне, если не лежит в кармане подвергается дополнительным рискам: всегда что-то может упасть на него или разлиться.
Как вариант, вскипять воду к моменту как проснусь или сварть яйца интересно.
Алиса, испеки мне пирожки :)
Не всегда это лучше )
1. Отсрочка старта.
2. Поддерживание любой температуры (для брожения например), добавить датчик просто и по его показаниям вкл/выкл конфорку.
3. Детектор закипания (с пищевым датчиком). Прога отслеживает температуру в кастрюле и при достижении температуры кипения автоматически переводит конфорку на слабый огонь.
4. Понаписывать параметры готовки для разных блюд. (Например, жмем «Пельмени», плита включается на 7 минут, «Макароны» — на 10, «Горох» — на 40).
для MIT App Inventor?
Про MIT App Inventor я упомянул, чтоб дать понять, что можно её же написать и без знания Java.
Просто о MIT App Inventor мало кто знает, а штука просто гениальная. Управление любыми устройствами с помощью нее можно перевести в телефон даже не будучи программистом.
Да и фотографировать там нечего, два в реле в плите, управляющая платка в глухой коробке за печью (скрыта от глаз).
пока в мыслях к колонке прикрутить подобный регулятор, но придётся реализовывать его совместно с редуктором и электроприводом…
хотел сделать к кофеварке, чтобы утром нас ждал кофе, но, как верно заметили, жениться проще))))) (а потом жена запрещает курочить кофеварку, ей нравится самой нажимать на кнопку)
да и чем может грозить вращение регулятора?
а вращение регулятора может грозить его поломкой.
Как выработкой ресурса вращения (протрется сильфон итп), так и тупо сворачиванием ему башки.
а вот если часто туда-сюда елозить, то да, можно протереть…
зря, электронные версии-то работают же как-то.
надо подумать.
благодарю за направление :)
автор период вкл. -выкл. 53 сек. делал как на заводском БУ. 10 сек наверное маловато будет.
53 секунды это многовато. Будет то кипеть то не кипеть. А 10 сек как раз, плавно получается. Почему маловато?
Конечно можно, поставить модуль в режим сервера и напрямую подключаться к нему.
Правильно делать вот так:
Вообще такие большие блоки даных нужно строить динамически и отдавать мелкими кусками, а не собирать в единую String строку. Но если это шаманство у вас работает и все устраивает, то ОК, путь живет :)
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.