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

Sistema Herb Box Eco

Componentes e suprimentos

Amazon Alexa Echo Dot
× 1
Arduino UNO
× 1
Espressif ESP8266 ESP-01
× 1
Arduino Proto Shield
× 1
Arduino 4 Relays Shield
× 1
Aqua Pump
× 2
Lâmpada para cultivo de plantas
× 1
Adaptador de alimentação 220 V DC
× 1
Adaptador de alimentação 12 V DC
× 1
USB Power Plug + Cable
× 1
Mangueira de ar
× 1
Fios de jumpers (genérico)
× 1

Aplicativos e serviços online

Arduino IDE
Amazon Alexa Skills Kit
Amazon Web Services AWS Lambda
Servidor da Web php

Sobre este projeto


Como minhas plantas sempre sofrem com o excesso ou menos água e gosto de colocar muitas ervas em meus pratos, decidi criar um sistema de irrigação personalizado. A caixa para minhas ervas deve ser configurável e funcionar automática ou manualmente. Portanto, existe uma interface para um site que permite uma configuração e mostra a umidade em um gráfico bonito. A última etapa foi a integração do controle de voz para solicitar umidade ao Amazon Alexa, ligar / desligar uma lâmpada de cultivo de plantas e iniciar a irrigação, caso a automação esteja desativada. Clique aqui para encontrar o resultado.

Comecei com a parte técnica do projeto e comprei um Arduino. Após alguns tutoriais, fiquei firme com o software e controlando o Arduino. Encomendei um controlador de wi-fi, alguns sensores de umidade, bombas, uma lâmpada de cultivo de plantas e hardware adicional necessário (proteção de relais para separar os circuitos da lâmpada e as bombas do Arduino, alguns fios e madeira de faia para a estrutura). O código Arduino do resultado é fornecido neste tutorial, além de algumas informações de como usar os componentes em seus projetos. O código do site / api não é fornecido (a menos que a demanda seja muito alta;)).





Etapa um:sensor de umidade


O primeiro marco foi ler a umidade com meu Arduino. O sensor de umidade YL-69 foi fácil de conectar ao Arduino. Você precisa conectar o pino VCC a um pino GPIO (no meu exemplo pino 06), aterrado ao aterramento e o A0 a um pino analógico (no meu exemplo pino A1) do Arduino.

Tutorial:Sensor de Umidade do Solo
  byte vccPin =6; byte dataPin =A1; configuração vazia () {pinMode (vccPin, SAÍDA); digitalWrite (vccPin, LOW); Serial.begin (9600); while (! Serial);} int readHumidity () {digitalWrite (vccPin, HIGH); atraso (500); // você precisa testar quanto tempo você pré-energiza antes da medição int value =analogRead (dataPin); digitalWrite (vccPin, LOW); retornar 1023 - valor;} void loop () {Serial.print ("HumidityLevel (0-1023):"); Serial.println (readHumidity ()); atraso (10000);}  





Etapa dois:relé para bombas e lâmpada


O próximo objetivo era instalar uma blindagem de relé (4 relés) para separar os circuitos da lâmpada, bombas e Arduino. O Arduino funciona com 5V, as bombas usam 12V e a lâmpada de crescimento da planta 230V. A blindagem precisa ser conectada aos pinos de 5 V e aterramento no Arduino. Cada relé precisa ainda de um pino GPIO de sua escolha para ligar e desligar. Por último, você pode usar um jumper para VCC JC para VCC no escudo, ou usar uma bateria extra (o que seria melhor, mas não tenho nenhuma bateria dentro do meu projeto, ainda).

É importante entender que meu escudo muda "On" com "LOW" no pino. Assim que meu pin é definido como OUTPUT, ele muda automaticamente para ativo. No código, você deve sempre alternar para INPUT e LOW, se quiser que o relé esteja desligado. Por padrão, os pinos do Arduino são INPUT e LOW.

Tutorial:Relay Shield

Informação:Por que relé OUTPUT + LOW =Active?
  byte pump1 =11; byte pump2 =10; configuração vazia () {Serial.begin (9600); while (! Serial); pinMode (pump1, OUTPUT); // variante baixo / alto digitalWrite (pump2, LOW); // entrada / saída variante} void loop () {digitalWrite (pump1, HIGH); // pump1 desativado pinMode (pump2, INPUT); // pump2 desativado delay (1000); digitalWrite (bomba1, BAIXA); // pump1 ativado pinMode (pump2, OUTPUT); // retardo ativado da bomba2 (1000);}  





Etapa três:WiFi com ESP-01


Conectar o espressif ESP8266 ESP-01 ao Arduino para WiFi foi a parte mais difícil. Levei horas para colocar o wi-fi em execução no meu script.

O ESP está conectado a:VCC =3,3 V, GND =GND, CH_PD =3,3 V, TX =Pino 02, RX =Pino 03. Para uso produtivo, você deve usar pelo menos um conversor de nível de 5 V a 3,3 V para o pino 02 e pino 03 também. No meu caso, funcionou bem.

Semelhante ao Arduino, o ESP-01 é outro microcontrolador. Se você deseja que os dois controladores se comuniquem, você deve usar a comunicação serial. O Arduino UNO usa por padrão os pinos 01 e 02 para RX e TX. Mas eles também são usados ​​para depuração de USB e, portanto, sugere-se incluir SoftwareSerial.h e definir pinos personalizados.
  #include  SoftwareSerial espSerial (3,2); // RX, configuração de TXvoid () {Serial.begin (9600); espSerial.begin (115200); // mudar para 9600 após AT + UART_DEF =9600,8,1,0,0 while (! Serial);} void loop () {if (espSerial.available ()) {Serial.write (espSerial.read ()); } if (Serial.available ()) {espSerial.write (Serial.read ()); }}  

Executando o script acima, você pode inserir comandos AT no monitor serial e ver os resultados. A comunicação serial está sujeita a falhas, portanto, diminuí a taxa de transmissão de comunicação usada pelo ESP de 115200 para 9600.

Tutorial:ESP8266 + Arduino | Tutorial:Geral ESP8266 (alemão)
  • Uma classe auxiliar útil (mas usou muita memória):Biblioteca:WiFiEsp
  • Ferramenta de verificação de memória:Biblioteca:MemoryFree

O script usa HTTP 1.0, porque com HTTP 1.1 os bytes fazem parte da resposta. É importante atentar para as quebras de linha para o comando a ser enviado após AT + CIPSEND. Se eles estiverem errados, você receberá um erro de envio de bytes.
  #include  SoftwareSerial espSerial (3,2); // RX, TXconst char * ssid =""; const char * pass =""; void setup () {Serial.begin (9600); espSerial.begin (9600); while (! Serial); while (! connectToWiFi ()); // solicitar o site e imprimir o resultado if (httpRequest ("my.server.com", "/site/subsite/index.php")) {while (espSerial.available ()) {Serial.write (espSerial.read () ); }}} void loop () {// executar continuamente if (espSerial.available ()) {Serial.write (espSerial.read ()); } if (Serial.available ()) {espSerial.write (Serial.read ()); }} bool connectToWiFi () {delay (2000;) espSerial.setTimeout (3000); while (espSerial.available ()) Serial.write (espSerial.read ()); Serial.println (F ("[ESP] Conectando ao WiFi")); espSerial.println (F ("AT + CIPSTATUS =2")); if (! espSerial.find ("OK")) {espSerial.setTimeout (10000); Serial.println (F ("[ESP] Módulo de reinicialização")); espSerial.println (F ("AT + RST")); if (! espSerial.find ("pronto")) {Serial.println (F ("[ESP] Reinicialização falhou")); retorna falso; } Serial.println (F ("[ESP] Definir CWMode")); espSerial.println (F ("AT + CWMODE =1")); if (! espSerial.find ("OK")) {Serial.println (F ("Modo [ESP] falhou")); retorna falso; } Serial.println (F ("[ESP] Conectar ao roteador")); espSerial.print (F ("AT + CWJAP =\" ")); espSerial.print (ssid); espSerial.print (F (" \ ", \" ")); espSerial.print (passagem); espSerial.println ("\" "); if (! espSerial.find ("OK")) {Serial.println (F ("[ESP] conexão WiFi falhou")); retorna falso; }} espSerial.setTimeout (3000); Serial.println (F ("[ESP] WiFi está conectado")); return true;} bool httpRequest (String server, String site) {String cmd =""; cmd + ="GET" + site + "HTTP / 1.0 \ r \ n"; cmd + ="Host:" + servidor + "\ r \ n"; cmd + ="Conexão:fechar"; int cmdLength =cmd.length () + 4; // Serial.println (cmd); espSerial.print (F ("AT + CIPSTART =\" TCP \ ", \" ")); espSerial.print (servidor); espSerial.println (F (" \ ", 80")); if (! espSerial.find ("OK")) {Serial.println (F ("[ESP] Erro de conexão TCP")); retorna falso; } espSerial.print (F ("AT + CIPSEND =")); espSerial.println (cmdLength); if (! espSerial.find (findGT)) {Serial.println (F ("[ESP] Send State Error")); retorna falso; } espSerial.print (F ("GET")); espSerial.print (site); espSerial.print (F ("HTTP / 1.0 \ r \ n")); espSerial.print (F ("Host:")); espSerial.print (servidor); espSerial.print (F ("\ r \ n")); espSerial.print (F ("Conexão:fechar \ r \ n")); espSerial.println (); if (! espSerial.find (":")) {Serial.println (F ("Bytes não enviados")); espSerial.print (F ("AT + CIPCLOSE")); retorna falso; } status de caractere [32] ={0}; espSerial.readBytesUntil ('\ r', status, sizeof (status)); if (strcmp (status, "HTTP / 1.1 200 OK")! =0) {Serial.print (F ("[ESP] Resposta inesperada:")); Serial.println (status); retorna falso; } if (! espSerial.find ("\ r \ n \ r \ n")) {Serial.println (F ("[ESP] Resposta inválida")); retorna falso; } // Ignorar cabeçalhos HTTP // if (! EspSerial.find (\ r \ n)) {Serial.println (F ("[ESP] Bytes não encontrados")); Retorna; } // pula bytes (para http 1.1) retorna verdadeiro; i}  





Etapa quatro:a caixa de madeira


A estrutura foi planejada para armazenar todos os eletrônicos e três potes de ervas do supermercado. Medi o tamanho de todos os componentes e estruturei as posições. Quatro sensores de umidade, duas bombas, a blindagem do Arduino +, uma blindagem do relé 4x e um plugue USB e alguns fios precisam caber na caixa. Foi feito de madeira de faia, para torná-lo resistente e últimos gotas de água sem esmalte adicional.

Os círculos foram serrados com serra de gabarito em uma mesa de serra de gabarito de fabricação própria. As montagens de plantas são coladas dentro dos círculos com cola quente. As laterais da caixa são coladas com cola de madeira (D3 para resistência à água). Além da eletrônica, não usei parafusos ou pregos ao lado da fixação do painel inferior.

Coloquei todos os circuitos, fios e tubos de água dentro da caixa, tirei os sensores e os tubos do tanque de água adicional. Antes de fechar a caixa, coloquei pires para evitar que a água se afogasse dentro da caixa para proteger o eletrônico.





Etapa cinco:API do site


A API e o site são baseados em jQuery, Bootstrap, X-editable (para formulários Ajax embutidos) e Chart.js (para gráfico de umidade), codificados em php. No site, você pode definir as configurações para o Arduino (por exemplo, pinos do sensor, intervalo de verificação de umidade, bombas por planta, pinos VCC da bomba, pino VCC de luz) e encontrar a umidade + gráfico atual.

A configuração é fornecida por JSON para o Arduino. Depois de iniciar e em um intervalo frequente, a caixa de ervas verifica se há novas configurações. Para analisar o JSON com o Arduino, usei a biblioteca ArduinoJson. Para o intervalo de votação, usei StensTimer.

Biblioteca:ArduinoJson | Biblioteca:StensTimer





Etapa seis:Integração Alexa


O site fornece uma API para comunicação Alexa. Ele serve como um hub para receber o pedido JSON de Alexa e o traduz em um JSON personalizado usado pelo Arduino (por exemplo, lâmpada acesa, irrigar planta 1, ...). O Arduino pesquisa novas ações e as executa.

Como as solicitações de voz são mais do que apenas liga / desliga, implementei uma habilidade Alexa e nenhuma casa inteligente Alexa. O AWS Lampda encaminha a solicitação JSON para minha API, que analisa as intenções.
  var https =require ('https'); exports.handler =(evento, contexto, retorno de chamada) => {var postData =JSON.stringify (evento); var options ={host:'', caminho:'', porta:443, método:'POST', cabeçalhos:{'Content-Type':'application / json' , 'Content-Length':postData.length,}}; // configurar a solicitação var postRequest =https.request (options, function (res) {res.setEncoding ('utf8'); res.on ('data', function (chunk) {console.log ('Response:' + chunk); // console.log (chunk); callback (null, JSON.parse (chunk));});}); // poste os dados postRequest.write (postData); postRequest.end ();};  

Um trecho das intenções que usei com minha habilidade:
  • ReadHumidityIntent Como estão minhas plantas
  • ReadHumidityIntent Como está meu {plantName}
  • IrrigatePlantIntent Irrigar minhas plantas
  • IrrigatePlantIntent Irrigar meu {plantName} por {durationSeconds} segundos
  • SwitchIntent Troque a lâmpada {switchState}
  • ReadIrrigateIntent Quais plantas precisam de água
  • ReadLastIrrigationIntent Quando foi a última irrigação do meu {plantName}

Por último, mas não menos importante, adicionei suporte local para uso em alemão e inglês.





O resultado


Como resultado, eu tenho uma caixa de madeira para colocar potes de ervas de supermercado, pego tubos de água e sensores de umidade no solo e os tubos em um tanque de água externo. Com a integração Alexa, posso dizer as seguintes frases:
  • " Alexa, pergunte à caixa de ervas como estão minhas plantas "- Resposta:" A planta 1 está bem, a planta 2 está seca, ... "
  • " Alexa, diga à caixa de ervas para irrigar meu manjericão por 5 segundos "- Resposta:" Irrigando manjericão por 5 segundos "
  • " Alexa, pergunte à caixa de ervas quais plantas precisam de irrigação "- Resposta:" Planta 1 está seca, Planta 3 está seca, ... "
  • " Alexa, pergunte à caixa de ervas quando foi a última irrigação de meu manjericão "- Resposta:" A última irrigação de manjericão foi há 36h "
  • " Alexa, diga à caixa de ervas para ligar a lâmpada "- Resposta:" Lâmpada de cultivo de plantas ligada "

Pedindo a Alexa a umidade da minha planta e irrigando-a depois (alemão):

Pedindo a Alexa para ligar a lâmpada de cultivo de plantas:

GIFs mostrando o resultado sem os vídeos:






Recursos planejados


Os seguintes recursos ainda não foram implementados, mas planejados para o futuro:
  • Modo de economia de energia para o código-fonte do Arduino
  • Adicionar Nanos Arduino externos com comunicação sem fio (2,4 GHz) para medição de umidade de outras plantas da casa (a caixa é o hub para WiFi) - usando apenas baterias
  • Estenda a API para várias instâncias da caixa de ervas, para amigos (e quem quer que seja, se você estiver interessado ?!)
  • Adicione um botão para irrigar e trocar a lâmpada na caixa sem site ou Alexa
  • Imagens Alexa (cartão em resposta de habilidade)





Atualização de 23/03/2018


Eu adicionei dois novos intents. Um deles é importante para o recurso planejado de Adruino Nanos externos que apenas registram a umidade.
  • Quais plantas estão secas
  • Quando foi a última irrigação

Código

  • EcoActionBuffer.h
  • EcoActionBuffer.cpp
  • Plant.cpp
  • Plant.h
  • WhiteWalnut.ino
  • WhiteWalnutApi.cpp
  • WhiteWalnutApi.h
EcoActionBuffer.h Arduino
 #ifndef ECOACTIONBUFFER_H # define ECOACTIONBUFFER_H # include "Arduino.h" #include "StensTimer.h" struct EcoActionBuffer:public IStensTimerListener {long entryNo; ação interna; pin int; longa duração; void timerCallback (Timer * timer); void switchPin (int pin, valor bool); void readStack (); processo vazio (); void toSerial (); void reset ();}; # endif 
EcoActionBuffer.cpp Arduino
 #include "EcoActionBuffer.h" #include "StensTimer.h" #include "WhiteWalnutApi.h" #define ACTION_ECOACTION_READ 1 # define ACTION_ECOACTION_HIGH 2 # define ACTION_ECOACTION_LOW 3void EcoActionBuffer {readStack) (reset) (); WhiteWalnutApi ::receiveActionFromStack (* this); if (entradaNão! =0) {processo (); // WhiteWalnutApi ::updateActionOnStack (* this); // desativado para desempenho}} void EcoActionBuffer ::process () {toSerial (); pinMode (pin, OUTPUT); digitalWrite (pin, HIGH); switch (ação) {case ACTION_ECOACTION_HIGH:switchPin (pin, true); pausa; case ACTION_ECOACTION_LOW:switchPin (pin, false); pausa; } if (duration! =0) {StensTimer ::getInstance () -> setTimer (this, -pin, duration); }} void EcoActionBuffer ::timerCallback (Timer * timer) {switch (timer-> getAction ()) {case ACTION_ECOACTION_READ:readStack (); pausa; } if (timer-> getAction () <0) {switchPin (abs (timer-> getAction ()), false); }} void EcoActionBuffer ::switchPin (int pin, valor bool) {switch (value) {case true:digitalWrite (pin, LOW); pausa; caso falso:digitalWrite (pin, HIGH); pausa; } WhiteWalnutApi ::switchPin (pin, value);} void EcoActionBuffer ::reset () {entryNo =0; ação =0; pin =0; duração =0;} void EcoActionBuffer ::toSerial () {Serial.print (entryNo); Serial.print (F ("- Ação:")); Serial.print (ação); Serial.print (F (", Pin:")); Serial.print (pin); Serial.print (F (", Duração:")); Serial.print (duração); Serial.println ();} 
Plant.cpp Arduino
 #include "Plant.h" #include "StensTimer.h" #include "WhiteWalnutApi.h" #define ACTION_PLANT_CHECKHUMIDITY 2 # define PIN_HUMIDITY_VCC 12void Plant ::checkHumidity () {if (umidadeDataPin! =0) {Serial.print (código); Serial.print (F ("- Verificar umidade ...")); digitalWrite (PIN_HUMIDITY_VCC, HIGH); atraso (200); // TODO int umidade =1023 - analogRead (umidadeDataPin); digitalWrite (PIN_HUMIDITY_VCC, LOW); Serial.println (umidade); WhiteWalnutApi ::sendHumidity (* this, umidade); if (umidadeCheckInterval ==0) umidadeCheckInterval =60000; StensTimer ::getInstance () -> setTimer (isso, ACTION_PLANT_CHECKHUMIDITY, umidadeCheckInterval); } else StensTimer ::getInstance () -> setTimer (this, ACTION_PLANT_CHECKHUMIDITY, 60000);} void Plant ::updateApi () {WhiteWalnutApi ::updatePlant (* this); // WhiteWalnutApi ::sendHeartbeat (* this); // desativado para desempenho pinMode (PIN_HUMIDITY_VCC, OUTPUT); toSerial ();} void Plant ::timerCallback (Timer * timer) {switch (timer-> getAction ()) {case ACTION_PLANT_CHECKHUMIDITY:checkHumidity (); pausa; }} void Plant ::toSerial () {Serial.print (code); Serial.print (F ("- DataPin:")); Serial.print (umidadeDataPin); Serial.print (F (", Intervalo:")); Serial.print (umidadeCheckInterval); Serial.println ();} 
Plant.h Arduino
 #ifndef PLANT_H # define PLANT_H # include "Arduino.h" #include "StensTimer.h" struct Plant:public IStensTimerListener {const char * code; int umidadeDataPin; long umidadeCheckInterval; void checkHumidity (); void timerCallback (Timer * timer); void toSerial (); void updateApi ();}; # endif 
WhiteWalnut.ino Arduino
 #include "EcoActionBuffer.h" #include "Plant.h" #include "StensTimer.h" #include "WhiteWalnutApi.h" struct TimerHelper:public IStensTimerListener {public:void updateApi (); void timerCallback (Timer * timer);}; StensTimer * stensTimer; TimerHelper apiTimer; Plant leftPlant; Plant centerPlant; Plant rightPlant; Plant externalPlant; EcoActionBuffer actionBuffer; #define ACTION_PLANT_UPDATE 1 # definir ACTION_ECOACTION.in00; while (! Serial); stensTimer =StensTimer ::getInstance (); leftPlant.code ="LEFT"; centerPlant.code ="CENTER"; rightPlant.code ="RIGHT"; externalPlant.code ="EXTERNAL"; while (! WhiteWalnutApi ::connectToWiFi ()) delay (2000); WhiteWalnutApi ::switchPin (0, false); apiTimer.updateApi (); leftPlant.checkHumidity (); centerPlant.checkHumidity (); rightPlant.checkHumidity (); externalPlant.checkHumidity (); actionBuffer.readStack (); StensTimer ::getInstance () -> setInterval (&apiTimer, ACTION_PLANT_UPDATE, 60000); StensTimer ::getInstance () -> setInterval (&actionBuffer, ACTION_ECOACTION_READ, 1000);} void loop () {stensTimer-> run ();} void TimerHelper ::updateApi () {leftPlant.updateApi (); centerPlant.updateApi (); rightPlant.updateApi (); externalPlant.updateApi ();} void TimerHelper ::timerCallback (Timer * timer) {switch (timer-> getAction ()) {case ACTION_PLANT_UPDATE:updateApi (); pausa; }} 
WhiteWalnutApi.cpp Arduino
você precisa adicionar suas configurações de WiFi e API
 #include "Arduino.h" #include "ArduinoJson.h" #include "EcoActionBuffer.h" #include "MemoryFree.h" #include "Plant.h" #include " SoftwareSerial.h "#include" WhiteWalnutApi.h "SoftwareSerial espSerial (3, 2); const char * ssid ="  "; const char * pass ="  "; const char * API_SERVER =""; const char * API_PLANT =""; const char * API_ACTION =""; char * findOK ="OK"; char * findRY ="pronto"; char * findGT =">"; char * findDP =":"; char * findHD ="\ r \ n \ r \ n"; char * findBT ="\ r \ n"; bool WhiteWalnutApi ::connectToWiFi () {espSerial.begin (9600); espSerial.setTimeout (3000); while (espSerial.available ()) Serial.write (espSerial.read ()); Serial.println (F ("[ESP] Conectando ao WiFi")); espSerial.println (F ("AT + CIPSTATUS =2")); if (! espSerial.find (findOK)) {espSerial.setTimeout (10000); Serial.println (F ("[ESP] Módulo de reinicialização")); espSerial.println (F ("AT + RST")); if (! espSerial.find (findRY)) {Serial.println (F ("[ESP] Reinicialização falhou")); retorna falso; } Serial.println (F ("[ESP] Definir CWMode")); espSerial.println (F ("AT + CWMODE =1")); if (! espSerial.find (findOK)) {Serial.println (F ("Modo [ESP] falhou")); retorna falso; } Serial.println (F ("[ESP] Conectar ao Roteador")); espSerial.print (F ("AT + CWJAP =\" ")); espSerial.print (ssid); espSerial.print (F (" \ ", \" ")); espSerial.print (passagem); espSerial.println ("\" "); if (! espSerial.find (findOK)) {Serial.println (F ("[ESP] conexão WiFi falhou")); retorna falso; }} espSerial.setTimeout (3000); Serial.println (F ("[ESP] WiFi está conectado")); return true;} void WhiteWalnutApi ::updatePlant (Plant &plant) {String site =String (API_PLANT) + "? action =get &code =" + String (plant.code); while (! httpRequest (site)) connectToWiFi (); JsonObject &root =parseJson (); if (root.success ()) {plant.humidityDataPin =root ["dataPin"]. as  (); plant.humidityCheckInterval =atol (root ["intervalo"]. as  ()); }} void WhiteWalnutApi ::sendHumidity (Planta &planta, umidade interna) {String site =String (API_PLANT) + "? action =umidade &code =" + String (plant.code) + "&umidade =" + String (umidade); while (! httpRequest (site)) connectToWiFi (); // TODO:REMOVE RETURN} void WhiteWalnutApi ::sendHeartbeat (Plant &plant) {String site =String (API_PLANT) + "? Action =heartbeat &code =" + String (plant.code); while (! httpRequest (site)) connectToWiFi ();} void WhiteWalnutApi ::receiveActionFromStack (EcoActionBuffer &actionBuffer) {while (! httpRequest (String (API_ACTION))) connectToWiFi (); JsonObject &root =parseJson (); if (root.success ()) {actionBuffer.entryNo =atol (root ["entryNo"]. as  ()); actionBuffer.action =root ["actionEnum"]. as  (); actionBuffer.pin =root ["pin"]. as  (); actionBuffer.duration =atol (root ["valor"]. as  ()); }} void WhiteWalnutApi ::updateActionOnStack (EcoActionBuffer &actionBuffer) {String site =String (API_ACTION) + "? action =processing &entryNo =" + String (actionBuffer.entryNo); while (! httpRequest (site)) connectToWiFi ();} void WhiteWalnutApi ::switchPin (int pin, valor bool) {String site =String (API_ACTION) + "? action =switch &pin =" + String (pin) + "&value ="+ String (valor); while (! httpRequest (site)) connectToWiFi ();} bool WhiteWalnutApi ::httpRequest (String site) {// char * cmd; // sprintf (cmd, "GET% s HTTP / 1.0 \ r \ nHost:% s \ r \ nConnection:close", site, API_SERVER); / * String cmd =""; cmd + ="GET" + site + "HTTP / 1.0 \ r \ n"; cmd + ="Host:" + String (API_SERVER) + "\ r \ n"; cmd + ="Conexão:fechar"; int cmdLength =cmd.length () + 4; Serial.println (cmd); * / int cmdLength =44 + site.length () + strlen (API_SERVER); // Serial.print (F ("[MEMORY]")); // Serial.print (freeMemory ()); // Serial.print (F ("-")); // Serial.println (site); // -> 785 para espSerial.print externo (F ("AT + CIPSTART =\" TCP \ ", \" ")); espSerial.print (API_SERVER); espSerial.println (F (" \ ", 80") ); if (! espSerial.find (findOK)) {Serial.println (F ("[ESP] Erro de conexão TCP")); retorna falso; } espSerial.print (F ("AT + CIPSEND =")); espSerial.println (cmdLength); // espSerial.println (strlen (cmd)); if (! espSerial.find (findGT)) {Serial.println (F ("[ESP] Send State Error")); retorna falso; } espSerial.print (F ("GET")); espSerial.print (site); espSerial.print (F ("HTTP / 1.0 \ r \ n")); espSerial.print (F ("Host:")); espSerial.print (API_SERVER); espSerial.print (F ("\ r \ n")); espSerial.print (F ("Conexão:fechar \ r \ n")); espSerial.println (); // while (espSerial.available ()) Serial.println (espSerial.readString ()); Retorna; if (!espSerial.find(findDP)) { Serial.println(F("Bytes not sent")); espSerial.print(F("AT+CIPCLOSE")); retorna falso; } char status[32] ={0}; espSerial.readBytesUntil('\r', status, sizeof(status)); if (strcmp(status, "HTTP/1.1 200 OK") !=0) { Serial.print(F("[ESP] Unexpected response:")); Serial.println(status); retorna falso; } // Check HTTP status if (!espSerial.find(findHD)) { Serial.println(F("[ESP] Invalid response")); retorna falso; } // Skip HTTP headers // if (!espSerial.find(findBT)) { Serial.println(F("[ESP] Bytes not found")); Retorna; } // skip bytes (for http 1.1) return true;}JsonObject&WhiteWalnutApi::parseJson() { const size_t capacity =JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2) + 60; DynamicJsonBuffer jsonBuffer(capacity); JsonObject&root =jsonBuffer.parseObject(espSerial); if (!root.success()) Serial.println(F("Parsing failed!")); return root;}
WhiteWalnutApi.hArduino
#ifndef WHITEWALNUTAPI_H#define WHITEWALNUTAPI_H#include "Arduino.h"#include "ArduinoJson.h"#include "EcoActionBuffer.h"#include "Plant.h"class WhiteWalnutApi { public:static bool connectToWiFi(); static void updatePlant(Plant&plant); static void sendHumidity(Plant&plant, int humidity); static void sendHeartbeat(Plant&plant); static void receiveActionFromStack(EcoActionBuffer&actionBuffer); static void updateActionOnStack(EcoActionBuffer&actionBuffer); static void switchPin(int pin, bool value); private:static bool httpRequest(String site); static JsonObject&parseJson();};#endif

Esquemas

Chart about the communication and interfaces All implemented intents you can ask Alexa, including the response.
(multilingual) If you are interested in the entrance step of your alexa json parsing.

Processo de manufatura

  1. Controlador DMX operado pela web
  2. Arduino Spybot
  3. Sistema de alarme Arduino:SERENA
  4. Arduino + ESP Weather Box
  5. Sistema de ventilação porão / crawlspace
  6. Sistema de atendimento baseado em Arduino e planilha do Google
  7. BLUE_P:Wireless Arduino Programming Shield
  8. Sistema de aviso de detecção de colisão baseado em Arduino
  9. TFT Shield para Arduino Nano - Iniciar
  10. Arduino Shield NCS314 NIXIE Tubes Clock IN-14