Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

Mangeoire pour animaux de compagnie facile à construire

Composants et fournitures

Arduino Nano R3
Il est préférable d'utiliser un Arduino Nano si vous souhaitez utiliser un boîtier compact
× 1
Horloge en temps réel Adafruit
× 1
Servo à rotation continue
× 1
Distributeur de céréales
× 1
Capteur Hall UNIPOLAIRE
× 1
Aimants à tige 3 mm de diamètre, 5 mm de longueur
× 6
Adafruit RGB rétro-éclairé LCD - 16x2
× 1
sac à dos lcd i2c
× 1
Apem Bouton poussoir momentané IP67
× 1
Petits boutons poussoirs momentanés
× 1
LED (générique)
× 6
Boîtier Hammond Multi ABS avec bride
× 1

Applications et services en ligne

Générateur de caractères LCD

À propos de ce projet

Mise à jour 2018-09-06

Mes deux mangeoires pour animaux fonctionnent parfaitement depuis 7 mois. Nous prenons soin de nos animaux pendant la journée bien sûr, mais ils reçoivent désormais leur nourriture à des heures régulières. Très satisfait du système !

Pourquoi une autre mangeoire pour animaux ?

Ma version d'une mangeoire pour animaux de compagnie est basée sur un microcontrôleur Arduino. Les matériaux utilisés sont relativement bon marché et je pense que c'est facile à construire !

Bien sûr, il existe de nombreuses versions mais je n'ai pas pu trouver de projet complet, prêt à être construit avec les fonctionnalités dont j'avais besoin, alors je suis parti de zéro.

Voici les fonctionnalités :

  • *Portions précises* livrées à chaque fois ! (en utilisant un capteur Hall)
  • Deux repas par jour
  • Horloge en temps réel *extrêmement* précise (uniquement avec une puce DS3231 authentique)
  • Vous pouvez annuler une tétée à venir individuellement pour les deux minuteries avec affichage et indicateur LED. L'annulation est automatiquement réinitialisée une fois le temps défini écoulé.
  • Fonction d'alimentation manuelle (une portion par pression de bouton)
  • Portions réglables pour chacune des deux heures d'alimentation (1-9 portions)
  • Aperçu de tous les paramètres définis sur l'écran principal
  • Système de menu facile à naviguer
  • Indication LED si l'alimentation a réussi
  • Minuterie de rétroéclairage LCD (désactivée après 30 secondes, activée en appuyant sur n'importe quel bouton)
  • L'heure et d'autres paramètres sont stockés en toute sécurité dans la mémoire (EEPROM)

VIDÉOS de démonstration :

pour la vidéo cliquez ICI

vidéo explicative plus détaillée :cliquez ICI

le Pet Feeder en action au ralenti ! cliquez ICI

Photos :

Pièces nécessaires :

  • 1x distributeur de céréales (pas cher sur Ebay)
  • du bois (ferraille) pour construire le support du distributeur de céréales
  • 1x Arduino Uno
  • 1x horloge temps réel I2C DS3231 (extrêmement précise) ou DS1307
  • 1 écran LCD 16 caractères / 2 lignes
  • 1x sac à dos I2C pour l'écran LCD
  • 1x Servo de rotation continue (achetez-en un bon !)
  • 1x capteur à effet Hall unipolaire Honeywell SS443R
  • 1 x alimentation externe 12 Volts/1 A (verrue murale)
  • 7 boutons-poussoirs - momentanés
  • 6x LED (2x ROUGE, 3x VERT, 1 JAUNE)
  • 2x résistance 1KΩ (pour les leds rouges)
  • 4x résistance 560Ω (pour les leds verte et jaune)
  • 1x boîtier pour l'électronique
  • prise d'alimentation femelle et connecteurs pour connecter le servo externe et le capteur à effet Hall
  • beaucoup, beaucoup de COLLE CHAUDE.

Il est préférable d'utiliser une tension plus élevée pour le servo si possible. Plus de pouvoir! Mon servomoteur HSR-2645CRH peut prendre 7,4 Volts, donc si vous voulez aussi faire cela, vous avez besoin de :

  • Planche de performances
  • Régulateur de tension variable LM317T
  • 3 résistances pour régler la tension de sortie (1KΩ, 150kΩ et 4K7)
  • 2 condensateurs polarisés (220µF, 10µF)
  • dissipateur thermique non nécessaire, le servo ne tournera que 1 à 2 secondes par jour ;)

En ligne, vous pouvez trouver de nombreuses calculatrices LM317.

Le conteneur d'aliments pour animaux

Les moins chers et les plus faciles à utiliser sont les distributeurs de céréales que vous pouvez trouver dans de nombreux magasins et sur Ebay. J'ai acheté un distributeur de céréales double sur Ebay pour 15 euros, envoi compris (Royaume-Uni aux Pays-Bas)

Le défi était de faire une monture pour la mangeoire et chercher sur Internet ne m'a pas beaucoup aidé alors j'ai regardé dans mon hangar et j'ai trouvé de beaux morceaux de bois de cèdre.

Le bois qui maintient le distributeur de céréales en plastique a une épaisseur de 3 cm donc pas de vacillement ! Vous devez être sûr que le trou (ma base d'alimentation est de 86 mm) est bien serré, alors mesurez avant de percer ! Mieux vaut percer un trou plus petit et le façonner un peu qu'un trou trop gros.

Regardez les photos pour avoir une idée pourquoi et comment elles s'emboîtent.

Le Servo et la fixation à la roue à aubes du distributeur

Assurez-vous d'acheter un bon servo. J'ai d'abord acheté un servomoteur MG996R que j'ai modifié pour une rotation continue mais c'était un gaspillage d'argent... Ensuite j'en ai eu de qualité, dans mon cas le servomoteur HSR-2645CRH

Ce doit être un modèle de rotation continue !! N'essayez pas de modifier un servo normal comme je l'ai fait. Il n'a pas fonctionné assez bien et lors de l'arrêt, ce n'était pas immédiat.

vidéo de l'essai servo :cliquez ICI

La connexion Servo à la roue à aubes du distributeur

Alors maintenant était la question :comment connecter le servo à la roue à aubes de l'alimentateur ? Cela semblait au début la partie la plus difficile du projet mais c'était en fait très simple.

J'ai pris un morceau de polycarbonate de 5 mm et avec une scie sauteuse j'ai découpé un disque rond d'environ 6 cm. Au centre j'ai percé un trou de 8 mm (l'épaisseur de l'axe du feeder. Cet axe en plastique est amovible de la roue à aubes)

A l'extérieur je perce 6 trous de 3 mm, l'épaisseur des aimants. Ceux-ci sont utilisés pour donner à l'Arduino un retour d'information sur la position de la roue à aubes de l'alimentation.

Parce que la roue à aubes avait 6 palettes en caoutchouc, j'ai utilisé 6 aimants et les ai répartis autour du bord du disque en polycarbonate. 360 degrés divisés par 6 font 60 degrés. Les tiges magnétiques s'adapteront parfaitement.

Le capteur à effet Hall détectera chacun des 6 aimants afin que nous puissions utiliser ces informations pour positionner et arrêter avec précision la roue à aubes. La variable de délai d'arrêt du servo est utilisée pour ajouter un délai après alimentation, avant d'arrêter le servo. Ainsi, avec ce délai, vous pouvez modifier la position exacte de la roue à aubes. Ceci est important car si la position « arrêt » est incorrecte, l'alimentation ne sortira pas complètement de la roue à aubes. De plus, la position du capteur à effet Hall peut être différente dans votre cas. Ajuster le temps variable du délai d'arrêt du servo résoudra ce problème.

Nous pouvons maintenant coller l'axe de la roue à aubes dans le disque en polycarbonate.

Le palonnier rond blanc est boulonné sur le disque en polycarbonate avec 3 boulons M3. utilisez des écrous supplémentaires comme espaceurs et ne serrez pas trop fort !

Maintenant, le servo fait partie de l'ensemble d'alimentation, nous pouvons donc le mettre dans le support en bois et mesurer la hauteur de la pièce de bois sous le servo.

Le capteur Hall

Le capteur à effet Hall que j'ai utilisé est de type UNIPOLAIRE. Il donnera une sortie FAIBLE si un aimant est proche et N'A PAS besoin de l'inversion de polarité de l'aimant pour réinitialiser à nouveau la sortie sur HIGH. Utilisez donc un capteur à effet Hall unipolaire, c'est beaucoup plus simple.

!!! Le capteur à effet Hall a besoin d'une résistance de rappel de 10 K.

J'ai installé une résistance SMD 0805 juste au-dessus du capteur à effet hall, mais vous pouvez le faire à votre façon. N'oubliez pas cette résistance !

Ensuite, j'ai pris un vieux stylo à bille et j'ai utilisé le plastique comme support pour le capteur.

Le boîtier électronique

J'ai utilisé un boîtier ABS Hammond avec bride. 120x65x40mm

pour les connexions externes, j'ai utilisé des connecteurs femelles de précision, pas les connecteurs chinois bon marché. Je les utilise beaucoup dans tous mes projets. Rien de pire que de mauvaises connexions provoquant des pannes (difficiles à trouver).

Pour faciliter la programmation de l'Arduino, j'ai une connexion FTDI externe :

Le panneau avant

J'ai essayé de nombreuses façons de faire un panneau avant bon marché et beau...

J'ai d'abord utilisé Mod Podge pour coller une impression laser en papier sur le devant du boîtier et le recouvrir de plus de Mod Podge. --> ÉCHEC

Ensuite, j'ai essayé un vernis transparent, à base de dispersion d'acrylate de polyuréthane. Très durable et solide une fois séché. J'ai très bien collé le papier sur le boîtier et le vernissage de la face supérieure de l'impression du panneau avant avait l'air très bien MAIS il n'adhèrerait pas aux parties du toner de l'imprimante laser de l'impression. --> ÉCHEC

Après cela, j'ai pris l'impression laser du panneau avant et j'ai seulement plastifié le dessus avec du pcv de plastification. très belle finition, protégeant la face avant et rehaussant joliment les couleurs. Là encore, j'ai collé le papier laminé sur le boîtier avec le vernis. Mon idée était que le vernis imprègne le papier, le rendant résistant à l'eau. Mais parce que j'ai utilisé du papier épais qui ne fonctionnait pas et le rendait humide pour tester la résistance à l'eau, le papier s'est enroulé du boîtier. --> ÉCHEC PARTIEL, à étudier plus avant.

Autre tentative :j'ai acheté une feuille d'aluminium spéciale, conçue pour l'impression laser. 2,25 euros par feuille. Le résultat était super mais je voulais protéger le toner avec une feuille transparente spéciale. Ce n'était pas un succès car je n'arrivais pas à me débarrasser des imperfections comme on le voit sur la photo 1 :

Puis une autre tentative de protection avec le vernis transparent, ça a rendu la feuille d'alu très brillante ! MAIS... encore une fois, le vernis n'adhérait pas au toner alors j'ai renoncé définitivement au vernis...

ENFIN... J'ai utilisé l'imprimé foil sans protection... Il montrera des empreintes Vinger lorsqu'il est manipulé souvent (regardez sous le bouton RETOUR de la photo en haut de cette page, logement dans l'alimentation du poulet) donc pas idéal mais toujours bon assez pour moi.

Plus de photos ne sont apparemment pas autorisées donc...

C'est tout les gens... avoir amusant !

Code

  • Pet Feed-O-Matic v 1.1 - 20-02-2018
Pet Feed-O-Matic v 1.1 - 20-02-2018Arduino
v 1.1 :appuyer sur les boutons Cancel1 ou 2 affichera une explication
// c++ stuff...//#include //#line 1//#line 1 "/Users/Erik/Documents/ PlatformIO/Projects/180202-151127-uno/src/Pet_Feeder_1_1_ENG.cpp"/* _ _ /\ | | (_) / \ _ __ __| |_ _ _ _ __ ___ / /\ \ | '__/ _` | | | | | '_ \ / _ \ / ____ \| | | (_| | |_| | | | | | (_) | /_/ \_\_| \__,_|\__,_|_|_| |_|\___/ _____ _ ______ _ | __ \ | | | ____| | | | |__) |__| |_ | |__ ___ ___ __| | ___ _ __ | ___/ _ \ __| | __/ _ \/ _ \/ _` |/ _ \ '__| | | | __/ |_ | | | __/ __/ (_| | __/ | |_| \___|\__| |_| \___|\___|\__,_|\___|_| Erik de Ruiter -------- -------------------------------------------------- ------------------- Pour faire :- alimentation à distance ? - délai d'arrêt de l'alimentation en tant qu'élément modifiable dans le menu dernière modification :20 février 2018 - 17:20:28 CARACTÉRISTIQUES :- *Portions précises* à chaque fois ! (en utilisant un capteur à effet Hall) - Deux heures d'alimentation, une fois par jour - Horloge en temps réel *extrêmement* précise (uniquement avec la puce DS3231 authentique) - Annulez l'alimentation à venir individuellement pour les deux minuteries avec affichage et indicateur LED Réinitialisation automatique une fois le temps écoulé. - Fonction d'alimentation manuelle (une portion par pression sur un bouton) - Portions réglables pour chacun des deux temps d'alimentation (1 à 9 portions) - Aperçu de tous les paramètres définis sur l'écran principal - Menu facile à naviguer système - Indication LED si l'alimentation a réussi - Minuterie de rétroéclairage LCD (éteinte après 30 secondes, allumée avec n'importe quel bouton) - Sauvegarde en cas de défaillance d'un capteur Hall - La LED du capteur Hass clignotera jusqu'à minuit si le capteur Hall a échoué - L'heure et d'autres paramètres sont stockés en toute sécurité dans les SITES WEB EEPROM :Site Web du générateur de caractères LCD HD44780 pour créer vos propres symboles LCD https://omerk.github.io/lcdchargen/ Croquis Arduino Générateur de commentaires de grandes lettres http://patorjk.com /software/taag/#p=display&c=c%2B%2B&f=Big&t=Commentaire Révisions :28 janvier 2018 - 20:17:10 */////////////////// ////////////////////////////////////////////////////////////// ////////////// VARIABLES MODIFIABLES PAR L'UTILISATEUR////////////////////////////// ////////////////////////////////////////////////////////////// utilisé pour la fonction de sauvegarde en cas d'échec du capteur Hall.// l'intervalle de temps doit être légèrement supérieur à un 60 degrés// tour du chargeur (une portion) #define HALL_SENSOR_BACKUP_VALUE 300 // délai avant d'arrêter le servo du chargeur après l'alimentation. De cette façon, vous pouvez// laisser la roue à pédales s'arrêter à la bonne position#define FEEDER_STOP_DELAY 100// rétroéclairage lcd à temps après avoir appuyé sur un bouton#define LCD_BACKLIGHT_ON_TIME 30000// quitter le menu sans enregistrer après un délai défini ici en ms#define MENU_TIMEOUT_VALUE 7000////////////////////////////////////////////// //////////////////////////////// https:// github.com/fdebrabander/Arduino-LiquidCrystal-I2C- library#include // https:// github.com/JChristensen/Button#include // http:// github.com/JChristensen/DS3232RTC#include // http://www.arduino.cc/playground/Code/Time#include // http://arduino.cc/en/Reference/Wire (inclus avec Arduino IDE)#include  #include // CONNEXIONS://// LCD (module I2C):// SCL - A5// SDA - A4// VCC// GND// broche du capteur hal d'interruption#define HALL_SENSOR_PIN 3#define BUTTON_BACK_PIN 4#define BUTTON_UP_PIN 5#define BUTTON_DOWN_PIN 6#define BUTTON_SELECT_PIN 7#define BUTTON_CANCEL1_PI N 8#define BUTTON_CANCEL2_PIN 9#define BUTTON_MANUAL_PIN 10#define LED_CANCEL1_PIN A0#define LED_CANCEL2_PIN A1#define LED_SUCCESS1_PIN A2#define LED_SUCCESS2_PIN Hall A3//feeder LED SERV_Adressage Pin#define/ENSPIN_IN_define LED_Sortie capteur Servo_IN_define (16x2) 0x27 ou 0x3FLiquidCrystal_I2C lcd(0x3F, 16, 2);// définir les paramètres de la bibliothèque de boutons// Un temps anti-rebond de 20 millisecondes fonctionne généralement bien// pour les boutons tactiles.#define DEBOUNCE_MS 20// ms requis avant de répéter sur appui long#define REPEAT_FIRST 1000// intervalle de répétition pour appui long#define REPEAT_INCR 200// Pour simplifier les choses, nous utilisons la résistance de rappel interne de l'Arduino.#define PULLUP true#define INVERT true// Déclarez les boutonsButton buttonSelect (BUTTON_SELECT_PIN, PULLUP , INVERT, DEBOUNCE_MS);Bouton buttonUp (BUTTON_UP_PIN, PULLUP, INVERT, DEBOUNCE_MS);Bouton buttonDown (BUTTON_DOWN_PIN, PULLUP, INVERT, DEBOUNCE_MS);Bouton buttonBack (BUTTON_BACK_PIN, PULLUP, INVERT, DEBOUNCE_MS); Button buttonCancel1 (BUTTON_CANCEL1_PIN, PULLUP, INVERT, DEBOUNCE_MS);Button buttonCancel2 (BUTTON_CANCEL2_PIN, PULLUP, INVERT, DEBOUNCE_MS);Button buttonManual (BUTTON_MANUAL_PIN, PULLUP, INVERT, DEBOUNCE_MS);// Le nombre précédent de count (initialisé pour s'assurer qu'il est différent quand// le sketch commence)int lastCount =-1;// Un temps variable qui est utilisé pour piloter les répétitions pour les appuis longsunsigned long rpt =REPEAT_FIRST;// utilisé pour le menu time-outunsigned long timeoutValue =0;// manuel annuler les heures d'alimentation variablesboolean manualCancelFeed1 =false;boolean manualCancelFeed2 =false;// Manaual feed optionboolean manualFeed =false;// Feed montant (en portions)int feedAmount1 =1;int feedAmount2 =1;bool feederSuccess =false;// feeder portionsint portions =0;int tours =0;// input actionsenum {btnSELECT, btnUP, btnDOWN, btnBACK, btnCANCEL1, btnCANCEL2, btnMANUAL, trigTIMEOUT};// États de la machine à états finis (FSM)enum STATES { PRINCIPAL, MENU_EDIT _FEEDTIME1, MENU_EDIT_FEEDTIME2, MENU_EDIT_FEEDAMOUNT, MENU_EDIT_TIME, MENU_EDIT_DATE, MENU_EDIT_SETTINGS, EDIT_FEED_TIME1_HOUR, EDIT_FEED_TIME1_MINUTE, EDIT_FEED_TIME1_ON_OFF, EDIT_FEED_TIME2_HOUR, EDIT_FEED_TIME2_MINUTE, EDIT_FEED_TIME2_ON_OFF, EDIT_FEED_AMOUNT1, EDIT_FEED_AMOUNT2, EDIT_HOUR, EDIT_MINUTE, EDIT_DAY, EDIT_MONTH, EDIT_YEAR, EDIT_SERVO_STOP_DELAY, EDIT_SERVO_BACKUP_DELAY,} // Maintient l'état actuel de l'état systemSTATES;int8_t userInput;int8_t trigger;int Seconde;int Minute;int Heure;int Jour;int Mois;int Année;int8_t DoW;String day_of_week;unsigned char address, data;int testt =0;int feed_time1_hour;int feed_time1_minute;bool feed_time1_active =false;bool alarm1Activated =false;int feed_time2_hour;int feed_time2_minute;bool feed_time2_active =false;bool alarm2Activated =false;// utilisé pour la fonction de clignotement lors de la modification des valeursuint32_t blink_intervaluiilli_t =500;uint32_Milli_Milli2_nt blink_previous; 0;boolean blink_state =false;// utilisé pour le fonction de clignotement lors de l'édition des valeursuint32_t spinningWheel_interval =170;uint32_t spinningWheel_previousMillis =0;uint32_t spinningWheel_currentMillis =0;int spinningWheelSymbol =0;// utilisé pour la fonction de sauvegarde en cas d'échec du capteur Hall// l'intervalle de temps doit être légèrement supérieur à 60 degrés// tour du chargeur (une portion).uint32_t hallSensorBackup_interval =HALL_SENSOR_BACKUP_VALUE;uint32_t hallSensorBackup_currentMillis =0;boolean hallSensorFail =false;// utilisé pour le rétroéclairage lcd timeruint32_t lcdBacklight_interval_ON32_booTIME_BACKLIGHT =false;// utilisé pour le rétroéclairage lcd timeruint32_t lcdBacklight_interval_ON32_booTIME_BACKLIGHT =LCD // Définir des symboles personnalisés pour l'affichage LCD.byte bell_symbol_Char[8] ={ B00100, B01110, B01110, B01110, B11111, B00100, B00000, B00000};byte inverted_one_Char[8] ={ 0b11111, 0b11011, 0b10011, 0b11011, 0b11011, 0b11011 , 0b10001, 0b11111};octet inverted_two_Char[8] ={ 0b11111, 0b11011, 0b10101, 0b11101, 0b11011, 0b10111, 0b10001, 0b11111};par te arrow_up_Char[8] ={ 0b00100, 0b01110, 0b11111, 0b01110, 0b01110, 0b01110, 0b01110, 0b00000};octet arrow_down_Char[8] ={ 0b00000, 0b01110, 0b01110, 0b01110, 0b01110, 0b11111, 0b01110;, 0b00octet inversé [8] ={ 0b11111, 0b10001, 0b10101, 0b10001, 0b10111, 0b10111, 0b11111, 0b00000};octet backslash_Char[8] ={ 0b00000, 0b10000, 0b01000, 0b00100, 0b00010, 0b00001, 0b00000, 0b00000};[8 octet épaisDash_ ] ={ 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b00000, 0b00000, 0b00000};volatile booléen hallSensorActivated =false;// Interruption 1void HallSensorIsr(){ hallSensorActivated =true ; // allume la LED du capteur Hall digitalWrite(LED_HALL_SENSOR_PIN, HIGH);}// Ces lignes sont nécessaires pour faire de ce sketch un fichier C++.// Je l'utilise car j'édite le code avec l'éditeur de texte Atom// et l'ajout de PlatformIO -onvoid HallSensorIsr();void setup();void loop();void change_states();void check_inputs();void transition(int trigger);void check_alarm();void check_manual_feed();void display_menu_option_set_feedtime1();void display_menu_option_set_feedtime2 ();void display_menu_option_set_feed_amount();void display_menu_option_set_time();void display_menu_option_set_date();void minuit_reset();void display_time();void displayFeedingAmouts();void displayFeedingTimes();void set_feedAmount();void set_time_date(); ();void set_feeding1_time();void set_feeding2_time();void get_time();void get_date();void write_time();void write_date();void write_feeding_time1();void write_feeding_time2();void write_feedamount();void get_feedamount ();void get_feed_time1();void get_feed_time2();void check_RTC();byte decToBcd(byte val);byte bcdToDec(byte val);void lead_zero(int digits);void blinkFunction();void displaySpinningWheel();void startFeederServo();void stopFeederServo();void activateFeeder(int portions);void check_LcdBacklight();void lcd_backlight_ON();void ledsAndLcdDisplayStartup();void hallSensorCheck();#line 355// ************************** ******************************************************** **// SETUPvoid ​​setup(){ // activer l'écran lcd lcd.begin(); // allume le rétroéclairage lcd et démarre la minuterie d'arrêt du rétroéclairage lcd_backlight_ON(); // démarre I2C Wire.begin(); // entrée du capteur à effet Hall pour détecter la rotation de la sortie du chargeur/de la quantité d'alimentation, vérifier pinMode (HALL_SENSOR_PIN, INPUT_PULLUP); pinMode(LED_HALL_SENSOR_PIN, SORTIE); pinMode(SERVO_OUTPUT_PIN, SORTIE); pinMode(LED_CANCEL1_PIN, SORTIE); pinMode(LED_CANCEL2_PIN, SORTIE); pinMode(LED_SUCCESS1_PIN, SORTIE); pinMode(LED_SUCCESS2_PIN, SORTIE); // définit l'état par défaut des LED sur OFF digitalWrite(LED_CANCEL1_PIN, LOW); digitalWrite(LED_CANCEL2_PIN, BAS); digitalWrite(LED_SUCCESS1_PIN, BAS); digitalWrite(LED_SUCCESS2_PIN, BAS); digitalWrite(LED_HALL_SENSOR_PIN, BAS); lcd.createChar(0, épaisDash_Char); lcd.createChar(1, bell_symbol_Char); lcd.createChar(2, barre oblique inverse_Char); lcd.createChar(3, inverted_p_Char); lcd.createChar(4, inverted_one_Char); lcd.createChar(5, inverted_two_Char); lcd.createChar(6, arrow_up_Char); lcd.createChar(7, arrow_down_Char); // définit le servomoteur d'alimentation sur l'état par défaut OFF stopFeederServo(); Fil.begin(); // définir RTC comme Syncprovider setSyncProvider(RTC.get); // temps en secondes de resynchronisation avec RTC setSyncInterval(60); // Désactive l'onde carrée par défaut de la broche SQW. RTC.squareWave(SQWAVE_NONE); // Attachez une interruption sur le capteur Hall (lorsque l'input passe à BAS) // à chaque tour de 60 degrés de l'arbre d'alimentation, le capteur Hall // doit générer une interruption attachInterrupt(INT1, HallSensorIsr, FALLING); // test d'affichage ledsAndLcdDisplayStartup(); // Etat initial du FSM state =MAIN; // lit la valeur d'alarme stockée dans la mémoire Arduino get_feed_time1(); get_feed_time2();}// Fin de la CONFIGURATION// *************************************** *************************************** // LOOPvoid ​​loop(){ // changer les états de FSM change_states(); // vérifier les entrées (boutons) check_inputs(); // vérifie si l'alarme a été appelée check_alarm(); // vérifie si l'alimentation manuelle a été demandée check_manual_feed(); // at midnight, reset some variables midnight_reset(); // check connection RTC check_RTC(); // Check the Hall sensor function hallSensorCheck(); // check if lcd backlight must be turned off check_LcdBacklight();}// End of LOOP// ******************************************************************************// ******************************************************************************// ******************************************************************************// ******************************************************************************//******************************************************************************// Finite State Machinevoid change_states(){ // states switch (state) { //--------------------------------------- case MAIN:display_time(); displayFeedingAmouts(); displayFeedingTimes(); Pause; //--------------------------------------- case MENU_EDIT_FEEDTIME1:display_menu_option_set_feedtime1(); Pause; //--------------------------------------- case MENU_EDIT_FEEDTIME2:display_menu_option_set_feedtime2(); Pause; //--------------------------------------- case MENU_EDIT_FEEDAMOUNT:display_menu_option_set_feed_amount(); Pause; //--------------------------------------- case MENU_EDIT_TIME:display_menu_option_set_time(); Pause; //--------------------------------------- case MENU_EDIT_DATE:display_menu_option_set_date(); Pause; //--------------------------------------- case EDIT_FEED_TIME1_HOUR:set_feeding1_time(); Pause; //--------------------------------------- case EDIT_FEED_TIME1_MINUTE:set_feeding1_time(); Pause; //--------------------------------------- case EDIT_FEED_TIME1_ON_OFF:set_feeding1_time(); Pause; //--------------------------------------- case EDIT_FEED_TIME2_HOUR:set_feeding2_time(); Pause; //--------------------------------------- case EDIT_FEED_TIME2_MINUTE:set_feeding2_time(); Pause; //--------------------------------------- case EDIT_FEED_TIME2_ON_OFF:set_feeding2_time(); Pause; //--------------------------------------- case EDIT_FEED_AMOUNT1:set_feedAmount(); Pause; //--------------------------------------- case EDIT_FEED_AMOUNT2:set_feedAmount(); Pause; //--------------------------------------- case EDIT_HOUR:set_time(); Pause; //--------------------------------------- case EDIT_MINUTE:set_time(); Pause; //--------------------------------------- case EDIT_DAY:set_date(); Pause; //--------------------------------------- case EDIT_MONTH:set_date(); Pause; //--------------------------------------- case EDIT_YEAR:set_date(); Pause; //--------------------------------------- }}//******************************************************************************// Check INPUTSvoid check_inputs(){ // first check if timeout has occurred if ( millis() - timeoutValue> MENU_TIMEOUT_VALUE ) { userInput =trigTIMEOUT; transition(userInput); } // check state of buttons buttonSelect.read(); buttonUp.read(); buttonDown.read(); buttonBack.read(); buttonManual.read(); buttonCancel1.read(); buttonCancel2.read(); // check manual cancel Feed1 button switch (buttonCancel1.wasPressed()) { case 1:// invert variable value (true to false and vise versa) manualCancelFeed1 =!manualCancelFeed1; //turn on lcd backlight manually lcd_backlight_ON(); // message when Cancel1 button is pressed if (manualCancelFeed1 ==1) { lcd.clear(); lcd.setCursor(0, 0); // 0123456789012345 - LCD screen character counter lcd.print("Upcoming Feed #1"); lcd.setCursor(0, 1); lcd.print("cancelled once "); retard (2000); lcd.clear(); } else if (manualCancelFeed1 ==0) { lcd.clear(); lcd.setCursor(0, 0); // 0123456789012345 - LCD screen character counter lcd.print("Upcoming Feed #1"); lcd.setCursor(0, 1); lcd.print("canceling undone"); retard (2000); lcd.clear(); } Pause; } // check manual cancel Feed2 button switch (buttonCancel2.wasPressed()) { case 1:// invert variable value (true to false and vise versa) manualCancelFeed2 =!manualCancelFeed2; //turn on lcd backlight manually lcd_backlight_ON(); // message when Cancel1 button is pressed if (manualCancelFeed2 ==1) { lcd.clear(); lcd.setCursor(0, 0); // 0123456789012345 - LCD screen character counter lcd.print("Upcoming Feed #2"); lcd.setCursor(0, 1); lcd.print("cancelled once "); retard (2000); lcd.clear(); } else if (manualCancelFeed2 ==0) { lcd.clear(); lcd.setCursor(0, 0); // 0123456789012345 - LCD screen character counter lcd.print("Upcoming Feed #2"); lcd.setCursor(0, 1); lcd.print("canceling undone"); retard (2000); lcd.clear(); } Pause; } // check manual Feed button switch (buttonManual.wasPressed()) { case 1:manualFeed =true; //turn on lcd backlight manually lcd_backlight_ON(); Pause; } // check MENU/SELECT button switch (buttonSelect.wasPressed()) { case 1:userInput =btnSELECT; //turn on lcd backlight manually lcd_backlight_ON(); transition(userInput); Pause; } // check UP button switch (buttonUp.wasPressed()) { case 1:userInput =btnUP; transition(userInput); //turn on lcd backlight manually lcd_backlight_ON(); Pause; } // check long press UP button switch (buttonUp.wasReleased()) { case 1:long_press_button =false; rpt =REPEAT_FIRST; Pause; } switch (buttonUp.pressedFor(rpt)) { case 1:// increment the long press interval rpt +=REPEAT_INCR; long_press_button =true; userInput =btnUP; transition(userInput); Pause; } // check DOWN button switch (buttonDown.wasPressed()) { case 1:userInput =btnDOWN; transition(userInput); //turn on lcd backlight manually lcd_backlight_ON(); Pause; } // check long press DOWN button switch (buttonDown.wasReleased()) { case 1:long_press_button =false; rpt =REPEAT_FIRST; Pause; } switch (buttonDown.pressedFor(rpt)) { case 1:// increment the long press interval rpt +=REPEAT_INCR; long_press_button =true; userInput =btnDOWN; transition(userInput); Pause; } // check btnBACK button switch (buttonBack.wasPressed()) { case 1:userInput =btnBACK; transition(userInput); //turn on lcd backlight manually lcd_backlight_ON(); Pause; }}//******************************************************************************// Check for state transition triggervoid transition(int trigger){ switch (state) { //--------------------------------------- case MAIN:// set time-out timr timeoutValue =millis(); if (trigger ==btnSELECT) { lcd.clear(); state =MENU_EDIT_FEEDTIME1; } else if (trigger ==btnBACK) { //lcd.clear(); //state =ALARM1_AND_2_TIME; } Pause; //--------------------------------------- case MENU_EDIT_FEEDTIME1:// set time-out timer timeoutValue =millis(); // check for time-out 'button' trigger if (trigger ==trigTIMEOUT) { lcd.clear(); state =MAIN; } // Now check for button triggers if (trigger ==btnUP) { //no action, this is the first menu } else if (trigger ==btnDOWN) { lcd.clear(); state =MENU_EDIT_FEEDTIME2; } if (trigger ==btnSELECT) { lcd.clear(); state =EDIT_FEED_TIME1_HOUR; } if (trigger ==btnBACK) { lcd.clear(); state =MAIN; } Pause; //--------------------------------------- case MENU_EDIT_FEEDTIME2:// set time-out timer timeoutValue =millis(); // check for time-out 'button' trigger if (trigger ==trigTIMEOUT) { lcd.clear(); state =MAIN; } // Now check for button triggers if (trigger ==btnUP) { lcd.clear(); state =MENU_EDIT_FEEDTIME1; } else if (trigger ==btnDOWN) { lcd.clear(); state =MENU_EDIT_FEEDAMOUNT; } if (trigger ==btnSELECT) { lcd.clear(); state =EDIT_FEED_TIME2_HOUR; } if (trigger ==btnBACK) { lcd.clear(); state =MAIN; } Pause; //--------------------------------------- case MENU_EDIT_FEEDAMOUNT:// set time-out timer timeoutValue =millis(); // check for time-out 'button' trigger if (trigger ==trigTIMEOUT) { lcd.clear(); state =MAIN; } // Now check for button triggers if (trigger ==btnUP) { lcd.clear(); state =MENU_EDIT_FEEDTIME2; } else if (trigger ==btnDOWN) { lcd.clear(); state =MENU_EDIT_TIME; } if (trigger ==btnSELECT) { lcd.clear(); state =EDIT_FEED_AMOUNT1; } if (trigger ==btnBACK) { lcd.clear(); state =MAIN; } Pause; //--------------------------------------- case MENU_EDIT_TIME:// set time-out timer timeoutValue =millis(); // check for time-out 'button' trigger if (trigger ==trigTIMEOUT) { lcd.clear(); state =MAIN; } // Now check for button triggers if (trigger ==btnUP) { lcd.clear(); state =MENU_EDIT_FEEDTIME2; } if (trigger ==btnDOWN) { lcd.clear(); state =MENU_EDIT_DATE; } if (trigger ==btnSELECT) { lcd.clear(); state =EDIT_HOUR; } if (trigger ==btnBACK) { lcd.clear(); state =MAIN; } Pause; //--------------------------------------- case MENU_EDIT_DATE:// set time-out timer timeoutValue =millis(); // check for time-out 'button' trigger if (trigger ==trigTIMEOUT) { lcd.clear(); state =MAIN; } // Now check for button triggers if (trigger ==btnUP) { lcd.clear(); state =MENU_EDIT_TIME; } else if (trigger ==btnDOWN) { //no action, end of menu items! } if (trigger ==btnSELECT) { lcd.clear(); state =EDIT_DAY; } if (trigger ==btnBACK) { lcd.clear(); state =MAIN; } Pause; //--------------------------------------- case EDIT_FEED_TIME1_HOUR:// set time-out timer timeoutValue =millis(); // check for time-out 'button' trigger if (trigger ==trigTIMEOUT) { lcd.clear(); state =MAIN; } // Now check for button triggers...This file has been truncated, please download it to see its full contents.

Schémas

Arduino based Pet Feeder I used Arduino IDE 1.8.2. BE CAREFUL NOT TO HAVE TWO VERSIONS OF THE SAME LIBRARIES IN YOUR LIBRARIES FOLDER!! arduino_pet_feeder_final_eng_v1_0-ino_hex_libraries_dsoo0HscCr.zip

Processus de fabrication

  1. Nourriture pour animaux de compagnie
  2. Console d'édition Photoshop DIY utilisant Arduino Nano RP 2040
  3. Arduino Spybot
  4. Fleurs - Arduino Nano, CrazyCircuits, DFRobot
  5. Jeu Arduino Nano Tetris sur matrice 16x8 maison
  6. clone Arduino Tamagotchi - animal numérique
  7. Arduino Nano :contrôler 2 moteurs pas à pas avec joystick
  8. Mangeoire télécommandée pour animaux de compagnie
  9. Compteur Geiger portable avec Arduino Nano