Índice:

Controle de acesso à comida de gato (ESP8266 + servo motor + impressão 3D): 5 etapas (com fotos)
Controle de acesso à comida de gato (ESP8266 + servo motor + impressão 3D): 5 etapas (com fotos)
Anonim
Image
Image
Controle de Acesso à Comida Cat (ESP8266 + Servo Motor + Impressão 3D)
Controle de Acesso à Comida Cat (ESP8266 + Servo Motor + Impressão 3D)

Este projeto repassa o processo que usei para criar uma tigela de comida de gato automatizada, para meu gato idoso e diabético, Chaz. Veja, ele precisa tomar café da manhã antes de conseguir sua insulina, mas muitas vezes me esqueço de pegar seu prato de comida antes de ir para a cama, o que estraga seu apetite e prejudica sua rotina de insulina. Este prato utiliza um servo motor para fechar a tampa dos alimentos entre a meia-noite e as 7h30. O esboço do Arduino do microcontrolador NodeMCU ESP8266 usa o Network Time Protocol (NTP) para controlar a programação.

Este projeto pode não ser adequado para gatos mais jovens e ativos. Chaz é tão velho e frágil que não está inclinado a tentar abrir a tigela, mas é possível.

Se você é novo no Arduino ou no ESP8266, pode aproveitar os seguintes guias de pré-requisitos:

  • Classe Arduino instrutíveis
  • Aula instrutível de Internet das coisas

Suprimentos

  • Impressora 3D (eu uso uma Creality CR-10s Pro)
  • Filamento de impressora 3D (estou usando PLA dourado)
  • Microcontrolador wi-fi NodeMCU ESP8266
  • Cabo USB (A para microB)
  • Adaptador de alimentação USB
  • Micro servo motor
  • Chave de fenda pequena e parafusos
  • Fio de conexão
  • Pinos de cabeçalho
  • Placa perma-proto

Para acompanhar o que estou fazendo, siga-me no YouTube, Instagram, Twitter, Pinterest e inscreva-se no meu boletim informativo. Como um associado da Amazon, ganho com as compras qualificadas que você faz usando meus links de afiliados.

Etapa 1: peças impressas em 3D

Peças impressas em 3D
Peças impressas em 3D
Peças impressas em 3D
Peças impressas em 3D

O suporte para tigela de comida de gato é baseado no design de Ardy Lai no Thingiverse. Eu a tornei maior para acomodar a tigela do meu gato, e também a tornei mais curta, já que aumentá-la a tornara muito alta. Eu adicionei um suporte para um micro servo motor e alguns orifícios para os cabos passarem para o interior.

Eu modelei uma tampa simples usando o Tinkercad, projetada para prender no chifre do micro servo. Você pode pegar meu design diretamente do Tinkercad e / ou baixar os STLs anexados a esta etapa.

Imprimi as peças em minha impressora Creality CR-10s Pro com filamento PLA dourado.

Divulgação: no momento da redação deste artigo, sou funcionário da Autodesk, que fabrica o Tinkercad.

Etapa 2: Anexe a tampa ao servo motor

Anexe a tampa ao servo motor
Anexe a tampa ao servo motor
Anexe a tampa ao servo motor
Anexe a tampa ao servo motor

Usei uma pequena broca para aumentar o tamanho dos orifícios no chifre do servo e, em seguida, usei parafusos para prender o servo à tampa impressa em 3D.

Etapa 3: construir o circuito NodeMCU ESP8266

Construir Circuito NodeMCU ESP8266
Construir Circuito NodeMCU ESP8266
Construir Circuito NodeMCU ESP8266
Construir Circuito NodeMCU ESP8266
Construir Circuito NodeMCU ESP8266
Construir Circuito NodeMCU ESP8266
Construir Circuito NodeMCU ESP8266
Construir Circuito NodeMCU ESP8266

O circuito é controlado por um microcontrolador wi-fi NodeMCU ESP8266. Eu usei pinos de cabeçalho em uma placa perma-proto para tornar o micro servo motor facilmente removível. Os conectores de servo são conectados ao NodeMCU da seguinte maneira:

Fio de servo amarelo: NodeMCU D1

Fio servo vermelho: alimentação NodeMCU (3V3 ou VIN)

Fio preto do servo: aterramento NodeMCU (GND)

Etapa 4: faça upload do código do Arduino e teste

Faça upload do código e teste do Arduino
Faça upload do código e teste do Arduino

Instale o conjunto do motor / tampa no recorte em forma de motor na parte impressa em 3D do suporte da tigela. Conecte o conector do motor aos pinos do conector da placa do microcontrolador e conecte o circuito ao computador com um cabo USB.

O esboço do Arduino usa o Network Time Protocol para buscar a hora atual e, em seguida, abre ou fecha a tampa de acordo com uma programação embutida em código. Copie o código a seguir, atualize suas credenciais de wi-fi e deslocamento de tempo UTC e faça upload para sua placa NodeMCU usando o IDE do Arduino.

#incluir

#include #include #include ESP8266WiFiMulti wifiMulti; // Cria uma instância da classe ESP8266WiFiMulti, chamada 'wifiMulti' WiFiUDP UDP; // Cria uma instância da classe WiFiUDP para enviar e receber IPAddress timeServerIP; // time.nist.gov endereço do servidor NTP const char * NTPServerName = "time.nist.gov"; const int NTP_PACKET_SIZE = 48; // O carimbo de hora NTP está nos primeiros 48 bytes do byte da mensagem NTPBuffer [NTP_PACKET_SIZE]; // buffer para conter os pacotes de entrada e saída Servo myservo; // cria um objeto servo para controlar um servo // doze objetos servo podem ser criados na maioria das placas int pos = 0; // variável para armazenar a posição do servo void setup () {myservo.attach (5); // anexa o servo no pino 5 também conhecido como D1 ao objeto servo // abre a tampa por padrão Serial.println ("abrindo a tampa"); for (pos = 95; pos> = 0; pos - = 1) {// vai de 95 graus para 0 graus myservo.write (pos); // diz ao servo para ir para a posição na variável 'pos' delay (15); // espera 15ms para o servo atingir a posição} Serial.begin (115200); // Inicia a comunicação serial para enviar mensagens ao computador delay (10); Serial.println ("\ r / n"); startWiFi (); // Tente se conectar a alguns pontos de acesso fornecidos. Então espere por uma conexão startUDP (); if (! WiFi.hostByName (NTPServerName, timeServerIP)) {// Obter o endereço IP do servidor NTP Serial.println ("DNS lookup failed. Rebooting."); Serial.flush (); ESP.reset (); } Serial.print ("IP do servidor de horário: / t"); Serial.println (timeServerIP); Serial.println ("\ r / nEnviando solicitação NTP …"); sendNTPpacket (timeServerIP); } intervalo longo sem sinal NTP = 60000; // Solicita a hora NTP a cada minuto unsigned long prevNTP = 0; longo sem sinal lastNTPResponse = millis (); uint32_t timeUNIX = 0; não assinado longo prevActualTime = 0; void loop () {Unsigned long currentMillis = millis (); if (currentMillis - prevNTP> intervalNTP) {// Se um minuto se passou desde a última solicitação NTP prevNTP = currentMillis; Serial.println ("\ r / nEnviando solicitação NTP …"); sendNTPpacket (timeServerIP); // Envia uma solicitação NTP} uint32_t time = getTime (); // Verifique se uma resposta NTP chegou e obtenha o horário (UNIX) if (time) {// Se um novo carimbo de data / hora foi recebido timeUNIX = time; Serial.print ("Resposta NTP: / t"); Serial.println (timeUNIX); lastNTPResponse = currentMillis; } else if ((currentMillis - lastNTPResponse)> 3600000) {Serial.println ("Mais de 1 hora desde a última resposta NTP. Reinicializando."); Serial.flush (); ESP.reset (); } uint32_t actualTime = timeUNIX + (currentMillis - lastNTPResponse) / 1000; uint32_t EasternTime = timeUNIX - 18000 + (currentMillis - lastNTPResponse) / 1000; if (actualTime! = prevActualTime && timeUNIX! = 0) {// Se um segundo se passou desde a última impressão prevActualTime = actualTime; Serial.printf ("\ rUTC time: / t% d:% d:% d", getHours (actualTime), getMinutes (actualTime), getSeconds (actualTime)); Serial.printf ("\ rEST (-5): / t% d:% d:% d", getHours (EasternTime), getMinutes (EasternTime), getSeconds (EasternTime)); Serial.println (); } // 7h30 if (getHours (EasternTime) == 7 && getMinutes (EasternTime) == 30 && getSeconds (EasternTime) == 0) {// abre a tampa Serial.println ("abrindo a tampa"); for (pos = 95; pos> = 0; pos - = 1) {// vai de 95 graus para 0 graus myservo.write (pos); // diz ao servo para ir para a posição na variável 'pos' delay (15); // espera 15 ms para o servo atingir a posição}} // meia-noite if (getHours (eastTime) == 0 && getMinutes (eastTime) == 0 && getSeconds (eastTime) == 0) {// feche a tampa Serial. println ("fechando a tampa"); for (pos = 0; pos <= 95; pos + = 1) {// vai de 0 graus a 95 graus // em passos de 1 grau myservo.write (pos); // diz ao servo para ir para a posição na variável 'pos' delay (15); // espera 15 ms para o servo atingir a posição}} / * // testando if (getHours (eastTime) == 12 && getMinutes (eastTime) == 45 && getSeconds (eastTime) == 0) {// feche a tampa Serial.println ("fechando a tampa"); for (pos = 0; pos = 0; pos - = 1) {// vai de 95 graus para 0 graus myservo.write (pos); // diz ao servo para ir para a posição na variável 'pos' delay (15); // espera 15ms para que o servo alcance a posição}} * /} void startWiFi () {// Tente se conectar a alguns pontos de acesso fornecidos. Em seguida, aguarde uma conexão wifiMulti.addAP ("ssid_from_AP_1", "your_password_for_AP_1"); // adicionar redes Wi-Fi que deseja conectar a //wifiMulti.addAP("ssid_from_AP_2 "," your_password_for_AP_2 "); //wifiMulti.addAP("ssid_from_AP_3 "," your_password_for_AP_3 "); Serial.println ("Conectando"); while (wifiMulti.run ()! = WL_CONNECTED) {// Aguarde o atraso de conexão do Wi-Fi (250); Serial.print ('.'); } Serial.println ("\ r / n"); Serial.print ("Conectado a"); Serial.println (WiFi. SSID ()); // Diga-nos a qual rede estamos conectados Serial.print ("endereço IP: / t"); Serial.print (WiFi.localIP ()); // Envia o endereço IP do ESP8266 para o computador Serial.println ("\ r / n"); } void startUDP () {Serial.println ("Iniciando UDP"); UDP.begin (123); // Comece a ouvir mensagens UDP na porta 123 Serial.print ("Porta local: / t"); Serial.println (UDP.localPort ()); Serial.println (); } uint32_t getTime () {if (UDP.parsePacket () == 0) {// Se não houver resposta (ainda) retorne 0; } UDP.read (NTPBuffer, NTP_PACKET_SIZE); // leia o pacote no buffer // Combine os 4 bytes do carimbo de data / hora em um número de 32 bits uint32_t NTPTime = (NTPBuffer [40] << 24) | (NTPBuffer [41] << 16) | (NTPBuffer [42] << 8) | NTPBuffer [43]; // Converte a hora NTP em um carimbo de data / hora UNIX: // A hora Unix começa em 1 de janeiro de 1970. São 2208988800 segundos em hora NTP: const uint32_t seventyYears = 2208988800UL; // subtrai setenta anos: uint32_t UNIXTime = NTPTime - seventyYears; return UNIXTime; } void sendNTPpacket (IPAddress & address) {memset (NTPBuffer, 0, NTP_PACKET_SIZE); // define todos os bytes no buffer para 0 // Inicializa os valores necessários para formar a solicitação NTP NTPBuffer [0] = 0b11100011; // LI, Versão, Modo // envia um pacote solicitando um carimbo de data / hora: UDP.beginPacket (endereço, 123); // Os pedidos NTP são para a porta 123 UDP.write (NTPBuffer, NTP_PACKET_SIZE); UDP.endPacket (); } inline int getSeconds (uint32_t UNIXTime) {return UNIXTime% 60; } inline int getMinutes (uint32_t UNIXTime) {return UNIXTime / 60% 60; } inline int getHours (uint32_t UNIXTime) {return UNIXTime / 3600% 24; }

Etapa 5: Use

Use-o!
Use-o!
Use-o!
Use-o!

Passe os fios para o interior do suporte da tigela e conecte o comedouro para gatos em uma tomada usando um adaptador CA USB. Da maneira como o código simples é escrito, ele deve ser inicializado no estado "aberto" e só mudará a posição da tampa nos limites de tempo especificados no esboço do Arduino.

Obrigado por acompanhar! Se você fizer sua própria versão, adoraria vê-la na seção Eu fiz abaixo!

Se você gosta deste projeto, pode estar interessado em alguns dos meus outros:

  • Suporte de prisma para retratos de arco-íris
  • Parede de armazenamento de madeira compensada com torre de gato
  • Lanternas LED para jarra de pedreiro (tampa impressa em 3D)
  • Caixa Seca de Filamento para Impressora 3D
  • Fonte de alimentação USB de emergência (impresso em 3D)
  • Doce de goma de LED brilhante
  • Plantador geométrico impresso em 3D com drenagem
  • Flores impressas em 3D brilhantes
  • Como instalar LEDs sob uma scooter (com Bluetooth)

Para acompanhar o que estou fazendo, siga-me no YouTube, Instagram, Twitter e Pinterest.

Recomendado: