Introduction
Je vous présente dans ce tuto un petit montage qui permet de nourrir votre chat en votre absence. Il possède 6 gamelles, donc 6 jours d’autonomie !
Le prix de ce montage est d’environ 40€
Le temps nécessaire est d’environ 10 heures, donc assez conséquent, mais si vous êtes à l’aise avec la mécanique, ça pourrait se faire bien plus vite. J’ai indiqué, pour chaque étape, le temps estimé.
Cette solution se base sur le matériel suivant
• 3x plateau à servir, Ikea, diamètre 43 cm, environ 7€ pièce
• 1x tige filetée de 10mm de diamètre, longue d’environ 100mm, avec 6 écrous, environ 3€
• 8x visses et écrous, 4x40mm
• 1x couvercle de bocal, si possible cranté, servant de roue d’entrainement
• 1x bon élastique
• 6x gamelles, commandées sur AliExpress, ici, pour environ 10€
• 1x module « NodeMCU ESP8260 », valeur d’environ 3€
• 1x driver moteur pas à pas Driver Shield stepping Stepper Motor Driver V44 A3967 microstepping driver, valeur d’environ 3€
• 1x alimentation 12V continu, quelconque mais capable de délivrer 500mA, récupérée à la déchetterie de mon village
• Motor Speed Measurement Hall Sensor Module Hall Switch Sensor Module, 1€ (facultatif) et un petit aimant
• 1x moteur pas à pas (voir le texte ci-dessous) ou alors AliExpress,Stepper Motor DC 5V 28BYJ-48 + ULN2003 Stepper Motor Driver Module for Arduino, mais attention, à alimenter en 5V. Dans mon montage, mon moteur fonctionne en 12V
Outillage nécessaire
• Perceuse
• Mèches de 10mm et 4mm
• Mèche cloche de 95mm
• Tournevis, clé à fourche, …
Ce tuto est découpé en 3 parties principales : une partie mécanique, une partie électronique et l’intégration dans la box eedomus.
1) La partie mécanique
Le montage est basé sur 3 plateaux
• Le plateau inférieur, servant de socle, sur lequel seront fixé le moteur et la partie électronique. Ce plateau est fixe.
• Le plateau du milieu, plateau tournant, qui contient les 6 gamelles, donc percé de 6 trous pour supporter les 6 gamelles.
• Le plateau supérieur, fixe, avec 1 seul trou. La gamelle du jour viendra se positionner sous ce trou, permettant au chat d’accéder à sa nourriture.
Il s’agit de percer les plateaux. Un trou de 10mm au centre, le plateau du milieu avec les 6 trous pour les gamelles, et le plateau supérieur avec un trou. Il faut être précis, car le plateau du milieu, celui donc qui tourne, doit présenter la gamelle exactement au-dessous du plateau supérieur.
Le traçage des plateaux (1 heure)
Je vous suggère de prendre le temps nécessaire pour le traçage, car il s’agit d’être bien précis. Commencer par tracer tout cela sur un plateau, le centre et 6 parties. Je vous suggère de regarder sur le web comment trouver cela. Pour les 6 parties, faîtes une recherche sur « découper une tarte en 6 parts égales ». Finalement, mes gamelles font 96mm de diamètre, et je laisse 10mm avant le bord, donc le centre du trou sera à 58mm (96/2+10) du bord. Je trace avec un compas depuis le centre.
Le perçage des plateaux (1h30)
Le trou central : Fixer les plateaux ensemble à l’aide d’un serre-joint, et les percer ensemble, avec une mèche de 10mm.
Les 6 trous pour les gamelles : Fixer 2 plateaux ensemble pour le premier trou, et ensuite, faire les 5 autres trous dans un seul plateau. Conserver la matière enlevée, on l’utilise à la prochaine étape !
Le traçage et perçage du module d’entrainement (1 heure)
Récupérer les disques des 7 trous percés. Dans mon cas, ils font ensemble une épaisseur de 30mm, ce qui est parfait. Donc sur ces 7 disques, il faut agrandir le trou central à 10mm pour qu’ils puissent s’enfiler dans la visse centrale. Il faut également percer en son centre d’un trou de 10 mm le couvercle cranté qui viendra se positionner face pleine contre les disques et servira de pignon d’entraînement. Ensuite, il faut percer 4 trous de 4mm, sur chaque disque et également sur le couvercle cranté et le plateau pour pouvoir fixer le tout au plateau. Pour tracer et percer à travers, utiliser un des disques comme chablon.
Voilà, il faudra fixer l’ensemble à l’aide de 4 visses et écrous, 4x40mm, et on peut remettre l’axe central et « pincer » ce montage entre deux écrous au-dessus, et deux écrous au-dessous. En tenant l’axe, le plateau doit pouvoir tourner facilement.
Fixation du moteur (30 minutes)
Le moteur est fixé au plateau inférieur, avec des vis/écrous de 4mm. A nouveau, il faudra faire quelques trous.
Fixation du capteur de positionnement (30 minutes)
Cette opération est facultative. Le moteur pas à pas est tellement précis, qu’il suffit de trouver en quelques essais le nombre d’impulsions nécessaires pour faire 1/6 de tour. Dans mon cas, c’est 5900. Plus de détails sur cela dans la section « Programme ».
J’ai d’abord fait quelques essais avec un interrupteur, un simple switch, le plateau tournant l’actionnant une fois par tour, tout simplement. Mais finalement, je me suis décidé pour un capteur effet hall, plus simple à installer mécaniquement et aussi ne nécessitant aucun contact mécanique.
Simple à monter, un petit morceau de bois coupé à bonne hauteur, avec deux trous pour le fixer sur le socle, et un l’aimant fixé sur le plateau tournant avec un scotch double-face.
Fixation des circuits électroniques (2 heures)
Les circuits électroniques sont simplement fixés sur un lino, attachés avec des brides plastique, et le lino est vissé sur le plateau inférieur. Voir le schéma ci-dessous. J’ai relié tout cela en wrapping, mais l’utilisation de câbles femelles/femelles est tout à fait possible.
Finalisation du montage et réglage (1 heure)
• Commencer par bien monter ensemble le module d’entrainement, c’est-à-dire le plateau central avec les 7 disques et le couvercle). Sur l’axe, serrer entre eux deux écrous. Le plateau tournant viendra se poser sur ces écrous. Régler la hauteur pour que le couvercle cranté se trouve à la même hauteur que la roue du moteur. Et toujours sur l’axe, au-dessus du plateau tournant, serrer entre eux deux autres écrous, et s’assurer que le module, en tenant fermement la tige filetée, tourne correctement.
• Insérer l’élastique, pour l’instant juste pour qu’il soit dans le montage, sans le tendre
• Fixer le module d’entrainement au socle, en mettant un écrou au-dessus et un écrou au-dessous, et les serrant entre eux
• Insérer l’élastique correctement
• Positionner le capteur Hall pour qu’il soit bien en face de l’aimant
• Et finalement, fixer le plateau supérieur en le serrant avec un écrou encore.
2) La partie électronique
Le moteur pas à pas
J’ai visité la benne « matériel informatique » de ma déchetterie et récupéré un ancien scanner. A l’intérieur, une bonne surprise avec un moteur pas à pas et ses engrenages, Mitsumi m42sp-7.
Un site qui m’a bien aidé à comprendre ce moteur : http://eskimon.fr/290-arduino-603-petit ... ur-pas-pas, sur lequel il y a un diagramme clair. Et cette vidéo : https://www.youtube.com/watch?v=IEmGOuMFPKQ
Donc, je suis en présence d’un moteur bipolaire, à 4 fils.
Il s’agit donc de repérer les bobines, dans mon cas,
• Bobine 1 : 6.6 ohms entre les câbles Jaune et Vert
• Bobine 2 : 6.6 ohms entre les câbles Blanc et Noir
Ma séquence est la suivante, sens « aiguille montre »
• Jaune+, Vert-
• Blanc+, Noir-
• Jaune-, Vert+
• Blanc-, Noir+
Le montage électronique
Pour mettre en route l’environnement de développement pour le NodeMCU ESP8266, je me suis basé sur les mini tutos que vous trouverez à cette adresse :
https://easycoding.tn/index.php/nodemcu/
La mise en œuvre est simple et rapide : en moins d’une heure, je pouvais déjà actionner la led interne du NodeMCU, et une heure plus tard, je pouvais faire la même chose, mais par Wifi. Bref, c’est un module assez impressionnant.
Le module ESP supporte une alimentation allant de 3.3V à 30V. Il possède un régulateur interne pour produire les 3.3V nécessaire à son fonctionnement. Le driver moteur lui fonctionne en 12V.
Donc, mon alimentation 12V alimentera les deux modules, le ESP ainsi que le driver du moteur.
J’utilise ensuite 3 pin entre le ESP et le driver du moteur
• D0 : Step : à chaque impulsion, le moteur tourne d’un pas
• D2 : Dir : Direction
• D3 : Sleep : Permet de mettre le module en mode sleep. En mode actif, il consomme, sous 12V, environ 350mA. En mode « sleep », c’est de l’ordre de 5-6mA
Le programme
La partie mécanique étant prête, le programme devient « un jeu d’enfant ». En résumé, charger ce programme, fixer l’adresse IP, et entrer la commande « help » pour avoir la liste des commandes à disposition.
Quelques informations quand même sur ce programme. Bien sûr, tout peut être modifié à votre guise
• Le module part sur une adresse IP fixe. DHCP fonctionne très bien aussi. A changer donc si vous préférez
• Fixer l’adresse IP ainsi que vos paramètres WIFI. J’ai mis des XXX ou YYY là où il faut adapter
• Pour tester le module, il suffit d’entrer dans un Explorer les commandes suivantes:
o http://192.168.0.XX/Calibrage
o http://192.168.0.XX/GamelleSuivante
- Code : Tout sélectionner
//Libraries
#include <ESP8266WiFi.h> //Required for WIFI
//For debug purpose, compiler commands
#define DEBUG //Comment this line to remove all debug lines
#ifdef DEBUG
#define DEBUG_PRINT(x) Serial.print(x)
#define DEBUG_PRINTLN(x) Serial.println(x)
#else
#define DEBUG_PRINT(x)
#define DEBUG_PRINTLN(x)
#endif
//Version of this software
const char* CVersion = "Gamelle Version v1.0 - CEN, February 2018";
const char* ssid = "XXX"; //WiFi ID
const char* password = "YYY"; //WiFi PWD
//Static IP, Gateway and Subnet of the ESP module (this device, the watchdog)
IPAddress staticIP (XXX, XXX, XXX, XXX);
IPAddress gateway (XXX, XXX, XXX, XXX);
IPAddress subnet(XXX, XXX, XXX, XXX);
//I/O Pin usage
int P_MotorStep = 4; //D2
int P_MotorDirection = 5; //D1
int P_MotorSleep = 0; //D3
int P_SensorPin = 12; //D6, Sensor Hall
//Variables
int TicTour=5900; //Default, overwritten by the calibration function, used in case the calibration doesn't work
int i; //for loops
int Direction=0; //0=clockwise
int GamelleActive=1; //Keep track of the active gamelle
//Start server
WiFiServer server(80);
void setup()
{
Serial.begin(115200); delay(10); //Debug serial line
pinMode(P_MotorStep, OUTPUT);
pinMode(P_MotorDirection, OUTPUT);
pinMode(P_MotorSleep, OUTPUT);
digitalWrite(P_MotorStep, LOW);
digitalWrite(P_MotorDirection, LOW);
digitalWrite(P_MotorSleep, HIGH); //Disable Motor Driver
pinMode(P_SensorPin, INPUT_PULLUP);
// Connect to WiFi network
DEBUG_PRINTLN("");DEBUG_PRINT("Connecting to WIFI Network ");DEBUG_PRINTLN(ssid);
WiFi.disconnect();
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) { delay(300); DEBUG_PRINT("."); }
WiFi.config(staticIP, gateway, subnet);
WiFi.hostname("Gamelle");
DEBUG_PRINTLN("");
DEBUG_PRINT("Connected to WIFI ");DEBUG_PRINTLN(ssid);
DEBUG_PRINT("My IP Address: ");DEBUG_PRINTLN(WiFi.localIP());
DEBUG_PRINT("My Gateway: ");DEBUG_PRINTLN((WiFi.gatewayIP().toString().c_str()));
DEBUG_PRINT("My hostname: ");DEBUG_PRINTLN(WiFi.hostname());
// Start the server
server.begin();
DEBUG_PRINTLN("Server started");
// Print the IP address
DEBUG_PRINT("Use this URL to connect: "); DEBUG_PRINT("http://"); DEBUG_PRINT(WiFi.localIP()); DEBUG_PRINT("/");DEBUG_PRINTLN("Calibration");
DEBUG_PRINT("Use this URL to connect: "); DEBUG_PRINT("http://"); DEBUG_PRINT(WiFi.localIP()); DEBUG_PRINT("/");DEBUG_PRINTLN("GamelleSuivante");
//Calibrate the device
DEBUG_PRINTLN("Calibration...");
Calibration();
DEBUG_PRINTLN("Gamelle 1 en place");
}
void loop()
{
// Check if a client has connected
WiFiClient client = server.available();
//Client has connected. Treat request
if (client) {
DEBUG_PRINTLN("Command received...");
// Read the first line of the request
String request = client.readStringUntil('\r');
client.flush();
DEBUG_PRINTLN(request);
// Match the request, for both requests (Calibration and GamelleSuivante),
if (request.indexOf("/GamelleSuivante") != -1) {
GamelleActive=(GamelleActive+1) % 6;
DEBUG_PRINT("Commande reçue pour positionner la gamelle ");DEBUG_PRINTLN(GamelleActive);
client.print("Gamelle ");client.print(GamelleActive);client.println(" en cours de positionnement<br>");
client.println("HTTP/1.1 200 OK"); //Acknoledge command
Move(TicTour);
} else if (request.indexOf("/Calibration") != -1) {
DEBUG_PRINTLN("Calibration");
client.println("Command Calibration<br>");
client.println("HTTP/1.1 200 OK"); //Acknoledge command
Calibration();
} else if (request.indexOf("/Help") != -1) {
DEBUG_PRINTLN("Command Help");
client.print("Use this URL to connect: http://");client.print(WiFi.localIP());client.print("/");client.println("Calibration<br>");
client.print("Use this URL to connect: http://");client.print(WiFi.localIP());client.print("/");client.println("GamelleSuivante<br>");
client.println("HTTP/1.1 200 OK"); //Acknoledge command
} else {
client.println("HTTP/1.1 404 Command not found>"); //Acknoledge command
}
} //if (client)
}
void Move(int s){
digitalWrite(P_MotorSleep, HIGH); //Enable Motor Driver
digitalWrite(P_MotorDirection, Direction); //Direction clock wise
for (i=0; i < s; i++){
digitalWrite(P_MotorStep, HIGH); delay(1);
digitalWrite(P_MotorStep, LOW); delay(1);
}
digitalWrite(P_MotorSleep, LOW); //Disable Motor Driver
}
void Calibration (){
digitalWrite(P_MotorSleep, HIGH); //Enable Motor Driver
digitalWrite(P_MotorDirection, Direction); //Direction clock wise
DEBUG_PRINT("Captor ="); DEBUG_PRINTLN(digitalRead(P_SensorPin));
//Move 2000 tics if we are under the sensor
if (digitalRead(P_SensorPin)== 0){
DEBUG_PRINTLN("Under the captor, move a bit");
for (i=0; i < 2000; i++){
digitalWrite(P_MotorStep, HIGH); delay(1);
digitalWrite(P_MotorStep, LOW); delay(1);
} //for
} //if
//Find the sensor, first time
i=0;
while (digitalRead(P_SensorPin)== 1){
digitalWrite(P_MotorStep, HIGH); delay(1);
digitalWrite(P_MotorStep, LOW); delay(1);
i++;
if (i > 45000) {
DEBUG_PRINTLN("Reference point 1 not found, use default value");
return;
}; //if
} //while
//Move 2000 tics, not to be under the sensor anymore
for (i=0; i < 2000; i++){
digitalWrite(P_MotorStep, HIGH); delay(1);
digitalWrite(P_MotorStep, LOW); delay(1);
} //for
//Do a full round until the sensor is found again
i=2000;
while (digitalRead(P_SensorPin)== 1){
digitalWrite(P_MotorStep, HIGH); delay(1);
digitalWrite(P_MotorStep, LOW); delay(1);
i++;
if (i > 45000) {
DEBUG_PRINTLN("Reference 2 not found, used default");
return;
};
} //while
TicTour=(i/6)+25; //TicTour=Global variable
DEBUG_PRINT("Reference 2 found, ");DEBUG_PRINT("Tics for one round= ");DEBUG_PRINT(i);DEBUG_PRINT("; Tics for 1/6 round= ");DEBUG_PRINTLN(TicTour);
digitalWrite(P_MotorSleep, LOW); //Disable Motor Driver
}
3) Intégration dans la box eedomus
Création d'un actionneur HTTP
• Nom: Gamelle Actionneur
• Pièce: Salon
• Usage:
• Avec 2 états: Calibrage, GamelleSuivante
• Calibrage: Placer l'URL suivante: http://192.168.0.XX/Calibrage
• GamelleSuivante : Placer l'URL suivante: http://192.168.0.XX/GamelleSuivante
Création d'une règle
• Nom: Gamelle
• Pièce: Salon
• Tous les jours, à 19h00,
• Action : Gamelle Chat Séjour -> GamelleSuivante
Améliorations possibles
• Vraiment un détail, mais il faut démonter le premier plateau pour accéder aux gamelles. Pour l’instant, j’ai mis un écrou, mais une vis à ailettes serait plus pratique au quotidien. On peut aussi scier la tige, qui est un peu trop longue.
• Tous les paramètres sont en durs dans le programme. Un changement d’adresse IP nécessite le rechargement du programme. Il serait intéressant de pouvoir paramétrer par réseau. Cela est possible, mais je n’ai pas encore « touché » cela. Il y a une librairie « EEPROM », qui permet de sauver cela.
• Rajouter des commandes pour aller directement sur une gamelle précise, par exemple GoTo1, GoTo2, ... Le capteur nous permet de connaitre une position, il suffit ensuite de travailler par offset par rapport à ce point de référence.
• Rajouter un MP3 ou simplement un buzzer pour informer le chat lorsqu’une nouvelle gamelle est disponible.
• Mettre un capteur RFID (merci Christian pour l’idée), et le montage présente la gamelle uniquement lorsque le chat approche.
Conclusions
Ce circuit NodeMCU 8266 est vraiment impressionnant. Il se programme comme un Arduino, offre des possibilités énormes, et cela pour quelques euros. Après l’automatisation de ma porte de garage, la création d’une surveillance d’appareil par pings régulier, un haut-parleur HIFI pour ma eedomus, voici donc une gamelle pour chat. Avez-vous d’autres idées ?