Différences entre versions de « Rasp-Hack-HDMI-Serveur »

De MCHobby - Wiki
Sauter à la navigation Sauter à la recherche
 
(33 versions intermédiaires par le même utilisateur non affichées)
Ligne 6 : Ligne 6 :
 
[[Fichier:Rasp-Hack-HDMI-Serveur.jpg|600px]]
 
[[Fichier:Rasp-Hack-HDMI-Serveur.jpg|600px]]
  
Alors que le Pi est capable de réaliser facilement beaucoup des tâches d'un Arduino et même plus encore... certain peuvent avoir des projets Arduino nettement plus complets (comme par exemple, un projet relatif à l'automatisation d'un Home Cinema) qui pourrait bénéficier d'une sortie HDMI.
+
Alors que le Pi est capable de réaliser facilement beaucoup des tâches d'un Arduino et même plus encore... certain peuvent avoir des projets Arduino nettement plus complets (comme par exemple, un projet relatif à l'automatisation d'un Home Cinema) qui pourraient bénéficier d'une sortie HDMI.
  
 
Les shield d'affichage pour Arduino ne sont pas les meilleurs marchés, pourquoi ne pas utiliser un RaspPi à la place? Il y aussi déjà eu des hack pour utiliser un RaspPi comme shield réseau, et ce projet y est fort semblable (vous pourriez juste changer un peu le code "côté Pi" pour avoir des commandes "réseaux" disponible en très peu de temps).
 
Les shield d'affichage pour Arduino ne sont pas les meilleurs marchés, pourquoi ne pas utiliser un RaspPi à la place? Il y aussi déjà eu des hack pour utiliser un RaspPi comme shield réseau, et ce projet y est fort semblable (vous pourriez juste changer un peu le code "côté Pi" pour avoir des commandes "réseaux" disponible en très peu de temps).
Ligne 14 : Ligne 14 :
 
Le matériel nécessaire pour ce Hack est très simple - Le Pi est raccordé à l'Arduino en utilisant l'interface Série disponible sur les deux plateformes.
 
Le matériel nécessaire pour ce Hack est très simple - Le Pi est raccordé à l'Arduino en utilisant l'interface Série disponible sur les deux plateformes.
  
Comme le Pi fonctionne en 3.3V et un Arduino en 5V, il faut utiliser un convertisseur de niveau logique (''level converter'' en anglais – cette fois j'ai utiliser [http://mchobby.be/PrestaShop/product.php?id_product=131 un convertisseur AdaFruit], il est incroyablement simple à utiliser et il n'y a aucun danger de surcharge pour votre Pi (au contraire d'un convertisseur à base de résistance, [http://codeandlife.com/2012/07/29/arduino-and-raspberry-pi-serial-communication/ voir cet autre Article de Joonas Pihlajamaa] ''en anglais'').
+
Comme le Pi fonctionne en 3.3V et un Arduino en 5V, il faut utiliser un convertisseur de niveau logique (''level converter'' en anglais – cette fois j'ai utiliser {{pl|131|un convertisseur logique AdaFruit}}, il est incroyablement simple à utiliser et il n'y a aucun danger de surcharge pour votre Pi (au contraire d'un convertisseur à base de résistance, [http://codeandlife.com/2012/07/29/arduino-and-raspberry-pi-serial-communication/ voir cet autre Article de Joonas Pihlajamaa] ''en anglais'').
  
 
[[Fichier:Rasp-Hack-HDMI-Serveur-PiSerialGPIO.png|100px]]  
 
[[Fichier:Rasp-Hack-HDMI-Serveur-PiSerialGPIO.png|100px]]  
Ligne 22 : Ligne 22 :
 
| image      = [[File:StopHand.png|40px|alt=Stop]]
 
| image      = [[File:StopHand.png|40px|alt=Stop]]
 
| textstyle  = color: red; font-weight: bold; font-style: italic;
 
| textstyle  = color: red; font-weight: bold; font-style: italic;
| text      = Ne raccordez jamais directement un Arduino et un Raspberry, Arduino fonctionne en 5v et le Raspberry en 3.3v... vous seriez assurez de détruire le GPIO et/ou votre Raspberry Pi.
+
| text      = Ne raccordez jamais directement un Arduino et un Raspberry, Arduino fonctionne en 5v et le Raspberry en 3.3v... vous seriez assuré de détruire le GPIO et/ou votre Raspberry Pi.
 
}}
 
}}
  
Les connexions sont réalisées comme suit par '''l'intermédiaire d'un [http://mchobby.be/PrestaShop/product.php?id_product=131 convertisseur logique]''' (''level converter'' en anglais) qui adapte les tensions entre le Raspberry Pi et votre Arduino.  
+
Les connexions sont réalisées comme suit par '''l'intermédiaire d'un {{pl|131|convertisseur logique}}''' (''level converter'' en anglais) qui adapte les tensions entre le Raspberry Pi et votre Arduino.  
  
 
[[Fichier:Rasp-Hack-HDMI-Serveur-LevelConverter.jpg]]
 
[[Fichier:Rasp-Hack-HDMI-Serveur-LevelConverter.jpg]]
  
Effectuez toutes les connections suivantes par l'<font color="red">intermédiaire du [http://mchobby.be/PrestaShop/product.php?id_product=131 convertisseur logique]</font>:  
+
Effectuez toutes les connections suivantes par l'<font color="red">intermédiaire du {{pl|131|convertisseur logique}}</font>:  
 
* connectez les GND (Ground, la masse en Français) entre les périphériques (soyez méfiant, vérifiez d'abord 3 fois qu'il s'agit bien de la masse!)
 
* connectez les GND (Ground, la masse en Français) entre les périphériques (soyez méfiant, vérifiez d'abord 3 fois qu'il s'agit bien de la masse!)
 
* Connectez le TX du Pi sur le RX d'Arduino (connectez uniquement après la programmation de votre Arduino, ne jamais programmer votre Arduino avec le Pi connecté!)
 
* Connectez le TX du Pi sur le RX d'Arduino (connectez uniquement après la programmation de votre Arduino, ne jamais programmer votre Arduino avec le Pi connecté!)
 
* Connectez le RX du Pi sur le TX d'Arduino
 
* Connectez le RX du Pi sur le TX d'Arduino
  
== Programmation ==
+
=== Sans Pi-Cobbler ===
 +
Voici le schéma de raccordement logique entre le Raspberry-Pi et Arduino.
 +
 
 +
[[Fichier:HDMI-Server-v1_bb.jpg|800px]]
 +
 
 +
Le raccordement est identique sur un {{link-product-piplus}} puisque les 26 premières broches du GPIO sont identiques.
 +
 
 +
=== Avec Pi-Cobbler ===
 +
Si vous disposez d'un {{link-product-picobbler}} ou un {{link-product-picobblerplus}}, votre raccordement s'en trouvera grandement facilité.
 +
 
 +
Voici comment opérer le raccordement logique entre le Raspberry-Pi et Arduino.
 +
 
 +
[[Fichier:HDMI-Server-v2_bb.jpg|800px]]
 +
 
 +
==== Pi-Cobbler ou Pi-Cobbler-Plus? ====
 +
 
 +
{{picobbler-compatibility}}
  
 
== Programme côté Raspberry Pi ==
 
== Programme côté Raspberry Pi ==
 +
=== Un serveur HDMI ===
 
Du côté logiciel, le PI agit comme un "serveur", acceptant des commandes d'affichage simple par l'intermédiaire de la connexion série.  
 
Du côté logiciel, le PI agit comme un "serveur", acceptant des commandes d'affichage simple par l'intermédiaire de la connexion série.  
  
Ligne 45 : Ligne 62 :
 
draw 5 15 10 10
 
draw 5 15 10 10
 
# quitter le serveur
 
# quitter le serveur
quit
+
exit
 
</nowiki>  
 
</nowiki>  
  
Ligne 60 : Ligne 77 :
 
# Code source ar2pi.py par Joonas Pihlajamaa pour codeandlife.com (Juillet 2012)
 
# Code source ar2pi.py par Joonas Pihlajamaa pour codeandlife.com (Juillet 2012)
 
# Article original: http://codeandlife.com/2012/12/27/raspberry-pi-as-arduino-hdmi-shield/
 
# Article original: http://codeandlife.com/2012/12/27/raspberry-pi-as-arduino-hdmi-shield/
#    original et credit par Joonas Pihlajamaa (www.joonaspihlajamaa.com)
+
#    original et credit par Joonas Pihlajamaa (www.joonaspihlajamaa.com) - Public Domain Code
 
# Article Francais: http://mchobby.be/wiki/index.php?title=Rasp-Hack-HDMI-Serveur
 
# Article Francais: http://mchobby.be/wiki/index.php?title=Rasp-Hack-HDMI-Serveur
 
#    Traduction CC-BY-SA par D.Meurisse (www.MCHobby.be)   
 
#    Traduction CC-BY-SA par D.Meurisse (www.MCHobby.be)   
Ligne 69 : Ligne 86 :
  
 
ser = serial.Serial("/dev/ttyAMA0",9600)
 
ser = serial.Serial("/dev/ttyAMA0",9600)
 +
# EN: On more recent version of Python (eg >= 2.7) the constructor did already opens serial port.
 +
#    In such case, executing open() will returns the error "Port is already open."
 +
#    Workaround: put the open() commande under comment
 +
# FR: Sur une version plus recente de python, (ex >= 2.7) le construteur ouvre deja le port serie.
 +
#    Si tel est le cas, l'execution de open() retournera l'erreur "Port is already open."
 +
#    Solution: mettre la ligne suivante en commentaire.
 
ser.open()
 
ser.open()
 +
print( "Open serial port: OK" )
  
 
pygame.init()
 
pygame.init()
 +
print( "PyGame init: OK" )
 +
 
window = pygame.display.set_mode((500, 500))
 
window = pygame.display.set_mode((500, 500))
 
colour = pygame.Color("blue")
 
colour = pygame.Color("blue")
 
pygame.mouse.set_visible(False)
 
pygame.mouse.set_visible(False)
 +
print( "PyGame configure: OK" )
 +
print( "Now waiting for serial command..." )
  
 
quit = False
 
quit = False
Ligne 93 : Ligne 121 :
 
</nowiki>
 
</nowiki>
  
=== Rendre le fichier exécutable ===
+
Notez que les commandes "rect" et "quit" sont les seuls mots clés reconnus et que le reste est simplement ignoré.
Par défaut, les fichier sont considéré comme des fichiers texte non exécutable... même s'il contiennent des scripts.
+
 
 +
Le "#" utilisé comme marqueur de commentaire (voir tout début de cette section) ne causera donc aucun problème.
 +
 
 +
=== Pygame et python-serial ===
 +
 
 +
Si vous disposez d'un système d'exploitation '''Raspbian-Wheezy''', vous ne devriez pas le paquet pygame.
 +
 
 +
Par contre, il faudra installé PySerial. Sur base de [[Pi-Python-Prepa|notre environnement Python]], nous avons exécuté la commande
 +
 
 +
sudo pip install pyserial
 +
 
 +
Si vous ne disposez pas de '''Raspbian-Wheezy''', vous devrez installer les paquets '''python-serial''' et '''pygame''' pour exécuter le script serveur.
 +
 
 +
Utilisez la commande suivante (mentionnée sur CodeAndLife) pour installer les paquets nécessaires: 
 +
 
 +
sudo apt-get install pygame python-serial
 +
 
 +
=== Disponibilité de ttyAMA0 ===
 +
 
 +
{{ambox | text = Par défaut, le périphérique /dev/ttyAMA0 est attaché au terminal série ('''serial terminal''') du Raspberry Pi. Vous aurez donc besoin de désactiver cette fonctionnalité dans /etc/inittab et de rebooter le Pi pour libéré le périphérique série }} 
 +
 
 +
# Ouvrir le fichier /etc/inittab à l'aide de <br />sudo nano /etc/inittab
 +
# Localiser la ligne contenant ttyAMA0
 +
# Mettre la ligne en commantaire à l'aide d'un #
 +
 
 +
=== Rendre ar2pi exécutable ===
 +
Par défaut, les fichiers sont considérés comme des fichiers texte non exécutable... même s'il contiennent des scripts.
  
 
Il faut donc indiquer au système d'exploitation qu'il peut autoriser l'exécution de notre raspi-blink.py
 
Il faut donc indiquer au système d'exploitation qu'il peut autoriser l'exécution de notre raspi-blink.py
 
  <nowiki>chmod +x ar2pi.py</nowiki>
 
  <nowiki>chmod +x ar2pi.py</nowiki>
  
=== Exécuter notre programme ===
+
=== Exécuter le serveur ===
 
  <nowiki>sudo ./ar2pi.py</nowiki>
 
  <nowiki>sudo ./ar2pi.py</nowiki>
  
 
Vous pouvez arrêter le programme en utilisant la commande "quit" depuis votre Arduino ou en utilisant la combinaison de touche CTRL + C.
 
Vous pouvez arrêter le programme en utilisant la commande "quit" depuis votre Arduino ou en utilisant la combinaison de touche CTRL + C.
 +
 +
== Programme côté Arduino ==
 +
 +
Du côté Arduino, vous n'avez besoin que d'un simple programme (sketch). Il ouvre la connexion série vers le Pi et envoi les différentes commandes d'affichage.
 +
 +
=== Programme Arduino ===
 +
<nowiki>int pos = 0, width = 1;
 +
 +
void setup() {
 +
  Serial.begin(9600); // Initialiser la connexion série
 +
 +
  // Envoyer la commande d'intialisation du ViewPort au serveur d'affichage du Pi.
 +
  // Cette commande n'est pas encore implémentée sur le serveur python... elle est donc ignorée
 +
  Serial.print("init 500 500\r\n");
 +
}
 +
 +
// Fonction d'aide pour enviyer la commande "draw x y w h\r\n" au Pi
 +
void draw_rect(int x, int y, int w, int h) {
 +
  Serial.print("rect ");
 +
  Serial.print(x);
 +
  Serial.print(' ');
 +
  Serial.print(y);
 +
  Serial.print(' ');
 +
  Serial.print(w);
 +
  Serial.print(' ');
 +
  Serial.print(h);
 +
  Serial.print("\r\n");
 +
}
 +
 +
void loop() {
 +
  int n;
 +
 
 +
  if(pos + width > 500)
 +
    return; // Sortir une fois que la commande "exit" est envoyée.
 +
   
 +
  delay(500); // Dessiner un nouveau rectangle toutes les 500 ms
 +
  draw_rect(pos, pos, width, width); // Carré placé à la position (pos, pos)
 +
 +
  pos += width; // incrémenter les position x et y
 +
  width++; // Agrandir la largeur (et hauteur) du rectangle
 +
 
 +
  if(pos + width > 500) // Le viewport est maintenant rempli
 +
    Serial.print("exit\r\n");
 +
}</nowiki>
 +
 +
=== Upload du programme ===
 +
 +
{{ambox | text = Notez que vous ne pouvez pas charger de sketch sur votre Arduino pendant que la broche RX de votre Raspberry PI est raccordée. Vous devez toujours retirer les fils raccordés sur le bornes RX/TX de votre Arduino avant de charger un nouveau programme.}}
 +
 +
== Serveur HDMI en action  ==
 +
 +
Vous pourrez voir, ci-dessous, les petits bouts de code en action. Vous pourrez me voir presser le bouton enter qui démarre le script Python correspondant au Serveur, et une fois l'affichage initialisé par PyGame (lorsque l'écran devient blanc), je presse le bouton Reset de mon arduino pour redémarrer le sketch qui dessine les rectangles.
 +
 +
Une fois que l'écran est plus ou moins remplit, Arduino envoi la commande “exit” au Pi. Quand le serveur Python reçoit la commande "exit", il retourne en mode terminal:
 +
 +
{{#Widget:Iframe
 +
|url=http://www.youtube.com/embed/f7NCWwJgqhk
 +
|width=560
 +
|height=315
 +
|border=0
 +
}}
 +
 +
Dans l'état actuel du projet, vous aurez besoin de démarrer le script Python (Serveur) à chaque fois.
 +
 +
Une version plus avancée du projet se comporterait comme un véritable “serveur d'affichage” qui fonctionne continuellement et initialiserait le ''ViewPort'' à la taille désirée avec une commande "init".
 +
 +
Les commande devrait également retourner un code statut... et vous pourriez même démarrer le serveur automatiquement au démarrage du Pi de façon à ne plus devoir le démarrer manuellement.
 +
 +
== Conclusions ==
 +
Cet article met en avant un "Serveur HDMI" relativement simple pour Raspberry Pi qui met en oeuvre PySerial pour recevoir des commande par l'intermédiaire de l'interface série du Raspberry Pi. PyGame est utilise pour l'affichage des primitives graphiques correspondant aux commandes envoyées.
 +
 +
En complément, un client Arduino est écrit pour envoyer ces commande vers le Pi, affichant une chaine de rectangles bleu sur l'écran du Pi.
 +
 +
De futures développements ajouterait des commandes incluant de nouvelles primitives comme circle, line, pixel, bitmap pour afficher respectivement des cercles, ligne, point, image, ainsi que des commande pour changer la couleur de rendu et d'autres paramètres.
 +
 +
Une canal de communication du Pi vers Arduino pourrait aussi être ajouté pour, par exemple, retourner l'état/contenu de l'affichage (via une commande "getpixel x y") ou permettre à Arduino de répondre à des évènements physique (événement souris ou pression d'un bouton).
 +
 +
Les commandes pourraient également aller au delà du traitement d'affichage - le Serveur Python pourrait récupérer et extraire des données provenant d'une requête sur Internet (URL)... ou jouer des sont, et tout ce qu'il est possible de réaliser à l'aide d'un Raspberry Pi (ce qui est presque sans limite).
 +
 +
Le Frameword actuel utilise des commandes de type texte, ce qui implique des délais de traitements... même a 115 200 bauds. Une version améliorée du framework utiliserait un protocole binaire. Le code nécessaire côté Arduino pourrait être encapsulé dans une librarie simple d'emploi, cachant ainsi les inutiles détails du framework au développeur.
 +
 +
Vous êtes tous libre de continuer les développement sur les bases de ce code  – Tous le code original de Joonas Pihlajamaa ci-dessus fait partie du domaine public ('''Public Domain''').
 +
 +
== Où Acheter ==
 +
Vous trouverez les différents éléments de ce montage [http://www.mchobby.be chez MCHobby].
 +
 +
Voici les directs vers les différents articles:
 +
* Le {{pl|131|Convertisseur Logique 4 Canaux d'AdaFruit}}
 +
* Un {{link-product-pi2}}
 +
* Un {{link-product-pi3}}
 +
* Un {{link-product-piplus}}
 +
* Un {{link-product-picobblerplus}} ou un {{link-product-picobbler}}
 +
* Un {{pl|10|Arduino}}
 +
* Un {{pl|53|Breadboard demi-taille}}
 +
* Des {{pl|34|fils breadboard extra-souples}}
  
 
<hr />
 
<hr />
Ligne 108 : Ligne 257 :
 
Source: Article "[http://codeandlife.com/2012/12/27/raspberry-pi-as-arduino-hdmi-shield/ Raspberry Pi as Arduino HDMI Shield]" de [http://www.joonaspihlajamaa.com/ Joonas Pihlajamaa] paru sur [http://codeandlife.com CodeAndLife]
 
Source: Article "[http://codeandlife.com/2012/12/27/raspberry-pi-as-arduino-hdmi-shield/ Raspberry Pi as Arduino HDMI Shield]" de [http://www.joonaspihlajamaa.com/ Joonas Pihlajamaa] paru sur [http://codeandlife.com CodeAndLife]
  
<small>Traduit avec l'autorisation de [http://www.joonaspihlajamaa.com/ Joonas Pihlajamaa], Translasted with autorization [http://www.joonaspihlajamaa.com/ Joonas Pihlajamaa].</small>
+
<small>Traduit avec l'autorisation de [http://www.joonaspihlajamaa.com/ Joonas Pihlajamaa], Translated with autorization [http://www.joonaspihlajamaa.com/ Joonas Pihlajamaa].</small>
  
 
{{MCH-Accord}}
 
{{MCH-Accord}}

Version actuelle datée du 29 février 2016 à 17:07

Introduction

C'est aujourd'hui l'occasion pour Joonas Pihlajamaa de CodeAndLife de mettre en oeuvre un projet qu'il planifiait depuis un moment:

Utiliser un Raspberry Pi comme un “shield HDMI” (relativement bon marché) pour une microcontroleur Arduino.

Rasp-Hack-HDMI-Serveur.jpg

Alors que le Pi est capable de réaliser facilement beaucoup des tâches d'un Arduino et même plus encore... certain peuvent avoir des projets Arduino nettement plus complets (comme par exemple, un projet relatif à l'automatisation d'un Home Cinema) qui pourraient bénéficier d'une sortie HDMI.

Les shield d'affichage pour Arduino ne sont pas les meilleurs marchés, pourquoi ne pas utiliser un RaspPi à la place? Il y aussi déjà eu des hack pour utiliser un RaspPi comme shield réseau, et ce projet y est fort semblable (vous pourriez juste changer un peu le code "côté Pi" pour avoir des commandes "réseaux" disponible en très peu de temps).

Raccordement

Le matériel nécessaire pour ce Hack est très simple - Le Pi est raccordé à l'Arduino en utilisant l'interface Série disponible sur les deux plateformes.

Comme le Pi fonctionne en 3.3V et un Arduino en 5V, il faut utiliser un convertisseur de niveau logique (level converter en anglais – cette fois j'ai utiliser un convertisseur logique AdaFruit, il est incroyablement simple à utiliser et il n'y a aucun danger de surcharge pour votre Pi (au contraire d'un convertisseur à base de résistance, voir cet autre Article de Joonas Pihlajamaa en anglais).

Rasp-Hack-HDMI-Serveur-PiSerialGPIO.png

Les connexions sont réalisées comme suit par l'intermédiaire d'un convertisseur logique (level converter en anglais) qui adapte les tensions entre le Raspberry Pi et votre Arduino.

Rasp-Hack-HDMI-Serveur-LevelConverter.jpg

Effectuez toutes les connections suivantes par l'intermédiaire du convertisseur logique:

  • connectez les GND (Ground, la masse en Français) entre les périphériques (soyez méfiant, vérifiez d'abord 3 fois qu'il s'agit bien de la masse!)
  • Connectez le TX du Pi sur le RX d'Arduino (connectez uniquement après la programmation de votre Arduino, ne jamais programmer votre Arduino avec le Pi connecté!)
  • Connectez le RX du Pi sur le TX d'Arduino

Sans Pi-Cobbler

Voici le schéma de raccordement logique entre le Raspberry-Pi et Arduino.

HDMI-Server-v1 bb.jpg

Le raccordement est identique sur un Raspberry Pi-B PLUS puisque les 26 premières broches du GPIO sont identiques.

Avec Pi-Cobbler

Si vous disposez d'un Pi-Cobbler ou un Pi-Cobbler PLUS, votre raccordement s'en trouvera grandement facilité.

Voici comment opérer le raccordement logique entre le Raspberry-Pi et Arduino.

HDMI-Server-v2 bb.jpg

Pi-Cobbler ou Pi-Cobbler-Plus?

Avec l'arrivée du Raspberry Pi 3, Raspberry Pi-2 et Raspberry Pi-B PLUS, Raspberry Pi Zero W vient également un GPIO étendu de 40 broches rétro-compatible avec le GPIO des premières générations du Raspberry-Pi qui, lui, n'avait que 26 broches.

GPIO-Compatibility-00v3.jpg

La seule vraie différence réside dans la longueur du GPIO du modèle Pi-3, Pi-2 ou B+ qui contient des broches en plus... et le Pi-Cobbler PLUS qui à également grandi pour accueillir les broches en plus.

Avec l'apparition du Pi Zero, nous pouvons reparler de la correspondance des GPIO.

Pour notre plus grand bonheur, le GPIO du Pi Zero et du Pi 3 (ou Pi 2) sont identiques :) chouette.

RASP-PIZERO-Correspondance-GPIO v2.jpg
Cliquez pour agrandir

Programme côté Raspberry Pi

Un serveur HDMI

Du côté logiciel, le PI agit comme un "serveur", acceptant des commandes d'affichage simple par l'intermédiaire de la connexion série.

Vous pouvez même démarrer le script serveur du Pi et vous conneter sur le port série à l'aide de Putty. La session pourrait ressembler à ceci:

# initialiser le viewport - pas encore implémenté dans le code serveur
init 500 500
# Dessiner un rectangle de 10x10 à la position (5,15)
draw 5 15 10 10
# quitter le serveur
exit
 

Le serveur Python utilise la libraire de communication pyserial, configurée sur 9600 bauds, mais le Pi et Arduino devraient également être capable de dialoguer à 115 200 bauds.

Pour l'interface graphique, c'est le framework de pygame qui est utilisé. La version du code initialize le viewport graphique à 500×500 points (500x500 pixels), mais il serait possible de passer ce paramètre à une commande "init" envoyée depuis un Arduino (comme cela, c'est le programme Arduino qui défini également le ViewPort).

Le code devrait être assez facile à comprendre: il n'y a que deux commandes supportées, “draw” (dessiner) avec 4 paramètres, et “quit” pour quitter le programme (sinon une boucle infinie attends les commandes de dessin).

Le fichier est nommé ar2pi.py.

#!/usr/bin/env python

# Code source ar2pi.py par Joonas Pihlajamaa pour codeandlife.com (Juillet 2012)
# Article original: http://codeandlife.com/2012/12/27/raspberry-pi-as-arduino-hdmi-shield/
#     original et credit par Joonas Pihlajamaa (www.joonaspihlajamaa.com) - Public Domain Code
# Article Francais: http://mchobby.be/wiki/index.php?title=Rasp-Hack-HDMI-Serveur
#     Traduction CC-BY-SA par D.Meurisse (www.MCHobby.be)   

import serial
import string
import pygame

ser = serial.Serial("/dev/ttyAMA0",9600)
# EN: On more recent version of Python (eg >= 2.7) the constructor did already opens serial port.
#     In such case, executing open() will returns the error "Port is already open."
#     Workaround: put the open() commande under comment
# FR: Sur une version plus recente de python, (ex >= 2.7) le construteur ouvre deja le port serie.
#     Si tel est le cas, l'execution de open() retournera l'erreur "Port is already open."
#     Solution: mettre la ligne suivante en commentaire.
ser.open()
print( "Open serial port: OK" )

pygame.init()
print( "PyGame init: OK" )

window = pygame.display.set_mode((500, 500))
colour = pygame.Color("blue")
pygame.mouse.set_visible(False)
print( "PyGame configure: OK" )
print( "Now waiting for serial command..." )

quit = False

while not quit:
        line = ser.readline()
        words = line.split()

        if words[0] == "rect":
                pygame.draw.rect(window, colour, (int(words[1]), 
                                 int(words[2]), int(words[3]), int(words[4])))
        elif words[0] == "exit":
                quit = True
                
        pygame.display.flip()

ser.close()

Notez que les commandes "rect" et "quit" sont les seuls mots clés reconnus et que le reste est simplement ignoré.

Le "#" utilisé comme marqueur de commentaire (voir tout début de cette section) ne causera donc aucun problème.

Pygame et python-serial

Si vous disposez d'un système d'exploitation Raspbian-Wheezy, vous ne devriez pas le paquet pygame.

Par contre, il faudra installé PySerial. Sur base de notre environnement Python, nous avons exécuté la commande

sudo pip install pyserial

Si vous ne disposez pas de Raspbian-Wheezy, vous devrez installer les paquets python-serial et pygame pour exécuter le script serveur.

Utilisez la commande suivante (mentionnée sur CodeAndLife) pour installer les paquets nécessaires:

sudo apt-get install pygame python-serial

Disponibilité de ttyAMA0

  1. Ouvrir le fichier /etc/inittab à l'aide de
    sudo nano /etc/inittab
  2. Localiser la ligne contenant ttyAMA0
  3. Mettre la ligne en commantaire à l'aide d'un #

Rendre ar2pi exécutable

Par défaut, les fichiers sont considérés comme des fichiers texte non exécutable... même s'il contiennent des scripts.

Il faut donc indiquer au système d'exploitation qu'il peut autoriser l'exécution de notre raspi-blink.py

chmod +x ar2pi.py

Exécuter le serveur

sudo ./ar2pi.py

Vous pouvez arrêter le programme en utilisant la commande "quit" depuis votre Arduino ou en utilisant la combinaison de touche CTRL + C.

Programme côté Arduino

Du côté Arduino, vous n'avez besoin que d'un simple programme (sketch). Il ouvre la connexion série vers le Pi et envoi les différentes commandes d'affichage.

Programme Arduino

int pos = 0, width = 1;

void setup() {
  Serial.begin(9600); // Initialiser la connexion série

  // Envoyer la commande d'intialisation du ViewPort au serveur d'affichage du Pi.
  // Cette commande n'est pas encore implémentée sur le serveur python... elle est donc ignorée
  Serial.print("init 500 500\r\n");
}

// Fonction d'aide pour enviyer la commande "draw x y w h\r\n" au Pi
void draw_rect(int x, int y, int w, int h) {
  Serial.print("rect ");
  Serial.print(x);
  Serial.print(' ');
  Serial.print(y);
  Serial.print(' ');
  Serial.print(w);
  Serial.print(' ');
  Serial.print(h);
  Serial.print("\r\n");
}

void loop() {
  int n;
  
  if(pos + width > 500)
    return; // Sortir une fois que la commande "exit" est envoyée.
    
  delay(500); // Dessiner un nouveau rectangle toutes les 500 ms
  draw_rect(pos, pos, width, width); // Carré placé à la position (pos, pos)

  pos += width; // incrémenter les position x et y 
  width++; // Agrandir la largeur (et hauteur) du rectangle
  
  if(pos + width > 500) // Le viewport est maintenant rempli
    Serial.print("exit\r\n");
}

Upload du programme

Serveur HDMI en action

Vous pourrez voir, ci-dessous, les petits bouts de code en action. Vous pourrez me voir presser le bouton enter qui démarre le script Python correspondant au Serveur, et une fois l'affichage initialisé par PyGame (lorsque l'écran devient blanc), je presse le bouton Reset de mon arduino pour redémarrer le sketch qui dessine les rectangles.

Une fois que l'écran est plus ou moins remplit, Arduino envoi la commande “exit” au Pi. Quand le serveur Python reçoit la commande "exit", il retourne en mode terminal:

{{#Widget:Iframe |url=http://www.youtube.com/embed/f7NCWwJgqhk |width=560 |height=315 |border=0 }}

Dans l'état actuel du projet, vous aurez besoin de démarrer le script Python (Serveur) à chaque fois.

Une version plus avancée du projet se comporterait comme un véritable “serveur d'affichage” qui fonctionne continuellement et initialiserait le ViewPort à la taille désirée avec une commande "init".

Les commande devrait également retourner un code statut... et vous pourriez même démarrer le serveur automatiquement au démarrage du Pi de façon à ne plus devoir le démarrer manuellement.

Conclusions

Cet article met en avant un "Serveur HDMI" relativement simple pour Raspberry Pi qui met en oeuvre PySerial pour recevoir des commande par l'intermédiaire de l'interface série du Raspberry Pi. PyGame est utilise pour l'affichage des primitives graphiques correspondant aux commandes envoyées.

En complément, un client Arduino est écrit pour envoyer ces commande vers le Pi, affichant une chaine de rectangles bleu sur l'écran du Pi.

De futures développements ajouterait des commandes incluant de nouvelles primitives comme circle, line, pixel, bitmap pour afficher respectivement des cercles, ligne, point, image, ainsi que des commande pour changer la couleur de rendu et d'autres paramètres.

Une canal de communication du Pi vers Arduino pourrait aussi être ajouté pour, par exemple, retourner l'état/contenu de l'affichage (via une commande "getpixel x y") ou permettre à Arduino de répondre à des évènements physique (événement souris ou pression d'un bouton).

Les commandes pourraient également aller au delà du traitement d'affichage - le Serveur Python pourrait récupérer et extraire des données provenant d'une requête sur Internet (URL)... ou jouer des sont, et tout ce qu'il est possible de réaliser à l'aide d'un Raspberry Pi (ce qui est presque sans limite).

Le Frameword actuel utilise des commandes de type texte, ce qui implique des délais de traitements... même a 115 200 bauds. Une version améliorée du framework utiliserait un protocole binaire. Le code nécessaire côté Arduino pourrait être encapsulé dans une librarie simple d'emploi, cachant ainsi les inutiles détails du framework au développeur.

Vous êtes tous libre de continuer les développement sur les bases de ce code – Tous le code original de Joonas Pihlajamaa ci-dessus fait partie du domaine public (Public Domain).

Où Acheter

Vous trouverez les différents éléments de ce montage chez MCHobby.

Voici les directs vers les différents articles:


Source: Article "Raspberry Pi as Arduino HDMI Shield" de Joonas Pihlajamaa paru sur CodeAndLife

Traduit avec l'autorisation de Joonas Pihlajamaa, Translated with autorization Joonas Pihlajamaa.

Toute référence, mention ou extrait de cette traduction doit être explicitement accompagné du texte suivant : «  Traduction par MCHobby (www.MCHobby.be) - Vente de kit et composants » avec un lien vers la source (donc cette page) et ce quelque soit le média utilisé.

L'utilisation commercial de la traduction (texte) et/ou réalisation, même partielle, pourrait être soumis à redevance. Dans tous les cas de figures, vous devez également obtenir l'accord du(des) détenteur initial des droits. Celui de MC Hobby s'arrêtant au travail de traduction proprement dit.