Un système audio pour la maison [Part 3]

Apres avoir vu (rapidement) les avantages des squeezebox, installé le serveur et les client, je vous propose donc d’ajouter deux petites choses à notre installation :

Un DAC

pour avoir un son de meilleur qualité. En raccordant le tout à une chaîne Hifi on obtiendra un son tout a fait correct (bon … je ne suis pas un audiophile, mais il me suffit tout à fait 😉 ). Le DAC va remplacer la carte son interne du Pi, qui n’est pas exceptionnelle.

A la suite de conseils précieux j’ai commandé un mini GAMAX pour 37$ sur dhgate (made in china c’est  sûr 😉 ) , cette petite bête est de la taille du Pi et propose :

  •  une entrée USB (qu’on reliera au Pi)
  • une sortie Jack
  • une sortie coax
  • une double sortie RCA (L/R)
  • une sortie numérique
  • une entrée micro

J’alimente ce petit boitier avec une vielle alimentation 12V qui correspond pil poil à ce que veut le DAC (9-24V avec le + au milieu).

Coté reconnaissance par le Pi il n’y eu aucun soucis. J’ai branché et squeezelite permet de vérifier sa présence :

squeezelite-armv6 -l

cela donne :


Output devices:
null - Discard all samples (playback) or generate zero samples (capture)
default:CARD=Set - C-Media USB Headphone Set, USB Audio - Default Audio Device
sysdefault:CARD=Set - C-Media USB Headphone Set, USB Audio - Default Audio Device
front:CARD=Set,DEV=0 - C-Media USB Headphone Set, USB Audio - Front speakers
surround40:CARD=Set,DEV=0 - C-Media USB Headphone Set, USB Audio - 4.0 Surround output to Front and Rear speakers
surround41:CARD=Set,DEV=0 - C-Media USB Headphone Set, USB Audio - 4.1 Surround output to Front, Rear and Subwoofer speakers
surround50:CARD=Set,DEV=0 - C-Media USB Headphone Set, USB Audio - 5.0 Surround output to Front, Center and Rear speakers
surround51:CARD=Set,DEV=0 - C-Media USB Headphone Set, USB Audio - 5.1 Surround output to Front, Center, Rear and Subwoofer speakers
surround71:CARD=Set,DEV=0 - C-Media USB Headphone Set, USB Audio - 7.1 Surround output to Front, Center, Side, Rear and Woofer speakers
iec958:CARD=Set,DEV=0 - C-Media USB Headphone Set, USB Audio - IEC958 (S/PDIF) Digital Audio Output
default:CARD=ALSA - bcm2835 ALSA, bcm2835 ALSA - Default Audio Device
sysdefault:CARD=ALSA - bcm2835 ALSA, bcm2835 ALSA - Default Audio Device

A vous de choisir votre sortie préférée suivant votre DAC . Je me suis cantonné à « sysdefault:CARD=Set » que j’ai mis dans le script de démarrage que je vous avait donné précédemment (/etc/initi.d/squeezelite-arm6  : variable SLOPTIONS)

Une télécommande

Pour cela j’utiliserai lirc, le port GPIO du Raspberry Pi et un TSOP 4838 (d’autres marcheront peut être, mais je n’en sais rien 😉 )

Le matériel

Le montage à utiliser est détaillé chez Adafruit, vous n’êtes pas du tout obligé d’utiliser cette télécommande. Personnellement j’ai recyclé celle d’un vieux lecteur CD mort depuis longtemps.

Si vous suivez le montage d’adafruit il suffit de connecter GND, 3,3V et le data du TSOP (recepteur IR 38kHz) aux ports adéquats du Pi (le Data utilisé est le n°18) .

Le Système

sudo modprobe lirc_rpi

chargera le module nécessaire pour lirc.
Edit : Ce module est à rajouter au fichier /etc/modules pour qu’il soit chargé automatiquement au démarrage du Raspberry Pi

vérifiez avec un

mode2 -d /dev/lirc0

que votre Pi reçoit bien les infos venant de la télécommande (appuyez et viser 😉 )

L’apprentissage de la télécommande

Sans doute la plus grosse partie du boulot qui reste à faire.

sudo irrecord -d /dev/lirc0 /etc/lirc/lircd.conf

La première phase va permettre de reconnaitre le protocole employé par la télécommande, il ne s’agit pas spécialement d’appuyer sur toutes les touches. Les informations à l’écran sont à lire (il faut toujours lire ce qui est affiché à l’écran 😉 )

La seconde phase est plus « laborieuse », il va falloir associer les touches une par une. Le programme demande un « mnémonique » tel que KEY_PLAY, KEY_STOP, … (la liste complète est trouvable grâce à

irrecord –list-namespace

).

Une fois l’apprentissage de toutes les touches effectuées il va falloir « câbler » ça avec squeelite

Donnons des ordre à squeezelite

Pour cela je vais utiliser le fichier de configuration de irexec : /etc/lirc/lircrc


begin
prog = irexec
button = KEY_PLAY
config = /usr/local/ir2squeeze/pause
end

begin
prog = irexec
button = KEY_NEXT
config = /usr/local/ir2squeeze/next
end

begin
prog = irexec
button = KEY_PREVIOUS
config = /usr/local/ir2squeeze/previous
end

begin
prog = irexec
button = KEY_POWER
config = /usr/local/ir2squeeze/power
end

J’associe donc à chaque touche un script shell qui va être appelé, de ce fait ma télécommande peut faire plus ou moins n’importe quoi !!!!

I except you know Expect

Pour piloter squeezelite je ne vais pas faire dans la dentelle (pour le moment), un script par touche. Et pour me faire comprendre je vais directement utiliser le protocole réseau avec une commande telnet. Pour ça il y a un utilitaire magnifique que j’ai découvert il y a peu : Expect

d’abord on va l’installer

apt-get install expect

Exemple du script /usr/local/ir2squeeze/pause :

#!/usr/bin/expect

spawn telnet 192.168.X.X 9090
expect "Escape character is *"
send "AA:BB:CC:DD:EE:FF pause\n"
expect "* pause"
send "exit\n"
expect eof

où 192.168.X.X est l’adresse IP du serveur squeezebox et AA:BB:CC:DD:EE:FF l’adresse MAC de la machine cliente. Cette adresse MAC peut être trouvée dans l’écran information du serveur ou par un ifconfig -a sur le client, ça tombe bien c’est celui sur lequel vous travaillez actuellement.

Edit : Afin que lirc démarre en même temps que votre système il faut le rajouter dans le mécanisme d’init.d.

ln -s /etc/init.d/lirc /etc/rc2.d/S15lirc

Le démarrage de lirc peut se faire à l’aide de la commande classique :

sudo service lirc

Je ne suis pas rentré dans tout les détails techniques  mais cela devrait vous donner quelques pistes pour (peut-être) faire fonctionner votre Pi en tant que squeezebox 😉

Publicités

Un système audio pour la maison [Part 2]

Dans le précédent article je vous ai décris (à la limite de la pub) ce que pouvait faire une squeezebox « du commerce »

Maintenant je vais vous parler de se faire sa propre squeezebox radio à base de Raspberry Pi.

Si on considère qu’on a déjà un Raspberry Pi d’installé l’opération est très simpe. Un tutoriel complet est décrit dans cet article, mais personnellement j’ai sabré bon nombre d’étapes (Wifi,..)

Dans les faits j’ai eu quelques problemes avec la distrib que j’avais installé à la base (la débian de base du Pi ? je ne sais plus), le son était mauvais. Des « clicks » se faisaient entendre. Vu que je n’avais pas grande idée sur le sujet j’ai utilisé la Raspifi que j’avais installé précédemment et appliqué la procédure ci dessus. Cette fois les « clicks » n’étaient pas présents.

A l’heure actuelle je fonctionne avec la Raspify, mais sans utiliser son interface. Il n’y a pas de conflit entre squeezelite et mpd donc je garde pour le moment 😉

Les étapes importantes à garder sont les suivante :

sudo apt-get update
sudo apt-get install libfaad2 libmad0

cd /usr/bin/
sudo wget http://squeezelite.googlecode.com/files/squeezelite-armv6
sudo chmod u+x squeezelite-armv6

A partir de ce moment là il est possible de lancer squeezelite-armv6 et de profiter du son (pour peu qu’on ai un serveur installé comme décrit dans la partie 1 … faut suivre 🙂 )

Pour lancer automatiquement le client j’utilise le script suivant, installé dans /etc/init.d/squeezelite-armv6 (j’ai pris comme base celui fourni avec le tuto cité précédemment ).

#! /bin/sh
### BEGIN INIT INFO
# Provides: squeezelite
# Required-Start:
# Required-Stop:
# Should-Start:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Squeezeslitee
# Description: Light weight streaming audio player for Logitech's Squeezebox audio server
### END INIT INFO</code>

# Author: Me
#
# Install Instructions
#
# Copy file to /etc/init.d/squeezeslite
# chmod 755 /etc/init.d/squeezeslite
# update-rc.d squeezeslitee defaults
#
# Create /etc/default/squeezeslite to override any default
# variables defined here. No not edit this file.
#
# Uninstall Instructions
#
# update-rc.d squeezeslite remove
#

# Do NOT "set -e"

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="Squeezebox client"
NAME=squeezelite-armv6
DAEMON=/usr/bin/$NAME
SCRIPTNAME=/etc/init.d/$NAME
SLOPTIONS="-a 120 -o default:CARD=ALSA"
SLLOG=/var/log/squeezeslite.log
# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] &amp;&amp; . /etc/default/$NAME

DAEMON_ARGS="${SLOPTIONS}"

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (&gt;= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions

#
# Function that starts the daemon/service
#
do_start()
{
    if [ -f ${SLLOG} ]; then
    rm ${SLLOG}
    fi
    start-stop-daemon --start --quiet --background --exec $DAEMON -- $DAEMON_ARGS || return 2
}

#
# Function that stops the daemon/service
#
do_stop()
{
    killall $DAEMON
    RETVAL="$?"
    [ "$RETVAL" = 2 ] &amp;&amp; return 2
}

# MAIN #
case "$1" in
start)
    [ "$VERBOSE" != no ] &amp;&amp; log_daemon_msg "Starting $DESC" "$NAME"
    do_start
    case "$?" in
        0|1) [ "$VERBOSE" != no ] &amp;&amp; log_end_msg 0 ;;
        2) [ "$VERBOSE" != no ] &amp;&amp; log_end_msg 1 ;;
    esac
    ;;
stop)
    [ "$VERBOSE" != no ] &amp;&amp; log_daemon_msg "Stopping $DESC" "$NAME"
    do_stop
    case "$?" in
        0|1) [ "$VERBOSE" != no ] &amp;&amp; log_end_msg 0 ;;
        2) [ "$VERBOSE" != no ] &amp;&amp; log_end_msg 1 ;;
    esac
    ;;
    status)
        status_of_proc "$DAEMON" "$NAME" &amp;&amp; exit 0 || exit $?
    ;;
    restart)
        log_daemon_msg "Restarting $DESC" "$NAME"
        do_stop
        case "$?" in
            0|1)
                do_start
                case "$?" in
                    0) log_end_msg 0 ;;
                    1) log_end_msg 1 ;; # Old process is still running
                    *) log_end_msg 1 ;; # Failed to start
                esac
                ;;
            *)
                # Failed to stop
                log_end_msg 1
                ;;
            esac
        ;;
        *)
            echo "Usage: $0 {start|stop|status|restart|force-reload}" &gt;&amp;2
            exit 3
        ;;
esac

N’oubliez pas de le rendre exécutable avant de faire un service squeezelite-armv6 start
Un update-rc.d squeezelite-armv6 defaults plus loin vous pouvez rebooter, il redémarrera tout seul 😉

C’est un peu brut de décoffrage , mais ça fonctionne … à suivre pour quelques raffinements

Un système audio pour la maison [Part 1]

Suite à un article trouvé chez Korben j’ai découvert la distribution Raspifi qui a pour but de lire ses mp3 à l’aide d’un rasperry pi.

La distrib s’installe sans trop de problème et j’ai pu lire les mp3 qui sont sur mon NAS.

N’ayant pas été convaincu par l’interface web de l’engin j’ai été aiguillé vers la solution de Logitech.

Bon disons le tout de suite, c’est une solution  propriétaire, donc qui pourrait disparaître à tout moment. Mais j’ai rarement vu une interface propriétaire qui autorise autant de possibilité, on est plutôt dans l’ère de la Pomme avec un simple bouton Play (pour les autres c’est en option 😉 ).

Cette solution réside sur une solution client/serveur et impose donc de laisser tourner un PC tout le temps. Vu que c’est déjà le cas pour moi ça ne me dérange pas ;). Il permet de lire des mp3, mais aussi des web radios (ce qui rejoint un de mes précédents articles).

Le serveur

De son petit nom « Logitech Media Server », il se télécharge sur le site du fabriquant de souris, et s’installe sous Linux (DEB ou RPM), Mac, Windows et quelques NAS. Une fois installé il faut s’enregistrer sur le site de logitech, cela permettrait théoriquement de contrôler les squezebox depuis internet. Dans les faits je n’ai jamais réussi à partir de ce site, mais ce n’est pas grave 😉 . Ensuite on lui faire indexer ses mp3, c’est assez classique. Il y a possibilité d’ajouter des plugins, des interrogations vers last.fm ou d’autre, … les possibilité sont assez étendues.

En l’état le système ne fonctionne pas, on a pas la possibilité de lire de mp3, pour cela il faut un (ou plusieurs clients)

Le client (payant)

Logitech ne faisant pas ça gratuitement compte quand même vendre du matos,en l’occurrence il s’agit des Squeezebox Radio. A priori la gamme était plus vaste il y a quelques années mais la marque a recentré sa stratégie 😦

J’ai donc acheté une Squeezebox Radio pour la cuisine. La petite bête est sympathique avec son Wifi et du son mono de bonne qualité. Disponible aux alentours de 130€ ça peut refroidir, mais je ne regrette pas du tout mon achat.

L’ergonomie de la petite bête est très agréable et dispose d’un excellent WAF ce qui fait qu’elle a été adoptée par madame de façon surprenante.

Le client (gratuit)

Là où la chose est beaucoup plus intéressante, c’est qu’il est possible d’installer squeezelite sur son ordinateur (ou sur un raspberry pi, mais j’y viendrais plus tard). à partir de ce moment là il est possible de streamer de la musique sur l’ordinateur depuis le serveur.

Et il peut y avoir plusieurs clients en même temps. Par exemple un serveur familiale avec la musique et des raspberry dans les autres pièces  raccordés aux enceintes.

D’ailleurs cette multitude de client a un fonctionnalité que je n’avais jamais vu avant c’est la « synchonisation » des clients. Par un menu il est possible d’indiquer que deux clients vont diffuser les mêmes programmes, idéal quand on se déplace dans la maison, une sorte de radio d’intérieure en somme.

Les interfaces

Afin de piloter la lecture il y a aussi foultitude de possibilité, on peu se connecter sur le site web de logitech (même si ça ne marche pas chez moi), on peu se connecter au serveur (et choisir sur quel client la lecture se passera). Il existe aussi des interfaces pour Android (même topo), la squeezebox radio est aussi autonome de ce coté là (mais peut aussi être pilotée par le réseau. Enfin il est aussi possible de piloter via le protocole réseau qui est disponible sur le Net (j’en reparlerais plus tard).

Et ceci n’est que le commencement … à suivre

Chasser les pertes de mémoire en C sous Linux

Pour un fois je vais pouvoir parler de ce que je fais pour le boulot. En effet, j’ai planché sur un sujet qui peut servir à autrui.
Un des programmes écrit par un de mes prédécesseur avait une fâcheuse tendance à prendre de plus en plus de mémoire jusqu’à bloquer la machine (tssss un process lancé en root).

Chasser les fuites mémoire est toujours un peu hasardeux, il suffit de peu pour que ça devienne mission impossible.

J’ai travaillé principalement avec deux « outils » : valgrind et /proc

L’approche valgrind

valgrind est un utilitaire dédié à l’inspection de la mémoire d’un programme. Il note toutes les zones allouées et vérifie si elles sont correctement désallouées a la fin de celui-ci.

Il existe de très bons tuto sur le net pour son utilisation, par exemple celui-ci : http://fr.openclassrooms.com/informatique/cours/debuguer-facilement-avec-valgrind

L’approche /proc/*/status

Bon ce n’est pas vraiment une méthode très académique, mais elle permet de se rendre compte précisément de la consommation mémoire en temps réel de son programme.

Le noyau Linux met a disposition de l’utilisateur un grand nombre d’information sur les processus en cours d’exécution.

Beaucoup de ses informations sont disponibles dans le point de montage /proc.

En ce qui nous concerne, chaque processus, connu par son pid met a disposition les informations sur sa conso mémoire dans le fichier /proc/<pid du processus>/status.

 $ cat /proc/523/status
 Name: firefox
 State: S (sleeping)
 Tgid: 523
 Pid: 523
 PPid: 1
 TracerPid: 0
 Uid: 1000 1000 1000 1000
 Gid: 1000 1000 1000 1000
 FDSize: 128
 Groups: 4 20 24 25 29 30 33 44 46 103 104 114 115 126 146 147 148 1000 1004 1010
 VmPeak: 1259364 kB
 VmSize: 1164072 kB
 VmLck: 0 kB
 VmPin: 0 kB
 VmHWM: 412984 kB
 VmRSS: 365880 kB
 VmData: 622216 kB
 VmStk: 200 kB
 VmExe: 92 kB
 VmLib: 116232 kB
 VmPTE: 1784 kB
 VmSwap: 0 kB
 Threads: 34
 SigQ: 0/95953
 SigPnd: 0000000000000000
 ShdPnd: 0000000000000000
 SigBlk: 0000000000000000
 SigIgn: 0000000000001000
 SigCgt: 0000000f800144af
 CapInh: 0000000000000000
 CapPrm: 0000000000000000
 CapEff: 0000000000000000
 CapBnd: ffffffffffffffff
 Cpus_allowed: f
 Cpus_allowed_list: 0-3
 Mems_allowed: 00000000,00000001
 Mems_allowed_list: 0
 voluntary_ctxt_switches: 3852953
 nonvoluntary_ctxt_switches: 874330
 

La zone qui m’intéresse dans le cas d’une zone mémoire c’est la ligne VmRSS (qui vaut ici 365880 kB).
Celle-ci reflete la quantité de mémoire alloué actuellement par le processus. Attention à la valeur des autres zones, certaines comme VmSize comptabilisent aussi les librairies partagées et les fichiers ouverts (même s’il ne sont pas chargés en mémoire !), il ne s’agit donc pas forcement de mémoire utilisée !

Grace à la lecture de ce pseudo fichier il est possible de vérifier en cours d’utilisation la mémoire consommée et de tracer son évolution à partir du programme.

En somme Valgrind permet de chasser la mémoire utilisée et /proc de vérifier qu’il n’y a pas de cas tordus qui pourraient passer à travers.

Pour automatiser la chose

un petit script

pid=`ps -fe | grep [nom du process] |grep -v grep | awk '{print $2}'` && cat /proc/$pid//status |grep Vm

une petite fonction

Vu qu’on me l’a demandé j’ai aussi une petite fonction (très fortement inspirée de celle-ci ) pour afficher dans la log l’état de la mémoire (en même temps que les éléments clef du programme)

int memStats()
{
  char * line;
  char *vmsize;
  char *vmdata;
  char *vmrss;
  char *vmstk;

  size_t len;

  FILE *f;
 
  vmsize = NULL;
  vmdata = NULL;
  vmrss = NULL;
  vmstk = NULL;
  len = 128;
  line = malloc ( len * sizeof( char ) ) ;

  char * path2status = malloc( 128 * sizeof( char ) );
  sprintf (path2status, "/proc/%d/status", getpid() );

  f = fopen(path2status, "r");
  if (!f)
  {
    free ( path2status );
    free ( line );
    return 1;
  }
  free ( path2status );
  /* Read memory size data from /proc/pid/status */
  while (!vmsize || !vmrss || !vmdata || !vmstk )
  {
    if ( fgets ( line, len, f ) == NULL )
    {
      /* Some of the information isn't there, die */
      free(line);
      fclose( f ) ;
      return 1;
    }

    /* Find VmSize */
    else if (!strncmp(line, "VmSize:", 7))
    {
      vmsize = strdup(&line[7]);
    }

    /* Find VmRSS */
    else if (!strncmp(line, "VmRSS:", 6))
    {
      vmrss = strdup(&line[7]);
    }

    /* Find VmData */
    else if (!strncmp(line, "VmData:", 7))
    {
      vmdata = strdup(&line[7]);
    }
    /* Find VmStk */
    else if (!strncmp(line, "VmStk:", 6))
    {
      vmstk = strdup(&line[7]);
    }

  }
  free(line);

  fclose(f);

  /* Get rid of " kB\n"*/
  len = strlen(vmsize);
  vmsize[len - 4] = 0;
  len = strlen(vmstk);
  vmstk[len - 4] = 0;
  len = strlen(vmrss);
  vmrss[len - 4] = 0;
  len = strlen(vmdata);
  vmdata[len - 4] = 0;

  /* Output results to stderr */
  fprintf( stderr, "<%s;%s;%s;%s>\n", vmrss, vmsize, vmstk, vmdata);

  free(vmstk);
  free(vmsize);
  free(vmrss);
  free(vmdata);
  return 0;
}

Bonne chasse …

Utilisation des Attiny

J’ai creusé du coté des Attiny pour avoir les même fonctionnalité que l’Arduino mais en moins cher.

J’ai retenu pour le moment l’Attiny 45 et le 85. Ces deux microcontroleurs ne disposent que de 8 pattes ce qui en fait un excellent moyen de diminuer la taille de ses montages. J’ai réussi à trouver sur ebay des Attiny 85 avec leurs sockets à moins de 2€ pièce (frais de port compris), par rapport à un arduino c’est déjà ça de gagné ! A noter qu’ils existent en plusieurs type de « casing », j’ai opté pour les ATTINY85-20PU.

Par contre ces petites machines sont limitées, j’ai bloqué sur l’Attiny 45 et sa limite de 4Ko de flash. En tentant de compiler un exemple simple utilisant RC-switch ( librairie de communication RF en 433 MHz) je n’ai pas réussi à descendre en dessous des 4Ko.

De plus les Attiny de la série X5 n’ont que 5 broches utilisables. Si votre projet en utilise plus vous pouvez regarder du coté des Attiny 44 et 84 ont plus de broches (mais pas plus de mémoire) ou directement des Atmgea328.

Bref, pour utiliser l’Attiny il suffit de suivre le tutoriel suivant :http://www.semageek.com/tuto-programmation-des-attiny45-avec-un-arduino/

Ce tutoriel est simple à suivre, un petit montage à faire, un programme à charger sur l’Arduino, quelques paramétrage de l’IDE de l’Arduino, le bootloader à charger sur l’Attiny et c’est parti.

EDIT du 3 juin : Et voici une version « propre » que j’ai réalisée à partir d’un Protoshield achetée sur Ebay. Le plus long a été de dessouder les connecteurs du dessus 😉

Programmateur Attiny

Programmateur Attiny

Faire de son Raspberry Pi une Web Radio

Pour faire une web Radio j’ai utilisé les capacités du lecteur « mpd » (je ne détaille pas l’explication de l’installation de mpd, « apt-get install mpd mpc »).

Pour commencer j’ai ajouté une web radio :
mpc add http://streaming.radio.rtl2.fr:80/rtl2-1-44-128

Ensuite j’ai réalisé un petit montage pour ajouter un écran LCD et quelques boutons.

Maestro

Câblage d’un écran LCD et de 4 boutons sur un Raspberry Pi

J’ai trouvé un bout de code Python permettant de gérer un écran LCD de type « HD44780 » (disponible sur ebay pour quelques euros) sur zem.fr . J’ai juste mis le code dans un module Python indépendant (LCD.py).

Les codes sources sont disponible dans mon nouveau repository dédié au Raspberry Pi (vu que je développe directement dessus, j’ai préféré le séparer du repository Arduino). Le Programme s’appelle Maestro et utilise pour le moment quatre boutons, l’un pour faire Pause/Play le second pour Next (changement de station) et les deux derniers pour la gestion du volume.

Il est tout à fait possible d’ajouter ou d’enlever des boutons dans le code, chaque bouton est un objet qui est défini par le port GPIO à utiliser pour le câblage et une fonction de callback.
Dans l’init du GUI, je défini un bouton. Ce bouton restera en attente de ce qui se passe sur un port GPIO. Il a son propre Thread pour la surveillance. A voir si augmenter le nombre de bouton dégrade les performances.

self.bouton4 = Button( 22, self.Button4Pressed )
self.bouton4.start()

Et la fonction de callback qui va augmenter le volume

 def Button4Pressed(self):
  os.system("mpc volume +10")

Le code est volontairement simpliste et ne fait appel qu’a mpc pour le contrôle. Je pars du principe qu’on ne va pas « spammer » les boutons et que le raspberry sera peu ou prou dédié à cette tache.

Je ne sais pas encore si j’utiliserais ce « mini projet », mais s’il s’avère que c’est le cas j’ai dans l’idée d’ajouter un bouton qui ferait passer du mode radio à un mode playlist. Cela permettrait de « meubler » quand la radio diffuse une pub ou une chanson qui ne me plait pas.

Edit : Dans les faits j’utilise effectivement un raspberry Pi pour lire de la musique au salon mais en utilisant un autre système que je décris ici

Mettre de la couleur dans vos shell en perl

En balayant mes archives je tombe sur une librairie que j’avais écrite il y a quelques années.

Elle permet de changer « simplement » les attributs d’un texte écrit par un script shell Unix (ou Linux).
La librairie propose 4 fonctions :

  • color_fg_set_str , modifie la couleur d’écriture du texte
  • color_bg_set_str , modifié la couleur de fond d’écran du texte
  • curs_pos_str , déplace le curseur
  • decoration_set_str , bascule en gras, souligné, clignotant, …

use constant ESC_FMT		=> "\033[%sm";
use constant ESC_FMT1	=> "\033[%dm";
use constant ESC_FMT2	=> "\033[%d;%dm";
use constant ESC_FMT3	=> "\033[%d;%d;%dm";
#use constant CLR_SCR		=> "\f";
use constant CLR_SCR		=> "\033[2J";
use constant CLR_EOL		=> "\033[K";
use constant POS_CUR		=> "\033[%d;%dH";
use constant CUR_SAV		=> "\033[s";
use constant CUR_RES		=> "\033[u";
use constant FLUSH		=> CUR_SAV . "\n" . CUR_RES;
use constant ESC_FMTC1	=> "\033[%d%s";
use constant ESC_FMTC2	=> "\033[%d;%d%s";
use constant ESC_DEFAULT	=> "\033[0m\033[37;40m";

#	DECORATIONS
use constant OFF	  	=>  0;
use constant BOLD		  =>  1;
use constant UNDER	  =>  4;
use constant BLINK	  =>  5;
use constant REVERSE	=>  7;
use constant CONCEAL  =>  8;

#	COULEURS
use constant BLACK		=>  30;
use constant RED			=>  31;
use constant GREEN		=>  32;
use constant YELLOW		=>  33;
use constant BLUE			=>  34;
use constant MAGENTA	=>  35;
use constant CYAN			=>  36;
use constant WHITE		=>  37;

sub color_fg_set_str
{
	my $color = shift;	#couleur désiré
	$color = $default_fg_color if (! $color);
	if ($color >= BLACK && $color <= WHITE)	# couleur connue
	{
		return sprintf ESC_FMT1, $color;				# changement de couleur
	}
	return "";
}

sub curs_pos_str
{
	my ($lig, $col)= ( @_ );

	if ( $lig > 0 and $col > 0 )
	{ return sprintf(POS_CUR, $lig, $col); }
	else
	{	return ""; }
}

sub color_bg_set_str
{
	my $color = shift;	#couleur désiré
	$color = $default_bg_color if (! $color);
	if ( ( $color>=BLACK && $color<=WHITE ) )	# couleur connue
	{
		return sprintf ESC_FMT1, ($color + 10);			# changement de couleur
	}
	return "";
}

sub decoration_set_str
{
	my $decoration = shift;	#decoration désiré
	$decoration = $default_decoration if (! $decoration );
	if ( ( $decoration>=OFF && $decoration<=CONCEAL ) )	# decoration connue
	{
		return sprintf ESC_FMT1, ($decoration);			# changement de decoration
	}
	return "";
}


En espérant que cela serve à quelqu’un un jour

PS : Une mine d’info https://wiki.archlinux.org/index.php/Color_Bash_Prompt

Brochages Arduino et Raspberry Pi

Un petit article bookmark pour citer deux liens particulièrement utiles.

[*] Les brochages de l’arduino, des Atmega328 mais aussi des attiny, à garder à portée de main

http://www.semageek.com/pratique-des-diagrammes-de-pinout-pour-arduino-et-atmega/

[*] Un petit PDF à découper et à enficher sur le port GPIO de votre Raspberry Pi, un must have pour ceux qui n’ont pas de Pi Cobbler

http://www.doctormonk.com/2013/02/raspberry-pi-and-breadboard-raspberry.html

Ajout d’un Ecran LCD sur ma Timelapse-Machine

J’avais détaillé il y a quelques mois comment réaliser un timelapse avec Arduino . J’ai depuis fait évoluer le montage pour utiliser un écran LCD et un bouton pour gérer les temps d’attente entre chaque prise de vue.

Dans la précédente approche j’utilisais un potentiomètre pour régler le temps entre chaque prise de vue. Or cette méthode se révèle à l’usage peu pratique. Le potentio n’est pas très sensible, une pichenette le fait passer de 1 à deux minutes entre chaque prises, et il surtout est facile de faire une fausse manip et le dérégler.
J’ai donc choisi une autre méthode en définissant des plages pré programmée. La liste que j’ai retenu est la suivante (temps en secondes) : 5, 10, 30, 60 (1 min), 120 (2 min), 300 (5 min), 600 (10 min), 1800 (30 min). Cette liste est « en dur » dans le code, mais ce n’est pas bien difficile de la faire évoluer (chez soi, certes, quand on fait des prises de vue à l’extérieur c’est mort 😉 )
Chaque pression sur le bouton modifie le timer de l’arduino vers la valeur suivante dans cette liste.

Pour pouvoir visualiser le temps sélectionné j’ai utilisé un petit LCD trouvé sur ebay à 2-3€ pièce : le HD44780.

Timelapse LCD en boite

Shield sur l’arduino dans son ravissant écrin en carton

Le montage n’est pas bien différent du précédent, j’ai juste câblé l’écran et un bouton

Le bouton est entre le pin 2 et les 5V

Le LCD :

VSS GND
VD 5V
V0 4.7k Ohm => GND
RS pin 12
RW GND
E pin 11
D0 non connecté
D1 non connecté
D2 non connecté
D3 non connecté
D4 pin 7
D5 pin 6
D6 pin 5
D7 pin 4
A 150 Ohm => +5V
K GND

J’ai utilisé une résistance fixe de 150 Ohms pour relier l’Anode (A) au +5V, cela joue sur le contraste de l’écran. Ce choix peut être différent chez vous. Vous pouvez aussi utiliser un potentiomètre pour le rendre réglable.

Le code est disponible sous mon repository Arduino et comme d’habitude vous pouvez le reprendre à votre sauce.

Problème d’accents circonflexes avec Ubuntu 12.04

Je viens de mettre à jour (pour le meilleur et pour le pire surtout) ubuntu en 12.04.

Outre une version de Unity que je peine à paramétrer (ne marchons pas dans le troll …) j’avais un problème avec la saisie d’accents.

En effet jusqu’à présent lorsque je voulais saisir un ‘ê’ j’appuyais sur ‘^’ puis sur ‘e’. Même fonctionnement pour ï ou î.

Or depuis cette (satanée) migration lorsque je presse ‘^’ puis ‘e’ ça affiche  ‘^’ puis ‘e’ 😦

 

Apres pas mal de tests infructueux ( j’ai suivi ce fil là  qui donne beaucoup de bons conseils), j’ai trouvé la solution qui fonctionne (chez moi du moins …).

 

dans un terminal tapez ‘im-switch’, dans la fenetre saisisez ‘Do not use Input Methode. (none)’, redemarrez la session et … ça remarche !

Input Method Switcher

 

 

Ouf …