Créer une application android avec appinventor #2 réception et émission de données en bluetooth

9761

Aujourd’hui on va continuer apprendre à utiliser appinventor et créer une application android pour commander un module bluetooth HC-05 avec un arduino.
On va ici recevoir des informations sur notre application android et essayer plusieurs petites fonctions à l’intérieur.

TutoAppinventor2_circuit

#include <SimpleDHT.h>
#include <SoftwareSerial.h> // va creer un serial virtuel

#define PIN_PIR 7
#define PIN_LED 3

SoftwareSerial BTSerial(10, 11); // RX | TX  = > BT-TX=10 BT-RX=11

// for DHT11, 
//      VCC: 5V or 3V
//      GND: GND
//      DATA: 2
int pinDHT11 = 5;
SimpleDHT11 dht11(pinDHT11);


int stAlarm = 0;
int stTemp = 0;
float slAlarmTemp = 35;
boolean blAlarm = 0;


byte temperature = 0;
byte humidity = 0;

long unsigned tempoMesure = 0;


void setup() {
  Serial.begin(9600);
  BTSerial.begin(9600); 
  tempoMesure = 0;
}

void loop() {

String message;

 while (BTSerial.available()){
  Serial.println("Recu sur bluetooth");
      // Lecture du message envoyé par le BT
      // Read message send by BT
      message = BTSerial.readString();
      // Ecriture du message dans le serial usb
      // write in serial usb
      
      // recuperation de l'etat initial pour definir la position des sliders
      if(message=="etat"){

        BTSerial.println("stalarm=" + String(stAlarm));
        delay(100);
        BTSerial.println("sttemp=" + String(stTemp));  
        delay(100);
        BTSerial.println("sltemp=" + String(slAlarmTemp));  
 
      }
 
      if(message=="sttemp=1"){
        stTemp=1;
        Serial.println("A");
      }
      else if(message=="sttemp=0"){
        stTemp=0;
        Serial.println("B");
      }
      else if(message=="stalarm=1"){
        stAlarm=1;
        Serial.println("C");
      }
      else if(message=="stalarm=0"){
        stAlarm=0;
        Serial.println("D");
      }      
      else if(message=="led"){
        digitalWrite(PIN_LED,HIGH);
        Serial.println("E");
      }
      else if(message=="noled"){
        digitalWrite(PIN_LED,LOW);
        Serial.println("F");
      }
      else{
        Serial.println("G");
        decoupeur(message);
      }
      
      Serial.println("#");
      Serial.println(message);
      Serial.println("#");
    }



// capteur de proximite

    if(digitalRead(PIN_PIR) == HIGH && blAlarm== 0){
      
      blAlarm = 1; // variable pour prendre en consideration 1 seul appui sur bouton 
        if(stAlarm == 1){
             BTSerial.println("alarm=1" ); 
            Serial.println("envoie au Bt de alarm=1");    
        }   
    }
    else if(digitalRead(PIN_PIR) == LOW){
      blAlarm = 0;
     
    }

///////////////////////////////////////// ????? l'alarme est elle envoyée plusieurs fois ?
 /* if(stAlarm == 1){
    if(blAlarm == 1){
      // envoie l'information alarme a l'application
      BTSerial.println("alarm=1" ); 
      Serial.println("envoie au Bt de alarm=1");
    }    
  }*/

//Temperature

  if(stTemp ==1 && ((millis() - tempoMesure) > 5000)){
    getTemperature();
    Serial.println("Envoie de la temperature au BT");
    BTSerial.println("temp=" + String(temperature) ); 
    delay(100);
    BTSerial.println("hum=" + String(humidity) );  
    delay(100);
    tempoMesure = millis();

  Serial.print("float temperature");
  Serial.println((float)temperature);
  Serial.print("slalarmtemp");
  Serial.println(slAlarmTemp);
    // on va comparer aussi la temperature a slAlarmTemp pour declencher l'alarme de l'arduino
    if( (float)temperature > slAlarmTemp ){
      Serial.println("Alarme arduino");
    }
    
  }

 


  while (Serial.available()){
    Serial.println("Recu sur serial");
      // Lecture du message envoyé par le serial usb
      // Read message send by serial usb
      message = Serial.readString();
      // Ecriture du message dans le BT
      // write in BT 
      BTSerial.println(message);
    }
  // start working...
  //Serial.println("=================================");
  //Serial.println(analogRead(PIN_PIR));
  //Serial.println(digitalRead(PIN_PIR2));
  
  

  
  
}


void getTemperature(){

   temperature = 0;
   humidity = 0;
  int err = SimpleDHTErrSuccess;
  if ((err = dht11.read(&temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
    Serial.print("Read DHT11 failed, err="); Serial.println(err);delay(1000);
    return;
  }

  Serial.print("Sample OK: ");
  Serial.print((int)temperature); Serial.print(" *C, "); 
  Serial.print((int)humidity); Serial.println(" H");

}

void decoupeur(String inputString){

      char inputChar[inputString.length()+1] ;
      inputString.toCharArray(inputChar,inputString.length()+1);
 
        // lit toute les commandes separes par des &
        // Read each command pair 
        char* command = strtok(inputChar, "&");
        // boucle sur toutes les commandes
        while (command != 0)
        {
            // decoupe command en deux valeurs , separateur :
            // Split the command in two values
            char* valueCommand = strchr(command, '=');
            if (valueCommand != 0)
            {
                *valueCommand = 0;
                ++valueCommand;         
                // aiguillage par rapport a la valeur de command 
                  if(String(command) == "slalarm"){
                    slAlarmTemp = String(valueCommand).toFloat();
                    
                  }else if(String(command) == "color"){
                    
                    //color = String(valueCommand) ;
                    
                  }
            }
            // Recherche une nouvelle commande separes pas un &
            // Find the next command in input string
            command = strtok(0, "&");
        }
}

En matériel il nous faut :
– 1 arduino
– 1 module bluetooth HC-05
– 1 DHT11
– 1 capteur PIR HC-SR501
– 1 led et résistance

Pour le câblage peu de fils :
– VCC sur le 5Volt
– GND au GND
– RX pin 11
– TX pin 10
– Key pin 9
– PIR pin 7
– DHT11 pin 5
– Led pin 3

Le but du programme est de pouvoir communiquer d’un téléphone android vers un arduino avec module HC-05 dans les deux sens.
Dans un précédent tutoriel on a vu comment envoyer des informations de notre téléphone vers notre arduino.

Ici dans le programme je vais récupérer les valeurs de température et d’humidité du DHT-11 , la présence de quelqu’un avec le PIR HC-SR501 (capteur de proximité ) et envoyer ses informations au téléphone. Le téléphone lui va afficher les valeurs de température si je lui demande de les récupérer , définir une température d’alarme, activer ou non l’alarme de proximité et allumer une led si j’appuie sur le bouton associé et l’éteindre quand je le lâche.

Pour le code arduino je commence par appeler la librairie SimpleDHT et la librairie SoftwareSerial, je définis ensuite les pin pour la led, le Pir, le software serial et le Dht11.
J’ai quelques variables pour savoir si l’alarme et la température est activée avec stAlarm et stTemp qui sont des int ( peuvent être des boolean ici, le nom des variables commencent par st abréviation de state ). La variable slAlarmTemp est un float car c’est la valeur d’alarme de température, initialisée a 35 °C (sl pour Slider sur l’application android).
Une variable blAlarm en boolean pour ne pas envoyer x fois le message d’alarme de présence.
J’ai mes deux variables température et humidity pour le capteur DHT11.
Je gère le temps entre les mesures de température et humidité avec tempoMesure.

Dans le setup on démarre le serial usb et le serial bluetooth avec begin.

Maintenant note boucle loop, j’ai crée une variable message en String qui va recevoir les messages reçues via bluetooth.
J’ai une première boucle while qui s’active tant que l’on va recevoir une information via bluetooth avec “BTSerial.available()”.
On va ensuite lire la valeur reçue via bluetooth avec “BTSerial.readString();” et on enregistre la valeur dans message.
J’ai ensuite plusieurs manières de lire nos messages, première partie en direct (sans traitement) avec un “if(message==”etat”)”, si je reçois “etat” alors je vais transmettre des informations à mon téléphone et j’envoie si mon alarme est activée, si la température est activée et la valeur d’alarme de température.
Toujours dans le même style de contrôle direct si je reçois “sttemp=1” , “sttemp=0”, “stalarm=1” , “stalarm=0”, je vais définir une valeur à une variable.
J’ai aussi une condition directe pour éclairer un non une led donc j’allume ou j’éteins une led suivant le message.
La dernière condition else après tous les else if permet d’appeler une fonction (decoupeur) pour traiter différemment le message reçu.
Et je termine mon while avec un affichage du message en brut avec des print sur le serial.

J’ai une première condition pour notre capteur de proximité PIR, si mon capteur est à l’état haut et que blAlarm est égal à 0, alors je peux mettre blAlarm à 1 pour éviter d’envoyer le signal d’alarme le temps que le capteur est activé.
Une autre condition à l’intérieur permet d’envoyer le message en bluetooth si “stAlarm == 1” , on envoie “alarm=1” avec “BTSerial.println”.
J’ai un else if sur ma première condition avec comme contrainte si mon capteur PIR est à l’état bas.

Ensuite nous allons poser nos conditions pour la température, si stTemp==1 et que le temps actuel “millis()” moins la dernière mesure “tempoMesure” est supérieur à 5000 alors on va mesurer la température avec “getTemperature()”.
Cette fonction “getTemperature()” récupère la valeur de la température et l’humidité et enregistre la valeur dans “temperature” et “humidity”.
Avec ses valeurs on va les envoyer en bluetooth avec BTSerial.println, en valeur “temp=String(temperature)” pour envoyer la valeur de température à notre téléphone. Idem pour l’humidité “hum…”.
Je n’oublie pas un delay de 100ms pour laisser le message être transmis.
On modifie la valeur de tempoMesure avec millis pour définir un temps de référence avant la prochaine mesure.
J’ai quelques serial print pour afficher mes valeurs en debug et j’ai à l’intérieur une condition pour déclencher l’alarme température si ma température est supérieure a ma température d’alarme “slAlarmTemp” .

Pour terminer dans la boucle loop on a un dernier while (Serial.available) qui est ici pour lire une variable saisie dans la console arduino et de l’envoyer par bluetooth.

Voyons notre fonction découpeur rapidement, on y récupère le message et notre variable qui contient le message est maintenant “inputString”. Le principe du découpeur est de découper notre message qui peut contenir plusieurs variables ( attention a la taille du message il y a une limite).
Donc je peux recevoir x=10&y=15 et mon découpeur est capable de traiter x et y.
Concentrez vous sur la partie aiguillage avec un “if(String(command) == “x”)” avec x de mon exemple, si je reçois un message qui contient x= alors je vais récupérer sa valeur qui va se retrouver dans “valueCommand”.
Dans mon programme si je reçois “slalarm=” alors je vais assigner la valeur transmise dans ma variable “slAlarmTemp” variable de température, j’ai fait un traitement avec “String(valueCommand).toFloat()” pour convertir ma valeur reçue en String puis en float (nombre à virgule).
J’ai laissé une autre condition qui ne me sert pas dans mon exemple, si on reçoit un message “color=” alors a nous de traiter notre information.

On en a terminé avec le code arduino maintenant passons à notre application avec appinventor.

Notre programme contient un bluetooth client pour se connecter, un notifier pour afficher des messages d’alerte à l’écran, des clock (définir des valeurs aux clock) et des sounds.
Pour me connecter et récupérer  la liste des bluetooth j’utilise une listpicker, des label pour afficher la température et l’humidité, un slider pour régler la température d’alarme et des boutons pour activer la température, l’alarme et pour allumer une led.

Passons aux block, à l’initialisation de notre programme si le bluetooth n’est pas activé j’affiche une alerte avec notice et je met la valeur du slider dans la variable SliderValue.
J’initialise des variables globales memoryBt , memoryAlarmTemp , memTemp et memAlarm qui vont être utilisés pour mémoriser des informations dans notre programme.

Avant de choisir un élément dans la liste du listpicker je récupère les adresse et noms des bluetooth et je les affectes dans les éléments du picker.
Apres le choix du picker on se connecte au bluetooth avec l’élément choisi, j’ai voulu enregistrer la valeur du bluetooth pour me reconnecter mais cela ne fonctionne pas avec appinventor et j’appelle BtGreen si mon bluetooth s’est connecté et BtRed si déconnecté.
J’ai mon ClockLostBt qui devrait essayer de me reconnecter au bluetooth si je perd ma connexion mais celui ci ne fonctionne pas (appinventor me bloque ou je n’ai pas compris quelque chose).
Pour gérer le slider j’ai sortie l’envoie de la valeur du changement de position du slider car il m’enverrait trop de valeur de slider. Donc j’ai mis l’envoie dans une horloge “ClockSlider”.
En changeant de position je change la valeur du label SliderValue et j’active ma ClockSlider.
Dans mon ClockSlider je désactive mon horloge et j’envoie a mon arduino la valeur du slider.

La grosse partie du programme est la réception des données en bluetooth, pour ça on passe par une clock qui va traiter la réception des informations toutes les 50ms.
Une première condition gère la condition, si bluetooth activé et que l’on a reçu une information bluetooth alors on passe au traitement.
J’initialise une liste de variable locale “templocal”, on découpe ensuite les valeurs qui contiennent un “=” et je stocke la liste dans “templocal”.
La condition suivante controle le nombre de donnée dans notre liste “templocal” et si elle est égale à deux alors je peux traiter les données ( évite la réception d’information vide ou érronée  ).
Ensuite on a une condition pour chaque valeur que l’on va vouloir traiter, pour la première valeur si l’élément “templocal” en position 1 est égal à temp, j’affecte un label avec ma valeur en position 2 de “templocal”. Et pour contrôler la valeur je n’hésite pas à contrôler si la valeur est un nombre ( number ) pour pouvoir contrôler si la valeur est supérieure à la valeur du slider, sans ce contrôle valeur number j’ai eu des erreurs.
Ensuite si la valeur reçue exemple “temp=25” est supérieur à la valeur du slider alors j’affiche une alerte sur le téléphone et je joue le Sound1.

J’ai ensuite les mêmes type contrôles pour “hum” qui sert à récupérer la valeur d’humidité, “alarm” pour déclencher l’alarme quand il y a détection de présence, “stalarm” pour changer la couleur du bouton pour activer l’alarme de présence, “sttemp” pour changer la couleur du bouton pour activer l’envoie des informations humidité et température, “sltemp” permet de recevoir la valeur d’alarme de température.

On a ensuite nos deux actions bouton alarme et bouton température.
Au clic d’un bouton on envoie en bluetooth la valeur inverse de la valeur mémorisée, exemple pour le bouton Alarm j’envoie la jointure (concaténation, “A+B”) de “stalarm=” et je regarde ce qu’il y a dans memAlarm, si il est égal à 0 alors la valeur sera 1 et si 1 il sera égal à 0.
Et if suivant si la valeur de “memAlarm=0” alors “memAlarm” va être égal à 1 et je change le background du bouton, dans le else je fais l’inverse.
Même principe pour le bouton “ButtonTemp”.

Et pour terminer petit exemple avec un bouton qui peut être utilisé pour commander une voiture électrique par exemple.
Quand j’appuie sur le bouton j’envoie led et quand je relache j’envoie noled.

J’en ai terminé sur l’explication des codes, j’ai essayé d’utiliser plusieurs principes pour vous aider à faire votre projet. Mon projet ici fait tout est rien il est la pour vous aiguiller 😀

Pour télécharger les codes :
TutoBluetoothAppinventor2
Programme android et appinventor

N’hésitez pas à poser vos questions sur les réseaux sociaux de la chaîne instagramtwitter , facebook ,youtube ; si vous ne comprenez pas certaines parties du tutoriel n’hésitez pas , me dire ce que vous aimeriez que je crée pour en faire des vidéos tutoriel  et à partager les projets que vous aimeriez créer etc…

Comme toujours allez sur la page de C’est quoi Retro et Geek pour connaître tout ce que je recherche à faire sur la chaîne.

Merci les RetroGeeker et RetroGeekeuse