Quentin PEYRÈGNEhttp://www.peyregne.info/2014-02-08T08:00:00+01:00Ecouter sa musique partout avec Subsonic2014-02-08T08:00:00+01:00Quentintag:www.peyregne.info,2014-02-08:subsonic.html<p>Pour continuer sur l'auto-hébergement, le service suivant concerne le streaming audio. Je possède sur mon serveur toute ma bibliothèque audio. Je cherchais depuis longtemps un service web pouvant s'installer sur un serveur et permettant de diffuser depuis mon serveur toute ma musique.</p>
<p>Après quelques recherches, je suis tombé sur <a class="reference external" href="http://www.subsonic.org">Subsonic</a> qui est un service auto-hébergeable et qui dispose de beaucoup de fonctionnalités :</p>
<ul class="simple">
<li>La lecture en streaming (via un petit lecteur en flash) de fichiers audios.</li>
<li>Le support de formats audio libres comme le <a class="reference external" href="http://www.vorbis.com/">Ogg Vorbis</a>. Dans les faits, le ogg est converti à la volée en mp3 par <tt class="docutils literal">ffmpeg</tt> (ou maintenant <tt class="docutils literal">avconv</tt>) pour la lecture sur le lecteur flash. Pour info, j'utilise l'application <tt class="docutils literal">k3b</tt> pour convertir mes CD audios en ogg.</li>
<li>La possibilité d'ajouter des flux de Podcasts qui seront automatiquement téléchargés dans le dossier configuré.</li>
<li>L'ajout de flux de web-radios.</li>
<li>La gestion de plusieurs utilisateurs et playlists associées.</li>
<li>La gestion des jaquettes, paroles des chansons, lien vers la fiche Wikipédia de l'artiste ou de l'album.</li>
</ul>
<p>Subsonic est un logiciel libre sous license GPL3, mais payant pour débloquer des fonctionnalités avancées. Du fait de sa license GPL3, les forks sont autorisés, et il existe une version entièrement débloquée (sans le système de license) disponible <a class="reference external" href="https://github.com/KHresearch/subsonic">sur ce dépôt GitHub</a>.</p>
<p>L'installation se fait très facilement en suivant <a class="reference external" href="http://www.subsonic.org/pages/installation.jsp">les instructions sur le site officiel</a>. Pour rendre le service disponible depuis l'extérieur, j'ai redirigé un sous domaine vers le port de l'application subsonic en utilisant la fonctionnalité de Proxy par Apache. Voici la configuration (Subsonic est en écoute sur le port 4040) :</p>
<div class="highlight"><pre><span class="nt"><VirtualHost</span> <span class="s">*:80</span><span class="nt">></span>
<span class="nb">ServerName</span> music.monsite.com
<span class="nb">ProxyRequests</span> <span class="k">Off</span>
<span class="nt"><Proxy</span> <span class="s">*</span><span class="nt">></span>
<span class="nb">Order</span> deny,allow
<span class="nb">Allow</span> from <span class="k">all</span>
<span class="nt"></Proxy></span>
<span class="nb">ProxyErrorOverride</span> <span class="k">On</span>
<span class="nb">ProxyPass</span> / http://localhost:4040/
<span class="nb">ProxyPassReverse</span> / http://localhost:4040/
<span class="nt"><Location</span> <span class="s">/</span><span class="nt">></span>
<span class="nb">Order</span> allow,deny
<span class="nb">Allow</span> from <span class="k">all</span>
<span class="nt"></Location></span>
<span class="nt"></VirtualHost></span>
</pre></div>
<p>Adieu les lecteurs audio sur les machines locales (et la prise de tête pour trouver un protocole de diffusion multi-plateforme), les services centralisés type Deezer ou Spotify ! Je peux enfin écouter <em>MA</em> musique partout où je le souhaite grâce à cette aplication très complète !</p>
Changer de moteur de recherche2014-01-16T00:00:00+01:00Quentintag:www.peyregne.info,2014-01-16:duckduckgo.html<p>Pour continuer <a class="reference external" href="http://www.peyregne.info/bonnes-resolutions.html">la série sur mes manières de me séparer des services centralisés</a> que j'utilisais auparavant, après avoir changé de navigateur, on continue avec un des services qu'on utilise le plus : le moteur de recherche. Le moteur de recherche est un service très important.</p>
<p>Pourquoi vouloir me séparer de Google pour mes recherches ?</p>
<ul class="simple">
<li>Google est un service hyper-centralisé, à tel point que pour de nombreuses personnes Google <em>est</em> Internet.</li>
<li>Google récolte sans complexe toutes nos données de navigation pour les vendre à des annonceurs qui affichent des pubs ultra-ciblées entre autres.</li>
<li>Google trie les résultats de recherche et effectue une sélection des résultats qu'il présente (selon nos précédentes recherches, cookies, notre profil, <a class="reference external" href="http://www.clubic.com/internet/google/actualite-435320-google-rejouit-resultats-filtre-anti-piratage.html">les volontés des gouvernements ou ayants-droit</a>, etc.). Google n'est donc pas du tout un moteur de recherche neutre.</li>
</ul>
<p>Différentes alternatives existent, l'une d'elle qui est de plus en plus connue s'appelle <a class="reference external" href="https://duckduckgo.com/">DuckDuckGo</a>. C'est un moteur de recherche qui se veut neutre, et respectueux de la vie privée. Tout ceci est expliqué (par DuckDuckGo) sur ce site : <a class="reference external" href="http://donttrack.us/">http://donttrack.us/</a>.</p>
<p>Pour avoir essayé ce moteur il y a 2 ou 3 ans, je n'avais pas trouvé les résultats pertinents du tout. Aujourd'hui après plusieurs semaines d'utilisation j'ai réussi à retrouver le confort de la recherche et la pertinence des résultats que je pouvais avoir sur Google. Voici les différentes adaptations que j'ai faites :</p>
<ul class="simple">
<li>Installation du <a class="reference external" href="https://addons.mozilla.org/en-US/firefox/addon/duckduckgo-for-firefox/">plug-in DuckDuckGo</a> pour Firefox</li>
<li>Personnalisation des préférences de DuckDuckGo (sur la page de recherche, aller dans les Paramètres et choisir la Région et la langue préférée pour les résultats).</li>
<li>Utilisation <strong>massive</strong> des <em>!bang</em>. <a class="reference external" href="https://duckduckgo.com/bang.html">Cette liste de mots clefs</a> permet d'effectuer des recherches directement sur d'autres moteurs de recherche, par exemple <tt class="docutils literal">printf !cpp</tt> ira directement chercher le mot <tt class="docutils literal">printf</tt> sur le site <em>cplusplus.com</em>. Le gain de temps est très vite appréciable ! De plus, ce point est très intéressant car le fait de pouvoir lancer des recherches directement sur d'autres site que le moteur de recherche en lui-même va dans le sens de la <strong>décentralisation</strong> que je recherche.</li>
</ul>
<p>A vous d'essayer !</p>
Installer Mozilla Sync sur son serveur2014-01-12T18:06:00+01:00Quentintag:www.peyregne.info,2014-01-12:mozilla-sync.html<p>Premier article d'une série consacrée à l'auto-hébergement. J'ai indiqué dans <a class="reference external" href="http://www.peyregne.info/bonnes-resolutions.html">mon article précédent</a> que je souhaitais petit à petit reprendre le contrôle de mes données, et cela passe notamment par trouver des alternatives libres et "auto-hébergeables" des services qui stockent mes données personnelles sur leurs serveurs.</p>
<p>Je dispose d'un petit serveur basse consommation allumé en permanence chez moi, et qui me sert principalement de NAS sur le réseau local, et héberge quelques services et sites en externe.</p>
<p>J'ai décidé de commencer par changer de navigateur. Auparavant j'étais sur <em>Google Chrome</em>, puis <em>Chromium</em>, avec pour principale raison la synchronisation automatique des données (onglets, favoris et plugins) sur toutes les machines que j'utilise. De fait, <em>Google</em> possède des informations sur tous mes centres d'intérêt, ce qui est pour lui des données intéressantes à revendre, par exemple à des régies publicitaires pour mieux me cibler.</p>
<p><em>Firefox</em> possède également une solution de synchronisation des données (qui n'existait pas au moment ou j'ai changé de navigateur), appelée <em>Mozilla Sync</em>. Par défaut, la fonction vous propose d'héberger vos données à synchroniser sur le serveur Sync de Mozilla, ce qui ne résout pas le problème initial.</p>
<p>Mais là oà ça devient intéressant, c'est que la partie serveur de <em>Sync</em> est libre, et qu'on peut l'installer sur son propre serveur ! Ainsi, mes données restent bien au chaud chez moi (les données sont cryptées lors de la synchronisation, rien ne circule en clair).</p>
<p>Pour l'installation, je vous laisse aller voir directement les <a class="reference external" href="https://docs.services.mozilla.com/howtos/run-sync.html">instructions d'installation sur le wiki de Mozilla</a>.</p>
<p>Le seul problème que j'ai eu à l'installation, qui est très bête, mais ça ne m'a pas sauté aux yeux directement. Dans le cas où la connexion au service ne fonctionne pas, et que le log indique :</p>
<pre class="literal-block">
IOError: [Errno 13] Permission denied: '/tmp/sync-error.log'
</pre>
<p>Il faut supprimer le fichier <tt class="docutils literal"><span class="pre">/tmp/sync-error.log</span></tt> qui n'a pas eu les bons droits lors de sa première création.</p>
<p>Au passage, voici la configuration Apache, si ça peut en aider certains (les sources sont installées dans <tt class="docutils literal"><span class="pre">/opt/mozilla/server-full</span></tt>) :</p>
<div class="highlight"><pre><span class="nt"><Directory</span> <span class="s">/opt/mozilla/server-full</span><span class="nt">></span>
<span class="nb">Order</span> allow,deny
<span class="nb">Options</span> -Indexes +ExecCGI
<span class="nb">Allow</span> from <span class="k">all</span>
<span class="nt"></Directory></span>
<span class="nt"><VirtualHost</span> <span class="s">*:80</span><span class="nt">></span>
<span class="nb">ServerName</span> sync.monsite.com
<span class="nb">DocumentRoot</span> <span class="sx">/opt/mozilla/server-full</span>
<span class="nb">WSGIProcessGroup</span> sync
<span class="nb">WSGIDaemonProcess</span> sync <span class="k">user</span>=sync <span class="k">group</span>=sync processes=2 threads=25
<span class="nb">WSGIPassAuthorization</span> <span class="k">On</span>
<span class="nb">WSGIScriptAlias</span> / <span class="sx">/opt/mozilla/server-full/sync.wsgi</span>
<span class="nb">CustomLog</span> <span class="sx">/var/log/apache2/ff-sync-access.log</span> combined
<span class="nb">ErrorLog</span> <span class="sx">/var/log/apache2/ff-sync-error.log</span>
<span class="nt"></VirtualHost></span>
</pre></div>
<p>Comme indiqué sur le wiki de Mozilla, ne pas oublier, une fois que vous avez créé vos comptes d'interdire la création de nouveaux comptes dans la configuration, pour éviter d'éventuels robots spammeurs. Dans le fichier <tt class="docutils literal">etc/sync.conf</tt>, décommenter la ligne :</p>
<pre class="literal-block">
allow_new_users = false
</pre>
<p>Puis redémarrer le serveur Apache comme à chaque modification de ce fichier.</p>
<p>Enfin, afin de garantir que mes données ne sont pas perdues, j'ai terminé l'installation en ajoutant à mon script de backup les données de la base stockant les données du serveur Sync (au pire, les données restent en local sur mes différents ordinateurs).</p>
Mes nouvelles "résolutions"2014-01-08T23:02:00+01:00Quentintag:www.peyregne.info,2014-01-08:bonnes-resolutions.html<p>Cela commence à faire un petit moment que je n'ai rien publié sur mon site, et
ce pour diverses raisons (déménagement, boulot, activités annexes,...). Bref,
toujours est-il qu'après cette petite pause j'ai pas mal de choses à partager.</p>
<p>Pour les fidèles du blog, vous pourrez commencer par remarquer que le site a
changé de tête, car j'ai quitté le traditionnel <em>Wordpress</em> pour essayer un
générateur de site statique <a class="reference external" href="http://docs.getpelican.com">Pelican</a> écrit en
<em>Python</em>. Au final, ça ne change pas grand-chose pour le visiteur du site (à
part qu'il se charge beaucoup, beaucoup plus vite), mais ça change énormément
pour moi pour la rédaction des articles et la facilité de publication et de
maintenance (puisqu'il y en a pratiquement pas!). Finit les mises à jour
Wordpress qui cassent tout à chaque fois ! ;-)</p>
<p>Je pense que je reviendrai à ce sujet dans quelques temps, après avoir pu me
faire un peu plus d'expérience avec cet outil.</p>
<p>Dorénavant également, il n'est plus possible de poster des commentaires sur le
site, et les commentaires qui existaient ont été supprimés. Ceci est lié au
fait que le site est maintenant statique (comprendre uniquement des fichiers
<tt class="docutils literal">.html</tt>). J'aurais pu installer <em>Disqus</em> qui permet de gérer des commentaires
dans ce genre de cas, mais j'ai choisi de ne pas utiliser cet outil <strong>externe</strong>
(dont je ne possède pas les données), mais de revenir au bon vieux mail pour
échanger avec moi (adresse à la fin de cet article).</p>
<p>Enfin, j'essaye de plus en plus de mettre en place des services en
auto-hébergement chez moi pour tenter de remplacer tous les services
centralisés que j'utilise (<em>Google</em>, <em>Dropbox</em>, <em>Deezer</em>, et encore bien
d'autres). L'idée a pas mal germée depuis la fermeture de Google Reader, et
depuis que j'ai vu la fameuse
<a class="reference external" href="http://www.fdn.fr/Internet-Libre-ou-Minitel-2,94.html">conférence Internet ou Minitel 2.0</a>
de <em>Benjamin BAYART</em>, et que je vous conseille de voir.</p>
<p>Une autre série d'articles à venir viendra donc expliquer en détails quelles
solutions j'ai mis en œuvre pour remplacer ces services.</p>
Radio Internet sur Raspberry Pi, partie 3 : commande à distance2013-01-20T17:26:00+01:00Quentintag:www.peyregne.info,2013-01-20:radio-internet-sur-raspberry-pi-partie-3-commande-a-distance.html<p>Nous avons précédemment vu comment installer un serveur audio sur le <em>Raspberry Pi</em>, et comment y ajouter des flux de radio internet.</p>
<p>Dans cet article, nous allons voir comment effectuer des commandes,
sans passer par une connexion ssh, mais en utilisant une application
smartphone connecté sur le réseau local.</p>
<p>Dans un premier temps, il faut configurer <em>mpd</em> sur le Raspi pour
autoriser des commandes à distance. Dans le fichier <tt class="docutils literal">/etc/mpd.conf</tt>,
modifier la variable <tt class="docutils literal">bind_to_address</tt> et la modifier (le paramètre
par défaut étant "localhost") :</p>
<div class="highlight"><pre>bind_to_address <span class="s2">"any"</span>
</pre></div>
<p>Puis redémarrer mpd :</p>
<div class="highlight"><pre>sudo /etc/init.d/mpd restart
</pre></div>
<p>On peut donc maintenant commander <em>mpd</em> à distance.</p>
<p>Ensuite il faut rechercher une application sur votre smartphone, en
tapant "mpd" comme mot clef. Il existe de nombreuses applications
permettant de contrôler <em>mpd</em> à distance. Attention, ces applications ne
vont pas rediriger le flux audio vers votre téléphone. Ce ne sont que
des télécommandes.</p>
<p>Sur iPhone, j'ai choisi <a class="reference external" href="https://itunes.apple.com/fr/app/mpod/id285063020?mt=8">MPoD</a>. J'ai regardé pour Android, il existe
tout un tas d'<a class="reference external" href="https://play.google.com/store/search?q=mpd">applications similaires</a>.</p>
<p>Voyons maintenant comment configurer <strong>MPoD</strong> pour Iphone. Je pense que
c'est similaire avec une autre application.</p>
<p>Une fois l'application lancée, il faut aller dans le menu "Players"
pour configurer le serveur <em>mpd</em> :</p>
<img alt="{filename}../images/Add_Player_button.png" src="http://www.peyregne.info/images/Add_Player_button.png" />
<p>Ensuite, ajouter un nouveau lecteur :</p>
<p><img alt="image:: {filename}../images/Add_Player.png" src="http://www.peyregne.info/images/Add_Player.png" /></p>
<p>Configurer le nom du lecteur, ainsi que l'adresse IP. Le reste des
paramètres est à laisser par défaut, à moins que vous n'ayez changé des
paramètres par défaut sur le serveur <em>mpd</em> :</p>
<p><img alt="{filename}../images/Add_Player_2.png" src="http://www.peyregne.info/images/Add_Player_2.png" /></p>
<p>Enfin, si tout est normal, le serveur est ajouté, et l'icône réseau
est allumée à côté du nom (sinon, elle sera grisée) :
<img alt="{filename}../images/Add_Player_3.png" src="http://www.peyregne.info/images/Add_Player_3.png" /></p>
<p>Enfin, quittez le menu en appuyant sur "Done", et vous devriez voir la
liste de lecture avec les différentes stations de radio ajoutées :</p>
<p><img alt="{filename}../images/MPoD_main.png" src="http://www.peyregne.info/images/MPoD_main.png" /></p>
<p>A partir de là, il est possible de changer de station, changer le
volume, éditer la playlist, etc. En revanche, la plupart des stations de
radio en streaming ne renseignent pas les champs "Titre" et "Artiste",
et par conséquent la liste de lecture n'est pas très <em>user friendly</em>...</p>
<p>A ce stade, vous disposez donc d'un Raspberry Pi configuré pour sortir
des flux de stations radio internet. Vous pouvez tout à fait en rester
là, mettre le Raspi derrière votre chaîne ou enceintes, et profiter de
toutes les radios disponibles sur internet !</p>
<p><a class="reference external" href="http://www.peyregne.info/images/Raspi_Power_ethernet_audio.jpg"><img alt="{filename}../images/Raspi_Power_ethernet_audio.jpg" src="http://www.peyregne.info/images/Raspi_Power_ethernet_audio-300x198.jpg" /></a></p>
<p>Dans la suite, je souhaite intégrer le Raspi dans un boîtier maison
avec enceintes, pour disposer d'une radio internet autonome, avec des
boutons et un écran pour changer les stations, le volume et visualiser
le nom des stations.</p>
<p>Bien évidemment, <em>mpd</em> est aussi capable d'aller chercher des
fichiers audio autres que des flux radio sur votre réseau, et on peut
donc tout à fait transformer le Raspi en Media Center audio ! ;-)</p>
Radio Internet sur Raspberry Pi, partie 2 : playlist de radios2013-01-02T09:57:00+01:00Quentintag:www.peyregne.info,2013-01-02:radio-internet-sur-raspberry-pi-partie-2-playlist-de-radios.html<p>Dans la première partie, nous avons vu comment installer <em>mpd</em> et <em>mpc</em> sur
le <em>Raspberry Pi</em>. Nous avons donc maintenant un Raspi capable de lire
des flux de radios internet. Dans cette deuxième partie, nous allons
voir comment créer une playlist contenant les flux vers vos radios
favorites. Premièrement, il faut récupérer les adresses des flux des
radios que vous souhaitez écouter. Pour cela, Google est votre ami, ou
bien ces sites qui recensent les radios principales françaises :</p>
<ul class="simple">
<li><a class="reference external" href="http://doc.ubuntu-fr.org/radio">http://doc.ubuntu-fr.org/radio</a></li>
<li><a class="reference external" href="http://flux.radio.free.fr/">http://flux.radio.free.fr/</a></li>
</ul>
<p>Sur les sites précédents, vous trouverez deux types de liens : soit des
lien en <strong>.mp3</strong>, d'autres en <strong>.m3u</strong> (format de playlist). Le second
type (.m3u) ne sera pas accepté par mpd comme flux unitaire. Il faudra
donc ouvrir les fichiers .m3u avec un éditeur de texte pour récupérer le
lien vers le flux mp3. Une fois votre liste d'adresse constituée,
connectez-vous sur le Raspi, puis vider la liste de lecture actuelle :</p>
<div class="highlight"><pre><span class="nv">$ </span>mpc clear
</pre></div>
<p>Enfin, ajoutez un à un les différentes adresses recueillies avec <em>mpc
add</em> :</p>
<div class="highlight"><pre><span class="nv">$ </span>mpc add http://mp3.live.tv-radio.com/franceinfo/all/franceinfo.mp3
<span class="nv">$ </span>mpc add http://radio.podradio.fr:8000/adsl
<span class="nv">$ </span><span class="c"># etc.</span>
</pre></div>
<p>Une fois tous les flux ajoutés, on peut enregistrer la liste de lecture
:</p>
<div class="highlight"><pre><span class="nv">$ </span>mpc save mes_radios
</pre></div>
<p>MPD va alors enregistrer la liste dans le dossier
<em>/var/lib/mpd/playlists/</em> (paramétrable dans <em>/etc/mpd.conf</em>). Enfin,
voici les commandes utiles pour afficher la playlist actuelle, écouter
une station, etc. :</p>
<div class="highlight"><pre><span class="nv">$ </span>mpc playlist
France Inter - 128 - mp3
podradio.fr: Bepod - Wii oui wii
...
<span class="nv">$ </span>mpc play 2 <span class="c"># pour lire le deuxième flux "podradio"</span>
<span class="nv">$ </span>mpc prev <span class="c"># pour lire le flux précédent dans la liste</span>
<span class="nv">$ </span>mpc next <span class="c"># pour lire le flux suivant</span>
<span class="nv">$ </span>man mpc <span class="c"># pour la liste de toutes les commandes possibles ;-)</span>
</pre></div>
<p>Voilà pour aujourd'hui. Nous verrons dans la suite comment accéder à
<em>mpd</em> autrement que via <em>mpc</em> sur une connexion ssh, ce qui n'est pas
forcément très sexy ;-).</p>
Radio Internet sur Raspberry Pi, partie 1 : MPD/MPC2012-12-17T21:35:00+01:00Quentintag:www.peyregne.info,2012-12-17:radio-internet-sur-raspberry-pi-partie-1-mpdmpc.html<p>Première partie sur la construction d'une radio Internet basée sur un
<a class="reference external" href="http://www.raspberrypi.org">Raspberry Pi</a>.</p>
<p>Je considère que vous possédez une Raspberry Pi, avec la distribution
<a class="reference external" href="http://www.raspbian.org/">Raspbian</a> installée et configurée, avec une connexion à distance
activée via ssh.</p>
<p>Dans cette première partie, nous allons installer MDP (<a class="reference external" href="http://fr.wikipedia.org/wiki/Music_Player_Daemon">Music Player
Daemon</a>) qui va
servir de lecteur de musique embarqué, ainsi que MPC (Music Player
Command) qui servira à piloter MPD (telle une télécommande) :</p>
<img alt="{filename}../images/MPD.png" src="http://www.peyregne.info/images/MPD.png" />
<div class="section" id="pre-requis">
<h2>Pré-requis</h2>
<p>Vérifier que le driver audio est correctement installé :</p>
<div class="highlight"><pre><span class="nv">$ </span>lsmod
</pre></div>
<p>Il doit apparaître le driver snd_bcm2835 dans le résultat. Si ce n'est
pas le cas, essayer :</p>
<div class="highlight"><pre><span class="nv">$ </span>sudo modprobe snd_bcm2835
</pre></div>
</div>
<div class="section" id="installation">
<h2>Installation</h2>
<p>L'installation est facile (après mise à jour des dépôts) :</p>
<div class="highlight"><pre><span class="nv">$ </span>sudo aptitude update
<span class="nv">$ </span>sudo aptitude install mpd mpc
</pre></div>
</div>
<div class="section" id="configuration">
<h2>Configuration</h2>
<p>Le fichier de configuration de mdp est /etc/mdp.conf. On pourra y
paramétrer les dossiers où MPD ira chercher la musique et les playlist
par exemple. Une fois les réglages effectués, redémarrer le service :</p>
<div class="highlight"><pre><span class="nv">$ </span>sudo /etc/init.d/mpd restart
</pre></div>
</div>
<div class="section" id="test">
<h2>Test</h2>
<p>Brancher un casque ou une paire d'enceintes sur la sortie audio du
Raspi. Nous allons maintenant ajouter un flux audio provenant d'une
radio internet, et lancer la lecture de ce flux :</p>
<div class="highlight"><pre><span class="nv">$ </span>mpc add http://mp3.live.tv-radio.com/franceinfo/all/franceinfo.mp3
<span class="nv">$ </span>mpc play
</pre></div>
<p>Tadaaam ! Normalement vous devriez entendre la radio.</p>
<p>Nous verrons dans le prochain article comment créer une liste de radio,
changer de station, régler le volume, etc. Si vous êtes pressés, il y a
toujours le manuel de mpc à lire ;-)</p>
</div>
Nouveau projet : une radio Internet basée sur un Raspberry Pi2012-12-16T21:05:00+01:00Quentintag:www.peyregne.info,2012-12-16:nouveau-projet-une-radio-internet-basee-sur-un-raspberry-pi.html<p>Comme tout bidouilleur qui se respecte, j'ai fait
l'acquisition d'un <a class="reference external" href="http://www.raspberrypi.org/">Raspberry Pi</a>. Au départ sans vraiment avoir d'idée
fixe de projet en tête (ni de temps pour le faire...), mais récemment
une idée m'est venue : réaliser une radio internet.</p>
<p>Le Raspberry Pi possède tout ce qu'il faut pour réaliser une radio
Internet :</p>
<ul class="simple">
<li>Une sortie audio via une prise Jack 3.5mm</li>
<li>Une prise Ethernet pour se connecter à Internet</li>
<li>Des ports USB pour une clef contenant de la musique, ou bien un dongle Wifi</li>
<li>Des entrées / sorties GPIO pour y connecter directement des boutons, LEDs ou autres</li>
<li>Un port série et I²C pour y mettre un écran LCD (pour visualiser le titre en cours, etc.)</li>
<li>La carte est petite, donc facilement intégrable, consomme peu et ne chauffe pas</li>
<li>Le Linux embarqué permettra tout type d'évolution, contrairement à une radio internet du commerce fermée.</li>
</ul>
<p>Je compte associer le Raspi à une paire d'enceintes de bureau
récupérées, et intégrer le tout dans un boîtier maison, pour au final
avoir une solution low-cost.</p>
<p>Je vais essayer de rédiger plusieurs articles pour détailler la démarche
pas à pas de réalisation de cette radio.</p>
<p>A bientôt ! ;-)</p>
Installer CrashPlan sur un serveur Debian2012-09-02T15:23:00+02:00Quentintag:www.peyregne.info,2012-09-02:installer-crashplan-sur-un-serveur-debian.html<p>Pour sauvegarder mes données, je dispose d'un petit serveur personnel
avec un gros volume en RAID5 sur lequel je sauvegarde toutes mes autres
machines, et où je stocke mes fichiers, principalement des photos. Je
suis alors théoriquement protégé contre une panne matérielle.</p>
<p>N'étant jamais trop prudent, j'ai décidé de mettre en place une solution
de sauvegarde distante, c'est à dire pas chez moi, dans le cas où la
sauvegarde sur le serveur venait à être perdue (cambriolage,
incendie,...).</p>
<img alt="{filename}../images/crashplan.png" src="http://www.peyregne.info/images/crashplan.png" />
<p>Après avoir fait rapidement le tour des solutions existantes sur le
marché, mon choix s'est arrêté sur <a class="reference external" href="http://www.crashplan.com/">CrashPlan</a> pour plusieurs raisons :</p>
<ul class="simple">
<li>Il existe un client pour Linux</li>
<li>Le tarif est plus que raisonnable (50$ par an, avec un volume de sauvegarde "illimité")</li>
<li>Les transferts et les fichiers sauvegardé sont encryptés</li>
</ul>
<p>Dans la suite de l'article je vais détailler l'installation et
l'administration de CrashPlan sur un serveur Debian.</p>
<p>CrashPlan est divisé en deux parties. Une application back-end qui
tournera en permanance sur le serveur, et une application front-end
graphique pour paramétrer le tout. Malheureusement on est obligé
d'utiliser cette application graphique pour paramétrer la sauvegarde.
N'ayant pas d'écran ni de serveur X sur le serveur, il faudra dans un
second temps paramétrer l'application graphique sur une autre machine
avec un écran pour qu'elle communique avec le serveur.</p>
<p>Sur le serveur et sur la machine qui servira à paramétrer, télécharger
CrashPlan. Pour cela, récupérer l'URL sur le site de téléchargement
: <a class="reference external" href="http://www.crashplan.com/consumer/download.html?os=Linux">http://www.crashplan.com/consumer/download.html?os=Linux</a></p>
<div class="highlight"><pre><span class="nv">$ </span>wget http://download.crashplan.com/installs/linux/install/CrashPlan/CrashPlan_3.2.1_Linux.tgz
</pre></div>
<p>Extraire l'archive puis lancer le script d'installation :</p>
<div class="highlight"><pre><span class="nv">$ </span>tar xzf CrashPlan_3.2.1_Linux.tgz
<span class="nv">$ </span>./install.sh
</pre></div>
<p>Suivre alors les indications. Notamment CrashPlan peut installer sa
propre machine virtuelle Java en parallèle de l'existante.</p>
<p>Nous allons maintenant, sur le serveur, modifier la locale. En effet,
CrashPlan gère très mal la locale POSIX, si bien qu'il ne sauvegardera
pas les dossiers contenant des accents (!).</p>
<p>Il faut donc installer puis configurer la locale fr_FR.utf8 (dans mon
cas) :</p>
<div class="highlight"><pre><span class="nv">$ </span>sudo aptitude install locales
<span class="nv">$ </span>sudo dpkg-reconfigure locales
</pre></div>
<p>Enfin, rajouter les deux lignes suivantes au fichier /etc/profile :</p>
<div class="highlight"><pre><span class="nb">export </span><span class="nv">LANG</span><span class="o">=</span>fr_FR.utf8
<span class="nb">export </span><span class="nv">LC_ALL</span><span class="o">=</span>fr_FR.utf8
</pre></div>
<p>Et recharger :</p>
<div class="highlight"><pre><span class="nv">$ </span><span class="nb">source</span> /etc/profile
</pre></div>
<p>Maintenant nous pouvons relancer le daemon Crashplan (je ne suis pas
certain que cette étape soit nécessaire, mais dans le doute ;-) ):</p>
<div class="highlight"><pre><span class="nv">$ </span>sudo /etc/init.d/crashplan restart
</pre></div>
<p>C'est tout pour la partie serveur.</p>
<p>Sur la machine avec écran, trouver puis éditer le fichier de
configuration de l'application graphique <em>CrashPlanDesktop</em> (voir les
messages de log lors de l'installation). Par défaut, le fichier se situe
ici : <tt class="docutils literal">/usr/local/crashplan/con/ui.properties</tt>. Suivre alors les
instructions <a class="reference external" href="http://support.crashplan.com/doku.php/how_to/configure_a_headless_client">disponibles ici</a>.</p>
<p>Vous pouvez maintenant lancer le client graphique pour paramétrer la
sauvegarde (volumes à sauvegarder, limitation de la bande passante,
etc.).</p>
<p>Voilà, vous pouvez maintenant dormir l'esprit tranquille ! :-)</p>
Installer Replicatorg sous Debian2012-02-24T22:40:00+01:00Quentintag:www.peyregne.info,2012-02-24:installer-replicatorg-sous-debian.html<p>Voici un petit article pour expliquer l'installation de
<a class="reference external" href="http://replicat.org">ReplicatorG</a> sous Debian, mais est très facilement adaptable à
tout autre distribution GNU/linux.</p>
<p>ReplicatorG est un logiciel de contrôle sur le PC qui permet de :</p>
<ul class="simple">
<li>Ouvrir et visualiser des fichiers 3D au format .STL</li>
<li>Générer le GCode en utilisant le moteur SkeinForge</li>
<li>Se connecter et envoyer des ordres à la carte de commande de la
RepRap.</li>
</ul>
<p>ReplicatorG est un logiciel assez populaire et beaucoup utilisé dans le
monde de l'imprimante 3D libre car il dispose de beaucoup d'options et
est compatible avec beaucoup de modèles d'imprimante.</p>
<p>Cette article ne couvrira que l'installation du logiciel, je ferais une
présentation détaillée plus tard.</p>
<ul>
<li><p class="first">Aller sur le site <a class="reference external" href="http://replicat.org/download">http://replicat.org/download</a> pour récupérer le
logiciel correspondant à votre OS, en l’occurrence "Linux".</p>
</li>
<li><p class="first">Décompresser l'archive :</p>
<div class="highlight"><pre>tar xvzf replicatorg-0029_r2-linux.tgz
</pre></div>
</li>
<li><p class="first">Installer le JRE Java pour la visualisation 3D (ne fonctionne pas
pour l'instant avec la version libre openjdk) :</p>
<div class="highlight"><pre>sudo aptitude install sun-java6-jre
</pre></div>
<p>Puis sélectionner la version de java à utiliser en choisissant la
ligne contenant <em>sun</em> :</p>
<div class="highlight"><pre>sudo update-alternatives --config java
</pre></div>
</li>
<li><p class="first">Ensuite il faut copier le driver librxtxSerial de votre système en
lieu et place du driver embarqué dans le dossier de Replicatorg (dans
mon cas, mon système est 64 bits) :</p>
<div class="highlight"><pre>cp /usr/lib/jni/librxtxSerial.so replicatorg-0029_r2/lib-x86_64/
</pre></div>
<p>Si vous ne faites pas cette étape, il se peut que vous vous
retrouviez avec ce type de crash :</p>
<pre class="literal-block">
*** buffer overflow detected ***: java terminated
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(__fortify_fail+0x37)[0x7f4fa22001d7]
/lib/x86_64-linux-gnu/libc.so.6(+0xfd0f0)[0x7f4fa21ff0f0]
/lib/x86_64-linux-gnu/libc.so.6(+0xfc569)[0x7f4fa21fe569]
/lib/x86_64-linux-gnu/libc.so.6(_IO_default_xsputn+0xd8)[0x7f4fa2176b98]
/lib/x86_64-linux-gnu/libc.so.6(_IO_vfprintf+0x1abd)[0x7f4fa214931d]
/lib/x86_64-linux-gnu/libc.so.6(__vsprintf_chk+0x94)[0x7f4fa21fe604]
/lib/x86_64-linux-gnu/libc.so.6(__sprintf_chk+0x7a)[0x7f4fa21fe54a]
/home/robert/3dprint/replicatorg-0025/lib-x86_64/librxtxSerial.so(fhs_lock+0x16f)[0x7f4f873e0a9f]
/home/robert/3dprint/replicatorg-0025/lib-x86_64/librxtxSerial.so(Java_gnu_io_RXTXCommDriver_testRead+0x65)[0x7f4f873e0b25]
</pre>
</li>
<li><p class="first">S'assurer qu'on appartient au groupe "dialout" avec la commande id.
Sinon, taper en root (en remplaçant nomUtilisateur par le votre) :</p>
<div class="highlight"><pre>usermod -a -G dialout nomUtilisateur
</pre></div>
</li>
<li><p class="first">Lancer le logiciel :</p>
<div class="highlight"><pre><span class="nb">cd </span>replicatorg-0029_r2
./replicatorg &
</pre></div>
<p>(au premier démarrage, les fichiers de préférences vont être créés)</p>
</li>
</ul>
<p><a class="reference external" href="http://www.peyregne.info/images/replicatorg.png"><img alt="{filename}../images/replicatorg.png" src="http://www.peyregne.info/images/replicatorg.png" /></a></p>
<p><em>Et voilà !</em></p>
<p>J'espère avec ce court article avoir pu vous aider à résoudre certains
problèmes d'installation, comme j'en ai eu ! ;-)</p>
Sprinter : un firmware pour la RAMPS 1.22012-02-06T22:06:00+01:00Quentintag:www.peyregne.info,2012-02-06:sprinter-un-firmware-pour-la-ramps-1-2.html<p>Après le préambule sur l'explication du rôle du firmware, et comme
promis, voici un exemple concret du paramétrage du Firmware Sprinter
pour la RAMPS 1.2.</p>
<p>Personnellement, j'ai passé beaucoup de temps à me renseigner, essayer,
configurer tout un tas de versions existantes : <em>Teacup</em>, <em>Tonokips</em>,
<em>Sprinter</em>,... Il y a beaucoup d'exemples, voire trop, et on est vite
perdu dans la jungle des exemples trouvés, et qui semblent ne pas
fonctionner sur sa machine.</p>
<p>Il faut alors s'armer de patience et de persévérance, car il faut faire
l'effort de comprendre à quoi servent les paramètres à régler, et
comment adapter un fimware pour qu'il fonctionne avec sa configuration.</p>
<p>Personellement, j'ai arrêté mon choix sur le Firmware <em>Sprinter</em>,
développé principalement par Kliment et caru, et qui est un fork du
Firmware Tonokips. Il est sous license GNU GPL v3, ce qui veut dire
qu'on a le droit de mettre les mains dedans, et de faire partager nos
modifications, ce que je vais m'empresser de faire !</p>
<p>Remplissez votre tasse de café ou votre verre de bière, cet article va
être long ! ;-)Tout ce qui va suivre est adapté en fonction de ma carte
de commande (la RAMPS v1.2) et de mon modèle de RepRap (Prusa), mais en
fouillant un peu, il peut se généraliser à d'autres cartes. Voici
précisément la liste des composants dont je dispose, et qu'il faut
paramétrer dans le firmware :</p>
<ul class="simple">
<li>Modèle Prusa</li>
<li>Moteurs pas à pas 200 pas / tour NEMA 17</li>
<li>Extruder modèle Wade avec moteur pas à pas 200 pas / tour</li>
<li>Thermistance d'extruder 100kOhm</li>
<li>Thermistance du lit chauffant 100kOhm</li>
<li>Electronique RAMPS version 1.2 avec driver POLOLU</li>
</ul>
<div class="section" id="telechargement-du-firmware">
<h2>Téléchargement du Firmware</h2>
<div class="section" id="pre-requis">
<h3>Pré-requis</h3>
<p>La carte RAMPS est basé sur la plateforme Arduino, il faut donc
récupérer l'IDE Arduino pour compiler et flasher facilement la carte.</p>
</div>
<div class="section" id="telecharger-le-code-source-avec-git">
<h3>Télécharger le code source avec git</h3>
<p>La méthode la plus simple est de récupérer le code sur le dépot GitHub
de Sprinter. Pour cela, il faut ouvrir un terminal, aller dans le
dossier où son ranger les sketchs Arduino, puis taper :</p>
<div class="highlight"><pre><span class="nv">$ </span>git clone https://github.com/kliment/Sprinter.git
</pre></div>
<p>Git va alors télécharger automatiquement le code source du Firmware. A
l'avenir, il sera simple de mettre à jour votre code en local avec les
modifications du dépot officiel en utilisant git, mais ce n'est plus le
propos de cette article.</p>
</div>
<div class="section" id="telecharger-le-code-source-pour-les-allergiques-a-la-ligne-de-commande">
<h3>Télécharger le code source, pour les allergiques à la ligne de commande</h3>
<p>Allez sur le dépot GitHub : <a class="reference external" href="https://github.com/kliment/Sprinter">https://github.com/kliment/Sprinter</a>, puis
cliquez sur l'icône "ZIP" pour télécharger un zip contenant le code
source, puis décompressez le dossier dans votre dossier contenant vous
sketchs Arduino.</p>
</div>
</div>
<div class="section" id="parametrage-du-firmware">
<h2>Paramétrage du firmware</h2>
<p>Ouvrez le Sketch Sprinter avec l'IDE Arduino, ce qui va ouvrir un tas
d'onglets avec tous les fichiers sources. N'ayez pas peur, nous n'aurons
besoin de modifier qu'un seul fichier : <em>Configuration.h</em>.</p>
<p>C'est dans ce fichier que nous réglerons tous les coefficients, gains,
vitesses, accélérations et caractéristiques des composants de la carte
électronique et de la machine. Ouvrez le fichier Configuration.h, et
voyons ce qu'il y a à paramétrer :</p>
<div class="section" id="le-type-de-carte-electronique">
<h3>Le type de carte électronique</h3>
<p>Chaque type de carte possède des entrées/sorties différentes et
spécifiques, qui sont renseignées dans le fichier pins.h. Reportez-vous
au commentaire du fichier pour trouver celui qui correspond à votre
carte. Pour la RAMPS 1.2, il s'agit du numéro 3.</p>
<div class="highlight"><pre><span class="c1">// MEGA/RAMPS up to 1.2 = 3,</span>
<span class="c1">// RAMPS 1.3 = 33</span>
<span class="c1">// Gen6 = 5,</span>
<span class="c1">// Sanguinololu up to 1.1 = 6</span>
<span class="c1">// Sanguinololu 1.2 and above = 62</span>
<span class="c1">// Teensylu (at90usb) = 8</span>
<span class="c1">// Gen 3 Plus = 21</span>
<span class="c1">// gen 3 Monolithic Electronics = 22</span>
<span class="c1">// Gen3 PLUS for TechZone Gen3 Remix Motherboard = 23</span>
<span class="cp">#define MOTHERBOARD 3</span>
</pre></div>
</div>
<div class="section" id="le-type-des-thermistances">
<h3>Le type des thermistances</h3>
<p>Ensuite, il faut renseigner le type de thermistance utilisée pour
l'extruder et le lit chauffant. La thermistance permet de mesurer la
température. En effet, sa caractéristique est d'avoir une résistance
variable en fonction de la température.</p>
<p>Pour les curieux, les tables de conversion sont visibles dans le
fichier <em>thermistortables.h</em>. Pour ma part, j'ai deux fois la même
résistance de 100k.</p>
<div class="highlight"><pre><span class="c1">// 1 is 100k thermistor</span>
<span class="c1">// 2 is 200k thermistor</span>
<span class="c1">// 3 is mendel-parts thermistor</span>
<span class="c1">// 4 is 10k thermistor</span>
<span class="c1">// 5 is ParCan supplied 104GT-2 100K</span>
<span class="c1">// 6 is EPCOS 100k</span>
<span class="c1">// 7 is 100k Honeywell thermistor 135-104LAG-J01</span>
<span class="cp">#define THERMISTORHEATER 1</span>
<span class="cp">#define THERMISTORBED 1</span>
</pre></div>
</div>
<div class="section" id="calibration-des-axes">
<h3>Calibration des axes</h3>
<p>La calibration des axes permet de relier le nombre de pas moteur au
déplacement de l'axe. Ayant le modèle Prusa, j'ai gardé les valeurs par
défaut fournies dans l'exemple. Pour faire le calcul, il faut connaître
:</p>
<ul class="simple">
<li>Le nombre de pas par tour du moteur <strong>Npas</strong> ( = 200 pour le NEMA 17)</li>
<li>La résolution de controle du moteur <strong>Res</strong> (en fonction du
paramétrage du driver de moteur pas à pas) (=1/16 pour les axes X,Y
et E, et 1/4 pour l'axe Z)</li>
<li>Le nombre de dents de la poulie, <strong>Ndents</strong> (=8 pour les axes X et Y)</li>
<li>La résolution de la courroie <strong>Rc</strong>, qui correspond au nombre de mm
par dent (=5mm pour une courroie standard T5 de reprap).</li>
</ul>
<p>Le paramètre de calibration vaut : step_per_unit = Npas / (Res *
Ndent * Rc) = 200 / (1/16* 8*5) = 80 pas par mm pour l'axe X par
exemple.</p>
<p>Le type de calcul est équivalent pour les axes Y et Z (et les valeurs
par défaut conviennent).</p>
<p>Là où ça se corse, c'est sur le calcul du paramètre pour l'extrudeur
"E". Il faut savoir combien il faut de pas moteur pour faire avancer le
fil en entrée de 1 mm. Attention cependant, en fonction de la version du
moteur de génération de trajectoire, <em>Skeinforge</em> (j'ai prévu de faire
un article là dessus, parce que si je commence à en parler maintenant,
je ne finirai jamais cet article), sur les anciennes versions ( <= 39)
il fallait indiquer combien de pas moteur il fallait pour avoir en
sortie de l'extruder un certain volume de matière.</p>
<p>Le plus simple est de se baser sur une version >= 40 de <em>Skeinforge</em>, et
de régler le premier type de paramètre, qui est pus facile à calculer.</p>
<p>En fonction de votre extruder, du moteur, du ratio de l'engrenage, le
ratio "step_per_unit" de l'extruder varie beaucoup d'un repraper à
l'autre. En ce qui me concerne, j'arrive à ce ratio :</p>
<div class="highlight"><pre><span class="c1">//// Calibration variables</span>
<span class="c1">// X, Y, Z, E steps per unit - Metric Prusa Mendel with Wade extruder:</span>
<span class="kt">float</span> <span class="n">axis_steps_per_unit</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">80</span><span class="p">,</span> <span class="mi">80</span><span class="p">,</span> <span class="mi">3200</span><span class="o">/</span><span class="mf">1.25</span><span class="p">,</span><span class="mi">700</span><span class="p">};</span>
</pre></div>
</div>
<div class="section" id="parametrage-des-fins-de-course">
<h3>Paramétrage des fins de course</h3>
<p>En fonction du type de fin de course, il faut indiquer si le capteur
retourne un signal haut ou bas. Si vous avez des fins de course avec une
fourche optique, laisser les valeurs par défaut à FALSE, sinon avec des
fins de course mécaniques (et en fonction du câblage), il faut inverser
le signal, et donc indiquer TRUE. Si malgré ce réglage les axes ne
bougent que sur la course de la butée, c'est qu'il faut inverser les
constantes.</p>
<div class="highlight"><pre><span class="c1">//// Endstop Settings</span>
<span class="cp">#define ENDSTOPPULLUPS </span><span class="c1">// Comment this out (using // at the start of the line) to disable the endstop pullup resistors</span>
<span class="c1">// The pullups are needed if you directly connect a mechanical endswitch between the signal and ground pins.</span>
<span class="c1">//If your axes are only moving in one direction, make sure the endstops are connected properly.</span>
<span class="c1">//If your axes move in one direction ONLY when the endstops are triggered, set [XYZ]_ENDSTOP_INVERT to true here:</span>
<span class="k">const</span> <span class="kt">bool</span> <span class="n">X_ENDSTOP_INVERT</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="k">const</span> <span class="kt">bool</span> <span class="n">Y_ENDSTOP_INVERT</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="k">const</span> <span class="kt">bool</span> <span class="n">Z_ENDSTOP_INVERT</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
</pre></div>
</div>
<div class="section" id="vitesse-de-communication">
<h3>Vitesse de communication</h3>
<p>Il faut paramétrer la vitesse de communication en bauds, et la retenir
pour l'indiquer plus tard au logiciel sur le PC pour qu'il puisse
communiquer correctement avec la carte. Je vous conseille de laisser la
valeur par défaut.</p>
<div class="highlight"><pre><span class="c1">// This determines the communication speed of the printer</span>
<span class="cp">#define BAUDRATE 115200</span>
</pre></div>
</div>
<div class="section" id="utilisation-d-une-carte-sd">
<h3>Utilisation d'une carte SD</h3>
<p>Si vous avez un lecteur de carte SD sur votre électronique, et que vous
souhaiter booter dessus au démarrage de l'imprimante, les lignes
suivantes sont faites pour ça. Sinon, laissez-les commentées.</p>
<div class="highlight"><pre><span class="c1">// Comment out (using // at the start of the line) to disable SD support:</span>
<span class="c1">//#define SDSUPPORT</span>
<span class="c1">// Uncomment to make Sprinter run init.g from SD on boot</span>
<span class="c1">//#define SDINITFILE</span>
</pre></div>
</div>
<div class="section" id="parametrage-des-axes">
<h3>Paramétrage des axes</h3>
<p>Je vais passer quelques lignes dont vous n'aurez a priori pas à toucher
pour une utilisation normale (inversion / désactivation des axes).</p>
</div>
<div class="section" id="id1">
<h3>Paramétrage des fins de course</h3>
<p>En fonction du placement de vos fins de course, il faut spécifier au
firmware si les fins de course correspondent au minimum de l'axe (-1) ou
au maximum (+1). Ainsi, lors de l'initialisation des axes (<em>Homing</em>), le
zéro sera fait en fonction du min ou du max de la course de l'axe.</p>
<div class="highlight"><pre><span class="c1">//// ENDSTOP SETTINGS:</span>
<span class="c1">// Sets direction of endstops when homing; 1=MAX, -1=MIN</span>
<span class="cp">#define X_HOME_DIR -1</span>
<span class="cp">#define Y_HOME_DIR -1</span>
<span class="cp">#define Z_HOME_DIR -1</span>
</pre></div>
<p>On peut également définir et activer des butées logicielles sur les
axes, ce qui permet de les arrêter avant d'arriver en butée physique, et
de forcer voire d'endommager l'axe. Pour celà, il suffit de mesurer la
capacité physique d'évolution de chaque axe à partir de la butée
d'initialisation.</p>
<div class="highlight"><pre><span class="k">const</span> <span class="kt">bool</span> <span class="n">min_software_endstops</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span> <span class="c1">//If true, axis won't move to coordinates less than zero.</span>
<span class="k">const</span> <span class="kt">bool</span> <span class="n">max_software_endstops</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span> <span class="c1">//If true, axis won't move to coordinates greater than the defined lengths below.</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">X_MAX_LENGTH</span> <span class="o">=</span> <span class="mi">200</span><span class="p">;</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">Y_MAX_LENGTH</span> <span class="o">=</span> <span class="mi">200</span><span class="p">;</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">Z_MAX_LENGTH</span> <span class="o">=</span> <span class="mi">100</span><span class="p">;</span>
</pre></div>
</div>
<div class="section" id="parametrage-des-vitesses-et-accelerations">
<h3>Paramétrage des vitesses et accélérations</h3>
<p>Vous pouvez ensuite définir respectivement les vitesses de déplacement
maximales des axes en mm/min (<em>feedrate</em>), les vitesses de déplacement
lors de la phase d'initialisation (rester sur des vitesses lentes pour
initialiser les axes avec précision). Les autres paramètres sont à
laisser aux valeurs par défaut.</p>
<div class="highlight"><pre><span class="c1">//// MOVEMENT SETTINGS</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">NUM_AXIS</span> <span class="o">=</span> <span class="mi">4</span><span class="p">;</span> <span class="c1">// The axis order in all axis related arrays is X, Y, Z, E</span>
<span class="kt">float</span> <span class="n">max_feedrate</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">200000</span><span class="p">,</span> <span class="mi">200000</span><span class="p">,</span> <span class="mi">240</span><span class="p">,</span> <span class="mi">500000</span><span class="p">};</span>
<span class="kt">float</span> <span class="n">homing_feedrate</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">1500</span><span class="p">,</span><span class="mi">1500</span><span class="p">,</span><span class="mi">120</span><span class="p">};</span>
<span class="kt">bool</span> <span class="n">axis_relative_modes</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="nb">false</span><span class="p">,</span> <span class="nb">false</span><span class="p">,</span> <span class="nb">false</span><span class="p">,</span> <span class="nb">false</span><span class="p">};</span>
</pre></div>
<p>Pour la suite, le paramétrage des accélérations est à laisser aux
valeurs par défaut, sauf si vous vous y connaissez suffisamment pour
paufiner les réglages de votre imprimante.</p>
</div>
<div class="section" id="reglage-de-la-commande-de-chauffage">
<h3>Réglage de la commande de chauffage</h3>
<p>Tous les paramètres suivants concernent le réglage de la partie
chauffante, et peuvent être délicats à régler, je vous conseille de
laisser les valeurs pas défaut. Cependant, il peut être intéressant de
limiter la valeur maximale de température, ce qui peut être utile pour
ne pas endommager l'imprimante.</p>
<div class="highlight"><pre><span class="cp">#define MAXTEMP 220</span>
</pre></div>
</div>
</div>
<div class="section" id="compilation-et-telechargement-du-firmware">
<h2>Compilation et téléchargement du firmware</h2>
<p>Maintenant tous ces paramètres renseignés, <a class="reference external" href="http://arduino.cc/fr/Main/DebuterPresentationLogiciel">compilez puis téléchargez le
programme sur la carte de commande</a> (cliquez pour l'aide Arduino). Vous
pouvez maintenant essayer de connecter l'imprimante au logiciel de
commande sur le PC (par exemple Replicatorg), et essayer de faire bouger
les axes un à un ou de commander la température avec l'interface de
controle du logiciel.</p>
<p>Je vous conseille fortement de garder la main sur l'interrupteur
d'alimentation tant que vous n'êtes pas sûrs que les vitesses, fin de
course et autre ne sont pas réglés correctement.</p>
<p>Pour la suite, je vous présenterai le logiciel <a class="reference external" href="http://replicat.org/">Replicatorg</a>, que
j'utilise, ainsi que le logiciel <a class="reference external" href="http://www.skeinforge.com/">Skeinforge</a>. D'ici là, si vous avez
des difficultés, vous pouvez m'en faire part dans les commentaires ;-) .</p>
</div>
RepRap : le firmware de la carte de commande.2012-02-05T14:34:00+01:00Quentintag:www.peyregne.info,2012-02-05:reprap-le-firmware-de-la-carte-de-commande.html<p>L'une des parties les plus compliqués dans mon aventure RepRap a été de
trouver un Firmware pour la carte de commande. Il s'agit du logiciel
embarqué dans la carte permettant de contrôler tout le hardware :</p>
<ul class="simple">
<li>Pilotage des moteurs pas à pas</li>
<li>Gestion des butées physiques et logicielles</li>
<li>Asservissement en température de l'extruder et du lit chauffant</li>
<li>Pilotage du ventilateur de refroidissement</li>
</ul>
<p>Attention, il ne faut pas confondre ce logiciel avec celui qui est
installé sur le PC et qui sert à convertir un object 3D en commandes
pour l'imprimante 3D.</p>
<p>Le Firmware ne connaît pas l'objet à imprimer, il ne fait que exécuter
les ordres transmis par l'ordinateur de commande : se déplacer, chauffer
l'extruder à 190°C, extruder, ...</p>
<p><a class="reference external" href="http://www.peyregne.info/images/liaisons_commande.png"><img alt="Liaisons Commande" src="http://www.peyregne.info/images/liaisons_commande.png" /></a></p>
<p>Cependant, l'ordinateur ne connaît pas du tout les caractéristiques du
matériel. Si le PC demandeà l'axe X d'avancer de 10mm, concrètement, il
va envoyer cette commande à la carte :</p>
<pre class="literal-block">
G0 X10
</pre>
<p>Je ne veux pas rentrer maintenant dans les détails du langage de
commande utilisé (le <a class="reference external" href="http://reprap.org/wiki/G-code">GCode</a>), c'est juste pour montrer un exemple.</p>
<p>Le PC demande donc à l'axe X d'avancer de 10mm, mais il ne dit pas
directement combien le moteur pas à pas doit faire de crans, avec quelle
accélération, si il faut s'arrêter quand on arrive en butée,... Tout ce
paramétrage se fait dans le Firmware de la carte. On commence donc a
comprendre qu'il y a potentiellement énormément de paramètres à
régler... et c'est le cas !</p>
<p>Fort heureusement, pour un modèle standard de RepRap, par exemple le
modèle Prusa avec le "Wade's Extruder", ces paramètres sont connus et il
n'y a plus qu'à copier/coller (enfin en théorie). De même, un firmware
peut convenir à plusieurs cartes électroniques, mais les principales
sont déjà intégrées dans le code de ces firmwares.</p>
<p>Je m'arrête là pour cet article, qui a pour vocation d'être un préambule
à un prochain article sur la présentation et au paramétrage du firmware
que j'utilise pour ma carte RAMPS v1.2, et qui arrive très bientôt
(je sais que certains de mes lecteurs l'attendent avec impatience ;-) )
!</p>
Alimentation stabilisée 5V et 12V2012-01-02T16:11:00+01:00Quentintag:www.peyregne.info,2012-01-02:alimentation-stabilisee-5v-et-12v.html<p>Pour alimenter une RepRap, ou tout autre équipement électronique, on a
souvent besoin d'une alimentation 5 ou 12V.</p>
<p>Dans cet article, nous allons voir rapidement comment transformer une
alimentation de PC de type ATX pour avoir une alimentation utilisable
facilement.</p>
<p><strong>ATTENTION : Cette manipulation peut être dangereuse car nous allons
ouvrir un appareil 220V, avec des condensateurs qui sont potentiellement
encore chargés. Faites bien attention !</strong></p>
<div class="section" id="premiere-etape-choisir-l-alimentation">
<h2>Première étape : choisir l'alimentation</h2>
<p>En fonction de la puissance dont vous avez besoin, vous pourrez
récupérer une vielle alimentation, ou acheter une alimentation Premier
Prix. Pour une RepRap, il faut avoir idéalement 15A sous 12V, ce que
peut délivrer une alimentation 300W. L'alimentation doit être compatible
ATX pour pouvoir ensuite piloter l’allumage et l'extinction.</p>
<a class="reference external image-reference" href="http://www.peyregne.info/images/before.png"><img alt="{filename}../images/before.png" src="http://www.peyregne.info/images/before.png" /></a>
</div>
<div class="section" id="deuxieme-etape">
<h2>Deuxième étape :</h2>
<p>Sur la grande prise, repérer le fil VERT (PS_ON) et coupez-le, ainsi
qu'un fil de masse NOIR (COM) à proximité.</p>
<a class="reference external image-reference" href="http://www.smpspowersupply.com/connector_atx_pinout.GIF"><img alt="http://www.smpspowersupply.com/connector_atx_pinout.GIF" src="http://www.smpspowersupply.com/connector_atx_pinout.GIF" /></a>
<a class="reference external image-reference" href="http://www.peyregne.info/images/prise.png"><img alt="{filename}../images/prise.png" src="http://www.peyregne.info/images/prise.png" /></a>
</div>
<div class="section" id="troisieme-etape">
<h2>Troisième étape :</h2>
<p>Ouvrir l'alimentation, et tirer les câbles que vous venez de couper.
Pour vérification, sur mon alimentation le fil vert est bien noté PS_ON
sur la carte :</p>
<a class="reference external image-reference" href="http://www.peyregne.info/images/PS_ON.png"><img alt="{filename}../images/PS_ON.png" src="http://www.peyregne.info/images/PS_ON.png" /></a>
<p>On peut alors connecter les deux fils précédemment coupés sur un
interrupteur :</p>
<a class="reference external image-reference" href="http://www.peyregne.info/images/interrupteur.png"><img alt="{filename}../images/interrupteur.png" src="http://www.peyregne.info/images/interrupteur.png" /></a>
</div>
<div class="section" id="derniere-etape">
<h2>Dernière étape :</h2>
<p>Intégrez l'interrupteur dans le boîtier, et c'est fini !</p>
<a class="reference external image-reference" href="http://www.peyregne.info/images/after.png"><img alt="{filename}../images/after.png" src="http://www.peyregne.info/images/after.png" /></a>
</div>
L'électronique de la RepRap : Arduino + RAMPS2012-01-02T13:20:00+01:00Quentintag:www.peyregne.info,2012-01-02:lelectronique-de-la-reprap-arduino-ramps.html<p>Un nouvel article pour expliquer l'électronique de la RepRap. Cet
article n'est pas spécifique à un modèle de RepRap en particulier, la
carte électronique peut être utilisée pour différents modèles
d'imprimante 3D.</p>
<p>Le modèle de l'électronique que j'ai choisi Arduino + RAMPS 1.2 en est
un parmis tant d'autres, je vous conseille d'aller sur le Wiki RepRap
pour avoir plus d'informations sur les autres modèles possibles. Une
vidéo vaut mieux qu'un long discours pour présenter la carte :</p>
<div align="center"><iframe src="http://www.youtube.com/embed/VkhUpxHMphs?rel=0&hd=1" height="360" width="640" frameborder="0"></iframe></div><p>D'une manière générale voici les fonctionnalités que vous retrouverez
sur la carte de commande d'une imprimante 3D :</p>
<ul class="simple">
<li>Contrôle des moteurs pas à pas pour les axes</li>
<li>Contrôle de l'extrudeur (moteur pas à pas ou CC en fonction du
modèle)</li>
<li>Commande des résistances de chauffage de l'extruder et du lit
chauffant</li>
<li>Acquisition des températures de l'extruder et du lit chauffant</li>
<li>Acquisition des informations de fin de course (mécanique ou fourche
optique)</li>
<li>Pilotage d'un ventilateur pour le refroidissement au niveau de
l'extruder</li>
</ul>
<p>Ci dessous, la photos de la carte RAMPS version 1.2 en pièces détachées
achetée sur le site GRRF.de. Je vous invite également à <a class="reference external" href="http://wiki.grrf.de/index.php/Ramps_v1.2_Elektronik">consulter leur
wiki</a> qui explique très bien comment assembler la carte étape par étape
avec beaucoup de photos (c'est en allemand, mais <a class="reference external" href="http://translate.google.fr/translate?hl=fr&sl=de&u=http://wiki.grrf.de/index.php/Ramps_v1.2_Elektronik&ei=eYsBT66fCcjsOZ3LuaQB&sa=X&oi=translate&ct=result">Google le traduit
bien</a> si vous le souhaitez).</p>
<a class="reference external image-reference" href="http://www.peyregne.info/images/ramps1.2.jpg"><img alt="{filename}../images/ramps1.2.jpg" src="http://www.peyregne.info/images/ramps1.2.jpg" /></a>
<p>Depuis, la boutique de <a class="reference external" href="https://shop.grrf.de/grrf-ramps-v14-p-372.html">GRRF.de propose la version RAMPS 1.4</a> qui
ajoute la possibilité d'ajouter un second extruder, et d'ajouter une
carte SD pour pouvoir imprimer sans l'ordinateur.</p>
Petit point sur l'avancement de ma RepRap2011-10-31T11:56:00+01:00Quentintag:www.peyregne.info,2011-10-31:petit-point-sur-lavancement-de-ma-reprap.html<p>Mon dernier article sur la RepRap date d'un mois. Entre temps, j'ai reçu
tout le matériel, monté, assemblé, soudé et réglé mon imprimante. Il y a
beaucoup de travail pour l'assembler entièrement, et pour comprendre
comment elle fonctionne. Je peux déjà dire que <strong>la RepRap ne s'adresse
pas à un public néophyte</strong>, tant il faut chercher à comprendre et
persévérer pour tout monter et régler l'imprimante. Je pense que les
imprimantes du commerce (<a class="reference external" href="http://www.makerbot.com/">MakerBot</a> par exemple) sont plus adaptées car
les réglages existent déjà, mais ce sont bien souvent des solutions deux
à trois fois plus chères.</p>
<p>Dans le cas d'une RepRap, il est beaucoup plus difficile de trouver des
réglages qui correspondent parfaitement à ce que l'on souhaite, du fait
de la diversité des composants. Mais au final, on a la <strong>satisfaction de
comprendre comment ça marche</strong>, et quand ce n'est pas le cas de
comprendre pourquoi ça ne fonctionne pas ;-).</p>
<p>Je reviendrai dans de prochains articles sur la description de ma
configuration (mécanique, électronique, et logicielle), et surtout
j'expliquerai tout ce qui m'a fait perdre du temps, en espérant
que cela puisse servir à d'autres !</p>
<p><a class="reference external" href="http://www.peyregne.info/images/first_print.jpg"><img alt="Première Impression" src="http://www.peyregne.info/images/first_print.jpg" /></a></p>
<p><em>Une des premières impressions, un cube d'étalonnage.</em></p>
Mettre à jour le firmware USB de l'Arduino Uno et Mega2011-10-04T00:17:00+02:00Quentintag:www.peyregne.info,2011-10-04:mettre-a-jour-le-firmware-usb-de-larduino-uno-et-mega.html<p>Les Arduino récents, Uno et Mega, comportent une puce Atmel Mega8U2 qui
fait office de convertisseur USB / Serie.</p>
<p>Récemment, je suis tombé sur un bug lié à cette puce Mega8U2, qui
visiblement ne se produit que sur les systèmes GNU/Linux. Les symptômes
sont les suivants :</p>
<ul class="simple">
<li>Le périphérique <em>/dev/ttyACM0</em> ne répond plus,</li>
<li>L'IDE Arduino freeze pendant plusieurs secondes,</li>
<li>Il faut parfois plus de 4-5 fois pour réussir à programmer l'Arduino</li>
</ul>
<p>En parcourant les forums, je suis tombé sur <a class="reference external" href="http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1286088093/30">ce topic</a>, en anglais, où
la solution à ce problème est donné par <em>stimmer</em>. Je vais donc traduire
en français la marche à suivre pour la résolution, en espérant que cela
puisse servir à d'autres !</p>
<p><strong>ATTENTION !</strong> Je vous encourage à bien vous renseigner sur la
procédure, car elle peut être risquée pour un néophyte.</p>
<ol class="arabic">
<li><p class="first">Préparation de la carte : sur l'Arduino Uno, il faut souder une
résitance de 100 kΩ aux bornes des pastilles entourées en rouge sur
la photo suivante (au dos de la carte) :</p>
<a class="reference external image-reference" href="http://www.peyregne.info/images/arduino_back.jpg"><img alt="Arrière de l'arduino" src="http://www.peyregne.info/images/arduino_back.jpg" /></a>
</li>
<li><p class="first">Installer le paquet dfu-programmer qui va permettre de reprogrammer
la puce :</p>
<div class="highlight"><pre><span class="c"># aptitude install dfu-programmer</span>
</pre></div>
</li>
<li><p class="first">Télécharger le binaire correspondant à votre carte (Uno ou Mega) sur
le site suivant :
<a class="reference external" href="https://github.com/arduino/Arduino/tree/new-extension/hardware/arduino/firmwares/arduino-usbserial">https://github.com/arduino/Arduino/tree/new-extension/hardware/arduino/firmwares/arduino-usbserial</a>
(clic sur le fichier, puis clic droit sur le bouton "Raw" et
Enregistrer Sous) :
* <em>Arduino-usbserial-uno.hex</em> pour l'Arduino Uno
* <em>Arduino-usbserial-mega.hex</em>pour l'Arduino Mega</p>
</li>
<li><p class="first">Brancher l'Arduino au PC avec le câble USB.</p>
</li>
<li><p class="first">Faire contact entre les deux pins entourées en rouge sur la photo
suivante :</p>
<a class="reference external image-reference" href="http://www.peyregne.info/images/arduino_front.jpg"><img alt="Arduino de face" src="http://www.peyregne.info/images/arduino_front.jpg" /></a>
<p>Cette opération permet de faire un <em>reset</em> de la puce Mega8U2.
L'Arduino ne doit alors plus apparaître dans /dev/ :</p>
<div class="highlight"><pre><span class="c"># ls /dev/ttyACM*</span>
</pre></div>
<p>Ne doit rien afficher.</p>
</li>
<li><p class="first">Ensuite, il n'y a plus qu'à flasher la puce avec les commandes
suivantes (à faire en root) :</p>
<div class="highlight"><pre><span class="c"># dfu-programmer at90usb82 erase</span>
<span class="c"># dfu-programmer at90usb82 flash --debug 1 Arduino-usbserial-uno.hex</span>
Validating...
4058 bytes used <span class="o">(</span>99.07%<span class="o">)</span>
<span class="c"># dfu-programmer at90usb82 reset</span>
</pre></div>
</li>
<li><p class="first">Il n'y a alors plus qu'à débrancher puis rebrancher l'Arduino, et
tous les bugs cités en introduction seront normalement résolus !</p>
</li>
</ol>
<p>[Sources]</p>
<ul class="simple">
<li><a class="reference external" href="http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1286088093/30">http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1286088093/30</a></li>
<li><a class="reference external" href="http://arduino.cc/en/Hacking/DFUProgramming8U2">http://arduino.cc/en/Hacking/DFUProgramming8U2</a></li>
</ul>
Installer l'IDE Arduino sur Debian2011-10-02T17:42:00+02:00Quentintag:www.peyregne.info,2011-10-02:installer-lide-arduino-sur-debian.html<p>Je suis passé sur un système GNU/Linux pour mon ordinateur personnel
depuis plusieurs mois, au début sur la distribution <a class="reference external" href="http://archlinux.fr/">ArchLinux</a>, et
depuis peu je suis passé sur une <a class="reference external" href="http://www.debian.org/index.fr.html">Debian</a>. Ce qui était bien sur Arch,
c'est d'avoir toujours la dernière version des paquets. L'inconvénient,
c'est la stabilité du système. C'est pour cette raison que j'ai préféré
passer sur une Debian. J'utilise Debian Wheezy comme système hôte
(Debian "Testing").</p>
<p>Actuellement, les paquets <em>arduino</em> et <em>arduino-core</em>, qui sont les
paquets officiels, sont en version 18 sur Wheezy, ce qui est une version
assez ancienne qui ne supporte pas la dernière version de l'<a class="reference external" href="http://www.peyregne.info/wp/?p=133">Arduino
Uno</a>.</p>
<p>Ne voulant pas passer ma machine en testing, ni jouer avec les
dépendances pour installer à la main la version 22 (qui est la dernière
version à ce jour) des paquets précédents, je me suis donc fait un
chroot contenant la version <em>unstable</em> nommée "Sid". Pour ça, un petit
coup de debootstrap :</p>
<div class="highlight"><pre><span class="c"># debootstrap --arch amd64 --variant=minbase sid /chemin/vers/chroot http://ftp.fr.debian.org/debian/</span>
</pre></div>
<p>Ensuite, j'ai un petit script (<em>launchChroot.sh</em>) pour monter
correctement les volumes nécessaires au chroot, lancer le chroot et tout
démonter correctement à la fin :</p>
<div class="highlight"><pre><span class="c">#!/bin/bash</span>
<span class="nv">chemin</span><span class="o">=</span>/chemin/vers/dossier/installation/du/chroot
mount --bind /dev <span class="nv">$chemin</span>/dev
mount --bind /proc <span class="nv">$chemin</span>/proc
mount --bind /sys <span class="nv">$chemin</span>/sys
cp <span class="o">{</span>,<span class="nv">$chemin</span><span class="o">}</span>/etc/resolv.conf
chroot <span class="nv">$chemin</span>;
<span class="c">#fin on demonte</span>
umount <span class="s2">"$chemin"</span>/<span class="o">{</span>dev,proc,sys<span class="o">}</span>
</pre></div>
<p>Ensuite, un petit coup de</p>
<div class="highlight"><pre><span class="c"># chmod 755 launchChroot.sh</span>
</pre></div>
<p>puis, pour lancer le tout :</p>
<div class="highlight"><pre><span class="c"># ./launchChroot.sh</span>
</pre></div>
<p>On est maintenant dans le système chrooté fraîchement installé. Nous
allons donc pouvoir installer les dernières version des paquets
<em>arduino</em> (qui a pour dépendance <em>arduino-core</em>) :</p>
<div class="highlight"><pre><span class="c"># apt-get install arduino</span>
</pre></div>
<p>Pour éviter de faire trop de bêtises, on se créer un compte utilisateur
:</p>
<div class="highlight"><pre><span class="c"># adduser nomUtilisateur</span>
</pre></div>
<p>On ajoute l'utilisateur au groupe <em>dialout</em> pour qu'il puisse accéder au
port série (sinon le sous menu <em>Tools > Serial Port</em> sera désactivé
quand on lancera l'IDE arduino)</p>
<div class="highlight"><pre><span class="c"># usermod -a -G dialout nomUtilisateur</span>
<span class="c"># su nomUtilisateur</span>
<span class="c"># arduino &</span>
</pre></div>
<p>Tadam !</p>
<a class="reference external image-reference" href="http://www.peyregne.info/images/Arduino.png"><img alt="arduino version 22" src="http://www.peyregne.info/images/Arduino.png" /></a>
<p>Ensuite petite vérification, sélectionner le Serial Port dans le menu
Tools. Si vous avez un Arduino Uno par exemple, le périphérique
/dev/ttyACM0 doit apparaître. Si ce n'est pas le cas, plusieurs raisons
:</p>
<ul>
<li><p class="first">L'utilisateur n'est pas dans le groupe <em>dialout</em></p>
</li>
<li><p class="first">Vous n'avez pas bindé /dev dans le chroot (voir script du lancement
de chroot ci-dessus)</p>
</li>
<li><p class="first">Vérifiez la version des paquets <em>arduino</em> et <em>librxtx-java</em> :</p>
<div class="highlight"><pre><span class="c"># dpkg -s arduino |grep Version</span>
</pre></div>
<p>(doit être >= 22)</p>
<div class="highlight"><pre><span class="c"># dpkg -s librxtx-java |grep Version</span>
</pre></div>
<p>(doit être >= 2.2pre2-3)</p>
</li>
<li><p class="first">Ou encore, comme j'ai eu, vous êtes victime d'un bug concernant les
drivers USB3. Je n'ai pas trop eu le temps de creuser, ce bug a l'air
d'être connu mais je ne saurait dire si ça vient du hard, du noyau ou
de la distro. Dans ce cas, il suffit dans brancher la carte sur un
port USB2, et ça fonctionnera.</p>
</li>
</ul>
<p>Bon amusement ! ;-)</p>
La mécanique de la RepRap2011-10-01T01:22:00+02:00Quentintag:www.peyregne.info,2011-10-01:la-mecanique-de-la-reprap.html<p>J'ai décidé de rentrer un peu plus dans les détails techniques de la
<strong>RepRap Prusa</strong>, et j'ai prévu de faire plusieurs articles pour
présenter l'électronique, la mécanique, l'extruder, le montage, la
configuration et l'utilisation de cette imprimante 3D. La plupart des
articles ne seront pas spécifiques au modèle Prusa, mais mon but n'est
pas de faire des comparatifs entre tous les modèles existants...</p>
<p>Pour ce premier article de la série, je vais parler de
l'<strong>architecture mécanique</strong> de la RepRap.</p>
<p>L'imprimante est articulée autour de <strong>trois axes X, Y et Z</strong> qui permet
de positionner la tête d'impression (en anglais "Extruder") en trois
dimensions relativement à l'objet à imprimer. Le mouvement du plateau
support est unidirectionnel selon l'axe Y, et la tête est mue selon les
axes X et Z. Lors de la dépose d'une couche de plastique, seuls les axes
X et Y bougent de manière synchronisée. Une fois la couche terminée, la
tête de lecture est déplacée légèrement selon l'axe Z, puis une nouvelle
couche peut être déposée.</p>
<p><a class="reference external" href="http://www.peyregne.info/images/axes.png"><img alt="Axes" src="http://www.peyregne.info/images/axes.png" /></a></p>
<p>Les mouvements selon les axes X et Y sont réalisés avec un moteur
par axe, tandis qu'il faut 2 moteurs de part et d'autre de l'imprimante
pour actionner l'axe Z.</p>
<p>Les moteurs sont des <strong>moteurs pas à pas</strong>, ce qui permet de les
piloter facilement en position (nous y reviendrons plus tard). Les
moteurs X et Y sont reliés à des courroies pour faire bouger la navette
et le plateau. Les moteurs pour l'axe Z sont reliés directement aux vis
permettant de monter et descendre la navette. Il existe aussi des
versions avec un seul moteur pour l'axe Z, avec une courroie pour relier
les deux vis permettant de faire monter la navette avec l'Extruder, mais
le problème est que ces deux vis doivent être parfaitement synchronisées
pour que l'axe X soit bien horizontal.</p>
<p>Le châssis de l'imprimante est composé de deux parties. <strong>Des tiges
filetées et des barreaux</strong> (en gris sur l'image ci-dessus), et des
<strong>pièces d'assemblage en plastique</strong> (en vert). Ce sont ces pièces qui
peuvent être imprimées par l'imprimante pour en recréer d'autres, ce qui
vaut à la RepRap sa qualification d'<strong>auto-réplicatrice</strong>!</p>
<p>Dans un prochain article, je vais me focaliser sur la tête d'impression.</p>
Ouvrir une liste d'URL2011-09-30T23:47:00+02:00Quentintag:www.peyregne.info,2011-09-30:ouvrir-une-liste-durl.html<p>Voici une petite astuce, pour ouvrir une liste d'URL (par exemple une
liste de photos Flickr, une liste de numéros de suivi de colis, une
liste d'objets eBay à surveiller, etc...).</p>
<ul class="simple">
<li>Le site <a class="reference external" href="http://www.urlopener.com/index.php">URLOpener.com</a> permet de saisir et d'ouvrir une liste d'URL</li>
<li>Le site <a class="reference external" href="http://www.openupper.com/">OpenUpper.com</a> permet de saisir et de sauvegarder des
listes d'URL pour les ouvrir plus tard (par exemple pour partager des
listes, ça peut être utile).</li>
</ul>
<p>C'est tout ! ;-)</p>
J'ai craqué pour une RepRap...2011-09-29T23:05:00+02:00Quentintag:www.peyregne.info,2011-09-29:jai-craque-pour-une-reprap.html<p>Oui je suis faible, j'ai craqué pour une <a class="reference external" href="http://reprap.org">RepRap</a>... ( enfin !! ;-) )</p>
<p>Je ne vais pas expliquer ce qu'est une RepRap ici, mes lecteurs sont
suffisamment geeks pour savoir ce que c'est :-).</p>
<p><a class="reference external" href="http://reprap.org"><img alt="RepRap" src="http://www.peyregne.info/images/reprap_logo3.png" /></a></p>
<p>Ça va faire plus de deux ans que j'ai pris connaissance du projet
RepRap, mais à l'époque je n'avais pas de sous j'étais étudiant, et le
modèle <a class="reference external" href="http://reprap.org/wiki/Mendel_(Fran%C3%A7ais)">Mendel "de base"</a> comportait beaucoup de pièces, qui étaient
rares donc chères. Depuis, les choses on beaucoup évolué. Tout un tas
de nouveaux modèles sont sortis, qui à chaque fois permettait
d'améliorer les performances de la machine, tout en diminuant le nombre
de pièces nécessaires et donc le coût total. Le modèle <a class="reference external" href="http://reprap.org/wiki/Prusa">Mendel Prusa</a> a
le vent en poupe ces derniers temps, et est maintenant considéré comme
la nouvelle référence RepRap. A titre de comparaison, la RepRap Mendel
originale nécessite 50 roulements à bille, contre 3 seulement pour la
RepRap Prusa.</p>
<p>Vouloir avoir une RepRap, beaucoup de gens en rêvent. Concrétiser son
rêve, c'est beaucoup plus compliqué, parce que :</p>
<ul class="simple">
<li>C'est quand même une petite somme d'argent à investir (cf plus bas),</li>
<li>Il faut beaucoup de temps pour se renseigner sur les différents
modèles et choisir le sien,</li>
<li>Il faut faire la liste des pièces nécessaires, fouiller sur internet,
les forums, les blogs,...</li>
<li>Il faut trouver où acheter les pièces. Et c'est là que ça se corse :
les vendeurs sur internet se font rares, et les pièces à vendre sur
eBay partent rapidement. Il faut donc être trèèèèès patient pour
trouver les bonnes pièces au meilleur prix sans se faire arnaquer,</li>
<li>Il faut avoir du temps pour fabriquer la RepRap. Et oui c'est quand
même plus marrant de tout faire soit même que d'acheter un kit déjà
monté (et surtout beaucoup moins cher !!),</li>
<li>Il faut avoir du temps pour modéliser les pièces et les imprimer. Il
faut compter 10 à 20 cm<sup>3</sup> par heure de débit de plastique
(enfin quand on en est rendu à cette étape, on est content)</li>
</ul>
<p>Personnellement, ça fait quelques semaines que je me renseigne
activement sur la RepRap, et j'ai jeté mon dévolu sur le modèle Prusa,
qui est suffisamment connu et diffusé pour qu'on trouve de la
documentation à son sujet. Cette étape est vraiment primordiale pour
bien savoir dans quoi on se lance, connaître les pièces à obtenir, les
différents organes de la machine, etc.</p>
<p>Vient ensuite la chasse aux meilleurs prix et aux disponibilités sur
internet. Le site officiel RepRap.org contient beaucoup de liens vers
des sites marchand qui fournissent des kits plus ou moins complest, mais
souvent à des prix prohibitifs. La solution pour moi a donc été de
chercher dans les recoins d'eBay des pièces détachées, pour petit à
petit cocher toutes les lignes de la liste des composants requis. En
faisant cela, je suis arrivé à un coût nettement inférieur aux
revendeurs de kits complets (de l'ordre de -40%, avec les frais de
ports).</p>
<p>Voici le détail du coût de ma RepRap:</p>
<ul class="simple">
<li>Kit de pièces imprimés "Prusa" métrique : 78€</li>
<li>Éléments mécaniques (tiges, vis, écrous,...) : 60€</li>
<li>Base chauffante : 33€</li>
<li>5 Moteurs pas à pas : 100€</li>
<li>Electronique complète : 200€</li>
<li>Tête chauffante : 50€</li>
<li><strong>TOTAL : 521€</strong></li>
</ul>
<p>En cherchant encore plus, j'aurais pu rogner encore quelques dizaines
d'euros, mais je n'avais pas envie de faire 50 commandes non plus...</p>
<p>Bref, je suis maintenant dans la phase d'attente de réception de tout ce
matériel, ce qui me laisse le temps de faire grandir ma liste d'objets à
imprimer... :D</p>
I'm back :-)2011-09-26T23:41:00+02:00Quentintag:www.peyregne.info,2011-09-26:im-back.html<p>Mon dernier article remonte à février... D'ailleurs <a class="reference external" href="http://www.peyregne.info/wp/?p=227">la réparation du
Macbook de mon frère</a> fonctionne toujours !</p>
<p>Entre temps, j'ai beaucoup été pris par le boulot, et par
<a class="reference external" href="http://www.atlantronic.fr">Atlantronic</a>, mon équipe participant à la Coupe de France de
robotique. Cette année, nous remettons le couvert pour une nouvelle
participation, ma cinquième :-)</p>
<p>Sinon j'ai beaucoup de projets personnels plus ou moins avancés (dont
<a class="reference external" href="http://www.peyregne.info/wp/?p=164">mon horloge binaire</a> à qui j'ai fait un beau boîtier), donc
potentiellement plein d'articles à écrire. Encore une fois, il faut que
je trouve le temps de faire tout ça, mais je ne désespère pas !</p>
Démarrer un Macbook Unibody sans clavier2011-02-20T21:15:00+01:00Quentintag:www.peyregne.info,2011-02-20:demarrer-un-macbook-unibody-sans-clavier.html<p>Récemment mon frère a renversé du Coca sur son Macbook Unibody, ce qui
est peu recommandé. Le problème est que son clavier fonctionnait
toujours, mais par intermittence, et parfois même des touches se
"tapaient" toutes seules. Il existe deux solutions pour résoudre le
problème :</p>
<ul class="simple">
<li>Celle du riche fainéant : faire remplacer le clavier par Apple (200€)</li>
<li>Celle du pauvre, pardon de l'étudiant curieux : acheter un clavier externe (20 €) et déconnecter l'interne.</li>
</ul>
<p>Le problème de la seconde solution, c'est que ça ne résout pas le
problème des frappes intempestives sur clavier interne. Une solution
facile est de déconnecter physiquement le clavier de la carte mère, et
pour cela j'ai fait confiance un très célèbre site <a class="reference external" href="http://www.ifixit.com/">iFixit</a>,
spécialiste des réparations de produits Apple. La manipulation est
décrite dans l'<a class="reference external" href="http://www.ifixit.com/Guide/Repair/Installing-MacBook-Unibody-Model-A1278-Logic-Board-Replacement/765/5">étape 15 de l'article de ce lien</a>.</p>
<p>Le gros soucis, c'est que le bouton de mise en marche est justement
relié par ce connecteur ! Qu'à cela ne tienne, j'ai donc cherché des les
recoins d'internet et je suis tombé sur <a class="reference external" href="http://forums.macrumors.com/showthread.php?t=949088">ce forum</a> ou quelqu'un décrit
quels sont les pins à relier ensemble pour simuler un appui sur le
bouton.</p>
<p>Pour pouvoir <strong>allumer le Macbook sans le clavier</strong>, il suffit dont de
<strong>faire contact entre les pins 5 et 29 du connecteur du clavier</strong>. Pour
éviter d'avoir à ouvrir le portable pour chaque mise en route, j'ai donc
soudé deux petits câbles, maintenus par un bon coup de pisto-colle, que
j'ai fait sortir par la grille de ventilation arrière, et le tour est
joué !</p>
<a class="reference external image-reference" href="http://www.peyregne.info/images/macbook_inside.jpg"><img alt="{filename}../images/macbook_inside.jpg" src="http://www.peyregne.info/images/macbook_inside.jpg" /></a>
<p>Et démarrer son Macbook à la MacGyver, ça n'a pas de prix !</p>
<a class="reference external image-reference" href="http://www.peyregne.info/images/macbook_outside.jpg"><img alt="{filename}../images/macbook_outside.jpg" src="http://www.peyregne.info/images/macbook_outside.jpg" /></a>
<p>(J'ai pensé à protéger un peu les contacts pour ne pas que la machine ne
démarre ou s'arrête toute seule...)</p>
Capteur de température DS1631 et Arduino2011-01-09T22:29:00+01:00Quentintag:www.peyregne.info,2011-01-09:capteur-de-temperature-ds1631-et-arduino.html<p>Le <a class="reference external" href="http://www.maxim-ic.com/datasheet/index.mvp/id/3241">DS1631</a> est un capteur de température, et est disponible en <a class="reference external" href="http://www.maxim-ic.com/samples">sample
sur le site de Maxim</a>, le fabriquant. Ce capteur s'interface facilement
avec l'Arduino avec une liaison I<sup>2</sup>C. Il retourne une
température avec une précision réglable allant jusqu'au 1/16<sup>ème</sup>
de degré.</p>
<a class="reference external image-reference" href="http://www.peyregne.info/images/DS1631.png"><img alt="{filename}../images/DS1631.png" src="http://www.peyregne.info/images/DS1631.png" /></a>
<p><em>Diagramme du DS1631</em></p>
<p>Ci-dessous un exemple de cablage avec l'Arduino, sachant qu'on peut
choisir une partie de l'adresse I<sup>2</sup>C avec les pins A0, A1, A2
ce qui peut s'avérer pratique pour gérer plusieurs capteurs en même
temps.</p>
<a class="reference external image-reference" href="http://www.peyregne.info/images/DS1631_Arduino.png"><img alt="{filename}../images/DS1631_Arduino.png" src="http://www.peyregne.info/images/DS1631_Arduino.png" /></a>
<p><em>Branchement du DS1631 avec l'Arduino</em></p>
<p>Et voici le code permettant de lire puis d'afficher la température sur à
l'aide d'une liaison série sur mon Minitel.</p>
<div class="highlight"><pre><span class="cm">/*</span>
<span class="cm"> * DS1631 Temperature sensor</span>
<span class="cm"> * www.peyregne.info</span>
<span class="cm">*/</span>
<span class="cp">#include</span>
<span class="c1">// Adress pins of the DS1631 device</span>
<span class="c1">// 0 if pin connected to GND, 1 to VDD</span>
<span class="cp">#define DS1631_A0 0</span>
<span class="cp">#define DS1631_A1 0</span>
<span class="cp">#define DS1631_A2 0</span>
<span class="cp">#define DS1631_CFG_R1 1 </span><span class="c1">// resolution 9 to 12 bits</span>
<span class="cp">#define DS1631_CFG_R0 1 </span><span class="c1">// set to 12 bits (750ms conversion time)</span>
<span class="cp">#define DS1631_CFG_POL 0 </span><span class="c1">// T_OUT polarity (1=active high, 0=active low)</span>
<span class="cp">#define DS1631_CFG_1SHOT 1 </span><span class="c1">// Conversion mode (1=one shot mode, 0=continuous mode)</span>
<span class="c1">// Do not change the following definitions</span>
<span class="cp">#define DS1631_ADDR (0x48 | DS1631_A2<<2 | DS1631_A1<<1 | DS1631_A0)</span>
<span class="cp">#define DS1631_CFG (DS1631_CFG_R1 << 3 \</span>
<span class="cp"> | DS1631_CFG_R0 << 2 \</span>
<span class="cp"> | DS1631_CFG_POL << 1 \</span>
<span class="cp"> | DS1631_CFG_1SHOT)</span>
<span class="cp">#define DS1631_DONE_MASK 0x80;</span>
<span class="kt">void</span> <span class="nf">setup</span><span class="p">()</span>
<span class="p">{</span>
<span class="c1">// Opening I2C interface as Master</span>
<span class="n">Wire</span><span class="p">.</span><span class="n">begin</span><span class="p">();</span>
<span class="c1">// First, stop the conversion (if configured in continuous</span>
<span class="c1">// conversion mode) to access the configuration register.</span>
<span class="n">Wire</span><span class="p">.</span><span class="n">beginTransmission</span><span class="p">(</span><span class="n">DS1631_ADDR</span><span class="p">);</span>
<span class="n">Wire</span><span class="p">.</span><span class="n">send</span><span class="p">(</span><span class="mh">0x22</span><span class="p">);</span> <span class="c1">// Stop conversion</span>
<span class="n">Wire</span><span class="p">.</span><span class="n">endTransmission</span><span class="p">();</span>
<span class="c1">// Configuration of DS1631 (see Datasheet)</span>
<span class="n">Wire</span><span class="p">.</span><span class="n">beginTransmission</span><span class="p">(</span><span class="n">DS1631_ADDR</span><span class="p">);</span>
<span class="n">Wire</span><span class="p">.</span><span class="n">send</span><span class="p">(</span><span class="mh">0xAC</span><span class="p">);</span> <span class="c1">// Access Configuration</span>
<span class="n">Wire</span><span class="p">.</span><span class="n">send</span><span class="p">(</span><span class="n">DS1631_CFG</span><span class="p">);</span>
<span class="n">Wire</span><span class="p">.</span><span class="n">endTransmission</span><span class="p">();</span>
<span class="cp">#if DS1631_CFG_1SHOT == 0</span>
<span class="c1">// If continuous mode is set, start continuous conversion</span>
<span class="n">Wire</span><span class="p">.</span><span class="n">beginTransmission</span><span class="p">(</span><span class="n">DS1631_ADDR</span><span class="p">);</span>
<span class="n">Wire</span><span class="p">.</span><span class="n">send</span><span class="p">(</span><span class="mh">0x51</span><span class="p">);</span>
<span class="n">Wire</span><span class="p">.</span><span class="n">endTransmission</span><span class="p">();</span>
<span class="n">delay</span><span class="p">(</span><span class="mi">750</span><span class="p">);</span> <span class="c1">// delay to be sure that the first value is correct</span>
<span class="cp">#endif</span>
<span class="n">UCSR0C</span> <span class="o">=</span> <span class="n">B00100100</span><span class="p">;</span> <span class="c1">// passage en mode 7bits + bit de parité</span>
<span class="n">Serial</span><span class="p">.</span><span class="n">begin</span><span class="p">(</span><span class="mi">1200</span><span class="p">);</span>
<span class="n">Serial</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span><span class="n">BYTE</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="nf">loop</span><span class="p">()</span>
<span class="p">{</span>
<span class="kt">float</span> <span class="n">t</span> <span class="o">=</span> <span class="mf">0.0</span><span class="p">;</span>
<span class="n">t</span> <span class="o">=</span> <span class="n">readTempOne</span><span class="p">(</span><span class="n">DS1631_CFG_1SHOT</span><span class="p">);</span>
<span class="n">Serial</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span><span class="n">BYTE</span><span class="p">);</span>
<span class="n">Serial</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="n">BYTE</span><span class="p">);</span>
<span class="n">Serial</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="mi">13</span><span class="p">,</span><span class="n">BYTE</span><span class="p">);</span>
<span class="n">Serial</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">"Temperature : "</span><span class="p">);</span>
<span class="n">Serial</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="n">t</span><span class="p">,</span><span class="mi">4</span><span class="p">);</span>
<span class="n">Serial</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">" degres"</span><span class="p">);</span>
<span class="n">delay</span><span class="p">(</span><span class="mi">10000</span><span class="p">);</span> <span class="c1">// wait 10 seconds</span>
<span class="p">}</span>
<span class="kt">float</span> <span class="nf">readTempOne</span><span class="p">(</span><span class="n">boolean</span> <span class="n">oneShotMode</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">float</span> <span class="n">temp</span> <span class="o">=</span> <span class="mf">0.0</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">oneShotMode</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">// Temperature conversion request</span>
<span class="n">Wire</span><span class="p">.</span><span class="n">beginTransmission</span><span class="p">(</span><span class="n">DS1631_ADDR</span><span class="p">);</span>
<span class="n">Wire</span><span class="p">.</span><span class="n">send</span><span class="p">(</span><span class="mh">0x51</span><span class="p">);</span>
<span class="n">Wire</span><span class="p">.</span><span class="n">endTransmission</span><span class="p">();</span>
<span class="n">delay</span><span class="p">(</span><span class="mi">750</span><span class="p">);</span> <span class="c1">// delay for 12 bits precision</span>
<span class="c1">// Now we wait the end of the conversion</span>
<span class="n">boolean</span> <span class="n">tempAvailable</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">tempAvailable</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">// See if the conversion is finished</span>
<span class="c1">// in the configuration byte</span>
<span class="n">Wire</span><span class="p">.</span><span class="n">beginTransmission</span><span class="p">(</span><span class="n">DS1631_ADDR</span><span class="p">);</span>
<span class="n">Wire</span><span class="p">.</span><span class="n">send</span><span class="p">(</span><span class="mh">0xAC</span><span class="p">);</span>
<span class="n">Wire</span><span class="p">.</span><span class="n">endTransmission</span><span class="p">();</span>
<span class="n">Wire</span><span class="p">.</span><span class="n">requestFrom</span><span class="p">(</span><span class="n">DS1631_ADDR</span><span class="p">,</span><span class="mi">1</span><span class="p">);</span>
<span class="n">Wire</span><span class="p">.</span><span class="n">available</span><span class="p">();</span>
<span class="n">tempAvailable</span> <span class="o">=</span> <span class="n">Wire</span><span class="p">.</span><span class="n">receive</span><span class="p">()</span> <span class="o">&</span> <span class="n">DS1631_DONE_MASK</span><span class="p">;</span>
<span class="n">delay</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="c1">// read result</span>
<span class="n">Wire</span><span class="p">.</span><span class="n">beginTransmission</span><span class="p">(</span><span class="n">DS1631_ADDR</span><span class="p">);</span>
<span class="n">Wire</span><span class="p">.</span><span class="n">send</span><span class="p">(</span><span class="mh">0xAA</span><span class="p">);</span> <span class="c1">// read last conversion</span>
<span class="n">Wire</span><span class="p">.</span><span class="n">endTransmission</span><span class="p">();</span>
<span class="n">Wire</span><span class="p">.</span><span class="n">requestFrom</span><span class="p">(</span><span class="n">DS1631_ADDR</span><span class="p">,</span><span class="mi">2</span><span class="p">);</span>
<span class="n">Wire</span><span class="p">.</span><span class="n">available</span><span class="p">();</span>
<span class="kt">int</span> <span class="n">tempMS</span> <span class="o">=</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span> <span class="n">Wire</span><span class="p">.</span><span class="n">receive</span><span class="p">();</span>
<span class="n">Wire</span><span class="p">.</span><span class="n">available</span><span class="p">();</span>
<span class="kt">int</span> <span class="n">tempLS</span> <span class="o">=</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span> <span class="n">Wire</span><span class="p">.</span><span class="n">receive</span><span class="p">();</span>
<span class="n">tempLS</span> <span class="o">>>=</span> <span class="mi">4</span><span class="p">;</span> <span class="c1">// last 4 bits are always 0</span>
<span class="k">if</span> <span class="p">(</span><span class="n">tempMS</span> <span class="o">&</span> <span class="mh">0x80</span><span class="p">)</span> <span class="c1">// if the signed bit = 1</span>
<span class="n">tempMS</span> <span class="o">-=</span> <span class="mi">256</span><span class="p">;</span>
<span class="c1">// Float conversion</span>
<span class="n">temp</span> <span class="o">=</span> <span class="p">(</span><span class="kt">float</span><span class="p">)</span> <span class="p">(</span><span class="n">tempMS</span> <span class="o">+</span> <span class="n">tempLS</span><span class="o">*</span><span class="mf">0.0625</span><span class="p">);</span>
<span class="k">return</span> <span class="n">temp</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<a class="reference external image-reference" href="http://www.peyregne.info/images/photo_ds1631.jpg"><img alt="{filename}../images/photo_ds1631.jpg" src="http://www.peyregne.info/images/photo_ds1631.jpg" /></a>
<p><em>Le programme en action</em></p>
Chargement du .bashrc avec MacOS2011-01-09T19:39:00+01:00Quentintag:www.peyregne.info,2011-01-09:chargement-du-bashrc-avec-macos.html<p>Voici une petite astuce qui pourrait aider des personnes sur MacOS. En
effet je lis souvent sur les forums que le <em>.bashrc</em> n'est pas pris en
compte en lançant Terminal par exemple.</p>
<p>En fait, quand on lance un terminal, on accède au shell d'accès, qui
n'est pas personnalisé. Pour faire simple, le <em>.bashrc</em>, <em>.profile</em>,
etc. ne sont pas chargés. On va alors forcer le chargement de ces
fichiers à l'ouverture d'un terminal.</p>
<p>Au lancement d'un shell, le fichier <em>.bash_profile</em> qui est situé à la
racine du dossier personnel est lu (s'il existe). Il suffit donc dans ce
fichier de dire qu'on souhaite charger le <em>.bashrc</em> avec la commande
<tt class="docutils literal">source</tt> (ou ".").</p>
<p>Voici à quoi doit ressemble le <em>.bash_profile</em> pour résoudre la
problème (créer le fichier à la racine de votre répertoire personnel si
ce n'est déjà fait) :</p>
<div class="highlight"><pre><span class="c">#!/bin/bash</span>
clear
<span class="nb">source</span> ~/.profile
<span class="nb">source</span> ~/.bashrc
</pre></div>
<p>Maintenant, à chaque lancement du terminal, votre <em>.bahrc</em> et autres
fichiers seront correctement pris en compte.</p>
Diff via SSH avec vimdiff2011-01-03T22:24:00+01:00Quentintag:www.peyregne.info,2011-01-03:diff-via-ssh.html<p>J'ai souvent besoin de comparer des fichiers similaires situés sur des
machines différentes. Plutôt que de copier les fichiers en local puis de
faire un traditionnel <tt class="docutils literal">diff</tt> (ou <tt class="docutils literal">vimdiff</tt> pour les durs),
j'utilise <tt class="docutils literal">vimdiff</tt> qui permet d'ouvrir directement des fichiers via
SSH avec le <a class="reference external" href="http://fr.wikipedia.org/wiki/Secure_copy">protocole SCP</a>, de les modifier et de les sauver sur la
cible :</p>
<div class="highlight"><pre><span class="nv">$ </span>vimdiff scp://user1@host1//chemin/fichier scp://user2@host2//chemin/fichier
</pre></div>
<p>Voici les commandes les plus utiles :</p>
<ul>
<li><dl class="first docutils">
<dt><tt class="docutils literal">do</tt> pour <strong>o</strong>btenir la version de l'autre fichier de la</dt>
<dd><p class="first last">modification courante,</p>
</dd>
</dl>
</li>
<li><p class="first"><tt class="docutils literal">dp</tt> pour <strong>p</strong>ropager la version à l'autre fichier,</p>
</li>
<li><p class="first"><tt class="docutils literal">]c</tt> pour aller à la différence suivante,</p>
</li>
<li><p class="first"><tt class="docutils literal">[c</tt> pour aller à la différence précédente,</p>
</li>
<li><p class="first"><tt class="docutils literal">ctrl + w</tt> deux fois pour changer de fichier.</p>
</li>
</ul>
<p>Pour finir, j'ai mappé les commandes <tt class="docutils literal">]c</tt> et <tt class="docutils literal">[c</tt> qui sont très peu
ergonomiques, en rajoutant ces lignes dans mon <em>.vimrc</em> :</p>
<div class="highlight"><pre>nmap ]<span class="k">c</span>
nmap [<span class="k">c</span>
</pre></div>
<a class="reference external image-reference" href="http://www.peyregne.info/images/vimdiff.png"><img alt="{filename}../images/vimdiff.png" src="http://www.peyregne.info/images/vimdiff.png" /></a>
<p><em>Sources</em> : <a class="reference external" href="http://vim.wikia.com/wiki/VimTip337">Wiki vim</a>, <a class="reference external" href="http://vimdoc.sourceforge.net/htmldoc/diff.html#vimdiff">aide vimdiff</a></p>
Horloge binaire RVB2010-12-19T00:44:00+01:00Quentintag:www.peyregne.info,2010-12-19:horloge-binaire-rvb.html<p>Après avoir récupéré tout plein de LEDs RGB (rouge, vert et bleu dans la
même LED), j'ai pu réaliser une idée qui me trottait dans la tête depuis
un petit moment, une horloge binaire avec un affichage simultané de
l'heure (en bleu), des minutes (en rouge) et des secondes (en vert).
Chaque LED affiche donc une couleur, combinaison de ces trois couleurs.</p>
<p style="text-align: center;">
<object width="640" height="385">
<embed src="http://www.youtube.com/v/v7wwtQ5El5c?fs=1&hl=fr_FR&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385">
</embed>
</object>
</p><p>L'horloge est contrôlée par un Arduino, qui pilote un driver de LEDs
<a class="reference external" href="http://focus.ti.com/docs/prod/folders/print/tlc5940.html">TLC5940 de Texas Instrument</a>, qui permet de générer 16 signaux PWM.
L'avantage d'utiliser des signaux modulés est de pouvoir régler la
luminosité des LEDS en fonction des combinaisons de couleurs. En effet
avec des signaux tout ou rien, une couleur seule (rouge par exemple)
serait beaucoup moins brillante que le blanc, qui est générée en
allumant les 3 couleurs. Le TLC5940 est disponible en sample sur le site
de TI. Par contre j'en avait commandé 5, et j'en ai reçu seulement un...</p>
<p>Pour l'application, j'utilise la <a class="reference external" href="http://www.arduino.cc/playground/Learning/TLC5940">bibliothèque TLC pour Arduino</a>, qui
permet de communiquer avec ces contrôleurs de LED de manière très
facile. Pour le décompte du temps, j'ai fait au plus simple, sans
utiliser les timers de l'ATMega, d'ailleurs comme écrit dans les
commentaires, l'horloge ne pourra pas fonctionner correctement très
longtemps. En même temps je ne sais pas quelle est la précision des
timers...</p>
<div class="highlight"><pre><span class="cp">#include "Tlc5940.h"</span>
<span class="n">byte</span> <span class="n">s</span><span class="p">;</span> <span class="c1">// seconds, in GREEN</span>
<span class="n">byte</span> <span class="n">m</span><span class="p">;</span> <span class="c1">// minutes, in RED</span>
<span class="n">byte</span> <span class="n">h</span><span class="p">;</span> <span class="c1">// hours, in BLUE</span>
<span class="k">static</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">time</span><span class="p">;</span> <span class="c1">// "cheap" timer</span>
<span class="kt">void</span> <span class="nf">setup</span><span class="p">()</span>
<span class="p">{</span>
<span class="c1">// Initialisation of the TLC</span>
<span class="n">Tlc</span><span class="p">.</span><span class="n">init</span><span class="p">();</span>
<span class="n">Tlc</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span>
<span class="n">Tlc</span><span class="p">.</span><span class="n">update</span><span class="p">();</span>
<span class="n">delay</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
<span class="c1">// Set the hour here...</span>
<span class="n">h</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
<span class="n">m</span> <span class="o">=</span> <span class="mi">30</span><span class="p">;</span>
<span class="n">s</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">time</span> <span class="o">=</span> <span class="n">millis</span><span class="p">();</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="nf">loop</span><span class="p">()</span>
<span class="p">{</span>
<span class="c1">// if 1000ms are passed, update the clock.</span>
<span class="c1">// /!\ the clock will die after the millis() counter</span>
<span class="c1">// will roll back to 0, but it will stand at least</span>
<span class="c1">// for about 50 days, which is enough for my test...</span>
<span class="k">if</span> <span class="p">(</span><span class="n">millis</span><span class="p">()</span> <span class="o">-</span> <span class="n">time</span> <span class="o">></span> <span class="mi">999</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">time</span> <span class="o">+=</span> <span class="mi">1000</span><span class="p">;</span>
<span class="n">updateClock</span><span class="p">();</span>
<span class="k">for</span> <span class="p">(</span><span class="n">byte</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o"><</span><span class="mi">6</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="n">setColor</span><span class="p">(</span><span class="n">i</span><span class="p">);</span>
<span class="n">Tlc</span><span class="p">.</span><span class="n">update</span><span class="p">();</span>
<span class="n">delay</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span> <span class="c1">// 1ms delay to update TLC</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="c1">// This function is called every second,</span>
<span class="c1">// and update the hours, minutes and seconds.</span>
<span class="kt">void</span> <span class="nf">updateClock</span><span class="p">()</span>
<span class="p">{</span>
<span class="o">++</span><span class="n">s</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">s</span><span class="o">></span><span class="mi">59</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">s</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="o">++</span><span class="n">m</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="n">m</span><span class="o">></span><span class="mi">59</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">m</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="o">++</span><span class="n">h</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="n">h</span><span class="o">></span><span class="mi">11</span><span class="p">)</span> <span class="c1">// 12 hours version, I don't have enough outputs for 24 hours...</span>
<span class="p">{</span>
<span class="n">h</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="c1">// This function sets the levels of each color</span>
<span class="c1">// in order to have better colors with the same</span>
<span class="c1">// level of brigthness (instead of just setting</span>
<span class="c1">// the signals full on or off)</span>
<span class="kt">void</span> <span class="nf">setColor</span><span class="p">(</span><span class="n">byte</span> <span class="n">n</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">boolean</span> <span class="n">g</span> <span class="o">=</span> <span class="p">(</span><span class="n">s</span> <span class="o">&</span> <span class="p">(</span><span class="mi">1</span><span class="o"><<</span><span class="n">n</span><span class="p">));</span>
<span class="n">boolean</span> <span class="n">r</span> <span class="o">=</span> <span class="p">(</span><span class="n">m</span> <span class="o">&</span> <span class="p">(</span><span class="mi">1</span><span class="o"><<</span><span class="n">n</span><span class="p">));</span>
<span class="n">boolean</span> <span class="n">b</span> <span class="o">=</span> <span class="p">(</span><span class="n">h</span> <span class="o">&</span> <span class="p">(</span><span class="mi">1</span><span class="o"><<</span><span class="n">n</span><span class="p">));</span>
<span class="kt">int</span> <span class="n">red</span><span class="p">,</span> <span class="n">green</span><span class="p">,</span> <span class="n">blue</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">r</span> <span class="o">&&</span> <span class="o">!</span><span class="n">g</span> <span class="o">&&</span> <span class="o">!</span><span class="n">b</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">//BLACK</span>
<span class="n">red</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">green</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">blue</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">r</span> <span class="o">&&</span> <span class="o">!</span><span class="n">g</span> <span class="o">&&</span> <span class="n">b</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">//BLUE</span>
<span class="n">red</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">green</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">blue</span> <span class="o">=</span> <span class="mi">4000</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">r</span> <span class="o">&&</span> <span class="n">g</span> <span class="o">&&</span> <span class="o">!</span><span class="n">b</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">//GREEN</span>
<span class="n">red</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">green</span> <span class="o">=</span> <span class="mi">4000</span><span class="p">;</span>
<span class="n">blue</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">r</span> <span class="o">&&</span> <span class="n">g</span> <span class="o">&&</span> <span class="n">b</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">//CYAN</span>
<span class="n">red</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">green</span> <span class="o">=</span> <span class="mi">1500</span><span class="p">;</span>
<span class="n">blue</span> <span class="o">=</span> <span class="mi">1500</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">r</span> <span class="o">&&</span> <span class="o">!</span><span class="n">g</span> <span class="o">&&</span> <span class="o">!</span><span class="n">b</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">//RED</span>
<span class="n">red</span> <span class="o">=</span> <span class="mi">4095</span><span class="p">;</span>
<span class="n">green</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">blue</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">r</span> <span class="o">&&</span> <span class="o">!</span><span class="n">g</span> <span class="o">&&</span> <span class="n">b</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">//MAGENTA</span>
<span class="n">red</span> <span class="o">=</span> <span class="mi">3000</span><span class="p">;</span>
<span class="n">green</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">blue</span> <span class="o">=</span> <span class="mi">2000</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">r</span> <span class="o">&&</span> <span class="n">g</span> <span class="o">&&</span> <span class="o">!</span><span class="n">b</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">//YELLOW</span>
<span class="n">red</span> <span class="o">=</span> <span class="mi">3000</span><span class="p">;</span>
<span class="n">green</span> <span class="o">=</span> <span class="mi">2000</span><span class="p">;</span>
<span class="n">blue</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span>
<span class="p">{</span>
<span class="c1">//WHITE</span>
<span class="n">red</span> <span class="o">=</span> <span class="mi">3000</span><span class="p">;</span>
<span class="n">green</span> <span class="o">=</span> <span class="mi">2000</span><span class="p">;</span>
<span class="n">blue</span> <span class="o">=</span> <span class="mi">1000</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">Tlc</span><span class="p">.</span><span class="n">set</span><span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="n">red</span><span class="p">);</span>
<span class="n">Tlc</span><span class="p">.</span><span class="n">set</span><span class="p">(</span><span class="n">n</span><span class="o">+</span><span class="mi">6</span><span class="p">,</span><span class="n">green</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">n</span><span class="o"><</span><span class="mi">4</span><span class="p">)</span>
<span class="n">Tlc</span><span class="p">.</span><span class="n">set</span><span class="p">(</span><span class="n">n</span><span class="o">+</span><span class="mi">12</span><span class="p">,</span><span class="n">blue</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
<p>Pour terminer ce projet, je compte utiliser un module RTC (Real Time Clock) qui me permettra de sauvegarder l'heure après la mise hors tension de l'Arduino, et utiliser des balles de ping-pong pour diffuser la lumière des LEDs !</p>
3615 MATOU2010-11-21T22:55:00+01:00Quentintag:www.peyregne.info,2010-11-21:3615-matou.html<p>Premier hack avec l'Arduino : le Minitel. Le Minitel n'est ni plus ni
moins qu'un terminal série, avec des standards d'encodage des caractères
préhistoriques. C'est donc après une bonne après-midi de boulot (le
temps de dompter le dinosaure) que j'ai réussi ce petit hack.</p>
<p style="text-align: center;">
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="640" height="385" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0">
<embed type="application/x-shockwave-flash" width="640" height="385" src="http://www.youtube.com/v/SWyDdiVrcHA?fs=1&hl=fr_FR" allowscriptaccess="always" allowfullscreen="true">
</embed>
</object>
</p><p>La méthode est loin d'être simple, j'ai dû utiliser un vieux programme
MSDOS permettant de convertir des images en mode Videotex, puis faire
quelques retouches pour afficher cette image avec une résolution
phénoménale de 80*72 pixels sur 4 niveaux de gris...</p>
Le nouvel Arduino Uno2010-11-21T17:06:00+01:00Quentintag:www.peyregne.info,2010-11-21:le-nouvel-arduino-uno.html<p>Récemment (cela fait qund même presque 2 mois maintenant), Arduino a
lancé une nouvelle version de ses cartes de développement maintenant
célèbres. Les cartes Arduino Duemilanove et Mega ont subis quelques
modifications et sont renommées en Arduino Uno et Arduino Mega2560.</p>
<a class="reference external image-reference" href="http://www.peyregne.info/images/arduino_1.jpg"><img alt="{filename}../images/arduino_1.jpg" src="http://www.peyregne.info/images/arduino_1.jpg" /></a>
<p><em>Le packaging de l'Arduino Uno, qui peut facilement faire
penser à un autre produit... ;-)</em></p>
<p>Depuis le temps que je lorgnais sur ces cartes, j'en ai profité pour
commander des Arduino Uno, et en bon fan d'électronique, je vous propose
un "<em>unboxing</em>" de la nouvelle Uno.</p>
<p>Après avoir ouvert la boîte, on trouve la platine Uno, un set
d'autocollants très sympathique et un petit dépliant explicatif :</p>
<a class="reference external image-reference" href="http://www.peyregne.info/images/arduino_3.jpg"><img alt="{filename}../images/arduino_3.jpg" src="http://www.peyregne.info/images/arduino_3.jpg" /></a>
<p>Petite remarque, sur une des cartes que j'ai acheté, la soudure du
composant gérant l'USB (une puce Atmel en passant) n'a pas été nettoyée,
et il y a quelques résidus de flux de soudure, ce qui n'est pas très
propre :</p>
<a class="reference external image-reference" href="http://www.peyregne.info/images/arduino_7.jpg"><img alt="{filename}../images/arduino_7.jpg" src="http://www.peyregne.info/images/arduino_7.jpg" /></a>
<p>Le packaging est donc assez sympathique, mais j'aurais aimé que la carte
soir un peu plus protégée, ne serait-ce que par un sachet plastique pour
éviter que la poussière du carton d'emballage ne salisse la carte et ne
se loge dans les connecteur, même si je n'ai pas eu de problèmes de ce
côté-là. De même, l'ajout de petits patins afin d'isoler la carte par
rapport à une table par exemple aurait été bienvenue. Enfin, l'ajout de
goodies est appréciable, pour revendiquer son appartenance à la
communauté Arduino !</p>
<p>La carte est ensuite très simple à utiliser. Il suffit de se rendre <a class="reference external" href="http://www.arduino.cc/fr/">sur
le site Arduino</a>, de télécharger l'IDE de développement et de se
laisser guider avec les exemples de base !</p>
<p>Par rapport à la version précédente, voici ce qui a changé dans la
version Uno :</p>
<ul class="simple">
<li>Un nouveau design, avec des informations plus explicites sur les
pins,</li>
<li>Une puce Atmega8U2 qui fait convertisseur USB-Série, en lieu et place
de l'ancienne puce FTDI, qui peut être reprogrammée pour créer de
vrais périphériques USB,</li>
<li>Un bootloader plus rapide, plus léger, donc plus de place pour le
programme utilisateur (+1,5Kb).</li>
</ul>
<p>J'ai pas mal de projets à faire avec cette carte, il ne me reste donc
plus qu'à me mettre au travail !</p>
Me voici ingénieur...2010-11-03T20:30:00+01:00Quentintag:www.peyregne.info,2010-11-03:me-voici-ingenieur.html<p>Après deux ans de classe prépa puis trois ans à l'École Centrale de
Nantes, je suis devenu officiellement <strong>ingénieur</strong>. Outre le fait que
ceci a changé le titre de mon site, j'ai aussi changé de région.</p>
<p>Après mon stage de fin d'études sur Paris (au passage je passe le
bonjour à toutes les personnes que j'ai connues là-bas), je suis revenu
dans ma Bretagne natale pour travailler dans le domaine qui me passionne
le plus : <strong>la robotique mobile</strong>.</p>
<p>Au passage, je rempile pour une année à la <strong>Coupe de France de
Robotique</strong> avec une équipe nouvellement crée, <a class="reference external" href="http://www.atlantronic.fr">Atlantronic</a>. Cette
équipe est composée d'un groupe d'anciens étudiants qui ont déjà
participé à la coupe. Nous espérons que notre expérience nous aidera à
créer un robot simple et performant !</p>
<p>Enfin, j'ai plein de projets en tête, et j'espère avoir du temps pour
les réaliser et les partager ici !</p>
Comment gérer ses mots de passe2010-08-11T21:27:00+02:00Quentintag:www.peyregne.info,2010-08-11:comment-gerer-ses-mots-de-passe.html<p>Les mots de passe nous servent tous les jours, aussi bien en utilisation
professionelle que personnelle. Dans cet article, je vais vous expliquer
la méthode que j'utilise pour gérer facilement mes mots de passe.</p>
<p>Voici les principales contraintes que je souhaite respecter :</p>
<ol class="arabic simple">
<li>Avoir un <strong>mot de passe différent</strong> pour chaque site ou service que
j'utilise (ainsi, si une personne mal intentionnée récupère mon mot
de passe, il ne fonctionnera pas ailleurs)</li>
<li>Avoir <strong>un seul mot de passe à retenir</strong> (en fait deux : un pour tout
ce qui est perso, et un pour le boulot)</li>
<li>Pouvoir <strong>modifier facilement</strong> mon mot de passe</li>
</ol>
<p>Tout d'abord, il faut choisir un mot de passe de base, constitué de
caractères minuscules, majuscules, chiffres et caractères spéciaux (sauf
" et ', on n'est jamais à l'abri d'un site mal codé). Pour cela, le plus
simple est d'aller sur un site de génération de mot de passe, <a class="reference external" href="http://strongpasswordgenerator.com/">comme
celui-ci</a>. Ensuite, je génère plusieurs mots de passe, jusqu'à en
trouver un qui puisse s'écrire relativement rapidement. En effet, mon
mot de passe sera long et je le tape souvent, donc autant que se soit
agréable. Par exemple, prenons cette base de 12 caractères :</p>
<p>8;M*w1/mEF2é</p>
<p>Ensuite nous allons utiliser cette base pour créer un mot de passe
unique pour chaque site. Pour l'exemple, prenons par exemple <em>Google</em>,
<em>Twitter</em> et <em>Flickr</em>. Bien sûr, il ne faut surtout pas faire ceci :</p>
<ul class="simple">
<li>8;M*w1/mEF2éGoogle</li>
<li>8;M*w1/mEF2éTwitter</li>
<li>8;M*w1/mEF2éFlickr</li>
</ul>
<p>En effet, la découverte d'un mot de passe mettra à mal tous les
autres... L'idée, c'est de <strong>camoufler la spécificité du site au sein du
mot de passe</strong>. Pour ceci, on peut utiliser plein de méthodes
différentes, et les combiner ou les adapter comme on le souhaite. Par
exemple :</p>
<ul class="simple">
<li>Ajouter le nombre de lettres du nom du site moins une au début du mot
de passe</li>
<li>Ajouter le nombre de voyelles dans le nom du site à la fin du mot de
passe</li>
<li>Utiliser la 3ème lettre du nom du site en 5ème position dans le mot
de passe et en majuscule</li>
<li>Utiliser la lettre suivante dans l'alphabet de la première lettre du
nom du site en 7ème position</li>
</ul>
<p>Bien sûr, ceci peut paraître très compliqué au premier abord, mais cette
gymnastique arrive très vite. Pour les trois sites cités précédemment,
on arrive alors en appliquant ces règles à :</p>
<ul class="simple">
<li><em>Google</em>: 58;Mo*Hw1/mEF2é3</li>
<li><em>Twitter</em> : 68;Mi*Uw1/mEF2é2</li>
<li><em>Flickr</em> : 58;Mi*Gw1/mEF2é1</li>
</ul>
<p>On arrive ainsi à trois mots de passe assez différents, tout en ayant un
seul mot de passe à retenir. En voyant la longueur finale du mot de
passe, on se rend bien compte qu'il faut que la base soit facilement
saisissable. Mais en tapant 10 fois le mot de passe par jour, ça devrait
rentrer !</p>
<p>Les deux premières contraintes sont donc satisfaites. Pour pouvoir à
l'avenir changer facilement les mots de passe de tout mes sites, c'est
très simple, j'enregistre dans un fichier l'adresse de changement de mot
de passe de chaque site, et ainsi je n'en oublie aucun lorsqu'il s'agit
de tout changer !</p>
<p>Je peux paraître un peu paranoïaque, mais <strong>il y a énormément de sites
qui stockent les mots de passe en clair</strong>, par exemple les sites
carrières de grandes entreprises. Et il devient donc potentiellement
très facile pour des personnes malveillantes d'aller explorer votre vie
privée avant une éventuelle embauche !</p>
<p>Voilà, j'espère vous avoir donné des astuces utiles...</p>
Supprimer automatiquement ses anciens tweets2010-08-08T21:55:00+02:00Quentintag:www.peyregne.info,2010-08-08:supprimer-automatiquement-ses-anciens-tweets.html<p>J'utilise beaucoup twitter, principalement pour suivre l'actualité, et
converser avec quelques amis. Mon compte est privé, c'est à dire que mes
tweets ne sont pas publiques, car ils n'intéressent potentiellement que
mes amis.</p>
<p>Étant quelque peu "parano" vis-à-vis des réseaux sociaux, je n'aime pas
laisser trainer des informations derrière moi. C'est pourquoi d'ailleurs
je n'utilise plus Facebook et que j'avais à l'époque supprimé un à un
tout ce que j'avais posté.</p>
<p>Dans cette optique, je cherchais une méthode pour supprimer
automatiquement mes tweets anciens, car de toute façon plus personne ne
les lira. Potentiellement, ils ne serviront donc qu'à une utilisation
détournée (publicitaires, statistiques, etc...), d'où mon souhait de
faire le ménage.</p>
<p>Une solution radicale est de supprimer mon compte, puis de le recréer.
Mais ce n'est pas envisageable car il faudrait à chaque fois se
ré-abonner à tous les comptes qu'on souhaite suivre. Un autre idée est
de le faire à la main, en cliquant un à un sur les messages à supprimer.
Or, j'ai presque atteint les 1000 tweets, ce qui peut être assez
rébarbatif...</p>
<p>Le but de cet article est donc de vous présenter une manière plus propre
de faire le ménage, en utilisant l'API twitter. En fait, je ne vais pas
utiliser directement l'API twitter, mais un bibliothèque python pour
l'utiliser : python-twitter, que vous pouvez trouver sur le <a class="reference external" href="http://code.google.com/p/python-twitter/">Google Code
du projet</a>. Pour l'installer sur MacOS avec Macports, tapez :</p>
<div class="highlight"><pre><span class="nv">$ </span>sudo port install py-twitter
</pre></div>
<p>Une remarque importante est que cette bibliothèque fonctionne avec la
version 2.4 de python. N'étant pas un grand expert de python, je ne sais
pas si c'est possible ni comment utiliser cette bibliothèque avec une
version supérieure. Mais pour ce qu'on souhaite faire, je ne sais pas si
ça a une grande importance...</p>
<p>Python-twitter est simple d'utilisation, et après une lecture de la
documentation, on arrive vite à se connecter à l'API, récupérer ses
followers, ou envoyer des tweets. Un exemple simple, ici pour envoyer un
tweet :</p>
<div class="highlight"><pre>import twitter
</pre></div>
<p><tt class="docutils literal">api = <span class="pre">twitter.Api(username='Votre_Username',</span> <span class="pre">password='azerty')</span> status = <span class="pre">api.PostUpdate("Ceci</span> est un test !") print status.text</tt></p>
<p><a class="reference external" href="http://www.peyregne.info/images/envoi_tweet.png"><img alt="{filename}../images/envoi_tweet.png" src="http://www.peyregne.info/images/envoi_tweet.png" /></a></p>
<p>Le résultat est immédiatement visible sur ma timeline :</p>
<p><a class="reference external" href="http://www.peyregne.info/images/resultat_tweet.png"><img alt="{filename}../images/resultat_tweet.png" src="http://www.peyregne.info/images/resultat_tweet.png" /></a></p>
<p>Bon, venons-en maintenant au cœur du problème. Nous allons
faire un petit script dont le principe est le suivant :</p>
<ul class="simple">
<li>On récupère notre timeline (en fait, ce sont seulement nos 20
derniers tweets)</li>
<li>On supprime les 20-<em>x</em> derniers tweets, où <em>x</em> est le nombre des
tweets les plus récents que l'on souhaite garder</li>
<li>On recommence, jusqu'à ce que tous les tweets soient supprimés.</li>
</ul>
<p>L'inconvénient est que lors de la mise en place de ce script, on a
généralement beaucoup de tweets, et donc il faut exécuter beaucoup de
fois cette boucle. Le problème, c'est que twitter <a class="reference external" href="http://support.twitter.com/forums/10711/entries/15364">n'autorise qu'une
fréquence limitée d'accès à son API</a>, à savoir 150 requêtes par heure.
Qu'à cela ne tienne on n'exécute la boucle qu'un petit nombre de fois,
et un petit cron exécuté régulièrement finira par purger la timeline !</p>
<p>Voici le script que j'ai écrit rapidement :</p>
<p><tt class="docutils literal">import twitter</tt></p>
<p><tt class="docutils literal">n = 10 # Nombre de tweets a garder dans sa timeline</tt></p>
<p><tt class="docutils literal">api = <span class="pre">twitter.Api(username='Votre_Username',</span> <span class="pre">password='azerty')</span> tl = api.GetUserTimeline(since_id=0) <span class="pre">print('Nombre</span> de tweets recuperes : %d' % len(tl)) print ('Supression des %d derniers tweets :' % <span class="pre">(len(tl)-n)</span> )</tt></p>
<p><tt class="docutils literal">for i in range(n,len(tl)) : status = tl[i] <span class="pre">print('Status</span> #%d' % status.id) api.DestroyStatus(status.id)</tt></p>
<p>Et le résultat :</p>
<p><a class="reference external" href="http://www.peyregne.info/images/py_clean_tl.png"><img alt="{filename}../images/py_clean_tl.png" src="http://www.peyregne.info/images/py_clean_tl.png" /></a></p>
<p>Pour mettre en place le cron, on édite le fichier utilisateur :</p>
<div class="highlight"><pre><span class="nv">$ </span>crontab -e
</pre></div>
<p>Puis on ajoute la ligne suivante, par exemple pour exécuter le cron
toute les 10 minutes :</p>
<p><tt class="docutils literal">*/10 * * * * python2.4 /chemin/vers/le/script/clean_timeline.py >> /chemin/vers/le/log/clean.log</tt></p>
<p>A terme, une fois ma timeline vidée, je remettrai le cron une fois par
jour, ce qui sera largement suffisant compte tenu de ma fréquence de
gazouillage.</p>
<p>Dernières remarques :</p>
<ul class="simple">
<li>Le mot de passe est stocké en clair dans le script, ce qui n'est pas
super...</li>
<li>Le script tel quel ne marche pas si vous souhaitez garder vos 50
derniers tweets par exemple.</li>
<li>Les données récupérées par l'API ont par défaut un cache de 60
secondes. Il est donc normal qu'un deuxième appel au script juste
après ne fasse rien !</li>
</ul>
<p>Maintenant, à vous de jouer pour adapter le script, par exemple pour
sauvegarder vos tweets avant de les supprimer !</p>
Coupe de France de robotique 20102010-05-18T20:36:00+02:00Quentintag:www.peyregne.info,2010-05-18:coupe-de-france-de-robotique-2010.html<p>Ce week-end, j'ai participé pour ma troisième année consécutive à la
<a class="reference external" href="http://www.planete-sciences.org/robot/index.php?section=pages&pageid=97">Coupe de France de robotique</a>. Pour cette édition 2010, le robot
devait récolter des tomates, maïs et oranges et les emmener dans un
panier.</p>
<a class="reference external image-reference" href="http://www.peyregne.info/images/feed_the_world_logo.png"><img alt="{filename}../images/feed_the_world_logo.png" src="http://www.peyregne.info/images/feed_the_world_logo.png" /></a>
<p>Cette coupe a été en quelque sorte la consécration du travail fournit
avec mon équipe du <a class="reference external" href="http://robot.campus.ec-nantes.fr/wordpress/">Club Robot de Centrale Nantes</a>. En effet, depuis
deux ans nous avons refait presque tout le robot (base motrice, carte
moteur, communication entre les cartes et architecture du code haut
niveau) suite à l'échec de la coupe 2008 où nous n'avions pas pu nous
homologuer.</p>
<img alt="{filename}../images/robot_merci_homologuer.jpg" src="http://www.peyregne.info/images/robot_merci_homologuer.jpg" />
<p>Cette année, le robot a été relativement performant, puisque nous nous
sommes homologués, et nous avons joué 5 matchs (2 victoires, 2 nuls et
une défaite). Nous terminons finalement 41ème sur environ 160 équipes
participantes.</p>
<p>Je vous invite à aller lire <a class="reference external" href="http://robot.campus.ec-nantes.fr/wordpress/?p=339">l'article plus détaillé sur le site du
club</a> (avec d'autres photos, ainsi que des vidéos).</p>
Faites parler le Mac en ligne de commande2010-04-05T23:20:00+02:00Quentintag:www.peyregne.info,2010-04-05:faites-parler-le-mac-en-ligne-de-commande.html<p>Parfois, il m'arrive de taper une ou deux lettre dans mon shell, puis de
regarder les résultats de l'autocomplétion. De cette façon, je découvre
souvent des programmes plus ou moins utiles.</p>
<a class="reference external image-reference" href="http://www.peyregne.info/images/say1.png"><img alt="{filename}../images/say1.png" src="http://www.peyregne.info/images/say1.png" /></a>
<p>Ma dernière découverte est le programme <tt class="docutils literal">say</tt>, qui permet tout
simplement de faire parler le Mac. Comment ? <tt class="docutils literal">say</tt> utilise la synthèse
vocale qui est présente sur MacOS. Un exemple :</p>
<div class="highlight"><pre><span class="nv">$ </span>say Win the yes, need the no to win, against the no !
</pre></div>
<p>Et oui, say permet de prononcer correctement des phrases en anglais,
mais en anglais seulement. Car Apple n'a toujours pas fait de
synthétiseur vocal dans une autre langue, alors que la firme <a class="reference external" href="http://www.youtube.com/watch?v=G0FtgZNOD44">a
introduit son premier synthétiseur en 1984</a> dans le célèbre Macintosh
128K.</p>
<p>En lisant le manuel, on peut trouver des options, comme l'enregistrement
de l'audio en AIFF, ou alors le choix de la voix de synthèse :</p>
<div class="highlight"><pre><span class="nv">$ </span>say -v Junior -o lecture.aiff Oh hi! I can has cheeseburger ?
</pre></div>
<p>Ce programme n'est pas très utile en soit, mais je pense que ça peut
être pratique dans un script automatisé pour donner des informations ou
des alertes.</p>
SFTP dans le Finder avec Macfusion2010-04-05T18:31:00+02:00Quentintag:www.peyregne.info,2010-04-05:sftp-dans-le-finder-avec-macfusion.html<p>Le Finder de MacOS (10.5, je ne sais pas ce qu'il en est pour la 10.6)
ne permet pas d'ouvrir directement une session sftp, ce qui a le don de
faire doucement rigoler mes amis linuxiens.</p>
<p><a class="reference external" href="http://www.peyregne.info/images/FinderSftp.png"><img alt="{filename}../images/FinderSftp.png" src="http://www.peyregne.info/images/FinderSftp.png" /></a></p>
<p>Il existe certe des logiciels qui permettent de se monter un disque par
ssh tels que <a class="reference external" href="http://cyberduck.ch/">Cyberduck</a>, mais ils ne permettent pas de naviguer avec
le Finder. J'ai donc cherché une solution, et j'ai trouvé un petit
logiciel gratuit très pratique : <a class="reference external" href="http://www.macfusionapp.org/">Macfusion</a>.</p>
<p>Après avoir téléchargé et installé Macfusion, il faut le lancer. Une
interface très minimaliste s'ouvre. Il faut alors ajouter un nouveau
serveur sur lequel on souaite se connecter, soit par ftp, soit par ssh
(ce qui est mon cas) :</p>
<p><a class="reference external" href="http://www.peyregne.info/images/Macfusion1.png"><img alt="{filename}../images/Macfusion1.png" src="http://www.peyregne.info/images/Macfusion1.png" /></a></p>
<p>Ensuite, il faut remplir les informations de connexion au serveur (le
mot de passe est retenu dans le trousseau de MacOS) :</p>
<p><a class="reference external" href="http://www.peyregne.info/images/Macfusion2.png"><img alt="{filename}../images/Macfusion2.png" src="http://www.peyregne.info/images/Macfusion2.png" /></a></p>
<p>Il est important de bien remplir "Path:" qui est le chemin où
on souhaite arriver à la connexion. Si on le laisse par défaut,
Macfusion indiquera l'erreur "<em>Could not mount filesystem:
Authentication has failed.</em>" (même si l'erreur n'a aucun lien avc un
problème d'identification).</p>
<p>Après avoir rempli ces informations, on valide et on monte le volume. Un
nouveau lecteur apparaît alors dans <tt class="docutils literal">/Volumes/</tt> ainsi que sur le
bureau et dans la barre latérale :</p>
<p><a class="reference external" href="http://www.peyregne.info/images/iconeSftp.png"><img alt="{filename}../images/iconeSftp.png" src="http://www.peyregne.info/images/iconeSftp.png" /></a></p>
<p>On peut maintenant accéder et travailler sur les fichiers en
toute transparence depuis le Finder :</p>
<p><a class="reference external" href="http://www.peyregne.info/images/sftpconnecte.png"><img alt="{filename}../images/sftpconnecte.png" src="http://www.peyregne.info/images/sftpconnecte.png" /></a></p>
<p>Remarque : une fois le volume monté, on peut fermer Macfusion sans
problèmes, le volume restera monté.</p>
<p>Il faudra quand même que je regarde pour une solution plus "simple",
c'est à dire en passant par le shell. Si vous avez des pistes, merci de
me le dire !</p>
Convertir un PDF en images PNG sous MacOS2010-04-05T11:43:00+02:00Quentintag:www.peyregne.info,2010-04-05:convertir-un-pdf-en-images-png.html<p>Récemment, j'ai voulu envoyer un pdf constitué d'images scannées d'un
manuel à quelqu'un. Mais ce pdf était beaucoup trop lourd pour passer
par un boîte mail. J'ai donc cherché une solution pour réduire la
qualité de pdf, mais sans succès (pas possible avec Aperçu, ni Adobe
Acrobat, et recherche sur Macports infructueuse).</p>
<p>J'ai donc voulu contourner le problème : je souhaitais extraire les
images du pdf pour pouvoir changer la qualité puis les assembler de
nouveau pour faire un pdf.</p>
<p>J'ai donc tapé au petit bonheur la chance "pdf2png" sur Google, et je
suis tombé sur <a class="reference external" href="http://evanjones.ca/pdf2png.m">ce lien</a>. Il s'agit d'un petit programme en Objective C
qui va automatiquement convertir les pages de fichiers pdf en images png
de haute qualité.</p>
<p>Voici les étapes pour compiler et installer le programme (sur Mac OS
seulement) :</p>
<div class="highlight"><pre><span class="nv">$ </span>gcc --std<span class="o">=</span>c99 -Wall -g -o pdf2png pdf2png.m -framework Cocoa <span class="nv">$ </span>sudo mv pdf2png /usr/bin/
</pre></div>
<p>Et voilà ! Il n'y a plus qu'à utiliser le programme sur mon fichier
pdf de 33 pages :</p>
<div class="highlight"><pre><span class="nv">$ </span>pdf2png manuel_vox.pdf
<span class="nv">$ </span>ls
manuel_vox-p01.png manuel_vox-p10.png manuel_vox-p19.png manuel_vox-p28.png manuel_vox-p02.png manuel_vox-p11.png manuel_vox-p20.png manuel_vox-p29.png manuel_vox-p03.png manuel_vox-p12.png manuel_vox-p21.png manuel_vox-p30.png manuel_vox-p04.png manuel_vox-p13.png manuel_vox-p22.png manuel_vox-p31.png manuel_vox-p05.png manuel_vox-p14.png manuel_vox-p23.png manuel_vox-p32.png manuel_vox-p06.png manuel_vox-p15.png manuel_vox-p24.png manuel_vox-p33.png manuel_vox-p07.png manuel_vox-p16.png manuel_vox-p25.png manuel_vox.pdf manuel_vox-p08.png manuel_vox-p17.png manuel_vox-p26.png manuel_vox-p09.png manuel_vox-p18.png manuel_vox-p27.png
</pre></div>
<p>Enfin, j'ai inséré toutes ces images dans un document Pages, puis
Exporter > PDF où j'ai choisit la qualité la plus faible qui est appelée
"Bonne" (en pensant à mettre toutes les marges à 0 pour conserver les
dimensions originales).</p>
<a class="reference external image-reference" href="http://www.peyregne.info/images/exportPDF.png"><img alt="{filename}../images/exportPDF.png" src="http://www.peyregne.info/images/exportPDF.png" /></a>
<p>Cette méthode est un peu fastidieuse, mais à défaut d'avoir trouvé autre
chose, elle fonctionne bien. Mon fichier de départ faisait 26,2 Mo, et
il fait maintenant 10,3 Mo, ce qui est plus facile pour diffuser le
fichier (la qualité n'étant pas ma priorité).</p>
Introduction2010-04-04T14:34:00+02:00Quentintag:www.peyregne.info,2010-04-04:hello-world.html<p>Bonjour,</p>
<p>Je vous souhaite la bienvenue sur mon site personnel. Je suis
actuellement en troisième et dernière année à l'<a class="reference external" href="http://www.ec-nantes.fr">École Centrale de
Nantes</a>. Je suis passionné par la robotique, et je souhaite travailler
plus tard dans le domaine des systèmes embarqués.</p>
<p>N'hésitez pas à me contacter pour plus de renseignements : quentin [at]
peyregne.info .</p>
<p>Bonne visite !</p>