Controlador de irrigação inteligente
Componentes e suprimentos
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
Aplicativos e serviços online
|
Sobre este projeto
Crie um controlador de irrigação inteligente com Arduino
Irrigue seu quintal de forma inteligente com ciclos de água dinâmicos. Pare de regar o quintal se estiver chovendo ou tiver chovido desde a última rega. Use o sensor de luz para detectar a hora do nascer do sol e ajustar automaticamente os horários de início da água de acordo. Pare de molhar seu quintal se estiver muito frio.
Lista de recursos
- Sensor de temperatura externa
- Sensor externo de chuva
- Sensor de luz externa
- Relógio em tempo real com bateria para programação semanal
- Armazenamento não volátil - nunca perca a irrigação devido à perda de energia
- detecção do nascer do sol
- A rega inteligente economiza na sua conta de água
- Regar antes do nascer do sol para permitir um tempo de imersão adequado
- Pare de regar quando estiver muito frio lá fora
- Reduzir o crescimento de fungos
- Fácil controle de programação
Peças necessárias para construir o controlador de irrigação inteligente
- Expansor IO
- x2 1 fio para I2C.
- Junção de 1 fio
- Conector óptico
- Divisor
- Arduino Nano.
- Relé de 4 canais DC 5V.
- Sensor de luz TSL2561.
- Sensor de temperatura à prova d'água DS18B20.
- Sensor infravermelho óptico de nível de água.
- Relógio de tempo real de precisão DS3231 AT24C32 IIC.
- Tela I2C SSD1306 OLED de 128x64.
- Caixa de plástico transparente à prova d'água de 200x120x75mm.
- Caixa de plástico transparente à prova d'água de 100x68x50mm.
- ip68 pg7 prensa-cabo de nylon à prova d'água.
- ip68 pg11 prensa-cabo de nylon à prova d'água.
- Tomada de terminal de parafuso RJ11 Keystone.
- Cabo RJ11 4C4P de 50 pés.
- Cabo RJ11 4C4P de 6 pés.
- Fio de plataforma de 2,54 mm.
- x2 Microinterruptor de botão momentâneo de 2 pinos SPST
- Fonte de alimentação do adaptador de parede 12VDC 1A.
Diagrama de fiação
Tela OLED
Pressione o botão Menu para exibir o menu e continue pressionando o botão para percorrer todas as opções do menu. O menu será removido automaticamente após 30 segundos de inatividade. Pressione o botão Selecionar para executar a função de menu desejada.
Então, por que usar o IO Expander?
- Mais simples de projetar
- Peças disponíveis no mercado
- Nenhum driver 1-Wire para escrever
- Nenhum driver DS3231 RTC para escrever
- Nenhum driver EEPROM para escrever
- Nenhum driver de exibição OLED para escrever
- Nenhuma fonte de exibição para ocupar espaço de código Arduino
- Nenhum driver de sensor de temperatura para escrever
- Nenhum secador de sensor óptico de chuva para escrever
- Economiza espaço de código no Arduino; apenas 12.710 bytes (39%)
- Apenas três dias para escrever o código
- Fácil de conectar usando o cabo telefônico RJ11 padrão
- Sem problemas de comprimento do cabo do sensor
- Mais barato de construir do que sistemas comerciais semelhantes
- Fácil de fazer alterações para se adaptar aos requisitos individuais
- Fonte de alimentação única
Construa o sistema
Conecte o Arduino Nano ao IO Expander e programe-o com o seguinte código. O cabeçalho de 6 pinos é a porta de depuração serial do software e não é necessário na instalação final.
Certifique-se de alterar o endereço definido ONEWIRE_TO_I2C_ROM1 e ONEWIRE-TO_I2C_ROM2 para corresponder ao endereço 1-Wire ao endereço I2C.
/ * Esboço do IO Expander otimizado
*
* Sistema de irrigação v1.1
*
* /
#include
Nota: Se você usar a porta USB para programar o Arduino Nano, deverá desconectá-lo do IO Expander, pois ele também está usando a mesma porta serial única; em vez disso, se quiser depurar, use a porta ICSP para programar o ATmega328P. Para ativar a porta de depuração de software, descomente a definição SERIAL_DEBUG.
O divisor deve primeiro ser configurado para isolar a linha de dados do sensor infravermelho óptico da linha do sensor remoto de 1 fio. Solda em um resistor 0603 de zero ohm em R2.
Faça um orifício de 7/16 "no gabinete pequeno e um orifício de 11/16" no gabinete maior no lado direito para o PG7 e PG11. Use uma ferramenta dremel para aumentar ligeiramente os orifícios até que a sobreposta se ajuste bem. O PG7 alimentará os sensores remotos e o PG11 para os fios 12VDC, 24VAC, manifold e o fio dos sensores remotos RJ11.
Ligue o microinterruptor de botão momentâneo SPST e conecte-o ao terminal de parafuso RJ11. Use tubulação termorretrátil para isolar os contatos.
Conecte todos os fios e monte / alimente todas as peças no gabinete grande. Seu fio RJ11 de 50 pés para os sensores remotos deve apenas passar pela sobreposta PG11 sem ter que cortá-lo.
Faça um orifício de 9/16 "na parte superior da caixa pequena para o sensor infravermelho óptico de água. Use uma ferramenta dremel para aumentar ligeiramente o orifício até que o sensor se encaixe. A pequena caixa do sensor remoto é um encaixe apertado, mas se o conteúdo são colocados na orientação recomendada em que devem se encaixar. Fazer os fios RJ11 o mais curtos possível ajudará a amontoar tudo no gabinete menor. Depois de montado, é recomendado adicionar um pouco de cola marinha na arruela da porca da bucha antes de aparafusar a porca, para criar um selo melhor.
Instale o invólucro do sensor remoto do lado de fora e monte-o elevado ao lado leste da sua casa com o sensor de água infravermelho ótico e o sensor de luz apontando para o céu sem obstruções.
Faça orifícios de 1/4 "na parte superior central inferior do gabinete grande e monte os botões. Use uma ferramenta dremel para aumentar ligeiramente o orifício até que os botões se encaixem.
Teste o sistema e verifique se tudo está funcionando corretamente. Para testar o relé e os sensores, desconecte o Arduino do IO Expander e conecte-o diretamente ao seu computador para controlá-lo manualmente. Depois de verificar se tudo está funcionando, monte todas as peças no gabinete usando fita dupla-face e espuma de embalagem para proteger suas placas e aproveite os benefícios e a economia de seu Controlador de irrigação inteligente.
Vídeo em operação
Atualização 12/09/2019
Lançada a v1.1, que corrigia um problema de inicialização caso o sistema perdesse energia por vários dias.
Atualização 02/10/2019
Ao conectar o 1-Wire a I2C ao DS3231 e depois à tela OLED do SSD1306, você terá um total de três pullups diferentes nas linhas SDA e SCL, conforme mostrado na imagem abaixo circulada. Isso resultará efetivamente em um pullup de 4,7k / 3 =1,56k que pode ser muito forte e resultar em corrupções de tela aleatórias.
Uma vez que o DS3231 usa um pacote de resistores que é usado por outras linhas, remova os outros resistores pullup:
- 1 fio para I2C R3 e R4.
- SSD1306 OLED R6 e R7.
Código
- Controlador de irrigação inteligente
Controlador de irrigação inteligente C / C ++
Use seu Arduino para regar seu quintal ou jardim de maneira inteligente./ * Esboço do IO Expander otimizado * * Sistema de irrigação v1.1 * * / # include#include // Arquivo localizado \ Programa Arquivos (x86) \ Arduino \ hardware \ tools \ avr \ avr \ include \ time.h # include #include #include #include "IOExpander. h "#define FAHRENHEIT # define INIT_BOARD "g5w1; g11w1; g11d0,75; g12w1; g12d0,75; RSF" #define ONEWIRE_TO_I2C_ROM1 "i4scc" #define ONEWIRE_TO_I2C_ROM2 "i6s8f" #define ONEWIRE_TEMPERATURE "t6s0300" #define RTC_SENSOR "s4te" # definir I2C_EEPROM "s4tf" #define I2C_OLED "s4t10" #define I2C_LIGHT "s3t9; sc0" #define OPTICAL_SENSOR "g5a" #define BUTTON1 "g11d" #define BUTTON2 "g12d" #define_VEL_VEL_SENSOR_DEFINIR_AVE_INDA_ELEFINHA_ELEFINE_ELEFINER_ELEFINE_ELEFINER_60_60LEFATER_LISE 100_ELEFINE_ELEFINE_ELEFINE_ELEFINE_ELEFATER_LISE define DO_NOT_WATER_TEMP 4.4444 // 40F # define MAX_ZONES 4 # define HOUR_IN_DAY 24L # define MIN_IN_HOUR 60L # define SEC_IN_MIN 60L # define SEC_IN_HOUR (MIN_IN_HOUR * SEC_IN_MIN) #define SEC_IN_DAY (HOUR_IN_DAY * SEC_DAY * NOSSO) #define DAYS_IN_WEEK 7 # define SEC_IN_WEEK (SEC_IN_DAY * DAYS_IN_WEEK) #define SUN 0x01 # define MON 0x02 # define TUE 0x04 # define WED 0x08 # define THR 0x10 # define FRI 0x20 # define SAT 0x40 # define EVERYDAY (DOM 0x40 # define EVERYDAY | MON | TER | WED | THR | SEX | SAT) #define SUNRISE 0x80 # define MENU_OPTIONS 9 # define MENU_TIME 30 # define OFF 0 # define ON 1 # define STATE_ON_OFF 0x01 // # define SERIAL_DEBUG # ifdef SERIAL_DEBUGSoftwareSerial swSerial (8,7); # endifchar weekday [] [4] ={"DOM", "SEG", "TER", "QUA", "QUI", "SEX", "SÁB"}; menu de caracteres [] [13] ={"Próximo", "Água", "Redefinir" , "Clock Min +", "Clock Min -", "Clock Hour +", "Clock Hour -", "Sunrise", "ON / OFF"}; enum {MENU_NEXT, MENU_WATER, MENU_RESET, MENU_CLOCK_MIN_PLUS, MENU_CLOCK_MIN_MINUS, MENU_CLOCK_HOUR_PLUS, MENU_CLOCK_HOUR_MINUS, MENU_SUNRISE, MENU_ON_OFF}; typedef struct {char descrição [16]; relé uint8_t;} ZONA; typedef struct {uint8_t zona; uint8_t dias; int8_t hour; int8_t min; duração uint8_t;} CALENDÁRIO; typedef struct {time_t sunrise_time; time_t last_water_time; uint8_t water_schedule; uint8_t water_duration; uint8_t rain [MAX_ZONES]; uint8_t state; uint8_t crc;} NVRAM; enum {ZONE1, ZONE2, ZONE3, ZONE4}; enum {RELAY1 =1, RELAY2, RELAY3, RELAY4}; ZONE zone [] ={{"Front Right", RELAY1}, {"Front Left" , RELAY2}, {"Bushes", RELAY3}, {"Left Side", RELAY4},}; AGENDAMENTO da programação [] ={{ZONE1, SUNRISE | DIÁRIO, -1, 0, 4}, {ZONA2, DIÁRIO, 6, 15, 5}, {ZONA3, DIÁRIO, 6, 0, 10}, {ZONA4, DIÁRIO, 6, 10, 6},}; NVRAM nvram; bool update_nvram =false; uint8_t crc8 (uint8_t * data, uint16_t comprimento) {uint8_t crc =0; while (comprimento--) {crc =_crc8_ccitt_update (crc, * dados ++); } return crc;} int led =13; bool init_oled =true; bool update_oled =true; bool init_board =true; #ifdef FAHRENHEIT # define C2F (temp) CelsiusToFahrenheit (temp) float CelsiusToFahrenheit (float celsius) {return ((celsius *) 9) / 5) + 32;} # else # define C2F (temp) (temp) #endifvoid SerialPrint (const char * str, float decimal, char erro) {Serial.print (str); if (erro) Serial.print (F ("NA")); else Serial.print (decimal, 1);} time_t NextScheduleTime (time_t last_time, uint8_t * next_schedule) {time_t next_time =-1; time_t clk_time; uint8_t i; tm clk; uint8_t wday; para (i =0; i SÁBADO) wday =DOMINGO; if (wday ==clk.tm_wday) break; // Verifique apenas uma semana} if (clk_time 0) {if (nvram.rain [i]> nvram.water_duration) nvram.water_duration =0; senão nvram.water_duration - =nvram.rain [i]; nvram.rain [i] =0; }} void WaterScheduleTime (void) {uint8_t i; nvram.water_duration--; update_nvram =true; i =agendar [nvram.water_schedule] .zone; if (i 0) Serial.println ("o"); else Serial.println ("f"); SerialReadUntilDone (); }} void setup () {Serial.begin (115200); # ifdef SERIAL_DEBUG swSerial.begin (115200); # endif pinMode (led, OUTPUT); // delay (1000); wdt_enable (WDTO_8S);} void loop () {static tm rtc; tm clk, sunrise_clk; time_t rtc_time; time_t clk_time; static time_t next_time; static uint8_t last_sec; static uint8_t last_min; bool error_rtc; bool error_light; bool error_temp; lux longo estático =0; temperatura de flutuação estática, chuva; estático uint8_t sunrise_counter =MIN_IN_HOUR; bool estático check_sunrise =false; uint8_t i; bool estático read_nvram =true; estático time_t water_time; static uint8_t water_schedule; uint8_t sz; uint8_t wday; long n; bool botão1, botão2; estático int8_t menu_select =-1; estático time_t menu_time =0; Serial.println (); if (SerialReadUntilDone ()) {if (init_board) {SerialCmdDone (INIT_BOARD); init_board =false; } if (init_oled) {if (SerialCmdNoError (ONEWIRE_TO_I2C_ROM1)) {SerialCmdDone (I2C_OLED "; si; sc; sd"); init_oled =false; } } if (SerialCmdDone(RTC_SENSOR)) { error_rtc =!SerialReadTime(&rtc); if (!error_rtc) { clk =rtc; // mktime() can change struct tm rtc_time =mktime(&clk); localtime_r(&rtc_time, &rtc); // Get wday. } if (read_nvram) { if (SerialCmdNoError(I2C_EEPROM)) { SerialReadEEPROM((uint8_t*)&nvram, 0, sizeof(nvram)); if (nvram.crc !=crc8((uint8_t*)&nvram, sizeof(nvram)-sizeof(uint8_t))) { //swSerial.println("CRC8 Failure!"); // Initialize nvram memset(&nvram, 0, sizeof(nvram)); clk =rtc; clk.tm_hour =6; clk.tm_min =0; clk.tm_sec =0; nvram.sunrise_time =mktime(&clk); if (nvram.sunrise_time SEC_IN_WEEK) nvram.last_water_time =rtc_time - SEC_IN_WEEK; // Check sunrise time if (rtc_time> nvram.sunrise_time) { localtime_r(&nvram.sunrise_time, &sunrise_clk); clk =rtc; clk.tm_hour =sunrise_clk.tm_hour; clk.tm_min =sunrise_clk.tm_min; clk.tm_sec =sunrise_clk.tm_sec; nvram.sunrise_time =mktime(&clk); if (nvram.sunrise_time 0) sunrise_counter--; else check_sunrise =true; } else { if (sunrise_counter =MENU_OPTIONS) menu_select =0; } menu_time =rtc_time; update_oled =true; } if (menu_select>=0) { button2 =SerialReadButton(BUTTON2); if (button2) { clk_time =rtc_time; switch(menu_select) { case MENU_NEXT:case MENU_RESET:if (nvram.water_duration) { nvram.water_duration =1; WaterScheduleTime(); } water_time =NextScheduleTime((menu_select ==MENU_NEXT) ? water_time :rtc_time, &water_schedule); pausa; case MENU_WATER:StartScheduleTime(water_time, water_schedule); WaterScheduleTime(); pausa; case MENU_CLOCK_MIN_PLUS:clk_time +=SEC_IN_MIN; pausa; case MENU_CLOCK_MIN_MINUS:clk_time -=SEC_IN_MIN; pausa; case MENU_CLOCK_HOUR_PLUS:clk_time +=SEC_IN_HOUR; pausa; case MENU_CLOCK_HOUR_MINUS:clk_time -=SEC_IN_HOUR; pausa; case MENU_ON_OFF:nvram.state ^=STATE_ON_OFF; update_nvram =true; pausa; } if (clk_time !=rtc_time) { if (SerialCmdDone(RTC_SENSOR)) { localtime_r(&clk_time, &clk); SerialWriteTime(&clk); rtc_time =clk_time; } } menu_time =rtc_time; update_oled =true; } } if (menu_select>=0 &&rtc_time - menu_time> MENU_TIME) { menu_select =-1; update_oled =true; } if (update_oled) { if (SerialCmdNoError(ONEWIRE_TO_I2C_ROM1)) { Serial.print("st10;so1;sc;sf0;sa0;sd0,0,\""); if (nvram.water_duration) Serial.print(nvram.water_duration); else { if ((nvram.state &STATE_ON_OFF) ==OFF) Serial.print("OFF"); else if (rain <=RAIN_DETECT_LEVEL) Serial.print("Rain"); else if (temp <=DO_NOT_WATER_TEMP) Serial.print("Cold"); else Serial.print("v1.1"); } Serial.print("\";sf2;sa1;sd75,0,\""); if (menu_select ==7) { // Sunrise clk_time =nvram.sunrise_time; localtime_r(&clk_time, &clk); } else clk =rtc; Serial.print(clk.tm_hour-((clk.tm_hour>12)?12:0)); Serial.print(":"); if (clk.tm_min <10) Serial.print("0"); Serial.print(clk.tm_min); Serial.println("\""); SerialReadUntilDone(); Serial.print("sf1;sa0;sd79,8,\""); Serial.print((clk.tm_hour>12)?"PM":"AM"); Serial.print("\";sf0;sa1;sd127,1,\""); Serial.print(weekday[clk.tm_wday]); Serial.print("\";sd127,13,\""); Serial.print(clk.tm_mon+1); Serial.print("/"); Serial.print(clk.tm_mday); Serial.println("\""); SerialReadUntilDone(); Serial.print("sf0;sa0;sd1,36,\""); i =schedule[water_schedule].zone; if (i SEC_IN_DAY) { Serial.print("\";sa1;sd126,36,\""); Serial.print(clk.tm_mon+1); Serial.print("/"); Serial.print(clk.tm_mday); Serial.print(" "); Serial.print(clk.tm_hour-((clk.tm_hour>12)?12:0)); Serial.print(":"); if (clk.tm_min <10) Serial.print("0"); Serial.print(clk.tm_min); Serial.print(" "); } else { Serial.print("\";sf1;sa1;sd111,30,\""); Serial.print(clk.tm_hour-((clk.tm_hour>12)?12:0)); Serial.print(":"); if (clk.tm_min <10) Serial.print("0"); Serial.print(clk.tm_min); Serial.print("\";sf0;sd126,36,\""); } Serial.print((clk.tm_hour>12)?"PM":"AM"); if (nvram.water_duration) Serial.print("\";so2;sc0,29,128,19"); Serial.println (); SerialReadUntilDone(); if (menu_select ==-1) { //Serial.print("\";sa0;sd0,52,\""); //Serial.print(rain); SerialPrint("\";so1;sa2;sd63,52,\"", C2F(temp), error_temp); if (!error_temp) Serial.print("\",248,\"" #ifdef FAHRENHEIT "F" #else "C" #endif ); Serial.print(" / "); Serial.print(lux); } else { Serial.print("\";so0;sc0,51,128,14;sf0;sa2;sd63,52,\""); if (menu_select ==MENU_ON_OFF) { Serial.print((nvram.state &STATE_ON_OFF) ? "OFF" :"ON"); } else Serial.print(menu[menu_select]); } Serial.println("\";sd"); SerialReadUntilDone(); update_oled =false; } else init_oled =true; } if (update_nvram) { if (SerialCmdNoError(I2C_EEPROM)) { nvram.crc =crc8((uint8_t*)&nvram, sizeof(nvram)-sizeof(uint8_t)); //swSerial.println(nvram.crc, HEX); SerialWriteEEPROM((uint8_t*)&nvram, 0, sizeof(nvram)); update_nvram =false; } } delay(50); } else { digitalWrite(led, HIGH); delay(500); digitalWrite(led, LOW); delay(500); init_board =true; init_oled =true; } wdt_reset();}
Esquemas
Intelligently water your yard or gardenProcesso de manufatura
- Projetando sistemas de agricultura inteligente de código aberto
- A placa do sensor inteligente acelera o desenvolvimento de IA de borda
- Controlador Smart Home de 433 MHz com Sensorflare e RaspberryPi
- Sensor de temperatura Raspberry Pi
- IoT celular:Lixeira inteligente
- Bartender inteligente
- Sensor de emoção / EEG
- Controlador de irrigação Win10 IOT com sensores de umidade
- Sensor ultra-sensível e resiliente para têxteis inteligentes
- Sensor ultrafino para lentes de contato inteligentes