Récupérer un flux RSS avec Arduino
Niveau : débutant
Grâce à l’API de Yahoo Weather Forecast, nous allons pouvoir récupérer la température en degrés celsius de pratiquement n’importe quelle ville du globe. Les données récupérées serviront changer la couleur d’une LED RGB sur une gamme de couleur représentant la température. En d’autres termes, nous allons faire un thermomètre lumineux !
Les données sont fournies au format XML (Extensible Markup Language) qui est un langage de balisage, il est couramment utilisé afin de structurer des données.
L’URL du flux XML que nous allons utiliser est la suivante http://weather.yahooapis.com/forecastrss?w=619163&u=c
Elle est composée du chemin d’accès à l’API Yahoo http://weather.yahooapis.com/forecastrss puis comporte ensuite deux arguments séparés par le caractère & :
- w=619163 correspond à l’ID de la ville sur laquelle on souhaite se baser (ici, Rennes), pour rechercher l’ID d’une ville, cliquez-ici
- u=c est relatif aux unités utilisées, ici le degré celsius à l’instar du fahrenheit
Comme on le constate sur l’image précédente, le fichier XML est organisé grâce à des balises possédant des attributs. Par exemple, temp est un attribut de la balise
Notre but est donc de récupérer ce flux XML depuis notre carte Arduino mais surtout cibler correctement l’information dont nous avons besoin. C’est l’étape de parsing (parser des données revient à extraire une ou plusieurs informations ciblées dans un ensemble de données).
Il existe plusieurs méthodes afin d’arriver au bon résultat. On peut parser des données manuellement ou bien, ce que nous allons faire ici, utiliser une librairie qui nous simplifiera la tâche. L’une des grandes forces du language Arduino et son extrême polyvalence et son extensibilité à l’aide de librairies écrites par la communauté, qui consistent en un ensemble de fonctions exécutants des tâches spécifiques. En d’autres termes, une librairie est un pack de Lego supplémentaire qui trouvera sa place sans aucun mal dans votre coffre à jouets informatique.
TextFinder (http://playground.arduino.cc/Code/TextFinder) nous aidera à extraire simplement l’information dont nous avons besoin dans le flux XML.
Téléchargez la librairie et copiez le dossier dans le répertoire des librairies d’Arduino.
Préparation du montage
Le montage ci-dessus représente une LED à anode commune reliée aux pins digitaux 3, 5, 6 de la carte Arduino. La résistance de 220 Ohms sur la masse permet de ne pas suralimenter la LED. Enfin, on notera l’utilisation de pins digitaux PWM (symbolisés par un le signe ~ à côté de leur numéro).
Ces pins sont particuliers puisqu’ils permettent la Power Width Modulation utilisée par la fonction analogWrite d’Arduino. Nous verrons leur utilité par la suite.
Test de la LED
Un programme Arduino comporte deux blocs principaux. La fonction setup exécutée une seule fois lors de la mise sous tension de la carte et la fonction loop dont le contenu est exécuté tant que la carte est sous tension.
Le programme que nous allons écrire permet de tester notre montage. Créez un nouveau sketch Arduino. La première étape consiste à déclarer les pins utilisés par notre LED, nous utilisons des variables afin de pouvoir changer par la suite ces pins si besoin, sans avoir à rectifier manuellement dans tout le programme les endroits où ils sont mentionnés.
1
2 3 4 |
//Déclaration des pins utilisés par la LED
int ledR = 6; int ledG = 5; int ledB = 3; |
Il n’y a pas besoin de déclarer ces pins comme étant des sorties (OUTPUT).
1
2 3 4 5 |
void setup(){// les pins utilisant analogWrite n’ont pas besoin d’etre déclarés en sorties}
|
Nous pouvons désormais écrire des valeurs de courant sur notre LED. Nous utilisons ici la fonction analogWrite, qui permettra par la suite de mixer les différentes intensités de Rouge Vert ou Bleu de notre LED afin d’en changer sa couleur.
1
2 3 4 5 6 |
void loop(){//Ecriture sur les pins de la LED
analogWrite(ledR, 64);} |
La LED est allumée en rouge à un quart de son intensité maximale. Les valeurs utilisées par la fonction analogWrite s’échelonnent de 0 à 255. Un premier exercice pourrait consister à mélanger les couleurs entre elles, par exemple :
1
2 3 4 |
//Ecriture sur les pins de la LED
analogWrite(ledR, 180); analogWrite(ledG, 200); analogWrite(ledB, 0); |
Ces valeurs me donnent du orange avec la LED que j’ai utilisée.
Déclaration d’une nouvelle fonction changement de couleur
Notre objectif principal et de colorer la LED en fonction de la température extérieure. Plutôt que d’écrire à chaque fois les couleurs manuellement, nous allons simplifier le processus à l’aide d’une fonction qui regroupera l’attribution des différentes intensités de rouge, vert, bleu en une seule ligne :
1
2 3 4 5 6 |
//Définition de la couleur grace à son code RGB
void setColor(int red, int green, int blue){ analogWrite(ledR, red); analogWrite(ledG, green); analogWrite(ledB, blue); } |
Connection à l’API Yahoo weather
Récupérer les informations météo est très simple. En effet, il s’agit d’une simple requête HTTP GET permettant de récupérer le contenu d’une page. L’API de Yahoo ne nécessite pas de s’authentifier afin de pouvoir accéder aux données. En revanche c’est le cas de certaines API comme celle de Twitter par exemple.
La suite du programme consiste à implémenter la récupération de la température en plusieurs étapes :
- Etablir une connexion entre Arduino et Internet
- Récupérer une page
- Parcourir la page et récupérer l’information dont on a besoin
- Stocker cette information
- Tester cette donnée et choisir la couleur de LED appropriée
- Recommencer
Fort heureusement, le langage Arduino est très bien conçu. La plupart des méthodes liées à la connexion à un réseau sont implémentées au travers d’une classe client qui est native au langage Arduino. Il existera donc très peu de nuances dans le programme pour utiliser ou bien un shield ethernet ou WiFi. Un shield ethernet sera utilisé pour fournir les explications de la suite de cet article, en revanche, les sketchs pour le shield WiFi sont également téléchargeables.
Reprenons le programme que nous avons précédemment écrit. On ajoute au tout début de ce dernier les librairies nécessaires :
1
2 3 |
#include <SPI.h>
#include <Ethernet.h> #include <TextFinder.h> |
On ajoute ensuite les paramètres nécessaires à l’initialisation d’une connection Ethernet
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
//Adresse MAC de la carte
byte mac[] = { 0xDE, 0xAF, 0xFF, 0xEF, 0xFE, 0xED};// initialize the library instance: EthernetClient client;//Adresse du serveur char server[] = « weather.yahooapis.com »;//Dernière connection au serveur en ms unsigned long lastConnectionTime = 0;//Etat de la connection boolean lastConnected = false;//délai entre chaque connection en ms (1mn) const unsigned long postingInterval = 60*1000; |
Le bloc d’instructions suivant est à placer dans le setup et permet l’initialisation de la connection
1
2 3 4 5 6 7 8 9 10 11 12 |
//Initialisation du port série, utile au débuggage
Serial.begin(9600);//Délai afin d’itnialiser correctement le module ethernet delay(1000);//Initialisation de la connection ethernet, attribution automatique d’une IP via DHCP Ethernet.begin(mac);//On affiche l’adresse IP du module Serial.print(« IP address: « ); Serial.println(Ethernet.localIP()); |
Passons maintenant au corps du programme
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
void loop(){//Les données sont envoyées sur le port série pour affichage
if (client.available()) { char c = client.read(); Serial.print(c); }//Si il n’y a pas de connection mais qu’il y en avait une lors de la dernière execution du loop //on arrete le client if (!client.connected() && lastConnected) { Serial.println(); Serial.println(« disconnecting. »); client.stop(); }//si il n’y a pas de connection mais que 10 secondes se sont écoulées depuis la dernière connection //on essaye de nouveau if(!client.connected() && (millis() – lastConnectionTime > postingInterval)) { httpRequest(); } //on stocke l’état de la connection lastConnected = client.connected();} |
Déclarons maintenant la fonction permettant de faire une requête HTTP
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
//fonction permettant d’effectuer une requete HTTP
void httpRequest() { // si la connection est réussie if (client.connect(server, 80)) { Serial.println(« connecting… »); // on envoie le HTTP GET client.println(« GET /forecastrss?w=12724564&u=c HTTP/1.0 »); client.println(« Host: weather.yahooapis.com »); client.println(« User-Agent: arduino-ethernet »); client.println(« Connection: close »); client.println();//on stock le moment de la dernière connection lastConnectionTime = millis(); } else { //si la connection échoue Serial.println(« connection failed »); Serial.println(« disconnecting. »); client.stop(); } } |
A ce stade, vous devriez voir grâce au moniteur série le contenu du fichier XML récupéré par la carte, il reste à parser les données afin de récupérer uniquement la température, c’est là qu’intervient TextFinder. Cette librairie permet de parcourir la page en fonction des balises que nous lui aurons demandé de cibler. Nous allons donc cibler l’attribut temp pour récupérer la température
Au début du programme sous EthernetClient, rajoutons l’instruction suivante qui a pour but d’initialiser l’objet client utilisé par la librairie
1
|
TextFinder finder( client );
|
La suite est un jeu d’enfant puisqu’elle tient en quelques lignes, c’est là qu’opère la magie d’Arduino, nous allons dans un premier temps déclarer une nouvelle variable globale (à la suite des déclarations de la LED par exemple) permettant de stocker la température
1
|
int temp;
|
On intègre ensuite à la fonction httpRequest le code magique permettant de récupérer la température, à placer en dessous de lastConnectionTime = millis();
1
2 3 4 5 6 7 8 9 10 11 |
// On cherche l’attribut temp
if(finder.find(« temp= ») ){ //On stocke la valeur voulue dans la variable temp temp = finder.getValue(); //On affiche cette valeur à des fins de débuggage Serial.print(« Temp C: « ); Serial.println(temp); } else{ Serial.print(« Pas de donnees »); } |
Nous allons commenter la portion de code suivant dans la boucle loop afin de ne pas être submergés d’informations dans le moniteur série
1
2 3 4 5 6 7 8 9 |
/*//Les données sont envoyées sur le port série pour affichage
if (client.available()) { char c = client.read(); Serial.print(c); }*/ |
Compiler et uploader le code sur la carte pour voir le résultat dans le moniteur série. Une précision IMPORTANTE, il faut changer le délai d’actualisation à 5 secondes pour obtenir un résultat immédiatement, en effet, les 60 secondes originales sont un délai plus qu’acceptable car la température ne change pas si rapidement, cependant, lorsque la carte est mise sous tension, le programme attend 60 secondes avant d’effectuer la première requête !
Test de la température et changement de couleurs
Souvenons nous de la fonction que nous avons écrit précédemment, setColor… c’est le moment de l’utiliser ! Il va falloir tester la température pour voir si il fait chaud ou froid. Commençons avec nos trois couleurs, rouge pour chaud, vert pour tempéré et bleu pour froid. Placer le code suivant à la fin du loop
1
2 3 4 5 6 7 8 9 10 11 12 13 14 |
//Si la température est inférieure ou égale à 15 degrès…
if(temp <= 15){ setColor(0, 0, 255); //Bleu }//Si la température est supérieure ou égale à 25 degrès… else if(temp >= 25){ setColor(255, 0, 0); //Rouge }//Si la température est supérieure à 15 degrès ou inférieure à 25 degrès… else if(temp > 15 || temp < 25){ setColor(0, 255, 0); //Vert } |
Vous venez de visualiser une donnée de manière tangible grâce à un actionneur. A vous de définir votre propre couleur en nuançant les couleurs par exemple, effets de fading sur la LED…
Récupérer un flux RSS avec Arduino (sans shield)
Niveau: débutant
Cet article à pour but d’atteindre le même objectif que l’article précédent, c’est à dire récupérer un flux RSS (température en degrés celsius de pratiquement n’importe quelle ville du globe) pour changer la couleur d’une LED RGB sur une gamme représentant la température. En d’autres termes, nous allons réaliser un thermomètre lumineux, cette fois-ci sans aucun shield. Il est fortement recommandé d’avoir lu l’article mentionné précédemment afin de comprendre la suite. En effet, je ne détaillerai pas de nouveau certaines étapes expliquées auparavant.
Nous allons remplacer le shield Ethernet ou WiFi par un programme Processing qui effectuera la requête puis l’enverra à Arduino en passant par la liaison série. Attention toute fois, cette technique nécessite que la carte soit reliée en permanence via USB.
Le flux RSS fourni par Yahoo est au format XML, ce qui est pratique car il permet une structure standardisée et intègre. Le XML organise les informations sous la forme d’une arborescence. Yahoo fourni un flux au format RSS (Really Simple Syndication) qui est une standardisation du format XML permettant de syndiquer du contenu web (news, articles…).
Merci de vous référer à l’article précédent afin de comprendre comment utiliser le flux RSS de Yahoo.
Processing
Parsing XML
Processing possède un objet XML representant les élements d’une arborescence XML. Quand un document est chargé, cet objet XML est toujours l’élément racine. On peut ainsi obtenir la température en passant par les étapes suivantes :
- La racine est le RSS
- RSS possède un enfant nommé channel
- channel possède un enfant nommé item
- item possède un enfant nommé yweather:condition
- La température se trouve dans l’attribut temp de yweather:condition
On peut traduire ces étapes avec le code Processing suivant:
1
2 3 |
XML root = loadXML(« http://xml.weather.yahoo.com/forecastrss?w=12724564&u=c »); // Etapes 1
XML condition = root.getChild(« channel »).getChild(« item »).getChild(« yweather:condition »); // Etapes 2-4 int temperature = condition.getInt(« temp »); //On stocke la température dans une variable temperature |
Remarque: ces instructions sont valables pour n’importe quel flux RSS d’où l’avantage de leur standardisation ! Il faudra bien sûr adapter l’adresse du flux en question et les éléments de son arborescence en fonction de vos besoins
La température est stockée dans la variable temperature, c’est elle que nous allons envoyer à Arduino via le port série.
Il faut préalablement importer la librairie permettant d’utiliser ces fonctionnalités:
1
2 3 4 |
//Import de la librairie Serial P5
import processing.serial.*;Serial myPort; // Création de l’objet serial |
On initialise ensuite la connexion dans le setup du programme:
1
2 3 4 5 6 7 8 |
void setup()
{ size(200, 200); print(Serial.list()); //On affiche la liste des ports séries disponibles String portName = Serial.list()[5]; //On utilise le port série correspondant à notre carte Arduino branchée en USB myPort = new Serial(this, portName, 9600); //On initialise la connection frameRate(25); //On définit le frameRate à 25 FPS } |
Remarque :Pensez à sélectionner le port série utilisé par votre carte Arduino, l’instruction print(Serial.list()); permet d’afficher la liste des ports disponibles sur votre machine
Afin d’actualiser le flux XML (donc la température) nous allons avoir besoin d’effectuer une requête de manière périodique, il existe plusieurs méthodes pour y parvenir. Le but de cet article n’est pas d’utiliser la manière la plus précise mais la plus rapide. Nous allons donc établir un frameRate fixe (à 25 images par secondes) qui nous servira de référence tout au long de l’éxecution de notre programme. Ainsi nous pourrons par exemple faire une requête toutes les 10 secondes. Une manière plus appropriée serait d’utiliser la fonction millis() qui permet de connaître de façon précise à un instant T le nombre de millisecondes écoulées depuis le début du programme.
Passons maintenant à notre boucle principale:
1
2 3 4 5 6 7 8 9 |
void draw() {
if (frameCount % 250 == 0) { //On entre dans la boucle toutes les 10 secondes (250 frames) XML root = loadXML(« http://xml.weather.yahoo.com/forecastrss?w=12724564&u=c »); // Etapes 1 XML condition = root.getChild(« channel »).getChild(« item »).getChild(« yweather:condition »); // Etapes 2-4 int temperature = condition.getInt(« temp »);myPort.write(temperature); //On écrit la valeur de temperature sur le port série } } |
Le programme que nous avons écrit permet donc d’éxécuter une requête sur le flux RSS de Yahoo Weather environ toutes les 10 secondes pour envoyer la température à Arduino via la liaison série.
Arduino
Le montage ci-dessus représente une LED à anode commune reliée aux pins digitaux 3, 5, 6 de la carte Arduino. La résistance de 220 Ohms sur la masse permet de ne pas suralimenter la LED. Enfin, on notera l’utilisation de pins digitaux PWM (symbolisés par un le signe ~ à côté de leur numéro).
Notre but est de changer la couleur de la LED en fonction de la température relevée par le programme Processing, pour ce faire, commençons par déclarer quelques variables:
1
2 3 4 5 6 7 |
//Déclaration des pins utilisés par la LED
int ledR = 6; int ledG = 5; int ledB = 3;int temp; //La variable qui stockera la température int incomingByte = 0; //variable pour les données provenant du port série |
On peut ensuite initialiser la liaison série dans notre boucle setup:
1
2 3 4 |
void setup(){
//Initialisation du port série Serial.begin(9600); } |
Il convient maintenant de programmer la partie relative à la réception des données:
1
2 3 4 5 6 7 8 9 10 |
void loop(){//Si l’on reçoit des données
if (Serial.available() > 0) { //On lit le byte qui arrive sur le port série incomingByte = Serial.read();//On le stocke dans la variable temp temp = incomingByte; } |
Une fois la donnée reçue, on peut effectuer un test sur celle-ci afin de choisir la couleur correspondante:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
//Si la température est inférieure ou égale à 15 degrès…
if(temp <= 15){ setColor(0, 0, 255); //Bleu }//Si la température est supérieure ou égale à 25 degrès… else if(temp >= 25){ setColor(255, 0, 0); //Rouge }//Si la température est supérieure à 15 degrès ou inférieure à 25 degrès… else if(temp > 15 || temp < 25){ setColor(0, 255, 0); //Vert }} |
Enfin, la fonction permettant le changement de couleur:
1
2 3 4 5 6 |
//Définition de la couleur grace à son code RGB
void setColor(int red, int green, int blue){ analogWrite(ledR, red); analogWrite(ledG, green); analogWrite(ledB, blue); } |
Vous pouvez désormais envoyer le programme sur la carte. Une fois le téléversement terminé, lancez le programme Processing et regardez la LED s’illuminer !
Remarque: cet article est en partie basé sur l’excellent tutoriel lié au parsing de données avec Processing
Twitter pt. 1 : Suivi d’un hashtag
Niveau : intermédiaire
Cet article aboutira à la réalisation d’un système de notification Twitter tangible. En étant à l’écoute des nouveaux tweets postés sur un certain hashtag, nous pourrons faire bouger un servomoteur à la réception de nouveaux tweet. Cet article s’adresse à un public déjà averti qui possède une culture du web et de la programmation. Nous utiliserons ainsi l’API de Twitter, un script PHP, un shield Ethernet pour Arduino ainsi qu’un servomoteur
Inscription à l’API de Twitter
Avant de nous lancer dans le script PHP permettant d’exploiter l’API de Twitter de manière rapide et surtout très simple, il est nécessaire de posséder un compte Twitter et créer une application associée à ce compte en allant sur https://dev.twitter.com
Cliquez sur « Create a new application« , donnez un nom à votre application puis saisissez votre site internet (dans notre cas, nous n’avons pas besoin d’URL de callback). Vous voilà désormais l’heureux propriétaire d’une application Twitter vous permettant d’utiliser OAuth, le protocole d’authentification de Twitter.
Cliquez sur votre application nouvellement créé pour récupérer les éléments suivants :
- Consumer key
- Consumer secret
- Access token
- Access token secret
Il me semble qu’a la première utilisation les access token n’existent pas encore et qu’il est nécessaire de cliquer sur le bouton permettant de les générer. Votre application Twitter est prête !
Nous allons écrire un petit programme en PHP qui permettra de détecter tout les Tweets contenants le hashtag #data lorsqu’il sera appelé par le sketch Arduino. Afin d’y parvenir, il vous faudra disposer d’un espace web capable d’interpréter du PHP ou bien une application pour faire la même chose en local EasyPHP (Windows) ou MAMP (OS X). Nos amis Linuxiens disposent sans doute déjà d’Apache installé sur leur distribution.
Si vous n’avez pas encore eu l’occasion d’utiliser ces logiciels, je vous invite à lire le guide d’introduction à EasyPHP ou MAMP
Programme PHP
La page que nous allons écrire en PHP permet d’effectuer une unique requête sur la Twitter Search API Vous devez sans doute vous demander comment pourra t’on être au courant de nouveaux Tweets ? Et bien c’est très simple, notre programme Arduino effectuera une requête HTTP GET périodique sur cette page et comparera le nouveau résultat à l’ancien résultat, si différence il y a, nouveau Tweet en vue !
Remarque : vous l’aurez compris, ce n’est donc pas du temps réel, c’est ce que l’on appelle du polling. Nous verrons dans un prochain article comment utiliser la Twitter Streaming API pour faire la même chose en temps réel.
Passons donc au code. Afin de nous simplifier la tâche sans avoir à implémenter toutes les méthodes liées à la construction d’une requête à l’API search de Twitter, nous allons utiliser un wrapper PHP disponible à cette adresse
Une fois téléchargée, créez un nouveau dossier sur votre serveur ou dans votre répertoire local de travail MAMP ou EasyPHP, appelons-le twitter puis placer les fichiers composer.json, index.php et TwitterAPIExchange.php dans un sous-répertoire nommé api.
Nous allons maintenant créer le fichier request.php qui nous permettra de faire notre recherche sur l’API
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
<?php//On formate le texte en UTF-8 pour éviter les problèmes d’encodage
header(‘Content-Type: text/html; charset=utf-8’);//Inclusion du oAuth Wrapper PHP require_once(‘./api/TwitterAPIExchange.php’);/** Déclaration des tokens, à mettre entre les guillemets – a voir sur: https://dev.twitter.com/apps/ **/ $settings = array( ‘oauth_access_token’ => « », ‘oauth_access_token_secret’ => « », ‘consumer_key’ => « », ‘consumer_secret’ => « » );//On spécifie l’URL de l’API que l’on utilise $url = ‘https://api.twitter.com/1.1/search/tweets.json’;//Construction de la requête, doc sur https://dev.twitter.com/docs/api/1.1/get/search/tweets for params $getfield = ‘?q=HASHTAG_A_SUIVRE+exclude:retweets&count=1&result_type=recent&geocode=48.85661,2.35222,2000km’;//La requête ne comporte pas beaucoup de paramètres, on utilise donc la méthode GET au lieu de POST $requestMethod = ‘GET’;//Initialisation de la connection à l’API Twitter $twitter = new TwitterAPIExchange($settings); $response = $twitter->setGetfield($getfield) ->buildOauth($url, $requestMethod) ->performRequest(); //Decodage de la réponse JSON founrie par Twitter //On définit arbitrairement une balise qui rendra plus facile le parsing sur Arduino //On print le Tweet //On ferme le tag ?> |
Vous pouvez maintenant tester si celà fonctionne pour vous en pointant votre navigateur sur la page request.php qui vous indiquera le dernier tweet contenant le mot-clé de votre choix
Remarque : n’oubliez pas de bien compléter vos access tokens (lignes 11 à 14) ainsi que remplacer HASHTAG_A_SUIVRE par le hashtag de votre choix (ligne 21)
Ecriture du programme Arduino
L’image ci-dessus représente comment raccorder un servomoteur à une carte Arduino
Je ne traiterai pas dans cette partie des étapes relatives à l’initialisation d’une connection avec Arduino qui ont déjà été abordées dans un précédent article, en revanche j’expliquerai toutes celles liées au parsing de nos données Twitter. Je suppose également que vous avez déjà utilisé un servomoteur avec Arduino, si ce n’est pas le cas, rendez-vous sur cette page
Ouvrons un nouveau sketch Arduino pour y placer le code suivant (les commentaires sont directement dans le code !)
1
2 3 4 5 6 7 8 |
#include <SPI.h>
#include <Ethernet.h> #include <Servo.h>//Paramètres du servomoteur attention à bien utiliser un pin PWM pour le servo ! int servoPin = 9; int sAngle = 50; Servo servo; |
On utilise ici la librairie servo car nous en avons besoin pour contrôler notre servomoteur relié au pin pwm 9
1
2 3 4 |
//Parsing
String readStr; String tweet; String lastTweet; |
Ce sont ces variables qui vont nous permettre de parser manuellement notre chaine de caractères. Souvenez-vous, nous avons défini une balise tweet dans notre script PHP. Les string tweet et lastTweet permettront la comparaison du tweet extrait d’une requête précédente et celle en court
1
2 3 4 5 6 7 8 9 10 11 |
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};EthernetClient client;//URL du serveur sur lequel votre script PHP est hebergé char server[] = « www.defidataplus.net »;unsigned long lastConnectionTime = 0; boolean lastConnected = false; const unsigned long postingInterval = 10L*1000L; |
A noter ici qu’il est important de changer l’URL du serveur par la votre ainsi que le postingInterval si vous le souhaitez. Attention cependant à ne pas faire de requête trop souvent pour ne pas dépasser le rate limit imposé par l’API Twitter, nous nous affranchirons de ce problème dans la version Twitter temps réel
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
void setup() {
Serial.begin(9600); delay(1000); Ethernet.begin(mac);Serial.print(« My IP address: « ); Serial.println(Ethernet.localIP());//On attache le servomoteur au PIN définit plus haut servo.attach(servoPin); //Position de départ à 5 degrès servo.write(5); delay(500);} |
Passons désormais au corps du programme
1
2 3 4 5 6 7 8 9 10 11 12 13 |
void loop() {while (client.available()) {
char c = client.read();//On stocke tout les caractères issus de la requete HTTP dans une String readStr.concat(c); }if (!client.connected() && lastConnected) { Serial.println(); Serial.println(« disconnecting. »); client.stop(); |
La partie suivante est très importante puisque c’est elle qui va nous permettre d’extraire uniquement le texte du Tweet
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
//On cherche la position dans la string readStr des début et fin du Tweet pour pouvoir nettoyer la string après
int tweetBegin = readStr.lastIndexOf(« <tweet> ») + 7; int tweetEnd = readStr.indexOf(« </tweet> »);//On extrait le tweet qui est entre nos deux balises tweet tweet = readStr.substring(tweetBegin, tweetEnd);Serial.println(tweet);//On vérifie si le tweet courant est différent du précédent if (tweet != lastTweet) { Serial.println(« le tweet est nouveau ! »);//On bouge le servo servoMove(); }lastTweet = tweet;}if(!client.connected() && (millis() – lastConnectionTime > postingInterval)) { httpRequest(); } lastConnected = client.connected(); } |
Il nous reste désormais à définir nos deux fonctions permettant d’effectuer la requête HTTP ainsi que les mouvements du servomoteur
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
//Fonction permettant de faire bouger le servo
void servoMove(){ servo.write(175); delay(5000); servo.write(5); }void httpRequest() {//On vide la string permettant la lecture readStr = « »;if (client.connect(server, 80)) { Serial.println(« connecting… »); //On effectue la requete GET sur la page request.php client.println(« GET /twitter/request.php HTTP/1.1 »);//Attention à bien remplacer le Host par le votre client.println(« Host: www.defidataplus.net »); client.println(« User-Agent: arduino-ethernet »); client.println(« Connection: close »); client.println();lastConnectionTime = millis(); } else { Serial.println(« connection failed »); Serial.println(« disconnecting. »); client.stop(); } } |
Vous pouvez désormais uploader le sketch sur votre carte Arduino et attacher un petit drapeau en papier au bout de votre servomoteur !
—
LED controlé depuis adresse IP
besoin : ethernet shield
#include <SPI.h>
#include <Ethernet.h>
static byte mac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 }; // mac-adresse unique pour le réseau
IPAddress ip(192,168,0,80); // adresse IP locale
EthernetServer server(80); //server port 80
String readString;
int ledverte = 5;
int ledjaune = 6;
int ledrouge = 7;
boolean vert, jaune, rouge ;
void setup()
{ pinMode(ledverte, OUTPUT);
pinMode(ledjaune, OUTPUT);
pinMode(ledrouge, OUTPUT);
Ethernet.begin(mac, ip);
server.begin();
}
void loop()
{ EthernetClient client = server.available();
if (client)
{ while (client.connected())
{ if (client.available())
{ char c = client.read();
if (readString.length() < 100)
{ readString += c; } // concatenation des caracteres lus
if (c == '\n') // fin de message
{ client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.println("<html>");
client.println("<head>");
client.println("<TITLE>Arduino YLC</TITLE>");
client.println("</head>");
client.println("<body bgcolor='#cccccc'>");
client.println("<H1 align='center'>Commande leds par internet</H1>");
client.println("<H3 align='center'>Tp semaine 13 (YLC)</H3>");
client.println("<hr />");
client.println("<p align='center'>");
client.println("     ");
client.println("<a href=\"/?onvert\"\">Allumer led verte</a>");
client.println("     ");
client.println("<a href=\"/?offvert\"\">Eteindre led verte</a><br /></p>");
client.println("<p align='center'>");
client.println("<a href=\"/?onjaun\"\">Allumer led jaune</a>");
client.println("     ");
client.println("<a href=\"/?offjaun\"\">Eteindre led jaune</a><br /></p>");
client.println("<p align='center'>");
client.println("<a href=\"/?onroug\"\">Allumer led rouge</a>");
client.println("     ");
client.println("<a href=\"/?offroug\"\">Eteindre led rouge</a><br /></p>");
client.println("</body>");
client.println("</html>");
if(readString.indexOf("?onvert") >0)
{ digitalWrite(ledverte, HIGH);
vert = true; }
if(readString.indexOf("?offvert") >0)
{ digitalWrite(ledverte, LOW);
vert = false ; }
if(readString.indexOf("?onjaun") >0)
{ digitalWrite(ledjaune, HIGH);
jaune = true ; }
if(readString.indexOf("?offjaun") >0)
{ digitalWrite(ledjaune, LOW);
jaune = false ; }
if(readString.indexOf("?onroug") >0)
{ digitalWrite(ledrouge, HIGH);
rouge = true ; }
if(readString.indexOf("?offroug") >0)
{ digitalWrite(ledrouge, LOW);
rouge = false ; }
client.println("<br /><p align='center'>Etat des leds :   ");
if (vert) client.println("<FONT color='green'>█");
else client.println("☼");
client.println("</FONT>     ");
if (jaune) client.println("<FONT color='yellow'>█");
else client.println("☼");
client.println("</FONT>     ");
if (rouge) client.println("<FONT color='red'>█");
else client.println("☼");
client.println("</FONT></p>");
readString = "";
delay(1);
client.stop();
}
}
}
}
}