jeudi 19 septembre 2013

Récupérer les trames NMEA d'un GPS

Dans cet article, nous allons récupérer les trames NMEA d'un GPS. Par la suite nous les stockerons sur la Raspberry PI afin de les afficher par la suite sur une carte Google Maps.



Matériel utilisé :
- RaspberryPI
- dongle Wifi
- un GPS permettant de récupérer les trames NMEA (Inforad dans un premier temps et GPS Seedstudio par la suite)

Vérifier la réception des trames NMEA

Pour tout savoir sur la norme NMEA.

L'objectif est d'analyser ses trames et de récupérer les informations de base pour placer un Marker sur une carte (latitude et longitude).

Dans un premier temps, j'ai récupéré un "assistant à la conduite" anciennement appelé "détecteur de radar" de marque Inforad. Ces petits appareils permettent de prévenir de la présence d'un radar d'une zone de danger lorsque l'on circule sur une route.
Ces appareils contiennent une base de données de radar, que l'on peut mettre à jour depuis son ordinateur, et se sert de la position GPS pour prévenir des zones à risque. Cela a évité un grand nombre d'amendes et de retraits de points d'accidents sur les routes.

Bref, ces appareils sont très intéressant puisqu'ils transmettent via le port série (port USB) les trames NMEA. Ils ont été remplacés par des modèles connectés ou par des GPS indiquant eux aussi les zones à risque. Si vous avez ce type d'appareil, ressortez le du placard ou demandez à un ami, sinon on peut en trouver pour moins de 10 euros sur les sites de revente.

On peut également trouver certains GPS qui envoient les trames NMEA via le port série. Chercher sur Internet ou sur la documentation du GPS la vitesse de transmission ou Bauds.
Le mien par exemple, et il semble que ce soit généralement le cas transmet à 4800 Bauds.

On va à présent vérifier que le GPS renvoie bien les trames NMEA. Pour cela on va brancher le GPS sur le port USB et vérifier le port COM.
On va utiliser Putty, mais on peut utiliser le logiciel de notre choix qui nous permet de se connecter aux ports COM (screen pour Linux par exemple).

1) Brancher le GPS sur l'ordinateur à l'aide du câble USB
2) Vérifier le numéro du port COM dans la liste des périphériques
3) Ouvrir Putty


4) Sélectionner Serial dans les boutons radios puis saisir le nom du port COM ainsi que la vitesse (ici port COM28 et 4800

5) Cliquer sur Open, un terminal s'ouvre et les lignes NMEA doivent s'afficher



A venir prochainement, la récupération des traces NMEA à partir d'une RaspberryPI et l'affichage sur une carte.

lundi 3 juin 2013

Arduino lent au démarrage et ouverture Outils?

Votre programme Arduino est lent à l'ouverture et lorsque vous ouvrez l'onglet Outil dans le menu.
Essayez de désactiver le Bluetooth de votre PC.
Arduino scan tous les ports COM à l'ouverture du logiciel Arduino et à l'ouverture du menu Outil. Le périphérique Bluetooth utilise des ports COM et ralentit le logiciel Arduino
src : http://arduino.cc/en/Guide/troubleshooting

mardi 28 mai 2013

[RaspberryPI] Commander des prises de courant par radio fréquence via un émetteur 433Mhz

J'ai acheté un pack de prises télécommandées de ce style :

J'avais envie de les commander via une interface Web. Quoi de mieux qu'une RaspberryPI pour ca?
Pour cela j'avais besoin :
- une RaspberryPI
- Un pack de prises télécommandées (voir ci-dessus)
- Un émetteur/récepteur 433Mhz (http://www.evola.fr/product_info.php/kit-transmission-433mhz-compatible-arduino-p-162)

Note importante!

Ces prises que l'on trouve dans le commerce utilise la fréquence 433Mhz pour dialoguer. En fait elle ne dialogue pas vraiment.
La télécommande est codée via 5 interrupteurs que l'on place en position 0 ou 1.
La télécommande est généralement composée de 4 on/off permettant d'allumer ou d'éteindre chaque prise.
Chaque prise est composée de 2 séries d'interrupteurs, le premier correspond au code de la télécommande, et l'autre au numéro de la prise (généralement ce sont des lettres).
En gros lors de l'appui sur un bouton de la télécommande, elle émet un signal composé :
1) du numéro de télécommande
2) du numéro de prise
3) de l'état voulu de la prise

Le code envoyer par chaque bouton est toujours le même.

Pendant ce temps là, les prises écoutes et attendent leur code de déclenchement.

Il est donc très facile de sniffer le code et le renvoyer (Man in the middle) mais heureusement on ne sera pas obligé de sniffer le code puisque des gens ont déjà travaillé dessus.

Nous utiliserons la librairie rc-switch ré-écrite pour la RaspberryPI et qui permet d'émuler, via un émetteur RF 433Mhz, une télécommande. A noter que rc-switch utilise la librairie Wiringpi.
La librairie rc-switch est également disponible pour Arduino et permet d'utiliser le recepteur RF.

Passons à l'installation

A présent nous allons mettre en place notre application.

Paramétrage des prises

1) Dans ce tutoriel, nous allons positionner les interrupteurs de chaque prises sur ON ou 1 (11111). Attention on va faire ca uniquement sur le code correspondant à la télécommande (celui avec 5 interrupteurs).
2) Ensuite on va attribuer une lettre différente pour chaque prise (de A à D)
3) Pour être sûr que cela fonctionne régler la télécommande avec le même code (11111) et brancher chacune des prises. Tester ensuite à l'aide de la télécommande pour voir si chaque prise s'allume et s'éteint.

Branchement du module RF 433Mhz sur la RaspberryPI


1) Relier Vcc > PIN 2 (5V)
2) Relier GND > PIN 6 (GND)
3) Relier output > PIN 11 (GPIO17)

Installer et configurer WiringPI

Installer RC-switch-pi

Tester les interrupteurs

Maintenant que tout est opérationnel, on va allumer une de nos prises.
Pour cela, on va utiliser le fichier send du dossier rc-switch et on va lui passer en paramètres :
1 : le code de la télécommande
2 : le numéro de la prise (1=A ; 2=B ; 3=C ; 4=D)
3 : l'état dans lequel on veut voir la prise (1=allumée ; 0=éteinte)
Exécuter donc la commande suivante (si vous êtes dans le dossier rc-switch) qui va allumer la première prise :
sudo ./send 11111 1 1 
Pour l'éteindre :
sudo ./send 11111 1 0 

Si ca ne fonctionne pas :
1) vérifier que la prise n'est pas à une distance trop éloigner de l'émetteur
2) vérifier les branchements de l'émetteur sur la RaspberryPI
3) reprendre le tuto...

Mettre en place l'interface

Installation du serveur lighttpd

Une fois que ca fonctionne on va pouvoir rendre accessible cette fonctionnalité via une interface Web.
Pour cela on va installer lighttpd qui suffira pour ce dont on a besoin de faire :
sudo apt-get install lighttpd

Création de l'interface

On va utiliser la librairie ainsi qu'un thème JQuery, pour cela configurer et télécharger un thème en suivant ce lien.
Dézipper ce dossier.
Créer un fichier index.php à la racine et y coller le code ci-dessous. Cette page va afficher 4 radio-boutons qui vont permettre d'allumer ou d'éteindre nos 4 interrupteurs.
<!doctype html>
<html lang="us">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0">
<title>Domo</title>
<link href="css/ui-darkness/jquery-ui-1.10.3.custom.css" rel="stylesheet">
<script src="js/jquery-1.9.1.js"></script>
<script src="js/jquery-ui-1.10.3.custom.js"></script>
<script>
$(function() {
$( "#radioset1" ).buttonset();
$( "#radioset2" ).buttonset();
$( "#radioset3" ).buttonset();
$( "#radioset4" ).buttonset();

$( ".ui-buttonset" ).change(function(){
var housecode=$(this).children("input[name='housecode']").val();
var numcode = $(this).children("input[name='num']").val();
var state = $(this).children(":checked").val();
console.log(housecode+"  : "+numcode+" : "+state);
$.post("sendVal.php", {housecode:housecode, numcode:numcode, state:state}, function(data){
console.log(data);
});
});
});
</script>
<style>
body{
font: 62.5% "Trebuchet MS", sans-serif;
}
.demoHeaders {
margin-top: 2em;
}
#dialog-link {
padding: .4em 1em .4em 20px;
text-decoration: none;
position: relative;
}
#dialog-link span.ui-icon {
margin: 0 5px 0 0;
position: absolute;
left: .2em;
top: 50%;
margin-top: -8px;
}
#icons {
margin: 0;
padding: 0;
}
#icons li {
margin: 2px;
position: relative;
padding: 4px 0;
cursor: pointer;
float: left;
list-style: none;
}
#icons span.ui-icon {
float: left;
margin: 0 4px;
}
.fakewindowcontain .ui-widget-overlay {
position: absolute;
}
</style>
</head>
<body>
<div id="radioset1" class="ui-buttonset">
Lumière 1 :
<input type="hidden" name="housecode" value="11111"/>
<input type="hidden" name="num" value="1"/>
<input type="radio" id="radio1" name="radio1" class="ui-helper-hidden-accessible" value="1"><label for="radio1" class="ui-button ui-widget ui-state-default ui-button-text-only ui-corner-left" role="button" aria-disabled="false" aria-pressed="false"><span class="ui-button-text">Allumer</span></label>
<input type="radio" id="radio2" name="radio1" checked="checked" class="ui-helper-hidden-accessible" value="0"><label for="radio2" class="ui-button ui-widget ui-state-default ui-button-text-only ui-state-active" role="button" aria-disabled="false" aria-pressed="true"><span class="ui-button-text">Eteindre</span></label>
</div>
<div id="radioset2" class="ui-buttonset">
Lumière 2 : 
<input type="hidden" name="housecode" value="11111"/>
<input type="hidden" name="num" value="2"/>
<input type="radio" id="radio3" name="radio2" class="ui-helper-hidden-accessible" value="1"><label for="radio3" class="ui-button ui-widget ui-state-default ui-button-text-only ui-corner-left" role="button" aria-disabled="false" aria-pressed="false"><span class="ui-button-text">Allumer</span></label>
<input type="radio" id="radio4" name="radio2" checked="checked" class="ui-helper-hidden-accessible" value="0"><label for="radio4" class="ui-button ui-widget ui-state-default ui-button-text-only ui-state-active" role="button" aria-disabled="false" aria-pressed="true"><span class="ui-button-text">Eteindre</span></label>
</div>
<div id="radioset3" class="ui-buttonset">
Lumière 3 : 
<input type="hidden" name="housecode" value="11111"/>
<input type="hidden" name="num" value="3"/>
<input type="radio" id="radio5" name="radio3" class="ui-helper-hidden-accessible" value="1"><label for="radio5" class="ui-button ui-widget ui-state-default ui-button-text-only ui-corner-left" role="button" aria-disabled="false" aria-pressed="false"><span class="ui-button-text">Allumer</span></label>
<input type="radio" id="radio6" name="radio3" checked="checked" class="ui-helper-hidden-accessible" value="0"><label for="radio6" class="ui-button ui-widget ui-state-default ui-button-text-only ui-state-active" role="button" aria-disabled="false" aria-pressed="true"><span class="ui-button-text">Eteindre</span></label>
</div>
<div id="radioset4" class="ui-buttonset">
Lumière 4 : 
<input type="hidden" name="housecode" value="11111"/>
<input type="hidden" name="num" value="4"/>
<input type="radio" id="radio7" name="radio4" class="ui-helper-hidden-accessible" value="1"><label for="radio7" class="ui-button ui-widget ui-state-default ui-button-text-only ui-corner-left" role="button" aria-disabled="false" aria-pressed="false"><span class="ui-button-text">Allumer</span></label>
<input type="radio" id="radio8" name="radio4" checked="checked" class="ui-helper-hidden-accessible" value="0"><label for="radio8" class="ui-button ui-widget ui-state-default ui-button-text-only ui-state-active" role="button" aria-disabled="false" aria-pressed="true"><span class="ui-button-text">Eteindre</span></label>
</div>
</body>
</html>

On va ensuite créer un fichier sendVal.php qui va recevoir les instructions des radio-boutons à envoyer via l'émetteur RF.
<?php
if(isset($_POST)){
if(isset($_POST['housecode']) &&
isset($_POST['numcode']) &&
isset($_POST['state'])){
$housecode = $_POST['housecode'];
$numcode = $_POST['numcode'];
$state = $_POST['state'];
$command = "sudo ./home/pi/rcswitch-pi/send ".$housecode." ".$numcode." ".$state;
system(escapeshellcmd($command));
echo 'ok';
}
}

?>

Envoyer le contenu du dossier dans le dossier /var/www de la RaspberryPI.
Saisir ensuite l'IP de la RaspberryPI dans un navigateur. La page avec les 4 radio-boutons devrait s'afficher.

Tester l'un des radio-boutons. Si cela fonctionne tant mieux! Sinon il faut aller jeter un œil dans les logs.
Personnellement j'avais une erreur d'authentification de l'utilisateur www-data (utilisateur de lighttpd). J'ai réglé cela en ajoutant dans le fichier /etc/sudoers :
www-data ALL=NOPASSWD: ALL

Re-tester, ca devrait fonctionner.

[RaspberryPI] Reconnexion wifi automatique

Grâce à un dongle wifi, la RaspberryPI (RPI) peut se connecter au réseau sans être relié par un câble Ethernet. Ceci permet de positionner sa carte n'importe ou à portée du signal wifi.

Certains utilisateurs, dont moi, ont remarqué qu'ils perdaient leur connexion wifi. Il faut alors débrancher et rebrancher la carte.

Pour éviter cela, il faut écrire un petit script qui va vérifier toutes les x minutes si la connexion est bien établie.
source : http://www.raspberrypi.org/phpBB3/viewtopic.php?t=16054

On va tout d'abord éditer un script shell qu'on placera dans le répertoire /root et qu'on nommera network-check.sh:

#!/bin/bash

while true ; do
   if ifconfig wlan0 | grep -q "inet addr:" ; then
      sleep 300 #300 secondes
   else
      ifup --force wlan0
      sleep 20
   fi
done


Il faut rendre le code éxecutable :
chmod +x network-check.sh

Ensuite on va exécuter le script au démarrage. Pour cela ouvrir le fichier /etc/rc.local et ajouter, avant la ligne exit 0, l'instruction suivante :
/root/network-check.sh &

Vous pouvez à présent rebooter la carte en tapant sudo reboot et votre carte récupérera le signal Wifi dans les 5 minutes qui suit.

mardi 21 mai 2013

Zoneminder, Ajouter une caméra IP à l'aide d'une Raspberry PI et d'une Webcam

Dans ce tutoriel, on va utiliser une Raspberry PI (RPI) comme caméra IP.
Pour cela on va brancher une Webcam en USB sur la RPI.
On peut soit utiliser le réseau filaire en branchant un câble Ethernet à la RPI (pas très utile), soit utiliser un dongle Wifi qui va permettre de la brancher près de n'importe quelle prise à portée du signal Wifi.

Une fois les branchement fait on démarre la RPI en connectant le câble d'alimentation. Si ce n'est pas déjà fait on la configure en autorisant la connexion SSH (si vous n'avez plus l'écran de configuration taper raspi-config dans le terminal. Il faudra évidemment débrancher un des périphériques USB et brancher un clavier).

A présent, on va se connecter en SSH depuis notre PC, en admettant avoir relevé l'adresse IP de la RPI précédemment, et en utilisant Putty ou autre.

Installer Motion qui va permettre de diffuser en streaming le flux vidéo de la caméra.

En local, on peut tester le bon fonctionnement en tapant http://ip-raspberry:8081/

On va à présent déclarer la nouvelle source vidéo sur Zoneminder. Pour cela :
1) Cliquer sur Add New Monitor
2) Sélectionner 'Remote' dans Source Type
3) Dans source, saisir l'adresse IP et le port et modifier la taille de l'entrée vidéo
4) Cliquer sur Save

La source doit maintenant être visible. En modifiant la fonction 'Modect', on peut activer la détection de mouvements.

Mise en place de ZoneMinder

Récupérer un vieux pc qui consomme peu de préférence puisqu'il sera tout le temps allumé. Personnellement j'ai récupéré un pc portable d'une amie avec l'écran cassé.

Ensuite, télécharger Ubuntu server ou une autre distribution qui vous chante. J'ai choisie Ubuntu car la documentation est riche sur le Net avec beaucoup de tutoriels. Créer votre Live CD et installer ceci sur votre pc de récupération.

Je passe toutes les étapes de configuration et de création de compte Linux car ceci et déjà très bien documenté.

Zoneminder utilise Apache Php et MySQL, il va donc falloir les installer (Choisir l'installation par paquets sur  ce tuto) et les configurer.

Ensuite il suffit d'installer Zoneminder. Brancher une Webcam et tester.

jeudi 9 mai 2013

Arduino motor shield + 2 servo-moteurs

Voici comment utiliser le Shield Arduino motor avec 2 servo-moteurs.

Le shield Arduino Motor est capable de piloter 2 moteurs à courant continu ou 1 moteur pas à pas à l'aide du courant fourni par une alimentation externe. De nombreux tutoriels explique comment utiliser ces fonctionnalités (voir http://www.instructables.com/id/Arduino-Motor-Shield-Tutorial/).

Ce shield permet également d'interfacer très facilement des capteurs ou des servo-moteurs grâce à ces 6 broches de 3 à 4 pins.
2 d'entre elles sont reliées à des pins PWM de l'arduino ce qui permet d'envoyer un signal entre 0 et 1024. Nous allons nous en servir pour nos servo-moteurs.

J'ai utilisé des servo-moteurs Emax ES08A dans mon exemple. J'ai du modifié la position des fils sur la broche pour correspondre aux pins sur le shield (de gauche à droite (rouge (+), jaune (analog), marron (-)).

Sur mon exemple j'ai branché 1 servo-moteur sur chaque broche orange du shield.

Il reste plus qu'à écrire le programme (J'ai utilisé l'exemple "sweep" et l'ai modifié pour l'adapter à mon exemple) :

// Sweep
// by BARRAGAN  
// modified by gpilot 
// This example code is in the public domain.

#include  
 
Servo myservo, myservo2;  // create servo object to control a servo 
                // a maximum of eight servo objects can be created 
 
int pos = 0;    // variable to store the servo position 
 
void setup() 
{ 
  Serial.begin(9600);
  myservo.attach(5);  // attaches the servo on pin 9 to the servo object 
  myservo2.attach(6);
} 
 
 
void loop() 
{ 
  for(pos = 0; pos < 170; pos += 1)  // goes from 0 degrees to 180 degrees 
  {                                  // in steps of 1 degree 
    myservo.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo2.write(pos);              // tell servo to go to position in variable 'pos' 
    Serial.println(pos);
    delay(10);                       // waits 15ms for the servo to reach the position 
  } 
  for(pos = 170; pos>=0; pos-=1)     // goes from 180 degrees to 0 degrees 
  {                                
    myservo.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo2.write(pos);              // tell servo to go to position in variable 'pos' 
    Serial.println(pos);
    delay(10);                       // waits 15ms for the servo to reach the position 
  } 
} 

mercredi 3 avril 2013

Forcer le redémarrage de Linux à l'aide de cron

Pour forcer le redémarrage d'un système Linux à l'aide de la crontab, on ouvre la crontab en tant que super-utilisateur :
sudo crontab -e
Et on ajoute l'entrée suivante pour redémarrer le système toutes les heures :
0 0 */1 * * sudo shutdown -r now 

mardi 26 février 2013

[Arduino] Uploader un programme après avoir séparé les pins d'auto-reset

Dans le précédent post, nous avons supprimer la connexion de 2 points sur la carte pour éviter le reboot au lancement du Serial.
Si vous avez fait cette manipulation sur une de vos carte ou si vous possédez une carte n'ayant pas d'auto-reset, vous vous rendrez compte rapidement que vous ne pourrez plus Uploader de sketch et que vous obtiendrez l'erreur suivante :
Téléchargement terminée 
avrdude: stk500_getsync(): not in sync: resp=0x00
Lorsque vous appuyer sur le bouton reset de la carte arduino, le Bootloader se lance et permet pendant un cours instant d'uploader un sketch sur la carte. En supprimant le point de soudure entre les 2 points nous avons enlevé la possibilité à la carte Arduino de faire un reset de manière automatique.
Il faut donc le faire manuellement.
Pour cela :
1) Appuyer sur le bouton reset de la carte Arduino
2) Cliquer sur le bouton Uploader du logiciel Arduino
3) Attendre que la Led RX clignote une fois
4) Relâcher immédiatement votre doigt du bouton reset (Si une autre Led clignote le temps de lacher le bouton il faudra recommencer)
5) Laisser le logiciel Uploader le sketch sur la carte Arduino

Si le message Téléchargement terminé s'affiche sans message d'erreur, votre sketch a été envoyé correctement sur la carte

[Arduino] Eviter le reset à l'ouverture du Serial

Pour éviter que la carte Arduino reboot à chaque ouverture du Serial, on peut supprimer le petit point de soudure entre 2 connexions sur la carte (voir ci-dessous).



lundi 25 février 2013

[Arduino] Lire une ligne Serial

On peut avoir besoin d'interagir via une carte Arduino par Serial (USB ou RXTX) en envoyant un ou plusieurs caractères.
Pour lire une ligne entrée dans le Serial, il suffit d'écrire le code suivant :


String msg;
int ledPin = 13;

void setup(){
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
}

void loop(){
  if(Serial.available() > 0){
    msg="";
    while (Serial.available()){
      delay(2);//Pour laisser le temps au buffer
      char c =Serial.read();
      msg += c;
    }
    Serial.println(msg);
  }
}


Ce code attend une entrée dans le Serial, lit les caractères entrés et les ré-écrit dans le Serial.

Cela permet par exemple d'allumer/éteindre une Led branchée sur l'arduino en fonction de l'entrée dans le Serial.

String msg;
int ledPin = 13;

void setup(){
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
}

void loop(){
  if(Serial.available() > 0){
    msg="";
    while (Serial.available()){
      delay(2);//Pour laisser le temps au buffer
      char c =Serial.read();
      msg += c;
    }
    if(msg.equals("on")){
      digitalWrite(ledPin, HIGH);
    }else if(msg.equals("off")){
      digitalWrite(ledPin, LOW);
    }
  }
}

Avec le code suivant : 
- en écrivant "on", vous allumerez la led sur la pin 13
- en écrivant "off", vous éteindrez la led sur la pin 13


vendredi 22 février 2013

[Windows] Installation de node.js + premier exemple

1) Aller sur http://nodejs.org/
2) Cliquer sur INSTALL
3) Créer un dossier dédier nodejs dans votre espace perso (C:/Users/[NOM_UTILISATEUR])
4) Copier l'exemple présent en bas de page et le coller dans un fichier example.js :
var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
5) Ouvrir un prompt (Attention si vous venez d'installer node.js et que vous aviez déjà un prompt d'ouvert il faudra en ouvrir un autre pour prendre en compte le PATH)
6) Aller dans le répertoire créé et taper la commande :
node example.js
7) Ouvrer un navigateur et taper http://127.0.0.1:1337/

jeudi 24 janvier 2013

C'est parti!

Un petit message de lancement pour la création de mon blog. Ce blog est destiné à conserver mes idées, trouvailles et autres sujets qui m’intéressent et les partager! Alors allons y!