Spisu treści:

Kontrola dostępu do karmy dla kota (ESP8266 + serwomotor + drukowanie 3D): 5 kroków (ze zdjęciami)
Kontrola dostępu do karmy dla kota (ESP8266 + serwomotor + drukowanie 3D): 5 kroków (ze zdjęciami)

Wideo: Kontrola dostępu do karmy dla kota (ESP8266 + serwomotor + drukowanie 3D): 5 kroków (ze zdjęciami)

Wideo: Kontrola dostępu do karmy dla kota (ESP8266 + serwomotor + drukowanie 3D): 5 kroków (ze zdjęciami)
Wideo: Wyprawka dla kota - 10 rzeczy, które musisz mieć 2024, Czerwiec
Anonim
Image
Image
Kontrola dostępu do karmy dla kota (ESP8266 + serwomotor + druk 3D)
Kontrola dostępu do karmy dla kota (ESP8266 + serwomotor + druk 3D)

Ten projekt omawia proces, którego użyłem do stworzenia automatycznej miski na karmę dla mojego starszego kota z cukrzycą Chaz. Widzisz, musi zjeść śniadanie, zanim będzie mógł dostać insulinę, ale często zapominam odebrać jego danie przed pójściem spać, co psuje mu apetyt i odrzuca harmonogram insuliny. To danie wykorzystuje serwomotor do zamykania pokrywy nad jedzeniem między północą a 7:30. Szkic Arduino mikrokontrolera NodeMCU ESP8266 wykorzystuje protokół NTP (Network Time Protocol) do sterowania harmonogramem.

Ten projekt może nie być odpowiedni dla młodszych, bardziej aktywnych kotów. Chaz jest tak stary i słaby, że nie ma ochoty podważać miski, ale jest to możliwe.

Jeśli jesteś nowicjuszem w Arduino lub ESP8266, możesz skorzystać z następujących przewodników dotyczących wymagań wstępnych:

  • Instrukcje klasy Arduino
  • Instruktażowa klasa Internetu rzeczy

Kieszonkowe dzieci

  • Drukarka 3D (używam Creality CR-10s Pro)
  • Filament do drukarki 3D (używam złotego PLA)
  • Mikrokontroler Wi-Fi NodeMCU ESP8266
  • Kabel USB (A do microB)
  • Zasilacz USB
  • Mikrosilnik serwo
  • Mały śrubokręt i śruby
  • Podłączyć przewód
  • Kołki nagłówka
  • Płyta Perma-proto

Aby być na bieżąco z tym, nad czym pracuję, śledź mnie na YouTube, Instagramie, Twitterze, Pintereście i subskrybuj mój newsletter. Jako partner Amazon zarabiam na kwalifikujących się zakupach, których dokonujesz za pomocą moich linków afiliacyjnych.

Krok 1: Części drukowane w 3D

Części drukowane w 3D
Części drukowane w 3D
Części drukowane w 3D
Części drukowane w 3D

Uchwyt na miskę na karmę dla kota jest oparty na projekcie Ardy Lai na Thingiverse. Zwiększyłem ją, aby pomieścić miskę mojego kota, a także skróciłem ją, ponieważ powiększanie jej sprawiło, że była zbyt wysoka. Dodałem uchwyt na mikrosilnik i kilka otworów na kable do poprowadzenia do środka.

Wymodelowałem prostą pokrywę za pomocą Tinkercad, zaprojektowaną do przymocowania do klaksonu mikro serwa. Możesz pobrać mój projekt bezpośrednio z Tinkercad i/lub pobrać pliki STL dołączone do tego kroku.

Wydrukowałem części na mojej drukarce Creality CR-10s Pro ze złotym filamentem PLA.

Ujawnienie: w chwili pisania tego tekstu jestem pracownikiem firmy Autodesk, która produkuje Tinkercad.

Krok 2: Przymocuj pokrywę do serwomotoru

Przymocuj pokrywę do serwomotoru
Przymocuj pokrywę do serwomotoru
Przymocuj pokrywę do serwomotoru
Przymocuj pokrywę do serwomotoru

Użyłem małego wiertła, aby zwiększyć rozmiar otworów na serwoklanie, a następnie użyłem śrub, aby przymocować serwo do drukowanej w 3D pokrywy.

Krok 3: Zbuduj obwód NodeMCU ESP8266

Zbuduj obwód NodeMCU ESP8266
Zbuduj obwód NodeMCU ESP8266
Zbuduj obwód NodeMCU ESP8266
Zbuduj obwód NodeMCU ESP8266
Zbuduj obwód NodeMCU ESP8266
Zbuduj obwód NodeMCU ESP8266
Zbuduj obwód NodeMCU ESP8266
Zbuduj obwód NodeMCU ESP8266

Obwód jest kontrolowany przez mikrokontroler Wi-Fi NodeMCU ESP8266. Użyłem pinów nagłówka na płycie perma-proto, aby łatwo odłączyć mikrosilnik. Serwonapędy są podłączone do NodeMCU w następujący sposób:

Żółty przewód serwa: NodeMCU D1

Czerwony przewód serwo: zasilanie NodeMCU (3V3 lub VIN)

Czarny przewód serwo: masa NodeMCU (GND)

Krok 4: Prześlij kod Arduino i przetestuj

Prześlij kod Arduino i przetestuj
Prześlij kod Arduino i przetestuj

Zainstaluj zespół silnika/pokrywy w wycięciu w kształcie silnika w części drukowanej 3D uchwytu miski. Podłącz nagłówek silnika do styków nagłówka płytki mikrokontrolera i podłącz obwód do komputera za pomocą kabla USB.

Szkic Arduino wykorzystuje Network Time Protocol do pobrania aktualnego czasu, a następnie otwiera lub zamyka pokrywę zgodnie z ustalonym harmonogramem. Skopiuj następujący kod, zaktualizuj dane uwierzytelniające Wi-Fi i przesunięcie czasu UTC, a następnie prześlij go na swoją płytę NodeMCU za pomocą Arduino IDE.

#włączać

#include #include #include ESP8266WiFiMulti wifiMulti; // Utwórz instancję klasy ESP8266WiFiMulti o nazwie 'wifiMulti' WiFiUDP UDP; // Utwórz instancję klasy WiFiUDP do wysyłania i odbierania adresu IP timeServerIP; // time.nist.gov adres serwera NTP const char* NTPServerName = "time.nist.gov"; const int NTP_PACKET_SIZE = 48; // znacznik czasu NTP znajduje się w pierwszych 48 bajtach wiadomości bajt NTPBuffer[NTP_PACKET_SIZE]; // bufor do przechowywania pakietów przychodzących i wychodzących Servo myservo; // utwórz obiekt servo do sterowania serwo // na większości płyt można utworzyć dwanaście obiektów serwo int pos = 0; // zmienna do przechowywania pozycji serwa void setup() { myservo.attach(5); // dołącza serwomechanizm na pinie 5 aka D1 do obiektu serwo //domyślnie otwiera pokrywę Serial.println("otwieranie pokrywy"); for (pos = 95; pos >= 0; pos -= 1) { // przechodzi z 95 stopni do 0 stopni myservo.write(pos); // powiedz serwo, aby przeszło na pozycję w zmiennej 'pos' delay(15); // czeka 15ms, aż serwo osiągnie pozycję } Serial.begin(115200); // Rozpocznij komunikację szeregową, aby wysyłać wiadomości do komputera delay(10); Serial.println("\r\n"); startWiFi(); // Spróbuj połączyć się z określonymi punktami dostępu. Następnie czekaj na połączenie startUDP(); if(!WiFi.hostByName(NTPServerName,timeServerIP)) { // Uzyskaj adres IP serwera NTP Serial.println("Wyszukiwanie DNS nie powiodło się. Ponowne uruchamianie."); Serial.flush(); ESP.reset(); } Serial.print("IP serwera czasu:\t"); Serial.println(IPSerweraCzasu); Serial.println("\r\nWysyłanie żądania NTP…"); sendNTPpacket(IPSerweraCzasu); } unsigned long intervalNTP = 60000; // Żądaj czasu NTP co minutę unsigned long prevNTP = 0; unsigned long lastNTPResponse = millis(); uint32_t timeUNIX = 0; unsigned long prevActualTime = 0; void loop() { unsigned long currentMillis = millis(); if (currentMillis - prevNTP > intervalNTP) { // Jeśli od ostatniego żądania NTP minęła minuta prevNTP = currentMillis; Serial.println("\r\nWysyłanie żądania NTP…"); sendNTPpacket(IPSerweraCzasu); // Wyślij żądanie NTP } uint32_t time = getTime(); // Sprawdź, czy nadeszła odpowiedź NTP i pobierz czas (UNIX) if (time) { // Jeśli otrzymano nowy znacznik czasu timeUNIX = czas; Serial.print("Odpowiedź NTP:\t"); Serial.println(timeUNIX); ostatnia odpowiedźNTP = bieżąca Millis; } else if ((currentMillis - lastNTPResponse) > 3600000) { Serial.println("Ponad 1 godzina od ostatniej odpowiedzi NTP. Ponowne uruchamianie."); Serial.flush(); ESP.reset(); } uint32_t aktualnyCzas = czasUNIX + (bieżącyMillis - ostatnia odpowiedźNTP)/1000; uint32_t EasternTime = timeUNIX - 18000 + (bieżącyMillis - ostatnia odpowiedź NTP)/1000; if (actualTime != prevActualTime && timeUNIX != 0) { // Jeśli od ostatniego wydruku minęła sekunda prevActualTime = aktualnyTime; Serial.printf("\rczas UTC:\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(); } // 7:30 if(getHours(easternTime) == 7 && getMinutes(easternTime) == 30 && getSeconds(easternTime) == 0){ //otwórz pokrywę Serial.println("otwieranie pokrywy"); for (pos = 95; pos >= 0; pos -= 1) { // przechodzi z 95 stopni do 0 stopni myservo.write(pos); // powiedz serwo, aby przeszło na pozycję w zmiennej 'pos' delay(15); // czeka 15ms, aż serwo osiągnie pozycję } } // północ if(getHours(easternTime) == 0 && getMinutes(easternTime) == 0 && getSeconds(easternTime) == 0){ //zamknij pokrywę Serial. println("zamykanie pokrywy"); for (poz = 0; poz <= 95; poz += 1) { // przechodzi od 0 stopni do 95 stopni // w krokach co 1 stopień myservo.write(poz); // powiedz serwo, aby przeszło na pozycję w zmiennej 'pos' delay(15); // czeka 15ms, aż serwo osiągnie pozycję } } /* // test if(getHours(easternTime) == 12 && getMinutes(easternTime) == 45 && getSeconds(easternTime) == 0){ //zamknij pokrywę Serial.println("zamykanie pokrywy"); for (pos = 0; pos = 0; pos -= 1) { // przechodzi z 95 stopni do 0 stopni myservo.write(pos); // powiedz serwo, aby przeszło na pozycję w zmiennej 'pos' delay(15); // czeka 15ms, aż serwo osiągnie pozycję } } */ } void startWiFi() { // Spróbuj połączyć się z określonymi punktami dostępowymi. Następnie poczekaj na połączenie wifiMulti.addAP("ssid_from_AP_1", "twoje_hasło_do_AP_1"); // dodaj sieci Wi-Fi, z którymi chcesz się połączyć //wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2"); //wifiMulti.addAP("ssid_from_AP_3", "twoje_hasło_do_AP_3"); Serial.println("Łączenie"); while (wifiMulti.run() != WL_CONNECTED) { // Czekaj na połączenie Wi-Fi delay(250); Serial.print('.'); } Serial.println("\r\n"); Serial.print("Połączony z"); Serial.println(WiFi. SSID()); // Powiedz nam, do jakiej sieci jesteśmy połączeni Serial.print("adres IP:\t"); Serial.print(WiFi.localIP()); // Wyślij adres IP ESP8266 do komputera Serial.println("\r\n"); } void startUDP() { Serial.println("Uruchamianie UDP"); UDP.początek(123); // Rozpocznij nasłuchiwanie komunikatów UDP na porcie 123 Serial.print("Lokalny port:\t"); Serial.println(UDP. LocalPort()); Serial.println(); } uint32_t getTime() { if (UDP.parsePacket() == 0) { // Jeśli nie ma (jeszcze) odpowiedzi return 0; } UDP.read (NTPBuffer, NTP_PACKET_SIZE); // wczytaj pakiet do bufora // Połącz 4 bajty znacznika czasu w jedną 32-bitową liczbę uint32_t NTPTime = (NTPBuffer[40] << 24) | (NTPBuffer[41] << 16) | (NTPBuffer[42] << 8) | NTPBuffer[43]; // Konwertuj czas NTP na sygnaturę czasową UNIX: // Czas uniksowy zaczyna się 1 stycznia 1970 r. To 2208988800 sekund w czasie NTP: const uint32_t seventyYears = 2208988800UL; // odejmij siedemdziesiąt lat: uint32_t UNIXTime = NTPTime - seventyYears; zwróć czas UNIX; } void sendNTPpacket(IPAddress&adres) { memset(NTPBuffer, 0, NTP_PACKET_SIZE); // ustaw wszystkie bajty w buforze na 0 // Zainicjuj wartości potrzebne do utworzenia żądania NTP NTPBuffer[0] = 0b11100011; // LI, Wersja, Tryb // wyślij pakiet żądający znacznika czasu: UDP.beginPacket(adres, 123); // Żądania NTP są kierowane do portu 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; }

Krok 5: Użyj go

Użyj tego!
Użyj tego!
Użyj tego!
Użyj tego!

Poprowadź przewody do wnętrza uchwytu na miskę i podłącz karmnik dla kota do gniazdka za pomocą zasilacza sieciowego USB. Sposób, w jaki napisany jest prosty kod, ma być uruchamiany w stanie „otwartym” i zmienia położenie pokrywy tylko w progach czasowych określonych w szkicu Arduino.

Dziękujemy za śledzenie! Jeśli stworzysz własną wersję, chciałbym ją zobaczyć w sekcji Zrobiłem to poniżej!

Jeśli podoba Ci się ten projekt, możesz zainteresować się niektórymi z moich innych:

  • Uchwyt na pryzmat do tęczowych portretów
  • Ściana do przechowywania sklejki z wieżą dla kota
  • Lampiony LED Mason Jar (pokrywka z nadrukiem 3D)
  • Suche pudełko na filament do drukarki 3D
  • Awaryjne źródło zasilania USB (druk 3D)
  • Świecące gumowe cukierki LED
  • Geometryczna donica z nadrukiem 3D z drenażem
  • Świecące kwiaty drukowane w 3D
  • Jak zainstalować diody LED pod skuterem (z Bluetooth)

Aby być na bieżąco z tym, nad czym pracuję, obserwuj mnie na YouTube, Instagramie, Twitterze i Pintereście.

Zalecana: