Outils pour utilisateurs

Outils du site


issue99:automatic_chicken_feeder

Last month I discussed the background and gave the layout for my Arduino powered automatic chicken feeder. This month we’ll discuss the code that it runs. Grab The Code You should first grab my code from: https://gist.github.com/ronnietucker/a68b26ff53b7164b7775 The Code Lines 8 to 61 are all procedures for the DHT11 (temperature) sensor. I’m not even going to pretend I know the ins and outs of them, but I know they are used in converting the DHT11 values to human readable temperature values. Lines 62 to 68 are all includes for the various libraries required. Each line has a comment which says what that library is used for. Line 81 is where the good stuff starts. UTFT myGLCD(QD_TFT180A,11,10,9,12,8); This line is for the TFT screen I used. The command myGLCD() contains the setup info for my particular screen. QD_TFT180A is the type of screen I used, and the numbers 11, 10, 9, 12 and 8 are the pins I used for the screen. We then have some setup for the various values that I need later. Setup() After some myGLCD commands (that we’ve used before), we have: setSyncProvider(RTC.get); This is to grab the time from the RTC (Real Time Clock). The RTC has a battery on board so it keeps the time even when the Arduino (and RTC board) is powered down. After that comes an if statement to see if the grab was successful.

Le mois dernier, j'ai présenté le contexte et donné la disposition de mon nourrisseur automatique de poulets avec Arduino. Ce mois-ci, je vous montre le code qui tourne dessus.

Récupérer le code

Vous devez d'abord récupérer mon code depuis : https://gist.github.com/ronnietucker/a68b26ff53b7164b7775

Le code

Des lignes 8 à 61, ce sont toutes les procédures pour le détecteur DHT11 (température). Je n'irai pas jusqu'à prétendre que je connais tout d'elles, mais je sais qu'elles sont utilisées pour convertir les valeurs du DHT11 en valeurs de températures lisibles par un humain.

Des lignes 62 à 68, ce sont tous les include pour les différentes bibliothèques nécessaires. Chaque ligne a un commentaire qui dit à quoi sert chaque bibliothèque.

A la ligne 81, commencent les bons morceaux.

UTFT myGLCD(QD_TFT180A,11,10,9,12,8);

Cette ligne est pour l'écran TFT que j'utilise. La commande myGLCD() contient les infos de réglage pour mon écran en particulier. J'utilise un type d'écran QD_TFT180A, et les nombres 11, 10, 9, 12 et 8 sont les picots que j'utilise pour l'écran.

Ensuite viennent quelques réglages de valeurs diverses dont j'ai besoin après.

Setup()

Après quelques commandes myGLCD (que nous avons déjà vues), nous avons :

setSyncProvider(RTC.get);

C'est pour récupérer le temps du RTC (Real Time Clock : horloge en temps réel). Le RTC a une batterie sur le circuit de façon à conserver l'heure même quand l'Arduino (et la carte RTC) est hors tension. Après cela, vient une déclaration if pour voir si la récupération a été effective.

Alarm.alarmRepeat(9,00,0,RTCAlarm); Alarm.alarmRepeat(11,00,0,RTCAlarm); The Alarm.alarmRepeat commands are daily. So, in the case above, the ‘alarm’ will go at 9am and 11am precisely every day. The 9,00,0 refers to hour, minutes and seconds. RTCAlarm is the procedure to jump to when the alarm time is reached. We’ll discuss that later. In my code, I have several daily alarms. Now that I’ve told the Arduino when I want alarms, I set up the servo and set the pin modes for my manual button and my green LED (which will illuminate when a feed is in progress). Loop() First in the loop, we jump to the digitalClickDisplay() procedure which will show the current time to the serial window. Next, we jump to the digitalTriggerDisplay() procedure. This will print the time of the next alarm to the serial. These were used prior to the screen being fitted. Lines 131 to 148 are where we begin printing the DHT11 temperature data to the serial too. Again, prior to the screen. Line 150 is the beginning of the LCD screen outputs. myGLCD.setColor(0, 255, 255); myGLCD.printNumI((float)DHT11.temperature,1,1); myGLCD.print(“'C”,35, 1); myGLCD.printNumI((float)DHT11.humidity,90,1); myGLCD.print(“%”,130, 1);

Alarm.alarmRepeat(9,00,0,RTCAlarm);

Alarm.alarmRepeat(11,00,0,RTCAlarm);

Les commandes Alarm.alarmRepeat sont journalières. Ainsi, dans le cas ci-dessus, l'« alarme » se déclenchera chaque jour à 9 h et 11 h du matin précisément. Le format 9,00,0 fait référence à l'heure, aux minutes et aux secondes. RTCAlarm est la procédure à démarrer quand l'heure d'alarme est atteinte. Nous en reparlerons plus tard.

Dans mon code, j'ai plusieurs alarmes journalières.

Maintenant que j'ai indiqué à Arduino quand je veux des alarmes, je règle mon servomoteur et précise le mode des picots pour mon bouton manuel et ma LED verte (qui s'éclaire quand l'alimentation est en cours).

Loop()

En premier, dans la boucle, nous sautons à la procédure digitalClickDisplay() qui présentera l'heure courante dans la fenêtre série. Ensuite, nous passons à la procédure digitalTriggerDisplay(). Ceci imprimera l'heure de la prochaine alarme sur la liaison série. Elles ont été utilisées avant que l'écran ne soit mis en place.

Aux lignes 131 à 148, nous commençons à imprimer la température du DHT11 sur la liaison série aussi. À nouveau, avant la mise en place de l'écran.

À la ligne 150 commencent les sorties vers l'écran LCD.

myGLCD.setColor(0, 255, 255);

myGLCD.printNumI((float)DHT11.temperature,1,1);

myGLCD.print(“'C”,35, 1);

myGLCD.printNumI((float)DHT11.humidity,90,1);

myGLCD.print(“%”,130, 1);

The code above is setting the colour to yellow, printing the temperature, printing ‘C, printing the humidity and, finally, a percentage (%) symbol. The two numbers at the end of each line are where that text should be printed with 1,1 being the very top left of the screen (in pixels). Lines 158 to 164 are the same idea with white text, but for the light level from the LDR. myGLCD.printNumI(hour()+1,1, 45); myGLCD.print(“:”,33, 45); myGLCD.printNumI(minute(),45, 45); myGLCD.print(“:”,80, 45); myGLCD.printNumI(second(),95, 45); These lines (above) are printing the time to the screen. The reason for the +1 is for daylight savings here in the UK. myGLCD.setColor(0, 200, 255); myGLCD.printNumI(hour(Alarm.getNextTrigger())+1,1, 65); myGLCD.print(“:”,33, 65); myGLCD.printNumI(minute(Alarm.getNextTrigger()),45, 65); myGLCD.print(“:”,80, 65); myGLCD.printNumI(second(Alarm.getNextTrigger()),95, 65); The lines above are for setting an orangey colour then printing the next alarm (again, +1 hr).

Le code ci-dessus règle la couleur en jaune, imprime la température, imprime 'C, imprime l'humidité et, pour finir, un symbole pourcentage (%). Les deux nombres à la fin de chaque ligne sont là où le texte doit être imprimé, 1,1 étant l'angle en haut à gauche de l'écran (en pixels).

Pour les lignes 158 à 164, c'est la même idée avec un texte blanc, mais pour le niveau de luminosité de la photorésistance (LDR - light-dependent resistor).

myGLCD.printNumI(hour()+1,1, 45);

myGLCD.print(“:”,33, 45);

myGLCD.printNumI(minute(),45, 45);

myGLCD.print(“:”,80, 45);

myGLCD.printNumI(second(),95, 45);

Ces lignes (ci-dessus) impriment l'heure sur l'écran. La raison du +1 vient de l'heure d'été ici au Royaume-Uni.

myGLCD.setColor(0, 200, 255);

myGLCD.printNumI(hour(Alarm.getNextTrigger())+1,1, 65);

myGLCD.print(“:”,33, 65);

myGLCD.printNumI(minute(Alarm.getNextTrigger()),45, 65);

myGLCD.print(“:”,80, 65);

myGLCD.printNumI(second(Alarm.getNextTrigger()),95, 65);

Les lignes ci-dessus règlent une couleur orangée, puis impriment la prochaine heure d'alarme (à nouveau, +1h).

Lines 186 to 219 are commented out and were used when I originally used a small font. I kept this chunk of code in there in case the big font didn’t work out and I had to revert back. button=digitalRead(4); Now we check to see if the button has been pressed for a manual feed. if (button==HIGH) { digitalWrite(greenLED, HIGH); GREEN LED ON Serial.println(“Button pressed”); dispense(opened,closed); digitalWrite(greenLED, LOW); GREEN LED OFF } If the button is pressed (it goes HIGH) then we light the green LED, print a confirmation to the serial, jump to a procedure called dispense(), then turn the LED off. Lastly, we have a one-second delay.

Les lignes 186 à 219 sont commentées ; elles étaient utilisées au début quand j'utilisais une petite police. J'ai gardé ce morceau de code ici au cas où la grande police ne marcherait pas et que j'aie à revenir en arrière.

button=digitalRead(4);

Maintenant, nous vérifions s'il y a eu une pression sur le bouton pour une alimentation manuelle.

if (button==HIGH)

{
  digitalWrite(greenLED, HIGH);   // GREEN LED ON - LED VERTE ALLUMÉE
  Serial.println("Button pressed");
  
  dispense(opened,closed);           
  digitalWrite(greenLED, LOW);    // GREEN LED OFF - LED VERTE ÉTEINTE
   
}

Si on a appuyé sur le bouton (il passe à l'état haut), alors nous allumons la LED verte, imprimons une confirmation sur la liaison série, sautons à la procédure appelée dispense(), puis éteignons la LED.

Enfin, nous avons un délai d'une seconde.

Jumping down to line 279 we see the RTCAlarm() procedure. In here we do a confirmation print to the serial, light the LED, jump to the dispense() procedure, and return to turn off the LED. Line 238 is the dispense() procedure. This is the main crux of the machine. It dispenses the grain for the chickens. myServo.write(opened); myGLCD.setColor(0, 0, 255); myGLCD.print(“FEEDING”,CENTER, 110); delay(2000); myServo.write(closed); myGLCD.setColor(0, 0, 0); myGLCD.fillRect(0,109,160,128); Here we turn the servo forward (“opened” was defined at the start of the code and is the angle the servo is to turn to). Next, we set the LCD colour to red, print ‘FEEDING’ to the screen, wait two seconds (the length of time for just enough grain), turn the servo back (“closed” was also declared at the start), set the LCD colour to black, and draw a rectangle to erase the ‘FEEDING’ text. It’s definitely the most difficult code I’ve worked on and it’s not perfect. More work could have been done in displaying the time. It’s a bit botched, but to write further code would have taken me over the limit for the Nano I used. For sheer amusement, have a look through the eight revisions on my GitHub Gist page and you’ll see it evolve through time.

En descendant à la ligne 279, nous voyons la procédure RTCAlarm(). Ici, nous avons une impression de confirmation de l'heure, l'éclairage de la LED, un saut vers la procédure dispense() et, au retour, l'extinction de la LED.

A la ligne 238, c'est la procédure dispense(). C'est l'essence même de la machine. Elle distribue du grain aux poulets.

myServo.write(opened);

myGLCD.setColor(0, 0, 255);

myGLCD.print(“FEEDING”,CENTER, 110);

delay(2000);

myServo.write(closed);

myGLCD.setColor(0, 0, 0);

myGLCD.fillRect(0,109,160,128);

Ici, nous faisons tourner le servomoteur en avant (« opened » a été défini au début du code ; c'est l'angle auquel tourne le servomoteur). Ensuite, nous réglons la couleur de la LED à rouge, imprimons « FEEDING » (en cours d'alimentation) sur l'écran, attendons deux secondes (juste le temps pour assez de grain), tournons le servomoteur en arrière (« closed » a aussi été déclaré au début), passons la couleur de la LED à noir et traçons un rectangle pour effacer le texte « FEEDING ».

C'est vraiment le code le plus difficile sur lequel j'ai travaillé et il n'est pas parfait. Plus de travail aurait pu être fait pour afficher l'heure. C'est un peu bâclé, mais écrire plus de code m'aurait fait aller au-delà de la limite du Nano que j'utilisais.

Pour le pur plaisir, regardez les huit révisions sur ma page Github Gist et en vous verrez son évolution dans le temps.

issue99/automatic_chicken_feeder.txt · Dernière modification : 2015/08/15 15:06 de andre_domenech