ROBOT
« Raspberry Zumo »

 by Frédéric JELMONI

 

Galerie photos >>>

SOMMAIRE

 

 

Présentation. 2

Liste des pièces mécaniques et électroniques. 3

Présentation rapide de carte Raspberry PI 5

Configuration de la Raspberry. 6

Gestion de la webcam et du flux video. 9

Schéma électronique. 10

Programmation. 12

 

 

 

1      Présentation

 

Ce petit robot a été réalisé à l’aide d’une carte « Raspberry PI », d’un châssis à chenille de chez « Pololu », et d’une webcam.

Sa connexion Wifi lui permet de diffuser les flux vidéo sur le réseau et d’être commandé à distance de façon  très simple, depuis un ordinateur ou éventuellement un smartphone type Iphone ou Andoid.

 

Je vous propose de décrire, en quelques lignes, les différentes étapes de cette réalisation ;  les aspects mécaniques, électroniques et informatiques.

 

 

<<<   Galerie photos   >>>

 

2      Liste des pièces mécaniques et électroniques

 

Voici la liste des pièces utilisées lors de la réalisation du robot :

 

Ø  Le chassis « Zumo » de chez Pololu.com                      

http://www.pololu.com/product/1418

 

Ø  Deux moteurs 6volt de chez Pololu.com

http://www.pololu.com/product/1101

Ø  Une carte Raspberry PI 512Mo Modèle B

Dispo chez : http://www.kubii.fr

 

Ø  Une carte SD de 8Go

 

Ø  Un module USB WIFI

 

Ø  Une Webcam Logitech QuickCam Pro9000     

http://www.logitech.fr/...

Ø  Une batterie ANKER de 3000mAh

http://www.amazon.fr/...

 

Ø  Un Circuit pont en H 1A SN754410

 … et aussi :

Ø  Un buzzer

Ø  Une LED tricolore

Ø  Un circuit imprimé type plaque pastille au pas 2,54mm

Ø  Quelques fils de connexion à connecteur femelle

Ø  Quelques entretoises, vis et écrous M3

 

 

Une grande partie des composants électroniques et petites pièces mécaniques sont disponibles chez Lextronic : http://www.lextronic.fr/

 

 

 

3      Présentation rapide de carte Raspberry PI

 

La carte « Raspberry PI » est un nano-ordinateur de la taille d’une carte de crédit (ou presque : 86x54cm) équipé d’un processeur ARM à 700Mhz.

Elle dispose, dans ca dernière version, de 512Mo de Ram, d’une interface Ethernet 10/100, de 2 interfaces USB, d’une sortie audio 5.1 de type jack 3,5mm et  de deux sorties vidéo (HDMI et composite).

Son processeur graphique embarqué permet un encodage/décodage de flux vidéo au format h264/Mpeg4.

Son support de carte SD lui permet d’accueillir l’élément de stockage principal où est installé le système d’exploitation.

 

Un connecteur de 2x13 broches fournit :

·         8 ports GPIO (entrée/sortie)

·         1 UART Rs232

·         2 bus SPI

·         1 bus I2C

·         Une alimentation 5V

·         Une alimentation 3,3V

 

La carte Raspberry PI est alimentée en 5V via son connecteur micro USB

nbl

 

 

 

4      Configuration de la Raspberry

4.1      Installation de la distribution

 

Même si 4 Go peuvent suffire, j’utilise une carte SD de 8 Go pour héberger le système d’exploitation, ce qui permet d’avoir une souplesse de stockage à des fins expérimental. Il est de plus intéressant d’opter pour une carte performante en termes de débit (30Mb/s par exemple).

 

Diverses distributions Linux ont été compilées pour le processeur ARM de la Raspberry. J’utilise « Raspbian », recommandé par la fondation Raspberry PI, qui est tout simplement une adaptation de la distribution Debian « wheezy ».

 

 

 

Il existe plusieurs méthodes pour installer le système, « Win32DiskImage » sous Windows,  « dd » sous linux ou mac …

 

Ø  La toute dernière méthode proposée par la fondation Raspberry PI et fonctionnant sous Windows ou Mac est encore plus simple !!! :

 

Exemple d’installation de l’OS sous Windows :

 

1/ Formater la carte SD avec l’utilitaire « SD Formatter 4.0 for SD/SDHC/SDXC » disponible ici : https://www.sdcard.org/...

 

2/ Télécharger la dernière version « NOOBS » offline  depuis le site officiel (~1,3Go) : http://www.raspberrypi.org/downloads

 

3/ Extraire le Zip et Copier l’intégralité des fichiers directement sur car SD

 

4/ Installer la carte SD dans le slot de carte Raspberry PI

 

5/ Démarrer la carte Raspberry en connectant écran, clavier, souris, interface réseau et alimentation

 

 

à Le mode « Recovery »  de la raspberry  fait le reste … !!!

 

 

4.2      Configuration système

 

Lors du premier démarrage, sélectionner l’installation de la distribution « Raspbian ».

Après quelques minutes d’installation et un premier reboot, l’utilitaire « raspi-config » se lance automatiquement. Il permet de définir :

·         le mot de passe

·         les locales  (par exemple : fr_FR ISO-8859-1 et fr_FR.UTF-8 UTF-8)

·         le fuseau horaire

·         le type de clavier

·         le nom de host

 

Première connexion avec le nom d’utilisateur « pi », et mise à jour du système :

 

# sudo -s

# apt-get update

 

Puis :

 

# apt-get upgrade

 

 

Et pour le fun, un peu de couleur dans vi :

 

# apt-get install vim

# echo syn on >> /etc/vim/vimrc.local

 

 

4.3      Installation des packages nécessaire

 

Dans cette distribution, les environnements de développement (Python, C, …) ainsi que  le module GPIO « python3-rpi.gpio » sont déjà installés, Il ne reste que peu de chose à installer.

La librairie « RPIO » sera nécessaire ; Elle permet de générer des signaux de type PWM.

 

# apt-get install python-setuptools

# easy_install -u RPIO

 

 

D’autres packages seront également utile,  pour le wifi, la webcam …   ils sont traités plus bas

 

 

 

 

 

4.4      Configuration du wifi

 

Dans sa configuration actuelle, le robot se connecte directement à la borne Wifi de mon domicile. Ce qui lui permet un accès complet aux diverses ressources du réseau local, et un accès à Internet.

Une autre solution (une évolution possible) pourrait être de configurer la carte Raspberry en Acces-Point Wifi (en « hotspot »), ce qui la rendrait entièrement autonome.

 

L’ajout de l’adaptateur Usb Wifi crée une interface réseau nommée « wlan0 »,  il suffit d’éditer le fichier  /etc/network/interfaces pour configurer une adresse IP, le SSID et mot de passe wifi.

 

vi  /etc/network/interfaces

 

auto wlan0

iface wlan0 inet static

        address 192.168.21.61

        netmask 255.255.255.0

        network 192.168.21.0

        broadcast 192.168.21.255

        gateway 192.168.21.1

        wpa-ssid "mon_wifi"

        wpa-psk "mon_mot_de_passe"

 

 

5      Gestion de la webcam et du flux video

 

L’objectif est de diffuser le simplement possible, le flux vidéo de la webcam sur le réseau local.

 

Après plusieurs tentatives avec diverses solutions tel que Motion, ffmpeg, vlc  ou autres,  j’ai fini par adopter « MJPG-Streamer » qui pour avantages d’être peu consommateur en ressources, d’embarquer son propre serveur web pour la diffusion, et le tout avec une faible latence !

 

MJPG-Streamer n’est pas packagé pour Raspbian, il faut donc le compiler pour le processeur ARM de la Raspberry.

Les sources sont disponibles sur sourceforge : http://sourceforge.net/projects/mjpg-streamer/

 

5.1      Installation de MJPG-Streamer

 

#  cd /home/pi

 

#  wget  http://sourceforge.net/projects/mjpg-streamer/files/mjpg-streamer/Sourcecode/mjpg-streamer-r63.tar.gz

#  tar -zxvf mjpg-streamer-r63.tar.gz

#  ln -s mjpg-streamer-r63 mjpg-streamer

#  cd mjpg-streamer

 

#  ln -s /usr/include/linux/videodev2.h /usr/include/linux/videodev.h

#  apt-get install libjpeg8-dev libmath++-dev

 

#  make clean all

 

  

5.2      Lancement  du processus  MJPG-Streamer

 

Ces 3 commandes permettent de démarrer MJPG-Streamer :

 

# cd  /home/pi/mjpg-streamer

# export LD_LIBRARY_PATH=.

# ./mjpg_streamer -o "output_http.so -w ./www"

 

 

Le tout dans un script shell, ce qui permet un démarrage en une seule commande : 

 

# /home/pi/mjpg-streamer/start.sh

 

MJPG Streamer Version.: 2.0

 i: Using V4L2 device.: /dev/video0

 i: Desired Resolution: 640 x 480

 i: Frames Per Second.: 5

 i: Format............: MJPEG

 o: www-folder-path...: ./www/

 o: HTTP TCP port.....: 8080

 o: username:password.: disabled

 o: commands..........: enabled

 

 

 

 

            Reste à vérifier :         http://Mon_Adresse_IP:8080

 

 

 

 

 

 

6      Schémas électroniques

6.1      Connecteur GPIO

Voici le détail du connecteur de 2x13 broches de Raspberry.

Les broches sont numérotées de 1 à 26 sont également identifiées par une référence GPIO qui est plus simple à utiliser lors de la programmation. Elles peuvent être configurées en entrée ou en sortie.

 

http://www.megaleecher.net/sites/default/files/images/raspberry-pi-rev2-gpio-pinout.jpg

 

 

      Le Robot « Raspberry Zumo » utilise (dans sa version actuelle) 8 sorties GPIO :

 

·         GPIO 25       à        Moteur Droite, marche avant

·         GPIO 24       à        Moteur Droite, marche arrière

·         GPIO 23       à        Moteur Gauche, marche avant

·         GPIO 18       à        Moteur Gauche, marche arrière

·         GPIO 22       à        LED tricolore, rouge

·         GPIO 27       à        LED tricolore, vert

·         GPIO 17       à        LED tricolore, bleu

·         GPIO 04       à        Buzzer

 

 

6.2      Précision sur l’alimentation

 

Le robot utilise deux sources d’énergie.

·         La batterie ANKER de 3000mAh fournit 5volt à la Rasberry et ces interfaces USB, comprenant le module Wifi et la Webcam. Elle alimente également la LED externe et le circuit SN754410

·         Quatre piles rechargeables placées dans le châssis à chenille fournissent environ 6Volt aux deux moteurs

 

 

6.3      Schéma du robot « Raspberry Zumo »

 

Les sorties GPIO fournissent 3.3Volt pour un courant maximum de 100mA. Il est donc très simple d’alimenter une LED ou un Buzzer.

En revanche pour commander les 2 moteurs 6volt à courant continu, et qui plus est, pour gérer leur sens de rotation, il est nécessaire d’utiliser un « circuit pont en H ». J’utilise un SN754410 (équivalant au L293D) qui permet de piloter deux moteurs CC de 4,5V à 36V provenant d’une source d’alimentation dédiée, pour un prix très économique.

 

 

 

 

7      Programmation

7.1      Descriptif des fonctions

 

L’objectif est de développer un petit programme permettant de piloter les deux moteurs, d’allumer la LED tricolor en mode « tout-ou-rien » pour chaque couleurs et d’envoyer un signal de type PWM au buzzer.

Pour faciliter l’envoie de commandes via le réseau et permettre de futurs évolutions, j’ai souhaité mettre en place une solution client/serveur. Le robot héberge un serveur IP qui crée un socket TCP sur le port 12345. Cela a comme principal avantage d’être complètement indépendant de la plate-forme cliente (Linux, MacOs, Windows, Smartphone..) et du langage utilisé (Java, C… ou autre). Telnet peut par exemple, et dans un premier temps, être très bon client !

 

Les différentes librairies et exemples sont disponibles pour la Raspberry en langage Python. De plus l’environnement de développement est déjà préinstallé dans la distribution Raspbian Wheezy. Le serveur est donc développé en Python. Les principales commandes (marche avant, marche arrière, tourner à droite ou à gauche ….etc) ont été implémenté ainsi qu’un petit menu à la connexion.

 

7.2      Le code

 

Le fichier « robot-srv.py » est créé dans le répertoire /home/pi,  l’attribut d’exécution doit être positionné sur ce fichier (chmod +x)

 

#!/usr/bin/python

# -*- coding:Utf-8 -*-

 

from RPIO import PWM

import RPIO

import socket

import RPi.GPIO as GPIO

import time

import sys

 

HOST = "0.0.0.0"

PORT = 12345

 

#-------------[ CABLAGE ]--------------------

My_LED = 22

 

Moteur_1_Forward = 25

Moteur_1_Reverse = 24

Moteur_2_Forward = 23

Moteur_2_Reverse = 18

 

LED_R = 22

LED_V = 27

LED_B = 17

BUZZER_PIN = 04

 

#-------------[ Initialisation ]--------------

 

GPIO.setwarnings(False)

GPIO.setmode(GPIO.BCM)

GPIO.setup(Moteur_1_Forward, GPIO.OUT)

GPIO.setup(Moteur_1_Reverse, GPIO.OUT)

GPIO.setup(Moteur_2_Forward, GPIO.OUT)

GPIO.setup(Moteur_2_Reverse, GPIO.OUT)

 

GPIO.setup(LED_R, GPIO.OUT)

GPIO.setup(LED_V, GPIO.OUT)

GPIO.setup(LED_B, GPIO.OUT)

 

BUZZER = RPIO.PWM.Servo()

 

 

#--------------------------------------------

def BIP() :

   BUZZER.set_servo(BUZZER_PIN,15000)

   time.sleep(.1)

   BUZZER.stop_servo(BUZZER_PIN)

   time.sleep(.01)

   BUZZER.set_servo(BUZZER_PIN,15000)

   time.sleep(.1)

   BUZZER.stop_servo(BUZZER_PIN)

 

def AVANT() :

    print "Marche Avant"

    GPIO.output(Moteur_1_Forward, GPIO.HIGH)

    GPIO.output(Moteur_2_Forward, GPIO.HIGH)

 

def ARRIERE() :

    print "Marche Arriere"

    GPIO.output(Moteur_1_Reverse, GPIO.HIGH)

    GPIO.output(Moteur_2_Reverse, GPIO.HIGH)

    time.sleep(0.5)

    STOP()

 

def DROITE() :

    print "tourne a droite"

    GPIO.output(Moteur_1_Forward, GPIO.HIGH)

    GPIO.output(Moteur_2_Reverse, GPIO.HIGH)

    time.sleep(0.5)

    STOP()

 

def DROITE_Toute() :

    print "tourne a droite"

    GPIO.output(Moteur_1_Forward, GPIO.HIGH)

    GPIO.output(Moteur_2_Reverse, GPIO.HIGH)

 

def GAUCHE() :

    print "tourne a gauche"

    GPIO.output(Moteur_1_Reverse, GPIO.HIGH)

    GPIO.output(Moteur_2_Forward, GPIO.HIGH)

    time.sleep(0.5)

    STOP()

 

def GAUCHE_Toute() :

    print "tourne a gauche"

    GPIO.output(Moteur_1_Reverse, GPIO.HIGH)

    GPIO.output(Moteur_2_Forward, GPIO.HIGH)

 

 

def STOP () :

    print "stop"

    GPIO.output(Moteur_1_Forward, GPIO.LOW)

    GPIO.output(Moteur_2_Forward, GPIO.LOW)

    GPIO.output(Moteur_1_Reverse, GPIO.LOW)

    GPIO.output(Moteur_2_Reverse, GPIO.LOW)

 

 

def LED_R_UP() :

    print "LED Rouge Marche"

    GPIO.output(LED_R, GPIO.HIGH)

def LED_V_UP() :

    print "LED Vert Marche"

    GPIO.output(LED_V, GPIO.HIGH)

def LED_B_UP() :

    print "LED Bleu Marche"

    GPIO.output(LED_B, GPIO.HIGH)

def LED_DOWN() :

    print "LED Stop"

    GPIO.output(LED_R, GPIO.LOW)

    GPIO.output(LED_V, GPIO.LOW)

    GPIO.output(LED_B, GPIO.LOW)

 

def MENU() :

    connexion.send( "\n\r" )

    connexion.send( "  A  --> en Avant\n" )

    connexion.send( "  R  --> en Arriere\n" )

    connexion.send( "  D  --> a Droite\n" )

    connexion.send( "  DD --> a Droite (sans stop)\n" )

    connexion.send( "  G  --> a Gauche\n" )

    connexion.send( "  GG --> a Gauche (sans stop)\n" )

    connexion.send( "  S  --> STOP\n" )

    connexion.send( "  1  --> LED Rouge ON\n" )

    connexion.send( "  2  --> LED Vert ON\n" )

    connexion.send( "  3  --> LED Bleu ON\n" )

    connexion.send( "  0  --> LED OFF\n" )

    connexion.send( "  B  --> BIP\n" )

    connexion.send( "  M  --> MENU\n" )

    connexion.send( "\n" )

 

print "GO"

print "Start\n"

 

# Creation du socket

mySocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

 

# Liaison du socket avec l'interface

try:

   mySocket.bind((HOST, PORT))

except socket.error:

   print "La liaison du socket à l'adresse choisie a échoué."

   sys.exit()

 

BIP()

# --------------------------------------

while 1:

 

   print "Serveur en attente ..."

   mySocket.listen(5)

 

   # Etablissement de la connexion :

   connexion, adresse = mySocket.accept()

   print "Client connecté, adresse IP %s, port %s" % (adresse[0], adresse[1])

 

   # Envoi d'un message qu client :

   connexion.send("\nWelcome to Fred's Robot Server\n\n")

   MENU()

 

   # Reception des message client

   while 1:

      msgClient = connexion.recv(10).rstrip()

      print "C>"+msgClient+"<"

      if msgClient.lower() == "fin" or msgClient =="" or msgClient.lower() == "stop":

         print "Break !!!"

         break

 

      elif msgClient.upper() == "M" :

         MENU()

 

      # Commandes Robot

      elif msgClient.upper() == "A" :

         AVANT()

      elif msgClient.upper() == "R" :

         ARRIERE()

      elif msgClient.upper() == "D" :

         DROITE()

      elif msgClient.upper() == "DD" :

         DROITE_Toute()

      elif msgClient.upper() == "G" :

         GAUCHE()

      elif msgClient.upper() == "GG" :

         GAUCHE_Toute()

      elif msgClient.upper() == "S" :

         STOP()

      elif msgClient.upper() == "1" :

         LED_R_UP()

      elif msgClient.upper() == "2" :

         LED_V_UP()

      elif msgClient.upper() == "3" :

         LED_B_UP()

      elif msgClient.upper() == "0" :

         LED_DOWN()

      elif msgClient.upper() == "B" :

         BIP()

 

 

   # Fin de la session

   connexion.send("By By !")

   print "Connexion interrompue."

   connexion.close()

 

   # fin du programme

   if msgClient.lower() == "stop":

      break

 

 

 

7.3      Tests

 

Et voilà !!!  Il ne reste plus qu’à tester !

 

Donc sur la raspberry PI,  heu … NON !!! à SUR LE ROBOT « Raspberry ZUMO », on lance la Webcam & le serveur :

 

# /home/pi/mjpg-streamer/start.sh

 

# /home/pi/robot-srv.py

 

      Et on test, depuis un poste Windows par exemple :

 

 

 

 

 

Frédéric JELMONI