Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

Uma solução de irrigação de plantas urbanas

Componentes e suprimentos

Sensor de umidade do solo
Qualquer sensor de umidade do solo com saída analógica pode ser usado. Dois eletrodos e um divisor de tensão também podem ser usados. ESTES SÃO OPCIONAIS.
× 2
Sensor de chuva
× 1
Jarro de leite
Qualquer recipiente que possa reter água, ser cortado e preso a uma superfície serve. Isso deve ser montado em uma superfície elevada.
× 1
Tubo oco flexível de plástico macio
Qualquer tipo de tubo serve. Usei uma corda de pular com as pontas cortadas, pois é muito flexível e o centro é oco.
× 1
Fios de jumpers (genérico)
Mais ou menos.
× 37
SparkFun Inventor's Kit para Arduino 101
Usei o Arduino 101, servo, placa de ensaio, potenciômetro e LCD.
× 1
Argila de modelagem
× 1
Haste curta de plástico
Ou qualquer haste não flexível. Isso é usado para apoiar o tubo de saída do tanque de água.
× 1
Resistor 330 ohm
× 1

Ferramentas e máquinas necessárias

Tesouras
Chave de fenda Phillips
Fita isolante
e também fita normal.

Aplicativos e serviços online

Nordic Semiconductor nRF Connect SDK
Arduino IDE

Sobre este projeto




Este dispositivo melhora a irrigação de plantas em ambientes urbanos. Alimentado por um Arduino 101, ele usa ferramentas integradas junto com alguns sensores externos para calcular as condições ideais para regar as plantas em seu próprio ambiente e, em seguida, regar a própria planta no tempo calculado.

Baseia-se nos seguintes conceitos:

Gravidade e pressão

Este dispositivo tira sua fonte de água de um reservatório, que fiz usando uma jarra de leite, tubo de plástico, argila para selar o tubo e um servo. Este recipiente é posicionado de forma que, além de ser elevado, possa captar a água da chuva de cima do aparelho.

O jarro é abastecido principalmente por um abastecimento de água doméstico (devido à chuva nem sempre estar disponível), mas é complementado por água da chuva. Quando a água está presente no jarro, a força atrativa da gravidade puxa a água em direção à Terra dentro do jarro. Um orifício é feito na base do jarro para permitir a inserção de um tubo de saída. A força da gravidade, portanto, puxa a água por esse tubo de saída. O servo regula quando a água pode sair totalmente do tubo. Em circunstâncias normais, o braço do servo está na posição vertical, o que evita que a água flua para fora do tubo. Ao regar a planta, no entanto, o braço abaixa 135 graus, permitindo que a água flua para fora do tubo e irrigue as plantas. O braço se levanta novamente quando isso é concluído.

A pressão da água contra a jarra não só auxilia na estabilidade da jarra, mas também na saída de água, permitindo um fluxo contínuo de água durante a irrigação.

Sensor de temperatura TMP36 e o ​​Intel Curie Pattern Matching Engine

Esta combinação de conceitos ajuda a conduzir o cálculo que determina o momento ideal para regar as plantas. O TMP36 é um sensor de temperatura que funciona como um termômetro, mas com saída analógica eletrônica. Essa saída pode ser lida por um dispositivo, como um microcontrolador, e convertida em temperatura. Neste projeto, o dispositivo tenta calcular o tempo ideal para regar as plantas, que é mais próximo de 25 graus Celsius. Faz 30 registros por hora, em intervalos de dois minutos, e ao final de cada período calcula a média de 29 destes (excluindo o primeiro, porque geralmente é impreciso). É aqui que entra o mecanismo de correspondência de padrões.

O Intel Curie PME, ou mecanismo de correspondência de padrões, é uma rede neural artificial embutida no Arduino 101. Suas bibliotecas estão disponíveis no GitHub. Composto por 128 neurônios, é capaz de aprender e classificar dados, salvos em vetores, a partir dos dados existentes, ou vetores classificados em categorias. Quanto mais categorias disponíveis, mais opções de classificação podem ser buscadas pelo PME.

Para este projeto, a PME registra dados de temperatura ao longo de um dia e tenta classificar a condição ótima, 25 graus Celsius, entre esses dados. O resultado passa a ser a hora do dia seguinte para regar a planta.

Os dados são registrados a cada hora, das 8h às 21h. Na primeira vez que isso for feito, os dados serão salvos no Flash serial integrado . Isso permitirá que o dispositivo seja inicializado em um conjunto de dados, mesmo que ele tenha sido desligado. Depois de obter o conjunto de dados, ele tenta classificar as condições ideais. Se for possível, a categoria selecionada passa a ser a hora usada para a próxima rodada. Caso contrário, o dispositivo usará constantes mensais ou a hora do dia de cada mês em que as temperaturas são mais altas. Deve-se observar que essas nem sempre são as melhores temperaturas para regar as plantas , por isso utilizei o PME.

Após o primeiro aprendizado, os dados são apagados e reaprendidos no dia seguinte, com a irrigação da planta no horário escolhido. Este ciclo se repete infinitamente, ou até que o aparelho seja desconectado da rede elétrica, momento em que ao ser ligado novamente usa os parâmetros salvos conforme a hora selecionada e segue em frente.

Intel Curie Real-Time Clock e Bluetooth Low Energy

O Intel Curie RTC, ou relógio em tempo real, é um componente crucial deste dispositivo. O RTC controla quando tudo ocorre no dispositivo. Para este projeto, o RTC é especialmente essencial para manter o controle da hora, usado para regar a planta e quando registrar os dados, e o mês, usado para determinar as constantes de temperatura de pico de backup. No entanto, a data precisa para este RTC precisa ser definida manualmente, em código ou por entrada do usuário. Isso foi resolvido com BLE.

Bluetooth Low Energy é uma versão mais recente do Bluetooth projetada para dispositivos de baixo consumo de energia. Ele opera em um sistema periférico central, onde uma central, ou entrada, grava em periféricos ou saídas. Isso funciona mais como um sistema de quadro de avisos, onde a central coloca os dados em um boletim para todos os periféricos lerem. Nesse caso, usei o nRF Connect da Nordic Semiconductor no meu dispositivo móvel como central e o Arduino 101 como periférico. O dispositivo móvel tem a capacidade de se conectar ao Arduino e enviar dados para ele. Nesse caso, o dispositivo móvel precisa enviar dados quatro vezes, uma para cada um dos campos de entrada obrigatórios.

A entrada de dados no dispositivo móvel é digitada em hexadecimal. Isso é bastante fácil de converter da base 10, mas um conversor online pode ser usado.

Como construir

Construir esta solução de irrigação requer um pouco de conhecimento de circuitos, mas não muito. Também requer alguns componentes não elétricos para terminar. Aqui está a lista de peças completa:

Componentes elétricos
  • Arduino 101
  • placa de ensaio 400 amarras, com + - trilhos
  • Potenciômetro rotativo
  • LCD 16x2
  • resistor de 330 Ohm
  • sensor de temperatura TMP36
  • servo 180 graus, com chifre servo
  • Sensor de chuva e painel de controle
  • Sensor de umidade do solo e placa de controle (opcional, hardware incluído como referência)
  • Uma quantidade considerável de fios de ligação; veja o diagrama de Fritzing

Para funcionar com baterias (pode não durar muito; a configuração que usei):
  • 2 caixas de bateria 4xAA com interruptor liga / desliga e fios elétricos
  • Pilhas recarregáveis ​​8X AA 1,2 V NiMH

Para funcionar com alimentação USB, de uma verruga de parede ou de um laptop:
  • Cabo USB Macho A - Macho B, cujo comprimento depende das suas necessidades

Componentes de hardware não elétricos
  • Jarro de leite
  • Tubo de plástico flexível, com cerca de 20-30 cm de comprimento
  • Argila de modelagem, cola quente ou qualquer coisa que possa ser usada como selante
  • Haste de plástico, para apoiar o braço da tubulação
  • Cesta de artesanato, para segurar o dispositivo
  • Superfície elevada para segurar o jarro, ou seja, um pequeno banco ou uma mesa
  • Uma planta

Ferramentas
  • Fita adesiva, normal e elétrica
  • tesouras
  • Chave de fenda Phillips, para conectar o chifre do servo ao servo

Passos

1. Construa o circuito de acordo com o diagrama de Fritzing abaixo. Observe que os sensores de umidade do solo são opcionais e que o sensor de chuva e o servo podem precisar de fios mais longos para alcançar os locais desejados. Veja a segunda foto abaixo para o arranjo final do circuito.



2. (Pule para a etapa 5 se estiver usando alimentação USB). Insira as baterias nas duas caixas de bateria e amarre o terminal positivo de uma caixa e o terminal negativo da outra.

3. Prenda as caixas com fita isolante. Prenda as caixas de forma que as tampas de ambas sejam colocadas e as caixas de ambas, e a tampa seja removível como uma peça. Deixe os slots abertos para os interruptores de energia.

4. Prenda a tampa dupla da caixa da bateria na parte inferior do Arduino 101 e da placa de ensaio. Isso permitirá que as baterias sejam substituídas facilmente, deslizando-as para fora da parte inferior da placa.

5. Insira o dispositivo na cesta de artesanato e corte duas fendas em um lado do dispositivo. O primeiro slot será para programação (ou alimentação USB se você escolher), e o segundo será uma tomada para os sensores e atuadores não localizados no dispositivo. Sinta-se à vontade para usar fita isolante para prender os fios soltos juntos nesta tomada.

6. Pegue um jarro de leite e corte a parte superior de forma que o jarro tenha uma abertura grande o suficiente para coletar água e uma capacidade grande o suficiente para ser confiável. Recomendo que o corte seja próximo à base do cabo.

7. Faça um pequeno furo na base do jarro, diretamente abaixo da maior parte da abertura no topo do jarro. Insira uma extremidade do tubo de plástico neste orifício. Certifique-se de que o orifício seja pequeno o suficiente para que o tubo permaneça na posição, mas grande o suficiente para não espremer o tubo.

8. Use a argila para selar as áreas superior e inferior ao redor do tubo no buraco. Certifique-se de que a argila não entre no próprio tubo.

9. Usando a argila e fita isolante, prenda o servo o mais baixo possível na base da jarra de leite. Cole o meio do tubo e uma haste de plástico no chifre do servo. Certifique-se de que a haste de plástico também esteja presa à extremidade superior do tubo. Use a imagem abaixo como referência para as etapas 8 a 10.

10. Prenda o jarro na superfície elevada. Use fita adesiva se necessário.

11. Coloque uma planta logo abaixo da saída do tubo quando na posição abaixada. Cole os sensores de umidade no solo se estiver usando-os e coloque o sensor de chuva próximo à planta ao longo do chão. Conecte os sensores e servo no dispositivo, com o dispositivo colocado um pouco mais longe do jarro e da planta.

Programação

Programe o Arduino 101 com o código anexado. Faça upload usando o IDE Arduino e o Curie Core 2.0.2 ou superior (se disponível). Muitos comentários úteis estão incluídos no código.

Operação do dispositivo

Quando o dispositivo é ligado pela primeira vez, ele aguarda a conexão de um dispositivo móvel. Uma vez que um dispositivo é conectado usando nRF Connect, ele irá aguardar a entrada de tempo. Para fazer isso, digite sequencialmente os códigos hexadecimais para a base de 10 horas, minutos, dia e mês em ordem no nRF Connect, conforme mostrado no diagrama abaixo.

Uma entrada de ID, ou qualquer número, deve ser digitada e enviada antes de inserir os tempos.

Após digitar a hora, o 101 irá aguardar o dispositivo móvel se desconectar. Depois disso, ele aguardará até as 8h, seja no dia atual ou no próximo.

Ao chegar às 8h, a placa verificará se há algo salvo no armazenamento da memória flash. Caso contrário, ele passará pelo processo de coleta de 14 horas conforme descrito anteriormente e, em seguida, classificará os dados e determinará o momento ideal, momento em que repetirá o ciclo de coleta. Se algo for armazenado, esses dados serão usados ​​como a constante de hora e os ciclos continuarão normalmente.

Durante os horários em que o conselho rega a planta, a presença de chuva ou excesso de umidade do solo (opcional) impedirá que a planta seja regada. Em seguida, ele irá ignorar a rega durante o dia e aguardar o próximo.

Esta solução foi projetada para tornar a irrigação de plantas urbanas mais simples e otimizada, empregando uma configuração automática para cuidar disso. Também conserva a água da chuva junto com o abastecimento doméstico existente, usando um reservatório, que faz um bom uso da chuva não dirigida às plantas.

Esperançosamente, este projeto fará do nosso mundo em constante mudança um lugar um pouco melhor!

Código

  • Sistema de irrigação Arduino 101
Sistema de irrigação Arduino 101 Arduino
Código para operar o sistema de irrigação Arduino 101. Faça upload usando Curie core 2.0.2 e qualquer IDE 1.8.x ou superior. O CuriePME pode ser encontrado no GitHub.
 / * Este é um esboço para uma solução de irrigação urbana. Ele usa o CuriePME para aprender os dados de temperatura e classificar a condição ideal de irrigação da planta em relação a eles. Em seguida, rega a planta naquele momento e reaprende os dados, alternando infinitamente. Observe que este esboço DEVE SER EXECUTADO ANTES das 8h do dia previsto para iniciar o dispositivo. Fontes de dados:"WeatherSpark.com." Tempo médio em Vancouver, Canadá, o ano todo - Weather Spark. N.p., n.d. Rede. 04 de julho de 2017. . "Just 4 Growers:Global Garden Community." Apenas para produtores. N.p., n.d. Rede. 10 de julho de 2017. . * /// Bibliotecas para uso com este código. Todos eles, exceto CuriePME, podem ser encontrados no ide. CuriePME pode ser baixado do repositório GitHub. # Include "CuriePME.h" #include  #include  #include  #include  #include  #include  // Código de pinagem do servo.Servo waterPipe; // Código de pinagem do LCD.LiquidCrystal lcd (12, 11, 5, 4, 3, 2); // Constantes / variáveis ​​globais. # define o termômetro A3 # definir rainSensor 1 # definir umidade1 A4 # definir umidade2 A1int tm1; int tm2; int tm3; int tm4; int tm5; int tm6; int tm7; int tm8; int tm9; int tm10; int tm11; int tm12; int tm13; int tm14; int tm15; int tm16; int tm17; int tm18; int tm19; int tm20; int tm21; int tm22; int tm23; int tm24; int tm25; int tm26; int tm27; int tm28; int tm29; int tm30; int média; int progav; tensão flutuante; temperatura flutuanteC; int tm; int horaTempo =-1; int horaTempo =-1; intdiaTempo =-1; int mêsTempo =-1; int confirmTime =-1; // serviço BLE data.BLEService plantService ("19B10000-E8F2-537E-4F6C-D104768A1214"); // característica BLE, legível / gravável por central.BLEUnsignedCharCharacteristic timeCha racteristic ("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite); void setup () {// É executado uma vez. waterPipe.attach (9); waterPipe.write (0); pinMode (rainSensor, INPUT); lcd.begin (16, 2); // Comece e limpe o LCD. lcd.clear (); if (! SerialFlash.begin (ONBOARD_FLASH_SPI_PORT, ONBOARD_FLASH_CS_PIN)); lcd.setCursor (0, 0); lcd.print ("Tempo de entrada:BLE"); // Inicialize o serviço BLE com nome, serviço, característica e valor característico. BLE.begin (); BLE.setLocalName ("Arduino 101"); BLE.setAdvertisedService (plantService); plantService.addCharacteristic (timeCharacteristic); BLE.addService (plantService); timeCharacteristic.setValue (0); // 0 até ser escrito por central. BLE.advertise (); lcd.setCursor (0, 1); lcd.print ("Em espera"); // Pronto para conectar.x:BLEDevice central =BLE.central (); if (central) {// Se um dispositivo se conectar à placa. lcd.setCursor (8, 1); lcd.print ("Concluído"); atraso (3000); while (central.connected ()) {// Enquanto o dispositivo ainda está conectado. if (timeCharacteristic.written ()) {// Código que preenche sequencialmente todos os slots de variáveis ​​de tempo após cada byte ser enviado do dispositivo. Os dados são enviados quatro vezes, mais uma para confirmação do link. if (confirmTime ==-1) {confirmTime =timeCharacteristic.value (); } else if (hourTime ==-1) {hourTime =timeCharacteristic.value (); } else if (minuteTime ==-1) {minuteTime =timeCharacteristic.value (); } else if (dayTime ==-1) {dayTime =timeCharacteristic.value (); } else if (monthTime ==-1) {monthTime =timeCharacteristic.value (); lcd.clear (); lcd.setCursor (0, 0); lcd.print ("Hora definida."); lcd.setCursor (0, 1); lcd.print ("Desconecte o dispositivo."); }}}} else {goto x; // Loop de volta se um dispositivo ainda não estiver conectado. } // Defina a hora com as variáveis ​​coletadas. Os segundos e o ano não importam para este sistema. setTime (hourTime, minuteTime, 00, dayTime, monthTime, 2017); // Inicialize o PME. lcd.clear (); CuriePME.begin (); lcd.setCursor (0, 0); lcd.print ("Verificando para salvar."); atraso (3000); const char * filename ="NeurData.dat"; if (check_if_exists (filename) ==true) {restoreNetworkKnowledge (); lcd.setCursor (0, 1); lcd.print ("Encontrado!"); atraso (3000); lcd.clear (); goto z; } else {lcd.setCursor (0, 1); lcd.print ("Não encontrado!"); atraso (3000); lcd.clear (); } / * A parte restante da configuração coleta dados de temperatura ao longo do dia. Ele faz 30 verificações por hora, espaçadas em intervalos de 2 minutos e, no final da hora, tira uma média dos dados da hora, encontrando a média aritmética de todos os dados, exceto para a primeira varredura. Essa média é então colocada no PME e aprendida. Isso se repete das 8h às 21h, momento em que o conjunto de dados completo aprendido pela PME é salvo na memória CurieFlash como padrão para se e quando o dispositivo perder energia ou precisar ser reiniciado. * / lcd.clear (); lcd.setCursor (0, 0); lcd.print ("Aprendizagem"); for (int i =8; i <22; i ++) // Repita 14 vezes, cada uma salvando em uma categoria diferente. {// Colete 30 dados de temperatura, salvos como um int mapeado entre 0 e 255. voltage =analogRead (thermometer) * 3.3; tensão / =1024,0; temperaturaC =(tensão - 0,5) * 100; tm =mapa (temperaturaC, -40, 125, 0, 255); tm1 =restrição (tm, 0, 255); atraso (114000); // Compensar o atraso de verificação acima. voltagem =analogRead (termômetro) * 3,3; tensão / =1024,0; temperaturaC =(tensão - 0,5) * 100; tm =mapa (temperaturaC, -40, 125, 0, 255); tm2 =restrição (tm, 0, 255); atraso (120000); voltagem =analogRead (termômetro) * 3,3; tensão / =1024,0; temperaturaC =(tensão - 0,5) * 100; tm =mapa (temperaturaC, -40, 125, 0, 255); tm3 =restrição (tm, 0, 255); atraso (120000); voltagem =analogRead (termômetro) * 3,3; tensão / =1024,0; temperaturaC =(tensão - 0,5) * 100; tm =mapa (temperaturaC, -40, 125, 0, 255); tm4 =restrição (tm, 0, 255); atraso (120000); voltagem =analogRead (termômetro) * 3,3; tensão / =1024,0; temperaturaC =(tensão - 0,5) * 100; tm =mapa (temperaturaC, -40, 125, 0, 255); tm5 =restrição (tm, 0, 255); atraso (120000); voltagem =analogRead (termômetro) * 3,3; tensão / =1024,0; temperaturaC =(tensão - 0,5) * 100; tm =mapa (temperaturaC, -40, 125, 0, 255); tm6 =restrição (tm, 0, 255); atraso (120000); voltagem =analogRead (termômetro) * 3,3; tensão / =1024,0; temperaturaC =(tensão - 0,5) * 100; tm =mapa (temperaturaC, -40, 125, 0, 255); tm7 =restrição (tm, 0, 255); atraso (120000); voltagem =analogRead (termômetro) * 3,3; tensão / =1024,0; temperaturaC =(tensão - 0,5) * 100; tm =mapa (temperaturaC, -40, 125, 0, 255); tm8 =restrição (tm, 0, 255); atraso (120000); voltagem =analogRead (termômetro) * 3,3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm9 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm10 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm11 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm12 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm13 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm14 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm15 =constrain(tm, 0, 255); // During the first learning period, plant watering will be done at the peak of the temperatures for that month. if ((month() ==1 || month() ==2 || month() ==11 || month() ==12) &&hour() ==12) { lcd.clear(); lcd.setCursor (0, 0); lcd.print("Running..."); // Water the plant if it is not raining and soil moisture is low enough. int readRain =digitalRead(rainSensor); if (readRain ==HIGH) { lcd.setCursor(0, 1); lcd.print("Raining right now."); goto a2; } // Uncomment to use moisture sensors. //else if (analogRead(humidity1)> 400 || analogRead(humidity2)> 400) // Adjust these to match your soil. //{ //lcd.setCursor(0, 1); //lcd.print("Soil too moist."); //goto a2; //} else { waterPipe.write(135); delay(7000); // Water for 7 seconds. waterPipe.write(0); } lcd.setCursor (0, 1); lcd.print("Done");a2:delay(3000); lcd.clear (); lcd.setCursor (0, 0); lcd.print("Learning"); } else if ((month() ==3 || month() ==4 || month() ==10) &&hour() ==14) { lcd.clear(); lcd.setCursor (0, 0); lcd.print("Running..."); lcd.clear (); lcd.setCursor (0, 0); lcd.print("Running..."); // Water the plant if it is not raining and soil moisture is low enough. int readRain =digitalRead(rainSensor); if (readRain ==HIGH) { lcd.setCursor(0, 1); lcd.print("Raining right now."); goto a31; } // Uncomment to use moisture sensors. //else if (analogRead(humidity1)> 400 || analogRead(humidity2)> 400) // Adjust these to match your soil. //{ //lcd.setCursor(0, 1); //lcd.print("Soil too moist."); //goto a31; //} else { waterPipe.write(135); delay(7000); // Water for 7 seconds. waterPipe.write(0); } lcd.setCursor (0, 1); lcd.print("Done");a31:delay(3000); lcd.clear (); lcd.setCursor (0, 0); lcd.print("Learning"); lcd.clear (); lcd.setCursor (0, 0); lcd.print("Learning"); } else if ((month() ==5 || month() ==6 || month() ==9) &&hour() ==15) { lcd.clear(); lcd.setCursor (0, 0); lcd.print("Running..."); lcd.clear (); lcd.setCursor (0, 0); lcd.print("Running..."); // Water the plant if it is not raining and soil moisture is low enough. int readRain =digitalRead(rainSensor); if (readRain ==HIGH) { lcd.setCursor(0, 1); lcd.print("Raining right now."); goto a3; } // Uncomment to use moisture sensors. //else if (analogRead(humidity1)> 400 || analogRead(humidity2)> 400) // Adjust these to match your soil. //{ //lcd.setCursor(0, 1); //lcd.print("Soil too moist."); //goto a3; //} else { waterPipe.write(135); delay(7000); // Water for 7 seconds. waterPipe.write(0); } lcd.setCursor (0, 1); lcd.print("Done");a3:delay(3000); lcd.clear (); lcd.setCursor (0, 0); lcd.print("Learning"); } else if ((month() ==7 || month() ==8) &&hour() ==16) { lcd.clear(); lcd.setCursor (0, 0); lcd.print("Running..."); lcd.clear (); lcd.setCursor (0, 0); lcd.print("Running..."); // Water the plant if it is not raining and soil moisture is low enough. int readRain =digitalRead(rainSensor); if (readRain ==HIGH) { lcd.setCursor(0, 1); lcd.print("Raining right now."); goto a4; } // Uncomment to use moisture sensors. //else if (analogRead(humidity1)> 400 || analogRead(humidity2)> 400) // Adjust these to match your soil. //{ //lcd.setCursor(0, 1); //lcd.print("Soil too moist."); //goto a4; //} else { waterPipe.write(135); delay(7000); // Water for 7 seconds. waterPipe.write(0); } lcd.setCursor (0, 1); lcd.print("Done");a4:delay(3000); lcd.clear (); lcd.setCursor (0, 0); lcd.print("Learning"); } delay(110000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm16 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm17 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm18 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm19 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm20 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm21 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm22 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm23 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm24 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm25 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm26 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm27 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm28 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm29 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm30 =constrain(tm, 0, 255); atraso (120000); // Reconvert the data to the temperature sensor's specifications. tm1 =map(tm1, 0, 255, -40, 125); tm1 =constrain(tm1, -40, 125); tm2 =map(tm2, 0, 255, -40, 125); tm2 =constrain(tm2, -40, 125); tm3 =map(tm3, 0, 255, -40, 125); tm3 =constrain(tm3, -40, 125); tm4 =map(tm4, 0, 255, -40, 125); tm4 =constrain(tm4, -40, 125); tm5 =map(tm5, 0, 255, -40, 125); tm5 =constrain(tm5, -40, 125); tm6 =map(tm6, 0, 255, -40, 125); tm6 =constrain(tm6, -40, 125); tm7 =map(tm7, 0, 255, -40, 125); tm7 =constrain(tm7, -40, 125); tm8 =map(tm8, 0, 255, -40, 125); tm8 =constrain(tm8, -40, 125); tm9 =map(tm9, 0, 255, -40, 125); tm9 =constrain(tm9, -40, 125); tm10 =map(tm10, 0, 255, -40, 125); tm10 =constrain(tm10, -40, 125); tm11 =map(tm11, 0, 255, -40, 125); tm11 =constrain(tm11, -40, 125); tm12 =map(tm12, 0, 255, -40, 125); tm12 =constrain(tm12, -40, 125); tm13 =map(tm13, 0, 255, -40, 125); tm13 =constrain(tm13, -40, 125); tm14 =map(tm14, 0, 255, -40, 125); tm14 =constrain(tm14, -40, 125); tm15 =map(tm15, 0, 255, -40, 125); tm15 =constrain(tm15, -40, 125); tm16 =map(tm16, 0, 255, -40, 125); tm16 =constrain(tm16, -40, 125); tm17 =map(tm17, 0, 255, -40, 125); tm17 =constrain(tm17, -40, 125); tm18 =map(tm18, 0, 255, -40, 125); tm18 =constrain(tm18, -40, 125); tm19 =map(tm19, 0, 255, -40, 125); tm19 =constrain(tm19, -40, 125); tm20 =map(tm20, 0, 255, -40, 125); tm20 =constrain(tm20, -40, 125); tm21 =map(tm21, 0, 255, -40, 125); tm21 =constrain(tm21, -40, 125); tm22 =map(tm22, 0, 255, -40, 125); tm22 =constrain(tm22, -40, 125); tm23 =map(tm23, 0, 255, -40, 125); tm23 =constrain(tm23, -40, 125); tm24 =map(tm24, 0, 255, -40, 125); tm24 =constrain(tm24, -40, 125); tm25 =map(tm25, 0, 255, -40, 125); tm25 =constrain(tm25, -40, 125); tm26 =map(tm26, 0, 255, -40, 125); tm26 =constrain(tm26, -40, 125); tm27 =map(tm27, 0, 255, -40, 125); tm27 =constrain(tm27, -40, 125); tm28 =map(tm28, 0, 255, -40, 125); tm28 =constrain(tm28, -40, 125); tm29 =map(tm29, 0, 255, -40, 125); tm29 =constrain(tm29, -40, 125); tm30 =map(tm30, 0, 255, -40, 125); tm30 =constrain(tm30, -40, 125); // Find the arithmetic mean and commit it to memory. average =(tm2 + tm3 + tm4 + tm5 + tm6 + tm7 + tm8 + tm9 + tm10 + tm11 + tm12 + tm13 + tm14 + tm15 + tm16 + tm17 + tm18 + tm19 + tm20 + tm21 + tm22 + tm23 + tm24 + tm25 + tm26 + tm27 + tm28 + tm29 + tm30) / 29; commitSample(i, average); } saveNetworkKnowledge(); // Save this new data to flash memory.z:delay(1);}void commitSample (int category, uint8_t s1){ // Commit to memory a single vector (the average), along with the category, which represents the hour of that data. uint8_t vector[1]; vector[0] =s1; CuriePME.learn(vector, 1, category);}void loop() { // Infinitely repeats. /* This code attempts to classify the optimum temperature for watering plants, 25 Celsius, among the data learned by the PME. If it can classify the data, the returned category becomes the hour at which the plant will be watered. The data is then erased and relearned, which infinitely repeats. IF IT CANNOT CLASSIFY THE DATA, it will take the monthly defaults from earlier in the sketch. */ uint8_t vector[1]; vector[0] =25; int answer =CuriePME.classify(vector, 1 ); if (answer ==CuriePME.noMatch) { lcd.clear(); lcd.setCursor (0, 0); lcd.print("NO MATCHES!"); if (month() ==1 || month() ==2 || month() ==11 || month() ==12) { answer =12; } else if (month() ==3 || month() ==4 || month() ==10) { answer =14; } else if (month() ==5 || month() ==6 || month() ==9) { answer =15; } else if (month() ==7 || month() ==8) { answer =16; }} else {lcd.clear (); lcd.setCursor (0, 0); lcd.print("Category:"); lcd.setCursor (0, 1); lcd.print(answer); } delay(3000); lcd.clear (); lcd.setCursor (0, 0); lcd.print("Optimization Done"); atraso (3000); CuriePME.forget(); // Erase and relearn. This does not erase the flash memory. lcd.clear (); lcd.setCursor (0, 0); lcd.print("Waiting"); while (hour() !=8); lcd.clear (); lcd.setCursor (0, 0); lcd.print("Learning"); // Learn the data again. for (int i =8; i <22; i++) { voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm1 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm2 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm3 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm4 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm5 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm6 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm7 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm8 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm9 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm10 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm11 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm12 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm13 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm14 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm15 =constrain(tm, 0, 255); // The time in the day at which to water the plant, as determined by the PME. if (hour() ==answer) { lcd.clear(); lcd.setCursor (0, 0); lcd.print("Running..."); // Water the plant if it is not raining and soil moisture is low enough. int readRain =digitalRead(rainSensor); if (readRain ==HIGH) { lcd.setCursor(0, 1); lcd.print("Raining right now."); goto a5; } // Uncomment to use moisture sensors. //else if (analogRead(humidity1)> 400 || analogRead(humidity2)> 400) // Adjust these to match your soil. //{ // lcd.setCursor(0, 1); // lcd.print("Soil too moist."); // goto a5; //} else { waterPipe.write(135); delay(7000); // Water for 7 seconds. waterPipe.write(0); } lcd.setCursor (0, 1); lcd.print("Done");a5:delay(3000); lcd.clear (); lcd.setCursor (0, 0); lcd.print("Learning"); } delay(110000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm16 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm17 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm18 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm19 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm20 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm21 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm22 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm23 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm24 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm25 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm26 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm27 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm28 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm29 =constrain(tm, 0, 255); atraso (120000); voltage =analogRead(thermometer) * 3.3; voltage /=1024.0; temperatureC =(voltage - 0.5) * 100; tm =map(temperatureC, -40, 125, 0, 255); tm30 =constrain(tm, 0, 255); atraso (120000); tm1 =map(tm1, 0, 255, -40, 125); tm1 =constrain(tm1, -40, 125); tm2 =map(tm2, 0, 255, -40, 125); tm2 =constrain(tm2, -40, 125); tm3 =map(tm3, 0, 255, -40, 125); tm3 =constrain(tm3, -40, 125); tm4 =map(tm4, 0, 255, -40, 125); tm4 =constrain(tm4, -40, 125); tm5 =map(tm5, 0, 255, -40, 125); tm5 =constrain(tm5, -40, 125); tm6 =map(tm6, 0, 255, -40, 125); tm6 =constrain(tm6, -40, 125); tm7 =map(tm7, 0, 255, -40, 125); tm7 =constrain(tm7, -40, 125); tm8 =map(tm8, 0, 255, -40, 125); tm8 =constrain(tm8, -40, 125); tm9 =map(tm9, 0, 255, -40, 125); tm9 =constrain(tm9, -40, 125); tm10 =map(tm10, 0, 255, -40, 125); tm10 =constrain(tm10, -40, 125); tm11 =map(tm11, 0, 255, -40, 125); tm11 =constrain(tm11, -40, 125); tm12 =map(tm12, 0, 255, -40, 125); tm12 =constrain(tm12, -40, 125); tm13 =map(tm13, 0, 255, -40, 125); tm13 =constrain(tm13, -40, 125); tm14 =map(tm14, 0, 255, -40, 125); tm14 =constrain(tm14, -40, 125); tm15 =map(tm15, 0, 255, -40, 125); tm15 =constrain(tm15, -40, 125); tm16 =map(tm16, 0, 255, -40, 125); tm16 =constrain(tm16, -40, 125); tm17 =map(tm17, 0, 255, -40, 125); tm17 =constrain(tm17, -40, 125); tm18 =map(tm18, 0, 255, -40, 125); tm18 =constrain(tm18, -40, 125); tm19 =map(tm19, 0, 255, -40, 125); tm19 =constrain(tm19, -40, 125); tm20 =map(tm20, 0, 255, -40, 125); tm20 =constrain(tm20, -40, 125); tm21 =map(tm21, 0, 255, -40, 125); tm21 =constrain(tm21, -40, 125); tm22 =map(tm22, 0, 255, -40, 125); tm22 =constrain(tm22, -40, 125); tm23 =map(tm23, 0, 255, -40, 125); tm23 =constrain(tm23, -40, 125); tm24 =map(tm24, 0, 255, -40, 125); tm24 =constrain(tm24, -40, 125); tm25 =map(tm25, 0, 255, -40, 125); tm25 =constrain(tm25, -40, 125); tm26 =map(tm26, 0, 255, -40, 125); tm26 =constrain(tm26, -40, 125); tm27 =map(tm27, 0, 255, -40, 125); tm27 =constrain(tm27, -40, 125); tm28 =map(tm28, 0, 255, -40, 125); tm28 =constrain(tm28, -40, 125); tm29 =map(tm29, 0, 255, -40, 125); tm29 =constrain(tm29, -40, 125); tm30 =map(tm30, 0, 255, -40, 125); tm30 =constrain(tm30, -40, 125); average =(tm2 + tm3 + tm4 + tm5 + tm6 + tm7 + tm8 + tm9 + tm10 + tm11 + tm12 + tm13 + tm14 + tm15 + tm16 + tm17 + tm18 + tm19 + tm20 + tm21 + tm22 + tm23 + tm24 + tm25 + tm26 + tm27 + tm28 + tm29 + tm30) / 29; progav =(tm30 - tm2) / 2; commitSample(i, average); }}/* A quick note on the flash memory data:The data will only ever be saved once; that is, it cannot be changed with this code. As a result, if the device loses power, IT WILL DEFAULT TO THE SETTINGS OF THE FIRST TIME IT WAS USED WHEN IT IS REACTIVATED, even if the monthly averages have changed. Keeping the device on an extra day will allow it to software obtain new averages, but the flash memory will stay the same. To erase flash completely, upload "EraseEverything" from "CurieSerialFlash" in the IDE. Then reupload this sketch to save new averages to the flash memory.*/void saveNetworkKnowledge() // Code for saving to flash memory....This file has been truncated, please download it to see its full contents.

Esquemas

Fritzing diagram for the circuit. Note that batteries would be attached on the left. The soil moisture sensors are optional. rainpoweredsmartirrigationsystem_OHtd4bVfb3.fzz

Processo de manufatura

  1. Titanium
  2. Castanholas
  3. Cole
  4. Tópico
  5. Acetileno
  6. Amianto
  7. Dados
  8. Lata
  9. Raspberry Pi Automated Plant Watering with Website
  10. Siemens, Bentley lança solução para acelerar a digitalização da fábrica