Pilotage d’un moteur avec arduino et raspberry pi

Porte automatique de poulailler avec Raspberry  Pi et Arduino

Préambule

Cet article est rédigé au fil de l’eau (de l’expérimentation).

Il me permet aussi de tester l’usage de wordPress que je découvre progressivement.

La mise en forme est approximative, elle pourra évoluer dans une version ultérieure de cet article.

Contexte :

Cet été 2014, mon fils et moi avons construit un poulailler : projet des vacances.
Il est habité par 5 poules depuis mi septembre.
Les poules se couchent avec le coucher du soleil et se réveillent à son lever.
Les 2 poules adultes pondent 1 oeuf chaque matin. Les 3 autres sont encore trop jeunes.
Pendant leur sommeil, il faut les protéger des prédateurs nocturnes.
Il faut donc enfermer les poules après leur coucher et les libérer le matin.
Fastidieux.
Comme beaucoup d’autres avant nous, l’idée est donc d’automatiser cette porte ! Voir sur youtube la multitude de réalisations !

Enjeu :

Ne plus se préoccuper de l’ouverture (le matin) et de la fermeture (le soir) de la porte du poulailler.

Objectif :

Mettre en place une porte automatisée asservie par les horaires de lever et de coucher du soleil.
Ceci en combinant un Raspberry Pi et un Arduino.

Les moyens :

  • un arduino
  • un raspbery pi
  • soit un servo moteur ou un moteur pas à pas (stepper motor)
  • un poulailler et des poules 😉

Différences entre un servo moteur et un moteur pas à pas

Stepper vs. Servo: The Verdict

Servo control systems are best suited to high speed, high torque applications that involve dynamic load changes. Stepper control systems are less expensive and are optimal for applications that require low-to-medium acceleration, high holding torque, and the flexibility of open or closed loop operation.
http://www.amci.com/tutorials/tutorials-stepper-vs-servo.asp

DC Motors

Fast, continuous rotation motors – Used for anything that needs to spin at a high RPM e.g. car wheels, fans etc.

Servo Motors

Fast, high torque, accurate rotation within a limited angle – Generally a high performance alternative to stepper motors, but more complicated setup with PWM tuning. Suited for robotic arms/legs or rudder control etc.

Stepper Motors

Slow, precise rotation, easy set up & control – Advantage over servo motors in positional control. Where servos require a feedback mechanism and support circuitry to drive positioning, a stepper motor has positional control via its nature of rotation by fractional increments. Suited for 3D printers and similar devices where position is fundamental.

https://www.modmypi.com/blog/whats-the-difference-between-dc-servo-stepper-motors

Conclusion : pour la porte du poulailler le servo moteur est plus adapté, plus simple à piloter, pas besoin de contrôle fin de la position, juste pouvoir agir sur un bras articulé pour ouvrir et fermer cette porte.

 

http://eskimon.fr/287-arduino-602-un-moteur-qui-de-la-tete-le-servo-moteur

Ressources on-line

Pilotage d’un servo moteur

avec un Arduino

voir exellent article : http://eskimon.fr/287-arduino-602-un-moteur-qui-de-la-tete-le-servo-moteur

Par exemple, si mon servo possède comme caractéristique des durées de 1ms pour 0° et 2ms pour 180° et que je l’ai branché sur la broche 2 :

#include <Servo.h>
Servo monServo;
void setup()
{
monServo.attach(2, 1000, 2000);
monServo.write(90);
}
void loop()
{}

autre exemple : http://www.zem.fr/controler-un-mini-servo-avec-arduino/

// Sweep
// by BARRAGAN <http://barraganstudio.com>
// This example code is in the public domain.

#include <Servo.h>

Servo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created

int pos = 0; // variable to store the servo position

void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
}

void loop()
{
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(15); // waits 15ms for the servo to reach the position
}
for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(15); // waits 15ms for the servo to reach the position
}
}

Voir aussi : http://arduino.alolise.org/doku.php?id=circ04_oomlout

Application avec mon Corona CS 939MG

  « S » Type Connector    Futaba « J » Connector    Wire Info 

Brown Wire

Black Wire

  Battery Negative 

Red Wire

Red Wire

  Battery Positive 

Orange Wire

White Wire

Signal

 

http://www.bphobbies.com/view.asp?id=D3925412&pid=E0835794

Astuce : pour trouver le bon port série : Select the serial device of the Arduino board from the Tools | Serial Port menu. This is likely to be COM3 or higher (COM1 and COM2 are usually reserved for hardware serial ports). To find out, you can disconnect your Arduino board and re-open the menu; the entry that disappears should be the Arduino board. Reconnect the board and select that serial port.

ça marche !

Changement de moteur : démontage ancienne visseuse/dévisseuse, cablage de l’inverseur avec un jeu de relais et programmation de l’Arduino.

Et … ça marche !

LE code :

int motor_pin = 13;// Motor command connected to digital pin 13
int relais1_pin = 12;
int relais2_pin = 8;

void setup()
{
pinMode(motor_pin, OUTPUT); // moteur sets the digital pin as output
pinMode(relais1_pin, OUTPUT); // inverseur sets the digital pin as output
pinMode(relais2_pin, OUTPUT); // inverseur sets the digital pin as output
}

void moteur_on()
{
digitalWrite(motor_pin, LOW); // sets the MOTOR on
}

void moteur_off()
{
digitalWrite(motor_pin, HIGH); // sets the motor off
}
void set_normal()
{
// normal, repos
digitalWrite(relais1_pin, HIGH); // relay 1 on
digitalWrite(relais2_pin, HIGH); // relay 2 on
}

void set_inverse()
{
digitalWrite(relais1_pin, LOW); // relay 1 on
digitalWrite(relais2_pin, LOW); // relay 2 on
}

void loop()
//void once()
{
set_normal();
moteur_on();
delay(5000); // waits for a 5 second
//marche normale pendant 5 seconde
//arret moteur
moteur_off();
delay(1000);
set_inverse();
moteur_on();
delay(5000); // waits for a 5 second
// arret moteur
moteur_off();
set_normal();
delay(10000);
}

 

avec un Raspberry Pi

voir :

 

Mécaniques …

Pour la mise en oeuvre de la porte automatique de nombreux scénarii sont possibles…

Ouverture latérale

Exemples :

Ouverture verticale

Exemples :

Ouverture de type « pont levis »

L’automatisme

Les déclencheurs

manuel

depuis une inerface web : interessant pour la fermeture et éviter soit d’écraser une poule, soit de laisser des poules à l’extérieur

selon le niveau d’obscurité

d’apres l’article ici (http://davenaves.com/blog/interests-projects/chickens/chicken-coop/arduino-chicken-door/), il semble que les poules soient surtout sensibles à la luminosité/obscurité plutôt qu’aux horaires de lever et coucher du soleil… Ca peut sembler logique. On aurait donc plutôt tendance à utiliser des capteurs de luminosité plutôt qu’à un éphéméride.

Inconvénient majeur : que se passe-t-il en cas d’obscurssissement en cours de journée, gros orage par exemple. La porte risque de se fermer inopinément avec les poules à l’extérieur ou sur le pas de la porte. A étudier …

selon les horaires de lever et coucher du soleil

Ce scénario est possible avec un Raspberry Pi en allant chercher sur internet les horaires, soit en préparant un fichier contenant les horaires de lever et coucher sur une ou plusieurs années.

Les contrôles de fin de course

Pour savoir si la porte est « ouverte » ou « fermée », il faut déterminer de façon sûre la position de la porte. On utilise classiquement des contacteurs de fin de course, qui lorsqu’ils ont activés indiquent au moteur qu’il doit s’arrêter, soit d’ouvrir, soit de fermer.

Dans l’article ici (http://davenaves.com/blog/interests-projects/chickens/chicken-coop/arduino-chicken-door/), il est recommandé d’éviter les interrupteurs mécaniques et de préférer les contacteurs magnétiques (contacts « reed »). Suis d’accord !

 L’informatique de commande

Utilisation d’un module Arduino piloté par le module Raspberry Pi (RasPi)

Apres un premier week-end consacré à

  • choisir le moteur et
  • bricoler une vieille visseuse/devisseuse,
  • à cabler un module Arduino et un kit de 4 relais (pour la commande du sens de la marche)
  • à assembler le tout sur une planche d’essai
  • à aligner quelques lignes de code pour tester dans l’environnement Arduino,

Le code test de la visseuse/devisseuse :

int motor_pin = 13;// Motor command connected to digital pin 13
int relais1_pin = 12;
int relais2_pin = 8;

void setup()
{
 pinMode(motor_pin, OUTPUT); // moteur sets the digital pin as output
 pinMode(relais1_pin, OUTPUT); // inverseur sets the digital pin as output
 pinMode(relais2_pin, OUTPUT); // inverseur sets the digital pin as output
}

void moteur_on()
{
 digitalWrite(motor_pin, LOW); // sets the MOTOR on
}

void moteur_off()
{
 digitalWrite(motor_pin, HIGH); // sets the motor off
}


void set_normal()
{
 // normal, repos
 digitalWrite(relais1_pin, HIGH); // relay 1 on
 digitalWrite(relais2_pin, HIGH); // relay 2 on
}

void set_inverse()
{
 digitalWrite(relais1_pin, LOW); // relay 1 on
 digitalWrite(relais2_pin, LOW); // relay 2 on
}

void loop()
//void once()
{
 set_normal();
 moteur_on();
 delay(5000); // waits for a 5 second
 //marche normale pendant 5 seconde
 //arret moteur 
 moteur_off();
 delay(1000);
 set_inverse();
 moteur_on();
 delay(5000); // waits for a 5 second
 // arret moteur 
 moteur_off();
 set_normal();
 delay(10000);
}

Le second week-end est consacré au raccordement du Raspberry Pi au module Arduino, pour commander le système depuis du code en Python.

Installation des modules logiciels côté RasPi : SerialPy, Nanpy, (cf The-Mag-Pi-issue-8, 15 et 16)

Installation Nanpy côté Arduino

Le code de tests permettant de commander le moteur (marche normale = monter)

#! usr/bin/env python

from nanpy import (ArduinoApi, SerialManager)
import time

print "CONNEXION"
#connection = SerialManager()
connection = SerialManager(device='/dev/ttyACM0')

print "ARDUINO"
a = ArduinoApi(connection=connection)


relais2 = 8
relais1 = 12
moteur = 7


#etat_relais1 = a.digitalRead(relais1)

print "SET UP"
a.pinMode(relais1,a.OUTPUT)
a.pinMode(relais2,a.OUTPUT)
a.pinMode(moteur,a.OUTPUT)


print "MONTER"
# sens MONTER
a.digitalWrite(relais1,a.HIGH)
a.digitalWrite(relais2,a.HIGH)

print "ALLUMAGE"
# moteur ON
a.digitalWrite(moteur,a.LOW)

print "BOUCLE 5s"
time.sleep(5)

print "STOP"
# moteur OFF
a.digitalWrite(moteur,a.HIGH)

Code test pour l’asservissement à une photoresistance :

#! usr/bin/env python

from nanpy import (ArduinoApi, SerialManager)
import time

print "CONNEXION"
connection = SerialManager()
#connection = SerialManager(device='/dev/ttyACM0')

print "SETTING ARDUINO"
a = ArduinoApi(connection=connection)
print "DONE"

photo = 14 #A0
#15 = A1
#16 = A2

a.pinMode(photo,a.INPUT)


while 1:
 luminosite = a.analogRead(photo)*(5.0/1024.0)
 print photo, luminosite
 time.sleep(0.5)
 #
 if (luminosite > 4):
 print "----> JOUR"
 if (luminosite < 2):
 print "----> NUIT"

Solution permettant de déclencher des scripts Python en fonction d’événements. Exemples :

  • Mettre moteur en marche lorsque la luminosité dépasse un certain seuil
  • Faire tourner le moteur tant que le capteur de fin de course « porte en haut » n’est pas activé
  • Alerter le gardien des poules qu’il est l’heure de fermer la porte (par interface web avec photo permettant de vérifier que toutes les poules sont rentrées) lorsque la luminosité est passée en dessous d’un certain seuil,
  • etc …

Il s’agit ici de mettre en oeuvre un « gestionnaire d’événement » (event handler). un modèle de développement logiciel à regarder est le « observer pattern« .

Voir aussi  (Functional) Reactive Programming et Trellis library.

voir : http://stackoverflow.com/questions/6190468/how-to-trigger-function-on-value-change

–> voir : http://stackoverflow.com/questions/16143842/raspberry-pi-gpio-events-in-python (exemple de code simple avec boucle, ou avec gestion multi process)

 Lancer un script Python depuis une page Web

Voir :

Essai avec webiopi :

  • http://code.google.com/p/webiopi/wiki/INSTALL
  • http://code.google.com/p/webiopi/wiki/Tutorial_Macros
  • Mise en place des 3 fichiers nécessaires :
    • etc/webiopi/config (il référence les 2 fichiers ci-dessous)
    • /home/pi/Poulailler/moniteur/html/index.html : c’est la page web qui contient les infos et les actionneurs
    • /home/pi/Poulailler/moniteur/Python/exemple.py : c’est le script python qui contient le code exécuté par webiopi et qui est en interaction avec la page web
  • lancement du serveur :
    • sudo webiopi -d -c /etc/webiopi/config
  • lancement du client (la page web)
    • http://192.168.1.12:8000/ (webiopi/raspberry)
  • arret/relance du serveur pour relecture du fichier python
    • sudo /etc/init.d/webiopi start and
      sudo /etc/init.d/webiopi stop
      You can even setup your system to start webiopi at startup :
      sudo update-rc.d webiopi defaults
  • Probleme avec « import nanpy » du fichier exemple.py   (module pas trouvé) : cause et résolution :
    • webiopi fonctionne avec python 3 alors que l’install de nanpy a été faite avec « python » (soit en 2.7 par defaut).
    • Le probleme est corrigé en faisant « sudo python3 setup.py install » qui appelle python3 explicitement et pas python2.7 ce qui a comme conséquence de placer la lib nanpy dans le bon répertoire de l’environnement python3.
    • content d’avoir trouvé !!!
  • Le fichier index.html :
  • <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
     <title>WebIOPi | Light Control</title>
     <script type="text/javascript" src="/webiopi.js"></script>
     <script type="text/javascript">
     webiopi().ready(function() {
     // Create a "Light" labeled button for GPIO 17
     //var button = webiopi().createGPIOButton(17, "Light");
    
     // Append button to HTML element with ID="controls" using jQuery
     //$("#controls").append(button);
    
     // Refresh GPIO buttons
     // pass true to refresh repeatedly of false to refresh once
     //webiopi().refreshGPIO(true);
    
     // Following function will process data received from set/getLightHours macro.
     var updateLightHours = function(macro, args, response) {
     var hours = response.split(";");
     // Following lines use jQuery functions
     $("#inputOn").val(hours[0]);
     $("#inputOff").val(hours[1]);
     };
    
     // Immediately call getLightHours macro to update the UI with current values
     // "getLightHours" refers to macro name
     // [] is an empty array, because getLightHours macro does not take any argument
     // updateLightHours is the callback function, defined above
     webiopi().callMacro("getLightHours", [], updateLightHours);
     
     // Create a button to call setLightHours macro
     var sendButton = webiopi().createButton("sendButton", "Send", function() {
     // Arguments sent to the macro
     var hours = [$("#inputOn").val(), $("#inputOff").val()];
     // Call the macro
     webiopi().callMacro("setLightHours", hours, updateLightHours);
     });
    
     // Append the button to the controls box using a jQuery function
     $("#controls").append(sendButton);
    
     // create a button to switch ON the engine
     turnonButton = webiopi().createButton("turnonButton","ON", function() {
     webiopi().callMacro("setMoteurOn");
     });
     $("#content").append(turnonButton); // append button to content div
    
     // create a button to switch OFF the engine
     turnoffButton = webiopi().createButton("turnoffButton","OFF", function() {
     webiopi().callMacro("setMoteurOff");
     });
     $("#content").append(turnoffButton); // append button to content div
    
    
     })
     
     </script>
     <style type="text/css">
     button {
     display: block;
     margin: 5px 5px 5px 5px;
     width: 160px;
     height: 45px;
     font-size: 24pt;
     font-weight: bold;
     color: white;
     }
     turnonButton {
     display: block;
     margin: 5px 5px 5px 5px;
     width: 160px;
     height: 45px;
     font-size: 24pt;
     font-weight: bold;
     color: black;
     }
     
     #gpio17.LOW {
     background-color: Black;
     }
     
     #gpio17.HIGH {
     background-color: Blue;
     }
     </style>
    </head>
    <body>
     <!--
     <div id="controls" align="center"></div>
    
     <div align="center">
     Turn On at :<input type="text" id="inputOn" /><br/>
     Turn Off at: <input type="text" id="inputOff" /><br/>
     </div>
     -->
     <div id="content" align="center"></div>
    </body>
    </html>
  • le fichier exemple.py
  • #! usr/bin/env python
    
    import webiopi
    import datetime
    import os
    import time
    
    from nanpy import (ArduinoApi, SerialManager)
    
    GPIO = webiopi.GPIO
    
    LIGHT = 17 # GPIO pin using BCM numbering
    
    HOUR_ON = 8 # Turn Light ON at 08:00
    HOUR_OFF = 18 # Turn Light OFF at 18:00
    
    #print "CONNEXION"
    #connection = SerialManager()
    connection = SerialManager(device='/dev/ttyACM0')
    
    #print "ARDUINO"
    a = ArduinoApi(connection=connection)
    
    relais2 = 8
    relais1 = 12
    moteur = 7
    
    
    # setup function is automatically called at WebIOPi startup
    def setup():
     
    
     #print "SET UP"
     a.pinMode(relais1,a.OUTPUT)
     a.pinMode(relais2,a.OUTPUT)
     a.pinMode(moteur,a.OUTPUT)
    
     #print "MONTER"
     # sens MONTER
     a.digitalWrite(relais1,a.HIGH)
     a.digitalWrite(relais2,a.HIGH)
     # moteur OFF
     a.digitalWrite(moteur,a.HIGH)
    
    
     # set the GPIO used by the light to output
     #GPIO.setFunction(LIGHT, GPIO.OUT)
    
     # retrieve current datetime
     now = datetime.datetime.now()
    
     # test if we are between ON time and tun the light ON
     #if ((now.hour >= HOUR_ON) and (now.hour < HOUR_OFF)):
     #GPIO.digitalWrite(LIGHT, GPIO.HIGH)
    
    
    # loop function is repeatedly called by WebIOPi 
    def loop():
     # retrieve current datetime
     now = datetime.datetime.now()
    
     # toggle light ON all days at the correct time
     #if ((now.hour == HOUR_ON) and (now.minute == 0) and (now.second == 0)):
     #if (GPIO.digitalRead(LIGHT) == GPIO.LOW):
     #GPIO.digitalWrite(LIGHT, GPIO.HIGH)
    
     # toggle light OFF
     #if ((now.hour == HOUR_OFF) and (now.minute == 0) and (now.second == 0)):
     #if (GPIO.digitalRead(LIGHT) == GPIO.HIGH):
     #GPIO.digitalWrite(LIGHT, GPIO.LOW)
     
     # gives CPU some time before looping again
     webiopi.sleep(1)
    
    # destroy function is called at WebIOPi shutdown
    def destroy(): 
     GPIO.digitalWrite(LIGHT, GPIO.LOW)
     a.digitalWrite(moteur,a.HIGH)
    
    
    @webiopi.macro
    def setMoteurOn():
     #print "ALLUMAGE"
     # moteur ON
     a.digitalWrite(moteur,a.LOW)
    
    @webiopi.macro
    def setMoteurOff():
     #print "ARRET"
     # moteur OFF
     a.digitalWrite(moteur,a.HIGH)
    
    @webiopi.macro
    def getLightHours():
     return "%d;%d" % (HOUR_ON, HOUR_OFF)
    
    
    @webiopi.macro
    def setLightHours(on, off):
     global HOUR_ON, HOUR_OFF
     HOUR_ON = int(on)
     HOUR_OFF = int(off)
     return getLightHours()

Le tout affiche une page web avec 2 boutons : ON et OFF qui respectivement mettent en marche et arrete le moteur de la visseuse !

En résumé :

  • le bouton de la page index.html déclenche un script javascript qui active la macro correspondant définie dans le fichier exemple.py
  • cette macro lance elle même une commande interprétée par nanpy pour transmettre l’ordre du raspberry vers l’Arduino via la liaison série USB.

C’est tout pour ce second week-end.

Edition des fichiers à distance ; Console graphique déportée, serveur FTP :

  • lancer Xming,
  • se connecter avec putty,
  • lancer startlxde. La session graphique du Raspi apparait ! (c’est le même résultat que j’avais obtenu avec VNC, le principe semble identique.)
    Plus d’info ici :
    http://www.raspians.com/Knowledgebase/how-to-remote-desktop-with-xming-and-putty/En complément :
  • status serveur FTP : sudo service proftpd status (OK, lancé au démarrage)
  • sinon : sudo service proftpd start
  • vérification : ps –aux | grep proftpd
  • lancement automatique : chkconfig proftpd on
  • sudo vi /etc/proftpd/proftpd.conf
  • Sudo service proftpd restart

Puis édition possible des fichiers :

  • soit depuis l’emulateur Xming
  • pour les fichiers non html : soit depuis Notepad++ en ayant configuré l’acces aux fichiers via FTP (module NppFTP) :
    NB : évite d’avoir à installer SAMBA
  • pour les fichiers html en mode source ou graphique : soit depuis Kompozer

Mise en place des fins de course (20141101-02)

Principe

Il faut pouvoir déterminer quand arrêter le moteur, soit en montée, soit en descente.

Pour cela, il faut placer 2 contacteurs sur la porte, un dans la partie haute, qui permettra d’indiquer que la porte est arrivée en position haute, et un autre dans la partie basse, pour indiquer que la porte est fermée.

Les contacteurs utilisés sont des contacteurs magnétiques semblable à (10 pour 10$, 5 pour 8$) :

Normally OPEN NO Magnetic Contact door window reed switch WHITE.2pairs

L’absence de parties mécaniques comme pour ce type de contacteur

(1)XZ7-121 NO+NC Micro Limit Switch SPDT Contact Hinge Roller Lever Type 10A125V ou MICRO SWITCH X88758 PW3 N.O. CONTACT BOOCK

est en effet préférable en usage extérieur, et en plus c’est moins cher.

L’inconvénient est peut être la précision ou l’ajustement dans la position du contact.

Le montage de principe est celui illustré ci-dessous : (http://arduino.cc/en/tutorial/button), avec un résistance de 10kOhms ( pull-down resistor) (marron, noir, orange)

Lorsque que les 2 parties du contact ne sont pas en vis à vis, le contact est OUVERT, l’état de la pin est LOW.

Lorsque la porte va bouger est que les 2 parties vont être en vis à vis, l’aimant va refermer le contact et l’état de la pi va passer à HIGH

Donc :

  • en position, état HIGH
  • en transition (la porte bouge, ou s’arrête inopinément)  : état LOW

Pour l’expérimentation, on va faire en sorte que l’état de ces 2 pins soit représentées sur l’interface web, en temps réel.

Ensuite, la logique de commande sera mise à jour  : une fois la commande « monter » ou « descendre » lancée, provoquer un arret sur événements :

  • déclenchement contact haut ou bas (contacts magnétiques)
  • nombre de secondes (paramètre)

Afficher état courant d’une variable ou d’un état en temps réel avec webiopi (20141101-02)

  • tester avec l’heure : OK
  • tester avec état des contacteurs : OK
  • la valeur de la luminosité : OK
  • mise en place bouton type bascule avec changement d’état : OK
  • affichage et changement du sens de marche du moteur : OK

Paramétrage envoi d’email (20141101-02)

  • cf sendEmail3.py : OK

Mise en place 2 sondes de température (20141111)

Cablage

mise en place du code

affichage sur la page web

mais pb avec les valeurs obtenues …

Mise en place de la logique associée au capteurs de fin de course (20141111)

Problème de perte de la connexion Wifi

le Raspi  tourne bien (vérification via le /var/log/syslog)  (donc la gestion de la porte est a priori  assurée, mais aucun moyen de communiquer à moins d’un hard reset sur place.

Détail ci-dessous de la trace qui indique la cause et la perte du wifi :

Nov 13 03:47:39 raspberrypi ifplugd(wlan0)[1693]: Link beat lost.
Nov 13 03:47:41 raspberrypi wpa_supplicant[1752]: wlan0: CTRL-EVENT-DISCONNECTED bssid=2c:39:96:29:8b:aa reason=0
Nov 13 03:47:41 raspberrypi wpa_action: WPA_IFACE=wlan0 WPA_ACTION=DISCONNECTED
Nov 13 03:47:41 raspberrypi wpa_action: WPA_ID=0 WPA_ID_STR= WPA_CTRL_DIR=/var/run/wpa_supplicant
Nov 13 03:47:41 raspberrypi wpa_action: ifdown wlan0
Nov 13 03:47:41 raspberrypi dhclient: Internet Systems Consortium DHCP Client 4.2.2
Nov 13 03:47:41 raspberrypi dhclient: Copyright 2004-2011 Internet Systems Consortium.
Nov 13 03:47:41 raspberrypi dhclient: All rights reserved.
Nov 13 03:47:41 raspberrypi dhclient: For info, please visit https://www.isc.org/software/dhcp/
Nov 13 03:47:41 raspberrypi dhclient: 
Nov 13 03:47:41 raspberrypi dhclient: Listening on LPF/wlan0/ac:a2:13:30:12:c4
Nov 13 03:47:41 raspberrypi dhclient: Sending on   LPF/wlan0/ac:a2:13:30:12:c4
Nov 13 03:47:41 raspberrypi dhclient: Sending on   Socket/fallback
Nov 13 03:47:41 raspberrypi dhclient: DHCPRELEASE on wlan0 to 192.168.1.1 port 67
Nov 13 03:47:41 raspberrypi avahi-daemon[2234]: Withdrawing address record for 192.168.1.12 on wlan0.
Nov 13 03:47:41 raspberrypi avahi-daemon[2234]: Leaving mDNS multicast group on interface wlan0.IPv4 with address 192.168.1.12.
Nov 13 03:47:41 raspberrypi avahi-daemon[2234]: Interface wlan0.IPv4 no longer relevant for mDNS.
Nov 13 03:47:41 raspberrypi wpa_action: removing sendsigs omission pidfile: /run/sendsigs.omit.d/wpasupplicant.wpa_supplicant.wlan0.pid
Nov 13 03:47:44 raspberrypi ntpd[2317]: Deleting interface #2 wlan0, 192.168.1.12#123, interface stats: received=742, sent=761, dropped=0, active_time=122167 secs
Nov 13 03:47:44 raspberrypi ntpd[2317]: 178.32.54.53 interface 192.168.1.12 -> (none)
Nov 13 03:47:44 raspberrypi ntpd[2317]: 188.165.255.179 interface 192.168.1.12 -> (none)
Nov 13 03:47:44 raspberrypi ntpd[2317]: 195.83.66.158 interface 192.168.1.12 -> (none)
Nov 13 03:47:44 raspberrypi ntpd[2317]: 212.83.187.62 interface 192.168.1.12 -> (none)
Nov 13 03:47:44 raspberrypi ntpd[2317]: peers refreshed
Nov 13 03:47:49 raspberrypi ifplugd(wlan0)[1693]: Executing '/etc/ifplugd/ifplugd.action wlan0 down'.
Nov 13 03:47:49 raspberrypi ifplugd(wlan0)[1693]: client: /sbin/ifdown: interface wlan0 not configured

–> ré essayer le paramétrage de l’IP fixe

mais les précédentes tentatives ont échoué…

la bonne config est la suivante

auto lo

iface lo inet loopback
iface eth0 inet dhcp

iface wlan0 inet manual  
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf

# ajout TGA pour config static NB : l'ordre est important. APRES le wpa-roam
#iface default inet dhcp
iface default inet static
#iface wlan0 inet static
address 192.168.1.111
netmask 255.255.255.0
network 192.168.1.0
broadcast 192.168.1.255
gateway 192.168.1.1

quelques commandes :

cat /etc/network/interfaces
ifconfig
netstat -nr
sudo ifup wlan0
iwconfig

 S’assurer du maintien de la connexion wifi : relancer la connexion une fois par jour avec CRON

Using Cron

To use cron for tasks meant to run only for your user profile, add entries to your own user’s crontab file. Start the crontab editor from a terminal window:

crontab -e

Edit the crontab using the format described in the next sections. Save your changes. (Exiting without saving will leave your crontab unchanged.)

Note that a great source of information about the format can be found at:

man 5 crontab

Commands that normally run with administrative privileges (i.e. they are generally run using sudo) should be added to the root user’s crontab (instead of the user’s crontab):

 sudo crontab -e

Crontab Sections

Each of the sections is separated by a space, with the final section having one or more spaces in it. No spaces are allowed within Sections 1-5, only between them. Sections 1-5 are used to indicate when and how often you want the task to be executed. This is how a cron job is laid out:

minute (0-59), hour (0-23, 0 = midnight), day (1-31), month (1-12), weekday (0-6, 0 = Sunday), command

01 04 1 1 1 /usr/bin/somedirectory/somecommand

The above example will run /usr/bin/somedirectory/somecommand at 4:01am on January 1st plus every Monday in January. An asterisk (*) can be used so that every instance (every hour, every weekday, every month, etc.) of a time period is used. Code:

01 04 * * * /usr/bin/somedirectory/somecommand

The above example will run /usr/bin/somedirectory/somecommand at 4:01am on every day of every month.

Comma-separated values can be used to run more than one instance of a particular command within a time period. Dash-separated values can be used to run a command continuously. Code:

01,31 04,05 1-15 1,6 * /usr/bin/somedirectory/somecommand

The above example will run /usr/bin/somedirectory/somecommand at 01 and 31 past the hours of 4:00am and 5:00am on the 1st through the 15th of every January and June.

The « /usr/bin/somedirectory/somecommand » text in the above examples indicates the task which will be run at the specified times. It is recommended that you use the full path to the desired commands as shown in the above examples. Enter which somecommand in the terminal to find the full path to somecommand. The crontab will begin running as soon as it is properly edited and saved.

You may want to run a script some number of times per time unit. For example if you want to run it every 10 minutes use the following crontab entry (runs on minutes divisible by 10: 0, 10, 20, 30, etc.)

*/10 * * * * /usr/bin/somedirectory/somecommand

which is also equivalent to the more cumbersome

0,10,20,30,40,50 * * * * /usr/bin/somedirectory/somecommand

Special strings

Cron also offers some special strings:

  • string

    meaning

    @reboot

    Run once, at startup.

    @yearly

    Run once a year, « 0 0 1 1 * ».

    @annually

    (same as @yearly)

    @monthly

    Run once a month, « 0 0 1 * * ».

    @weekly

    Run once a week, « 0 0 * * 0 ».

    @daily

    Run once a day, « 0 0 * * * ».

    @midnight

    (same as @daily)

    @hourly

    Run once an hour, « 0 * * * * ».

     

Usage: « @reboot /path/to/execuable1 » will execute /path/to/executable1 when the system starts. See « man 5 crontab » for more info.

Finalement :

apres mains déboires,

retour à la simplification :

allow-hotplug wlan0
iface wlan0 inet manual # MANUAL imposé par wpa-roam
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface wlan0 inet manual 
iface default inet dhcp #IMPORTANT !!!

et utilisation de la fonction de bail DHCP static pour fixer l’adresse IP

lancement du serveur au démarrage

sudo crontab -e 
@reboot sh /home/pi/scripts/runwebiopi.sh

A faire ensuite :

  • extraire le code de lecture des capteurs de température et les gérer via cron pour une lecture toutes les heures par exemple
  • mettre en place emetteur email pour confirmer ouverture et fermeture porte. En profiter pour mettre température intérieure/extérieure et diverses info (actus, …). cf sendmail.py. Voir aussi mise en place MTA ? (cf erreur du CRON)
  • afficher sur la page web
    • l’image de l’intérieur du poulailler
      • avec un bouton permettant d’activer un éclairage (reste un relais dispo, et utilisation de leds ?)
    • l’état de la porte :
      • lire en continue la valeur de la sortie digitale, pour avoir confirmation visuelle de l’arrêt de la commande du moteur
      • position haute ou basse
    • un module permettant d’envoyer un email ou un SMS lorsque la luminosité passe en dessous d’un certain seuil
    • changer les logins/mdp raspi, pi, webiopi et ouvrir un port pour un acces distant

NB : info à classer :

Laisser un commentaire