Projet IMA3 P5, 2015/2016, TD1

De Wiki de Projets IMA
Révision datée du 26 février 2016 à 17:33 par Fduport (discussion | contributions) (Partie informatique)

Projet IMA3-SC 2015/2016 : Sonde Thermique

Cahier des charges

L'objectif de notre projet SC est de réaliser un objet connecté qui permettra de relever la température dans un lieu donné. Une LED s'allumera en fonction de la température et de l'encadrement saisi par l'utilisateur sur l'application. Un affichage tricolore sera utilisé pour indiquer l'état thermique actuel selon le code couleur : ROUGE pour un dépassement de la plus grande des valeurs saisies, VERT pour une température respectant l'encadrement et BLEU sinon.

L'interface WEB permettra à l'utilisateur de saisir les valeurs supérieure et inférieure de température avant le déploiement de l'objet, puis affichera celles-ci ainsi que la température mesurée.


Le matériel

  • la nanoBoard FPGA
  • la RaspBerry PI
  • une Arduino
  • 3 LEDs de couleur unique (Rouge, Vert et Bleu) ou une LED RGB
  • un capteur de température
  • PCs et logiciels nécessaires au développement du projet


Optionnel

Ajouter des afficheurs sept segments pour que la valeur exacte de la température apparaisse sur l'objet connecté.

Séance 1

Partie électronique

Conversion Analogique-Numérique

Dans le circuit électronique, nous allons utiliser un capteur de température de type analogique. Ce capteur sera connecté à la carte arduino dans un premier temps puis à une carte FPGA dans un second temps. L'arduino possède des ports capables de recevoir des données analogiques et effectue donc la conversion automatiquement, mais pas la FPGA. On aura donc besoin de rajouter un convertisseur analogique-numérique (CAN ou ADC en anglais).

Deux possibilités se sont présentées à nous :

  • Réaliser le convertisseur sur la carte FPGA. Il faudrait pour cela utiliser un comparateur auquel on envoie deux tensions : une tension analogique de référence, la sortie du capteur, et une autre que l'on augmente petit à petit à l'aide d'un compteur. Lorsque celle-ci atteint la tension de référence, la conversion s'arrête et la valeur du compteur est l'équivalent numérique de la tension de référence.
  • Connecter la sortie du capteur à un composant conçu pour réaliser la conversion et récupérer sa sortie numérique.

Nous avons fait le choix d'utiliser un composant, que nous avons commandé auprès du magasin électronique de Polytech'Lille. Le ADC0820BCNA+ correspondait à ce que nous recherchions.

Schéma du composant

Nous avons également récupéré sa datasheet qui nous permettra de déterminer comment le connecter au circuit.

En étudiant celle-ci, nous avons déduit le fonctionnement du composant :

Envoyer 0 à RD si on souhaite commencer la conversion.
La conversion s'effectue.
Lorsqu'elle est terminée, le composant envoie 0 sur INT.
On peut lire les bits de sortie (DB0, ... DB7).
On envoie 1 à RD lorsqu'on a terminé.
Quand RD est mis à 1, INT aussi est mis à 1 automatiquement.
On peut de nouveau effectuer une conversion.

On connectera donc le composant comme sur le schéma ci-dessous.

Schéma du composant connecté

Partie informatique

Nous avons commencé par installer la bibliothèque Web 2.0 JQuery puis une bibliothèque C de Websocket sur le poste qui nous a été attribué en salle info. JQuery nous permettra de lancer des requêtes HTTP asynchrones et de faciliter la programmation JavaScript, tandis que Websocket servira à créer un serveur embarqué sur la Raspberry avec lequel nous communiquerons depuis la page web.

Simulation sur ARDUINO

  • Dans un premier temps, un schéma général du fonctionnement de notre système a été réalisé sur le logiciel logisim. Nous considérons dans ce modèle que l'entrée (capteur de température) arrivait convertie en binaire. Nous avons ainsi simulé l'allumage des LEDs en fonction de la valeur d'entrée et des températures de seuil. Ici, nous avons imposé les valeurs de 5 et 20, soient 0x05 et 0X14 en héxadécimal. Voici un petit gif de la simulation :
Animation réalisée à partir d'un circuit construit sur Logisim.

Il est à noter que dans cette simulation, les résistances du montage ne sont pas représentées. Par la suite, n'ayant pas à notre disposition de LED de couleur BLEUE, nous utiliserons pour les montages une LED de couleur JAUNE en compensation.

  • Dans un deuxième temps, le câblage a été réalisé sur l'arduino RedBoard. Cette fois-ci, les résistances ont été incluses ainsi que le capteur de température. Le capteur de température est connecté au pin analogique 0 : le pin central va sur A0. Les autres pins sont reliés à 5V et à la masse. La première LED1 est connectée au pin 9 et à la masse, la LED2 au pin 10 et à la masse et la LED3 au pin 11 et à la masse. Voici une photographie du montage :
Photographie du montage.

Le code Arduino suivant a ensuite été réalisé :

const int analogInPin = A0; //capteur de température
const int LED1 = 9;
const int LED2 = 10;
const int LED3 = 11;

 //On impose des valeurs de seuil pour réaliser les tests
const int inferieur = 10;
const int superieur = 60;

int sensorValue = 0; //valeur lue par le capteur de température
int outputValue = 0; //valeur de sortie (LED)

void setup() {
 // initialisation
 pinMode(LED1,OUTPUT);
 pinMode(LED2,OUTPUT);
 pinMode(LED3,OUTPUT);
}

void loop() {
 // lecture de la valeur analogique
 sensorValue = analogRead(analogInPin);

 //restriction de l'intervalle
 outputValue = map(sensorValue,0, 1023, 0, 255);

  //ligne à rajouter afin de simuler une variation de la valeur convertie du capteur
 //outputValue = 80;

 if(outputValue < inferieur)
 {
   digitalWrite(LED1,HIGH);
 }

 if(outputValue > superieur)
 {
   digitalWrite(LED3,HIGH);
 }

 if((outputValue <= superieur) && (outputValue >= inferieur))
 {
   digitalWrite(LED2,HIGH);
 }
 
 delay(100);
 
}

La fonction map s'utilise de la manière suivante : map(valeur, limite_basse_source, limite_haute_source, limite_basse_destination, limite_haute_destination). Or ici, nous passons d'une valeur allant de 0 à 1023 à une valeur allant de 0 à 255.

Les LEDs s'allument bien en fonction des valeurs prises par le capteur de température.

Protocoles de communication

Nous nous sommes aussi intéressés aux protocoles de communication entre les différentes entités de notre projet (ordinateur et momentanément arduino). Nous avons donc réalisé le protocole de communication de l'arduino vers le PC et étudié la communication du PC vers l'arduino. C'est à dire la transmission plus que la réception. Pour cela nous avons dû définir les données à transmettre et leur sens.

L'arduino calcule elle-même la position de la température vis à vis des bornes que l'utilisateur donne, il suffit donc de renvoyer la température afin de faire un affiche sur l'interface utilisateur.

Le PC doit lui envoyer l'encadrement de température désiré (Temp_min et Temp_Max) ainsi que la décision de faire fonctionner le système de détection (Depart_Arret).

//Inserer ici le Tableau

Le code ARDUINO est simple mais peut-être compléter pour envoyer une information seulement lorsque le programme fonctionne ou que la température change :

void setup()
{
 Serial.begin(9600) 
}

void loop() 
{
  Serial.write(temp); // envoi de la température 
}

Séance 2

Partie électronique

Partie informatique

Communication Port Serie

Sur cette séance, nous avons terminé la programmation des protocoles de connexion entre le pc et la carte ARDUINO. Nous avons ainsi modifié le programme ".ino" principalement en rajoutant les méthodes de type Serial :


void setup() {
 // initialisation
 pinMode(LED1,OUTPUT);
 pinMode(LED2,OUTPUT);
 pinMode(LED3,OUTPUT);

 Serial.begin(9600); // début de la communication
}

void loop() {

if(Serial.available()>0) // si il y'a une donnée en attente de lecture sur le bus
{
 inferieur =Serial.read(); // on lit la première donnée en attente correspondant à la borne inférieure de température.
 superieur = Serial.read(); // on lit la seconde donnée en attente correspondant à la borne supérieure de température.
}

// lecture de la valeur analogique
sensorValue = analogRead(analogInPin);

digitalWrite(LED1,LOW);
digitalWrite(LED2,LOW);
digitalWrite(LED3,LOW);

//restriction de l'intervalle
outputValue = map(sensorValue,0, 1023, 0, 255);
Serial.write(outputValue); // On met sur le bus de données la valeur de sortie du 
                           //capteur ne correspondant pas a la température mais a une valeur de tension
//Serial.write(inferieur);
//Serial.write(superieur);

if(outputValue < inferieur)
{
  digitalWrite(LED1,HIGH);
  digitalWrite(LED2,LOW);
  digitalWrite(LED3,LOW);
}

else if(outputValue > superieur)
{
  digitalWrite(LED1,LOW);
  digitalWrite(LED2,LOW);
  digitalWrite(LED3,HIGH);
}

else if((outputValue <= superieur) && (outputValue >= inferieur))
{
  digitalWrite(LED1,LOW);
  digitalWrite(LED3,LOW);
  digitalWrite(LED2,HIGH);
}

delay(1000);

}

Nous avons aussi forcé les LEDs à l'état haut ou bas selon les conditions réalisées ce qui rend le programme interactif avec de nouvelles données envoyées par l'ordinateur. Chaque fois que le PC enverra des données et une fois par seconde maximum la carte ARDUINO enregistre les données pour les bornes de température. Toutes les secondes l'arduino vérifie la température la compare aux bornes et l'envoi au PC.

Pour la communication du point de vue PC, nous avons adapté le programme exemple selon nos besoins. La carte ARDUINO est en fonctionnement donc l'utilisateur peut exécuter le programme. Il rentre la borne inférieure puis la borne supérieure de l'encadrement de température. Alors le programme en C met l'encadrement sur le bus de données à destination de l'ARDUINO. Puis tant que l'on n’arrête ni le programme ni l'ARDUINO, le programme relève la donnée de température sur le bus et l'affiche

int main(void){
unsigned char temp_min=0,temp_max=0,temp =0;
int sd=serialOpen(SERIAL_DEVICE,SERIAL_BOTH);
serialConfig(sd,B9600);
printf("Rentrez la température inferieure :");
scanf("%hhd", &temp_min);
printf("Rentrez la température superieure :");
scanf("%hhd", &temp_max);
//envoyer la température min
if(write(sd,&temp_min,sizeof(char))!=1){ perror("main.write"); exit(-1); }
//envoyer la température max
if(write(sd,&temp_max,sizeof(char))!=1){ perror("main.write"); exit(-1); }


// Lecture des données envoyées
while(1)
{
 if(read(sd,&temp,sizeof(char))!=1){ perror("main.read"); exit(-1); }
 printf("%d\n",temp);
 usleep(10000); // attendre
}
serialClose(sd);
exit(0);
}

Séance 3

Partie électronique

Partie informatique

Démonstration

Conclusion