BateauRaspberry : bateau piloté avec un Pi (par Tim)

Bonjour à tous,

Il y a quelques semaines je vous présentais le projet BateauRaspberry de Tim : http://www.magdiblog.fr/divers/bateauraspberry-un-bateau-entierement-fait-main-pilote-par-un-pi/

timelapse_2014-04-21_17-42-00_08Après quelque souci pour héberger l’article très complet qu’il à réalisé sur son projet, j’ai proposé à Tim d’héberger et de rellayer son travail 🙂 Voici donc la retranscription complète de son article 🙂

RASPBERRY BATEAU

Sommaire

  • Le Raspberry Bateau
  • Inventaire des éléments utilisés
  • Connexion 3g / Hotspot Wifi
  • Commande des Servomoteurs
  • Commande photo par Webcam et serveur distant
  • Interface graphique Web sur mobile
  • Streaming du flux vidéo de la webcam
  • Commander un projecteur à LEDs
  • Mais alors ça donne quoi tout ça ??!

Introduction

En 1999, j’ai fabriqué une maquette de bateau en bois d’environ 1 mètre de long. Ce bateau embarque deux servomoteurs. L’un est rattaché à un variateur qui permet de faire tourner plus ou moins vite un moteur sur lequel est rattaché une hélice. L’autre permet de changer l’angle du gouvernail. Ces deux servomoteurs peuvent être contrôlés par onde radio à l’aide d’une télécommande que l’on trouve dans les magasins de modélisme ou d’électronique.

Le défi que je me suis donné était de remplacer la télécommande par un téléphone ou une tablette. Je voulais aussi ajouter une caméra pour voir ce que le bateau voit et pouvoir prendre des photos.

Je me suis dit que d’autres auraient des défis similaires donc j’ai décidé de partager tous les détails techniques sur mon expérience. Bien-sûr, ne soyez pas trop critiques, il existe probablement des choix bien meilleurs que les miens.

Je voudrais remercier tout particulièrement Olivier, l’auteur du blog MagdiBlog qui a été une véritable source d’inspiration pour moi. Son blog est exceptionnellement bien écrit et agréable à lire. Ces projets sont intéressants, détaillés et précis. Plusieurs parties de mon projet n’auraient pas pu être réalisées sans ses explications. J’ai réutilisé des codes appartenant à plusieurs de ses projets pour arriver à mes fins. Je recommande vivement son site à tous ceux qui s’intéressent au Raspberry Pi.

Vous le trouverez ICI.

Le Raspberry Bateau

Passons au vif du sujet. Voici la bête ! 🙂

tim_bateau_telecommande_raspberry_piLa cabine se retire pour accéder aux moteurs, servomoteurs, Raspberry Pi, batteries etc.

Sur le dessus de la cabine, on retrouve la webcam qui permet de filmer et prendre des photos. Le pont arrière laisse ressortir un adaptateur USB WIFI :

20140423_200747

Inventaire des éléments utilisés

2014-04-29_08h45_55Voici le dongle WIFI D-Link DWA-131 Nano que j’ai utilisé :

http://www.amazon.fr/D-Link-DWA-131-Nano-WiFi-N300/dp/B002PD61Y4

 

 

Lorsque l’on ouvre les entrailles du bateau, voici les différents éléments que l’on retrouve :

20140423_200523-21. Une batterie 6V 12A pour alimenter le moteur.

2. Un moteur auquel est rattaché un arbre moteur qui entraîne l’hélice du bateau.

3. Un servomoteur qui pilote par son angle de rotation et à l’aide de la tige métallique un variateur.

4. Le variateur qui va définir la vitesse et le sens de rotation du moteur.

5. Un Raspberry Pi modèle B 512MB protégé par une coque dont j’ai découpé une partie pour laisser l’accès aux broches GPIO. C’est lui le chef d’orchestre qui va :

  • 2014-04-29_08h21_10recevoir les commandes de mon téléphone
  • piloter le servomoteur qui contrôle le moteur
  • piloter le servomoteur qui contrôle l’angle du gouvernail
  • prendre des photos à l’aide la webcam, les stocker en local sur sa carte SD et envoyer une miniature à mon téléphone par mail.
  • filmer à l’aide de la webcam et « streamer » le flux vidéo à mon téléphone :

    http://www.amazon.fr/gp/product/B0050FBISI/ref=oh_details_o01_s00_i00?ie=UTF8&psc=1

Le modèle de mon Raspberry Pi : http://www.amazon.fr/Raspberry-Pi-RBCA000-Carte-1176JZF-S/dp/B008PT4GGC/ref=sr_1_1?ie=UTF8&qid=1398751245&sr=8-1&keywords=raspberry+pi+512

2014-04-29_08h26_56

Un exemple de coque de protection qui laisse une ouverture au port GPIO : http://www.amazon.fr/gp/product/B00A543LNE/ref=ox_sc_sfl_title_4?ie=UTF8&psc=1&smid=A2717MKXZVZ1ZW

2014-04-29_08h29_50

2014-04-29_08h20_57Le système peut être installé sur une petite carte SD cependant, afin de pouvoir stocker les photos prises, j’ai opté pour une carte SD avec plus de capacité : http://www.amazon.fr/gp/product/B0087ECDH4/ref=oh_details_o00_s00_i00?ie=UTF8&psc=1

 

6. Assembled Pi Cobbler Breakout Kit :

Il sert à raccorder facilement le port GPIO de Raspberry Pi sur un breadboard sur lequel je branche les servomoteurs : http://www.amazon.fr/Assembled-Cobbler-Breakout-Kit-Raspberry/dp/B0093K6QQ0/ref=pd_sim_ce_1?ie=UTF8&refRID=1NRAZVQWQXB29CYX3Z2C

2014-04-29_08h21_53 2014-04-29_08h21_44

 

 

 

 

 

 

 

 

 

 

7. Batterie portable :

2014-04-29_08h20_30On ne la voit pas très bien mais il s’agit d’une batterie externe portable qui sert de chargeur de secours pour des téléphones ou tablettes Apple. Celle-ci convient parfaitement comme source d’alimentation du Raspberry Pi. Elle tient d’ailleurs pas mal de temps j’étais agréablement surpris : http://www.amazon.fr/gp/product/B0089MLH7Q/ref=oh_details_o02_s00_i00?ie=UTF8&psc=1

8. Une pile 4.5 V qui me permet d’alimenter un petit projecteur à LED contrôlé par une broche du port GPIO.

Pour plus de simplicité et afin faire une livraison groupée, j’ai essayé de trouver tous les éléments électroniques sur Amazon. En ce qui concerne les éléments batteries, coupleurs de piles, moteur et servomoteurs, je les ai obtenus dans un magasin d’électronique et de modélisme ici : http://www.electronique-diffusion.fr/

Une fois les courses faites et tous les éléments assemblés, il est temps de mettre un peu les mains dans le code !

Je ne m’étendrai pas sur tout ce qui concerne l’installation du système du Raspberry Pi car tout est très bien expliqué sur leur site ou sur de nombreux blogs. Pour ce projet, j’ai installé le système Raspbian : http://www.raspberrypi.org/downloads/

Connexion 3g / Hotspot Wifi

Commençons par la connexion entre le téléphone et le bateau.
Il existe plusieurs possibilités mais le principe est bien de créer un réseau sans fils entre le téléphone (ou la tablette) et le Raspberry Pi. Ce réseau doit être fiable car ce serait bête de perdre la connexion alors que le bateau se trouve au milieu du lac !

2014-04-29_08h21_25

http://www.amazon.fr/gp/product/B004UIVIBS/ref=oh_details_o03_s00_i00?ie=UTF8&psc=1

J’ai tout d’abord essayé de configurer (connecté au Raspberry Pi) un modem usb 3g dans lequel j’ai mis une carte SIM de l’opérateur Free. En suivant les instructions du site d’Olivier ici j’ai pu configurer le modem et obtenir du réseau internet sur le Raspberry. Ce système est très dépendant de la qualité du réseau 3g de Free et malheureusement les performances n’étaient pas au rendez-vous… J’ai eu plusieurs déconnexions. Cependant, sachez que ce système fonctionne avec le Raspberry Pi si vous cherchez à avoir de l’internet n’importe où. Si vous voulez plus d’infos sur cette partie, j’ai pris des notes que je peux partager mais je ne les ai pas mises sur ce blog car j’ai opté pour la solution du hotspot Wifi.

J’ai donc opté pour la création d’un réseau privé WIFI. Mon téléphone Android et mon opérateur me permettent de transformer mon téléphone en modem WIFI. Vous trouverez sur internet plein de tutoriels pour réaliser cette opération. Votre téléphone créé alors un point d’accès WIFI auquel il est possible de se connecter comme le fait votre box. L’idée est de créer se réseau et de configurer le Raspberry Pi pour qu’il s’y connecte automatiquement au démarrage.

Une fois le téléphone configuré, vous devez trouver sur quelle plage ip il se connecte.

Tout d’abord, il faut connecter le dongle WIFI usb au Raspberry Pi :

20140423_200609

NOTE : J’ai choisi d’utiliser un câble USB d’extension pour faire sortir le dongle du bateau.

Connectez aussi votre Raspberry à votre réseau ethernet et connectez vous en SSH au Raspberry. Je ne m’étendrai pas sur comment réaliser cela car tout est expliqué en détail sur internet.

NOTE : Je passe toutes mes commandes en root comme ça je ne suis pas embêté à entrer sudo, le mot de passe etc… Je sais c’est pas bien mais… on s’en fiche ! 🙂

Modifiez le fichier « /etc/network/interfaces » comme suivant à l’aide de la commande vi :

auto lo

iface lo inet loopback
iface eth0 inet dhcp

allow-hotplug wlan0
auto wlan0
iface wlan0 inet dhcp

wpa-ssid NOM_DE_VOTRE_WIFI
wpa-psk MOT_DE_PASSE_DU_WIFI

Relancez le réseau wifi à l'aide des commandes suivantes :

sudo ifdown wlan0
sudo ifup wlan0

Pour connaître l’ip que votre téléphone vous a attribué, entrez la commande « ifconfig » et notez l’adresse ip de la carte wlan0. Voici ce que me donne ma configuration :

2014-04-29_10h50_52

Le téléphone peut aussi vous indiquer qu’un nouveau périphérique s’est connecté au réseau.

Quand le bateau n’est pas connecté :

device-2014-03-18-193736Quand le dongle Wifi obtient une adresse ip :

device-2014-03-18-193417

L’adresse ip du bateau sera donc 192.168.43.115. Comme c’est une configuration DHCP, l’adresse pourrait changer au reboot mais le téléphone enregistre la MAC adresse de la carte et pour ma part l’ip attribuée a toujours été la même. Si on souhaite vraiment qu’elle ne change pas, il suffit de modifier le fichier précédent et d’enregistrer l’ip comme static.

Note importante : Activez toujours le point d’accès wifi depuis votre téléphone avant de démarrer le Raspberry. Ainsi, il prendra tout de suite l’ip. Dans le cas contraire, si vous n’avez pas la possibilité de vous connecter en ethernet (par exemple vous êtes déjà au bord du lac), il vous faudra éteindre votre Raspberry « non-proprement » en lui retirant l’alimentation ce qui risque de corrompre le système de fichier et bloquer le système au prochain démarrage.

Bien ! Nous savons maintenant faire en sorte que le Raspberry Pi et le téléphone se retrouve dans le même réseau WIFI privé au démarrage. Après plusieurs tests je n’ai vraiment pas été déçu par la portée de ce petit réseau. J’arrive à piloter le bateau jusqu’à une bonne dizaine de mètres.

Commande des Servomoteurs

Pour piloter les servomoteurs, j’ai utilisé le logiciel pour Raspberry ServoBlaster. Celui-ci créé une interface pour piloter plusieurs servomoteurs depuis les broches du port GPIO. Voici les commandes pour l’installer et le configurer :

sudo apt-get install git
git clone git://github.com/richardghirst/PiBits.git

Positionnez-vous dans le dossier « /PiBits/ServoBlaster/user« . Vous devriez y trouver les fichiers suivants :

root@raspberrypi:~/PiBits/ServoBlaster/user# ls
init-script  Makefile  servod.c

Ensuite :

root@raspberrypi:~/PiBits/ServoBlaster/user# make servod
gcc -Wall -g -O2 -o servod servod.c -lm
root@raspberrypi:~/PiBits/ServoBlaster/user# ./servod

Board revision:                  2
Using hardware:                PWM
Using DMA channel:              14
Idle timeout:             Disabled
Number of servos:                8
Servo cycle time:            20000us
Pulse increment step size:      10us
Minimum width value:            50 (500us)
Maximum width value:           250 (2500us)
Output levels:              Normal

Using P1 pins:               7,11,12,13,15,16,18,22
Using P5 pins:

Servo mapping:
0 on P1-7           GPIO-4
1 on P1-11          GPIO-17
2 on P1-12          GPIO-18
3 on P1-13          GPIO-27
4 on P1-15          GPIO-22
5 on P1-16          GPIO-23
6 on P1-18          GPIO-24
7 on P1-22          GPIO-25

Après installation, ci-dessus, la configuration par défaut est affichée. Pour en savoir plus sur le fonctionnement de ServoBlaster, vous pouvez aussi entrer la commande help :

Image

C’est à vous ensuite d’en apprendre plus sur le modèle de votre servomoteur pour savoir quelles valeurs configurer. Par exemple pour les miens en faisant une petite recherche Google :

ImagezED

Je me sers ensuite de ces informations pour configurer au mieux ServoBlaster. J’ai trouvé que le plus simple était de faire des tests en envoyant des commandes de pourcentage courtes pour voir comment le servo réagi et où se trouvent les extrémités. Au final, j’ai utilisé les broches 7 et 11 pour piloter mes deux servomoteurs (c’est à dire les GPIO 4 et 17 d’après le tableau de mapping plus haut). Voici un exemple de fichier de test pour mes deux servomoteurs :

echo "Configuring..."

/root/PiBits/ServoBlaster/user/servod --cycle-time 30000 --max=300 --p1pins=7,11

echo "-------->"
echo 0=56% > /dev/servoblaster
echo 1=47% > /dev/servoblaster
sleep 0.5

echo "<--------"
echo 0=20% > /dev/servoblaster
echo 1=29% > /dev/servoblaster
sleep 0.5

echo "-------->"
echo 0=56% > /dev/servoblaster
echo 1=47% > /dev/servoblaster
sleep 0.5

echo "<--------"
echo 0=20% > /dev/servoblaster
echo 1=29% > /dev/servoblaster
sleep 0.5

echo "TOUT DROIT"
echo 0=38% > /dev/servoblaster
echo 1=39% > /dev/servoblaster
sleep 0.5

echo "-------->"
echo 0=56% > /dev/servoblaster
echo 1=47% > /dev/servoblaster
sleep 0.5

echo "<--------"
echo 0=20% > /dev/servoblaster
echo 1=29% > /dev/servoblaster
sleep 0.5

echo "-------->"
echo 0=56% > /dev/servoblaster
echo 1=47% > /dev/servoblaster
sleep 0.5

echo "<--------"
echo 0=20% > /dev/servoblaster
echo 1=29% > /dev/servoblaster
sleep 0.5

echo "TOUT DROIT"
echo 0=38% > /dev/servoblaster
echo 1=39% > /dev/servoblaster
sleep 0.5

echo "Lentement droite"
echo 0=40% > /dev/servoblaster
echo 1=41% > /dev/servoblaster
sleep 0.2

echo 0=42% > /dev/servoblaster
echo 1=43% > /dev/servoblaster
sleep 0.2

echo 0=44% > /dev/servoblaster
echo 1=45% > /dev/servoblaster
sleep 0.2

echo 0=46% > /dev/servoblaster
echo 1=47% > /dev/servoblaster
sleep 0.2

echo 0=48% > /dev/servoblaster
sleep 0.2

echo 0=50% > /dev/servoblaster
sleep 0.2

echo 0=52% > /dev/servoblaster
sleep 0.2

echo 0=54% > /dev/servoblaster
sleep 0.2

echo "TOUT DROIT"
echo 0=38% > /dev/servoblaster
echo 1=39% > /dev/servoblaster
sleep 0.2

echo "<--------"
echo 0=20% > /dev/servoblaster
echo 1=29% > /dev/servoblaster
sleep 0.2

echo "Lentement gauche"
echo 0=22% > /dev/servoblaster
echo 1=31% > /dev/servoblaster
sleep 0.2

echo 0=24% > /dev/servoblaster
echo 1=33% > /dev/servoblaster
sleep 0.2

echo 0=26% > /dev/servoblaster
echo 1=35% > /dev/servoblaster
sleep 0.2

echo 0=28% > /dev/servoblaster
echo 1=37% > /dev/servoblaster
sleep 0.2

echo 0=30% > /dev/servoblaster
echo 1=39% > /dev/servoblaster
sleep 0.2

echo 0=32% > /dev/servoblaster
echo 1=41% > /dev/servoblaster
sleep 0.2

echo 0=34% > /dev/servoblaster
echo 1=43% > /dev/servoblaster
sleep 0.2

echo "TOUT DROIT"
echo 0=38% > /dev/servoblaster
echo 1=39% > /dev/servoblaster
sleep 0.2

echo "Poweroff moteur"
echo 0=0 > /dev/servoblaster
echo 1=0 > /dev/servoblaster

echo "END"

En regardant de plus prés les explications sur ServoBlaster et les exemples, vous n’aurez aucun mal à comprendre mon fichier de test. Attention à bien donner les droits d’exécution au fichier.

Voici le résultat à l’exécution du fichier :

2014-04-29_11h55_41

Un petit schéma de connexion des servomoteurs s’impose :

Sans+titre

L’alimentation est constituée d’un coupleur de 4 piles AAA de 1,5V bloquées derrière le gouvernail :

20140423_200600

Conclusion, à travers une commande SSH je peux piloter au degré près l’angle de rotation du moteur et ainsi l’angle du gouvernail et l’angle sur le variateur de vitesse du moteur.

Commande photo par Webcam et serveur distant

20140423_200617

Ok ok ma webcam a une sale tête… En fait, mon premier projet était de la mettre sous le bateau dans un boitier transparent pour pouvoir filmer sous l’eau. J’ai voulu rendre étanche tout ça avec de la mousse isolante mais j’ai eu quelques petits soucis (imaginez l’état de mes doigts…). J’ai donc opté pour la simplicité en la mettant sur la cabine :

20140423_200747

De cette façon je pourrai voir en direct ce que voit le bateau et prendre des photos sympas.

En ce qui concerne la partie « prendre des photos », ce que je souhaite est que la webcam prenne une photo quand je le commande à l’aide mon téléphone, qu’il stocke la photo sur la carte SD (d’où la carte de 32 GB), que le Raspberry compresse et miniaturise cette photo et qu’il me l’envoie par mail avec la date et l’heure.

Voici le résultat. On peut voir mon frère en face qui pilote son bateau avec une télécommande radio :

timelapse_2014-04-21_17-42-00_08

Alors ! Comment ça marche !?

Tout d’abord, comme c’est très bien expliqué sur le site d’Olivier, il me faut un serveur qui recevra les miniatures du Raspberry et me les transférera par mail sur mon téléphone. Comme le bateau est piloté en Wifi, ma 3g est toujours activée et connectée au net donc je peux recevoir les photos sans problèmes.

J’ai loué un petit serveur dédié chez OVH pour cette tâche. J’ai créé un domaine et une base de donnée dans laquelle on stockera les dates et les chemins vers les images. Cette partie là est propre à l’administration de votre serveur donc je ne m’étendrai pas sur le sujet.

Je créé une table dans ma base à l’aide de mon compte phpmyadmin comme ceci :

2014-04-29_12h28_18

Pour le reste, j’ai suivi les instructions et codes qu’Olivier fourni sur son site donc je ne vais pas tout ré-expliquer. Vous trouverez tout sur le script pour la prise de photo ICI et sur le code côté serveur et la base de donnée ICI. Olivier l’explique beaucoup mieux que moi. Attention, il y a quand même des petites choses à connaitre (et des choses à modifier dans les scripts, votre nom de domaine, les identifiants de connexion à la base de donnée etc.) en php et mysql donc si vous n’y connaissez rien, ne vous attendez pas à ce que ce soit du copier-coller des scripts.

En tout cas, après avoir pris quelques photos, voici le résultat dans la base de donnée sur le serveur OVH :

2014-04-29_16h49_29

A la différence du projet d’Olivier, la photo est prise quand le Raspberry Pi reçoit la commande SSH qui lui dit d’exécuter le script timelapse.sh. Si vous n’avez pas bien tout lu, sachez que c’est le logiciel streamer qui permet de prendre ces photos depuis le Raspberry et la commande convert compresse et redimensionne la photo et la commande curl pour l’envoyer au serveur OVH. Tout ça se trouve dans le script php.

Interface graphique Web sur mobile

Au début, je voulais commander le bateau à l’aide de mon téléphone en développant une application Android native. J’ai donc développé une application qui permet d’envoyer des commandes SSH. Vous me direz « Olalala, faut utiliser les sockets c’est plus rapide et plus efficace ! » sauf que je ne suis pas un bon développeur Android et que je n’ai pas eu le temps de fouiller le code pour savoir comment le faire. Comme je savais par contre comment envoyer des commandes SSH je me suis dit parfait. Sauf que le résultat n’était vraiment pas terrible et lent même si ça marchait. Et puis je me suis dit que ce serait sympa de faire une interface web plutôt qu’une application native. Comme ça je pourrai d’une part me perfectionner sur PHP et d’une autre part piloter mon bateau depuis n’importe quel mobile que ce soit de l’Android ou du Mac. L’idée me plaisait donc c’est parti.

Voilà d’abord le résultat :

device-2014-04-29-170117

L’image que l’on voit en bas c’est ce que film la caméra. J’en parlerai plus loin.

Je ne me suis pas cassé la tête et il y a sûrement des codes beaucoup plus propres que le mien mais au moins ça a le mérite de fonctionner. Le principe est simple, chaque bouton envoie une commande SSH en passant par php à un serveur web installé sur le Raspberry. Ensuite, le Raspberry traite la commande comme si je venais de la taper en direct dans une console. J’étais agréablement surpris car même en Wifi ça réagit très vite.

Quelques explications sur les boutons :

eteindre_le_rpiEnvoie la commande au Raspberry Pi de s’éteindre proprement. Comme ça une fois qu’on a fini de faire « mumuse » avec son bateau on est pas obligé d’éteindre brutalement le Raspberry en lui retirant l’alimentation. ça évite la corruption du système de fichier linux.

 

take_photoPrend une photo, en fait une miniature et l’envoie au serveur OVH.
Petite remarque ! Pour le moment, je ne peux pas prendre des photos et en même temps que je retransmet le flux vidéo (j’en parle plus bas). Pour prendre une photo, il faut d’abord appuyer sur l’arrêt de la Webcam et ensuite sur le bouton l’appareil photo.

 

stop_video start_videoÉteint ou allume la webcam.

 

 

 

stopMet le servomoteur qui contrôle la vitesse en position ou le variateur arrête le moteur.

 

 

 

avance_tout_droitLes flèches indiquent la direction où je souhaite que le bateau aille. A l’appui sur un bouton de direction, si la flèche va vers l’avant, le gouvernail change d’angle suivant la direction et le moteur tourne dans le sens qui fait avancer le bateau. Donc à chaque appui sur une flèche, une commande php exécute une commande de ServoBlaster ce qui modifie l’angle des servomoteurs.

huitCe bouton commande tout simplement l’exécution du script qui fait bouger les servomoteurs un peu dans tous les sens (comme la vidéo plus haut) ce qui permet de tester que tout fonctionne avant de le mettre à l’eau. On pourrait imaginer aussi un script qui fait tourner le bateau en huit comme une sorte de pilotage automatique.

 

avance_doucementL’appui sur l’un de ces boutons change l’angle du servomoteur qui contrôle la vitesse. On peut imaginer ce que l’on veut mais dans mon cas j’ai choisi le faire ralentir le bateau.

 

 

Alors c’est parti pour l’installation du serveur web sur le Raspberry Pi !

Entrez la commande pour installer les librairies qui vont bien (php, apache etc.) :

apt-get install apache2 php5 libapache2-mod-php5

Pour voir si ça fonctionne il suffit de se connecter à l’adresse de votre raspberry dans un navigateur qui se trouve sur le même réseau :

ImagesdSinon par exemple pour montrer l’état d’une broche de votre port GPIO dans la page web, vous pouvez créer le fichier suivant dans /var/www :

<?php
exec ( "gpio read 0", $status );
print_r ( $status );
?>

On raffraichi la page web et on obtient l’état de la broche 0 :

ImageqefqfAttention, le service Apache a un utilisateur www-data qui n’a pas les droits d’exécuter des scripts qui se trouvent dans /root avec la commande php exec. Pour régler ce problème il faut éditer le fichier des sudoers comme ceci :

# visudo

Ajouter cette ligne :

# User privilege specification
root    ALL=(ALL:ALL) ALL
www-data ALL=(ALL:ALL) NOPASSWD:ALL

Ok ok encore une fois c’est pas le top de la sécurité mais on s’en fiche c’est un réseau privé.

Sinon pour un peu plus de sécurité vous pouvez préciser les commandes que vous souhaitez passer en sudo :

www-data ALL = (root) NOPASSWD: /bin/cp /root/test1 /root/test2

Ensuite dans la page php :

<?php
exec ( "sudo /root/timelapse.sh", $status );
print_r ( $status );
?>

Bon une fois que tout ça est fait il ne nous reste plus qu’à coder les actions de l’appui sur les boutons de la page html.

Voici le fichier index.php qui se trouve dans /var/www/Web. Dans mon cas je l’ai mis dans un répertoire Web mais vous le mettez où vous voulez du moment que c’est dans /var/www :

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" media="screen" type="text/css" title="style" href="test.css" />
<title>Raspberry Boat</title>
</head>

<body style="background-color: black;"><center>
<!-- On/Off button's picture -->

<div class="float"> <!-- colonne 1 -->

<!-- eteindre_le_rpi.php -->

<form action="eteindre_le_rpi.php" method="post" class="form">
<p>
<input type="image" src="data/img/eteindre_le_rpi.png" alt="Submit Form" />
</p>
</form>

<!-- tourne_un_peu_a_gauche.php -->

<form action="tourne_un_peu_a_gauche.php" method="post" class="form">
<p>
<input type="image" src="data/img/tourne_un_peu_a_gauche.png" alt="Submit Form" />
</p>
</form>

<!-- tourne_a_gauche -->

<form action="tourne_a_gauche.php" method="post">
<p>
<input type="image" src="data/img/tourne_a_gauche.png" alt="Submit Form" />
</p>
</form>

<!-- recule_a_gauche -->

<form action="recule_a_gauche.php" method="post">
<p>
<input type="image" src="data/img/recule_a_gauche.png" alt="Submit Form" />
</p>
</form>

</div>

<div class="float"> <!-- colonne 2 -->

<!-- take_photo -->

<form action="take_photo.php" method="post">
<p>
<input type="image" src="data/img/take_photo.png" alt="Submit Form" />
</p>
</form>

<!-- avance_tout_droit -->

<form action="avance_tout_droit.php" method="post">
<p>
<input type="image" src="data/img/avance_tout_droit.png" alt="Submit Form" />
</p>
</form>

<!-- Stop -->

<form action="stop.php" method="post">
<p>
<input type="image" src="data/img/stop.png" alt="Submit Form" />
</p>
</form>

<!-- recule_tout_droit -->

<form action="recule_tout_droit.php" method="post">
<p>
<input type="image" src="data/img/recule_tout_droit.png" alt="Submit Form" />
</p>
</form>

</div>

<div class="float"> <!-- colonne 3 -->

<!-- start_video -->

<form action="start_video.php" method="post">
<p>
<input type="image" src="data/img/start_video.png" alt="Submit Form" />
</p>
</form>

<!-- tourne_un_peu_a_droite -->

<form action="tourne_un_peu_a_droite.php" method="post">
<p>
<input type="image" src="data/img/tourne_un_peu_a_droite.png" alt="Submit Form" />
</p>
</form>

<!-- tourne_a_droite -->

<form action="tourne_a_droite.php" method="post">
<p>
<input type="image" src="data/img/tourne_a_droite.png" alt="Submit Form" />
</p>
</form>

<!-- recule_a_droite -->

<form action="recule_a_droite.php" method="post">
<p>
<input type="image" src="data/img/recule_a_droite.png" alt="Submit Form" />
</p>
</form>

</div>

<div class="float"> <!-- colonne 4 -->

<!-- stop_video -->

<form action="stop_video.php" method="post">
<p>
<input type="image" src="data/img/stop_video.png" alt="Submit Form" />
</p>
</form>

<!-- avance_doucement -->

<form action="avance_doucement.php" method="post">
<p>
<input type="image" src="data/img/avance_doucement.png" alt="Submit Form" />
</p>
</form>

<!-- avance_normal -->

<form action="avance_normal.php" method="post">
<p>
<input type="image" src="data/img/avance_normal.png" alt="Submit Form" />
</p>
</form>

<!-- huit -->

<form action="huit.php" method="post">
<p>
<input type="image" src="data/img/huit.png" alt="Submit Form" />
</p>
</form>

</div>

<!-- afficher l'écran vidéo stream -->
<img src="http://192.168.0.34:8083/?action=stream">
<img src="http://192.168.43.115:8083/?action=stream">

</center></body>

</html>

Bon c’est plutôt basique est il y a sûrement encore plus simple mais je le rappelle je ne suis pas développeur php ! Après comme je le dis souvent, ça a le mérite de marcher et de satisfaire mes besoins ! 🙂

Chaque bouton a une méthode post qui appelle un autre script php qui demande l’exécution d’un script stocké sous root. Woooooo ! 🙂 Dans ce script il y a la commande qui déclenche l’action.

Exemple ! 🙂

  • Je veux aller tout droit. J’appuie sur le bouton flèche « tout droit ».
  • Cette partie du script html est exécutée :
<!-- avance_tout_droit -->

<form action="avance_tout_droit.php" method="post">
<p>
<input type="image" src="data/img/avance_tout_droit.png" alt="Submit Form" />
</p>
</form>

Le script avance_tout_droit.php est appelé (il est stocké au même endroit que le fichier index.php).

Voilà à quoi ressemble ce fichier php :

<?php

exec('bash -c "exec nohup setsid sudo /root/avance_tout_droit.sh > /dev/null 2>&1 &"');
header('Location: index.php');

?>

Lors de son exécution, grâce aux commandes exec et sudo il execute en bash le script stocké dans /root.
Le header permet de faire comme si on avait rafraîchi la page web.

Le script /root/avance_tout_droit.sh est alors exécuté :

/root/PiBits/ServoBlaster/user/servod --cycle-time 30000 --max=300 --p1pins=7,11

#gouvernail tout droit
echo 0=38% > /dev/servoblaster
#avancer vite
echo 1=29% > /dev/servoblaster
sleep 0.2

et là on retrouve les commandes qui permettent le contrôle des servomoteurs.

NOTE : N’oubliez pas de rendre vos scripts exécutables ! (chmod …..)

Pour le fichier css c’est tout simple ! Je dirai même il n’y a pas plus simple ! J’ai découpé mon interface en 3 colonnes pour que les icônes des boutons soient bien alignés :

.float {
float: left;
width: 25%;
margin: 1em 0;
}

Une fois que vous avez compris le principe des fichier php qui appellent des script dans /root et bien il suffit de créer un fichier par action que vous souhaitez réaliser.

Encore une fois je sais qu’il est possible de ne pas créer autant de fichier et de faire quelque chose de plus propre mais je n’avais pas le temps de m’y plonger.

Streaming du flux vidéo de la webcam

Comme promis plus haut voici quelques explications sur la vidéo :

Note : Bon j’aurais pu en parler plus haut mais pour vérifier que votre webcam est reconnue par le Raspberry Pi, vérifiez que l’entrée video0 existe dans /dev.

Le logiciel que j’utilise pour transmettre le flux vidéo est MJPG-streamer. C’est comme un petit server HTTP installé sur le Raspberry Pi qui transmet le flux vidéo capturé par la webcam en utilisant le protocol http dans le format motion jpeg. Pour voir le flux une fois que le serveur est actif, il suffit d’ouvrir un navigateur compatible et d’entrer l’ip du Raspberry avec le port associé à MJPG-streamer.

Il faut installer certains package (n’oubliez pas d’abord de mettre à jour votre système avec update et upgrade d’apt-get) :

apt-get install libv41-0

Récupérez le package mjpg-streamer (créé par Tom Stoeveken) ou alors il existe aussi un package un peu customisé pour le Raspberry que l’on peut récupérer :

wget http://iqjar.com/download/jar/soft/mjpg-streamer.tar.gz
tar -zxvf mjpg-streamer-rpi.tar.gz
cd mjpg-streamer
./mjpg-streamer.sh start

Pour tester si tout fonctionne et que l’on voit le flux vidéo dans une page web, ouvrez un navigateur :

http://example.com:8083/?action=stream

Le port par défaut est 8083.

Si on veut l’intégrer dans une page web comme je l’ai fait, il faut utiliser une balise image :

<img src=”http://example.com:8083/?action=stream” width=”640″ height=”480″/>

Pour moi ça n’a pas marché donc j’ai retiré les paramètres de taille et là miracle ! 🙂 J’ai testé avec Chrome, Firefox, le navigateur natif d’android et celui d’apple, ça fonctionne très bien ! 🙂

<img src="http://192.168.0.34:8083/?action=stream">

Donc pour déclencher la caméra et récupérer un flux vidéo :

root@raspberrypi:~/mjpg-streamer# ./mjpg-streamer.sh start
8083 800x600 15
started

Pour l’arrêter :

root@raspberrypi:~/mjpg-streamer# ./mjpg-streamer.sh stop
stopped

Donc pour utiliser les bouton et les codes php pour déclencher le streaming vidéo, on opère de la même façon :

<?php

exec('bash -c "exec nohup setsid sudo /root/mjpg-streamer/mjpg-streamer.sh start > /dev/null 2>&1 &"');
header('Location: index.php');
?>

Commander un projecteur à LEDs

Comme je voulais filmer sous l’eau, je souhaitais aussi pouvoir allumer un projecteur à leds pour donner un peu de lumière à la camera dans les eaux un peu troubles. ça fonctionne très bien aussi.

J’ai récupéré une petite lampe à leds qui sert à éclairer en se branchant sur le port usb d’un ordinateur.

2014-04-29_18h53_55

J’ai découpé le pied et retiré le tuyau flexible et ça m’a donné un excellent projecteur à leds alimenté en 5V.

C’est un broche du port GPIO qui va contrôler l’allumage et l’extinction des LEDs. Encore un petit schéma rapide :

Sans+qsdtitreImqsfdage

Pour contrôler l’état des broches du GPIO, le plus simple est d’utiliser WiringPi :

git clone git://git.drogon.net/wiringPi
cd ./wiringPi
./build

On met la broche 7 en sortie :

gpio mode 7 out

On lit l’état du tableau :

gpio readall

Ce qui devrait afficher :

+----------+-Rev2-+------+--------+------+-------+
| wiringPi | GPIO | Phys | Name   | Mode | Value |
+----------+------+------+--------+------+-------+
|      0   |  17  |  11  | GPIO 0 | IN   | Low   |
|      1   |  18  |  12  | GPIO 1 | IN   | Low   |
|      2   |  27  |  13  | GPIO 2 | IN   | Low   |
|      3   |  22  |  15  | GPIO 3 | IN   | Low   |
|      4   |  23  |  16  | GPIO 4 | IN   | Low   |
|      5   |  24  |  18  | GPIO 5 | IN   | Low   |
|      6   |  25  |  22  | GPIO 6 | IN   | Low   |
|      7   |   4  |   7  | GPIO 7 | OUT  | Low   |
|      8   |   2  |   3  | SDA    | IN   | High  |
|      9   |   3  |   5  | SCL    | IN   | High  |
|     10   |   8  |  24  | CE0    | IN   | Low   |
|     11   |   7  |  26  | CE1    | OUT  | High  |
|     12   |  10  |  19  | MOSI   | IN   | Low   |
|     13   |   9  |  21  | MISO   | IN   | Low   |
|     14   |  11  |  23  | SCLK   | IN   | Low   |
|     15   |  14  |   8  | TxD    | ALT0 | High  |
|     16   |  15  |  10  | RxD    | ALT0 | High  |
|     17   |  28  |   3  | GPIO 8 | ALT2 | Low   |
|     18   |  29  |   4  | GPIO 9 | ALT2 | Low   |
|     19   |  30  |   5  | GPIO10 | ALT2 | Low   |
|     20   |  31  |   6  | GPIO11 | ALT2 | Low   |
+----------+------+------+--------+------+-------+

On voit bien que la broche 7 est en sortie mais sa valeur est LOW donc le transistor ne laissera pas passer le courant qui allumera les LEDs. Il faut donc passer la sortie de cette broche au niveau haut (High) :

root@raspberrypi:~/wiringPi# gpio write 7 1

Les leds s’allument !

root@raspberrypi:~/wiringPi# gpio readall

+----------+-Rev2-+------+--------+------+-------+
| wiringPi | GPIO | Phys | Name   | Mode | Value |
+----------+------+------+--------+------+-------+
|      0   |  17  |  11  | GPIO 0 | IN   | Low   |
|      1   |  18  |  12  | GPIO 1 | IN   | Low   |
|      2   |  27  |  13  | GPIO 2 | IN   | Low   |
|      3   |  22  |  15  | GPIO 3 | IN   | Low   |
|      4   |  23  |  16  | GPIO 4 | IN   | Low   |
|      5   |  24  |  18  | GPIO 5 | IN   | Low   |
|      6   |  25  |  22  | GPIO 6 | IN   | Low   |
|      7   |   4  |   7  | GPIO 7 | OUT  | High  |
|      8   |   2  |   3  | SDA    | IN   | High  |
|      9   |   3  |   5  | SCL    | IN   | High  |
|     10   |   8  |  24  | CE0    | IN   | Low   |
|     11   |   7  |  26  | CE1    | OUT  | High  |
|     12   |  10  |  19  | MOSI   | IN   | Low   |
|     13   |   9  |  21  | MISO   | IN   | Low   |
|     14   |  11  |  23  | SCLK   | IN   | Low   |
|     15   |  14  |   8  | TxD    | ALT0 | High  |
|     16   |  15  |  10  | RxD    | ALT0 | High  |
|     17   |  28  |   3  | GPIO 8 | ALT2 | Low   |
|     18   |  29  |   4  | GPIO 9 | ALT2 | Low   |
|     19   |  30  |   5  | GPIO10 | ALT2 | Low   |
|     20   |  31  |   6  | GPIO11 | ALT2 | Low   |
+----------+------+------+--------+------+-------+

Pour allumer la led depuis une page web et faire en sorte que l’affichage soit dynamique (c’est à dire que lorsque j’appuie sur le bouton allumer les LEDs l’image du bouton change pour montrer que c’est allumé) il faut utiliser du php mais aussi du javascript.

green red

Voici le code à mettre dans /var/www/Web. Il y a 3 fichiers et un répertoire contenant les images. Je me suis inspiré d’un tutoriel sur un site mais je n’arrive pas à le retrouver pour le citer… 🙁

INDEX.PHP

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Raspberry Pi Gpio</title>
</head>

<body style="background-color: black;">
<!-- On/Off button's picture -->
<?php
//this php script generate the first page in function of the gpio's status
$status = array (0);
$i = 3; // Numéro de la PIN utilisée

//set the pin's mode to output and read them
system("gpio mode ".$pin." out");
exec ("gpio read ".$i, $status[$i], $return );
//if off
if ($status[$i][0] == 0 )
{
echo ("<img id='button_".$i."' src='data/img/red/red_".$i.".jpg' alt='off'/>");
}
//if on
if ($status[$i][0] == 1 )
{
echo ("<img id='button_".$i."' src='data/img/green/green_".$i.".jpg' alt='on'/>");
}

?>

<!-- javascript script.js est inclu dans le fichier -->
<script src="script.js"></script>
</body>
</html>

GPIO.PHP

<!-- This page is requested by the JavaScript, it updates the pin's status and then print it -->
<?php
//Getting and using values
if (isset ($_GET["pin"]) && isset($_GET["status"]) )
{
$pin = strip_tags($_GET["pin"]);
$status = strip_tags($_GET["status"]);
//set the gpio's mode to output
system("gpio mode ".$pin." out");
//set the gpio to high/low
if ($status == "0" ) { $status = "1"; }
else if ($status == "1" ) { $status = "0"; }
system("gpio write ".$pin." ".$status );
//reading pin's status
exec ("gpio read ".$pin, $status, $return );
//printing it
echo ( $status[0]);
} //print fail if cannot use values
else { echo ("Erreur dans l'URL"); }
?>

SCRIPT.JS

//JavaScript, use pictures as buttons, sends and receives values to/from the Rpi

var button_3 = document.getElementById("button_3");

//this function sends and receives the pin's status
function change_pin (pin, status) {
//this is the http request
var request = new XMLHttpRequest();
request.open( "GET" , "gpio.php?pin=" + pin + "&status=" + status );
request.send(null);
//receiving information
request.onreadystatechange = function () {
if (request.readyState == 4 && request.status == 200) {
return (parseInt(request.responseText));
}
//test if fail
else if (request.readyState == 4 && request.status == 500) {
alert ("server error");
return ("fail");
}
//else
else { return ("fail"); }
}
}

//these are all the button's events, it just calls the change_pin function and updates the page in function of the return of it.
button_3.addEventListener("click", function () {
//if red
if ( button_3.alt === "off" ) {
//use the function
var new_status = change_pin ( 3, 0);
if (new_status !== "fail") {
button_3.alt = "on"
button_3.src = "data/img/green/green_3.jpg";
return 0;
}
}
//if green
if ( button_3.alt === "on" ) {
//use the function
var new_status = change_pin ( 3, 1);
if (new_status !== "fail") {
button_3.alt = "off"
button_3.src = "data/img/red/red_3.jpg";
return 0;
}
}
} );

Mais alors ça donne quoi tout ça ??!

Rien ne vaut une petite vidéo ! 🙂

Désolé pour la qualité de la vidéo c’est pas terrible mais j’ai pas pu faire mieux… En tout cas j’espère que ce tutoriel vous a plu. N’hésitez pas à laisser un petit commentaire ICI. Vous pouvez aussi poser vos questions ou demander des précisions. Je m’efforcerai d’y répondre au mieux.

Timothé Poznanski

16 réflexions au sujet de « BateauRaspberry : bateau piloté avec un Pi (par Tim) »

  1. Ping : BateauRaspberry : un bateau entièrement fait main, piloté par un Pi (màj) | MagdiBlog

  2. Ping : BateauRaspberry : bateau piloté avec un ...

  3. Ping : Tim nous mène en bateau avec le Raspberry Pi | Framboise 314, le Raspberry Pi à la sauce française….

  4. hervé

    Joli !
    Si tu désires bricoler un peu plus, un pont en H pour le pilotage de ton moteur et bye bye le variateur d’un autre temps !
    amicalement

    Répondre
    1. Olivier Auteur de l’article

      Tout à fait 🙂
      Avez vous des plans de montage pour piloter un pont en H avec le GPIO du Pi ?

      Répondre
      1. Pascal

        Bravo pour ce projet … clap clap clap …. 😉 …, il existe des petites cartes à base du circuit L298 qui intègre 2 ponts en H (2A), cela nécessite 4 sorties numérique du port GPIO de la carte Raspberry.

        Ex:(http://www.tinydeal.com/fr/L298N-Stepper-Motor-Driver-Controller-Board-for-Arduino-Works-with-Official-Arduino-Boards-Red-EDC-274622-p-118185.html?currency=EUR&gclid=CjwKEAjwuYOeBRCy3pLljpjDkDcSJAAhA4mtqq5qBdFY0cQkoN8aa9L_LCEcFwiJFvtXJKcIjWWKdxoCSVjw_wcB)

        Votre projet de drone m’intéresse, j’espère qu’on pourra échanger, je suis pas trop mauvais en électronique, cordialement Pascal.

        Répondre
  5. Ping : Créer un bateau avec un Raspberry Pi - Culture MakerCulture Maker

  6. Ping : Créer un bateau avec un Raspberry Pi - CultureMaker

  7. Ping : Créer un bateau avec un Raspberry Pi - Culture Maker

  8. octopus

    Bonjour. Projet très intéressant. Je pense que le principe peut aisément être utilisé pour réaliser une ipcam motorisée. Encore merci. Avez vous une vidéo de l vision sous l’eau

    Répondre
    1. Olivier Auteur de l’article

      Bonjour,
      Je n’ai pas de vidéo sous marine sur ce projet.
      En revanche j’ai un nouveau projet de bateau bcp plus évolué à l’étude 😉 j’en parlerai bientôt sur le blog 😉

      Répondre
  9. gregouille

    Super projot! Comme vous je ne suis pas développeur et j’ai bidouillé un robot sur chenille animé par un raspb et un pont en H pour commander les moteur via un script auquel j’accede en telnet, j’aimerais tellement réussir à commander mon robot simplement via un smartphone avec le stream intégré sur la page de commande! quelqu’un saurais fusionner les deux programmes?

    Répondre
  10. Ping : Commande Servomoteur Webcam Raspberry via HTML5 | Domotic and stupid geek stuff

  11. Evan

    Bonjour,
    Super projet !
    Juste une petite question à propos de la wifi : quelle est la portée maximum de vous à votre bateau ?
    Merci à vous !

    Répondre

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.