Étape 4: Module de récepteur Arduino
Nous allons passer à la partie la plus difficile, le module de récepteur Arduino que j’appelle la "mère" Arduino. En fait, il n’est pas difficile, mais vous devez faire attention.
Comme auparavant, nous allons commencer par câblage jusqu'à l’Arduino. Une fois de plus, j’ai utilisé broche 2 sur l’Arduino broche de données et la broche 3 pour axe de données de l' émetteurdu récepteur. Le Conseil Bluefruit est connecté comme suit (configuration par défaut) :
- CTS sur la broche 11
- TXO sur la broche 10
- RXI sur broche 9
- VIN sur 5V
- GND sur GND
Les tiges de MOD, RTS et DFU ne sont pas utilisés dans cet exemple. Notez que pour cet exemple, le Bluefruit Conseil d’administration doit être réglé au mode CMD sur le petit interrupteur.
J’ai connecté 3 LEDs avec une résistance de 220 Ω pour chacun d’eux à broches 5, 6 et 7. C’est facultatif, mais peut être utile dans certains cas.
Maintenant que le câblage est fait, nous pouvons commencer à coder. Vous aurez besoin de plusieurs bibliothèques pour le faire fonctionner. Les bibliothèques Arduino.h, SPI.h et SoftwareSerial.h sont déjà présent dans l’IDE Arduino et RH_ASK.h est celui que dans le code précédent, nous avons utilisé. Les bibliothèques Adafruit_BLE.h, Adafruit_BluefruitLE_SPI.h et Adafruit_BluefruitLE_UART.h peuvent être téléchargés du site Web de Adafruit. BluefruitConfig.h est un fichier de configuration pour le Conseil de Bluefruit.
#include < Arduino.h >#include < RH_ASK.h >
#include <SPI.h >
#if non défini (_VARIANT_ARDUINO_DUE_X_) & & non défini (_VARIANT_ARDUINO_ZERO_)
#include <SoftwareSerial.h >
#endif
#include « Adafruit_BLE.h »
#include « Adafruit_BluefruitLE_SPI.h »
#include « Adafruit_BluefruitLE_UART.h »
#include « BluefruitConfig.h »
Voici les variables globales utilisées dans le présent code :
Les variables nbRooms définit le nombre total de chambres, assurez-vous que vous modifier celui-ci, si vous utilisez plus ou moins 3 émetteur Arduinos
Les valeurs de variables est un tableau de longueur nbRooms qui sera utilisé pour stocker les données reçues par l’émetteur Arduinos.
La variable LEDpin est un tableau contenant les numéros de broches pour les LEDs.
La limite variable est un tableau qui va stocker les limites pour la luminosité au cours de laquelle les lumières sont considérés comme activé ou désactivé. Notez que j’ai oublié de remplacer les 3 avec la variable nbRooms , qui vous devez faire.
Les variables temps et currentTime sont utilisés pour stocker des valeurs obtenues à partir de la fonction millis .
La variable dataToSend est utilisée pour stocker les données à envoyer au Smartphone
La variable de requêtes est un tableau de caractères contenant les demandes à envoyer à l’émetteur Arduinos. N’oubliez pas de changer cela, si vous utilisez un nombre différent d’émetteurs.
Le * demande variable est un pointeur vers la demande à être envoyé à l’émetteur Arduino.
Les booléens gotResponse, firstRequest et l’envoi seront expliqués plus tard.
les valeurs int [nbRooms] ; Utilisé pour stocker les données recueillies à partir des émetteurs
int [] LEDpin = {5, 6, 7} ; Épingles utilisées pour les LEDs
int limite [3] ; Utilisé pour stocker les limites de luminosité au cours de laquelle la lumière est considéré comme éteint
Utilisé pour stocker les valeurs de millis()
unsignedLong temps ;
unsignedLong currentTime ;
String dataToSend ; Utilisé pour stocker les données envoyées vers le Smartphone
char * prie [] = {"a0", "a1", "a2"} ; Utilisé pour stocker les demandes, n’oubliez pas de le changer si vous utilisez plus ou moins 3 émetteur Arduinos
char * demander ; Utilisé pour stocker la demande doivent être envoyés
bool gotResponse = false ;
bool firstRequest = true ;
bool bleIsConnected = false ;
envoi de bool = true ; Pour l’arrêt de la diffusion de BLE
Dans cette partie, nous créons les objets nécessaires.
Comme avant, nous créons l’objet RH_ASK nommé pilote, mais cette fois vous avez besoin définir l’axe Ptt sur une broche inutilisées (ou broche -1) étant la valeur par défaut une broche 10 qui est déjà utilisée par le jury de Bluefruit.
Nous créons ensuite les objets bluefruitSS et ble . Les paramètres utilisés pour ces objets sont celles spécifiées dans le fichier BluefruitConfig.h .
Paramètres de le SoftwareSerial et la Adafruit_BluefruitLE_UART stocké dans le fichier BluefruitConfig
SoftwareSerial bluefruitSS = SoftwareSerial(BLUEFRUIT_SWUART_TXD_PIN, BLUEFRUIT_SWUART_RXD_PIN) ;
Adafruit_BluefruitLE_UART ble (bluefruitSS, BLUEFRUIT_UART_MODE_PIN, BLUEFRUIT_UART_CTS_PIN, BLUEFRUIT_UART_RTS_PIN) ;
Viennent ensuite quelques définitions de réglage. L’une spécifie si vous voulez le Conseil Bluefruit pour effectuer une usine réinitialise lorsqu’il démarre. L’autre définit la version du firmware minimale et le dernier d'entre eux le comportement de la rouge a conduit le Conseil d’administration. Je recommande de laisser ces paramètres intacte.
#define FACTORYRESET_ENABLE 1#define MINIMUM_FIRMWARE_VERSION « 0.6.6 »
#define MODE_LED_BEHAVIOUR « MODE »
Dans la partie de l’installation , nous allons commencer par configurer les broches de la LED mode de sortie . Ensuite, nous avons mis toutes les limites à 0 afin qu’ils ne sont pas null, ce qui nous empêcherait de faire toute comparaison. Ils seront modifiés sur l’application mobile par la suite.
voidsetup(void){
pour (int i = 0; i < sizeof(LEDpin); i ++)
{
pinMode (LEDpin [i], sortie) ; Initialisation des broches de la LED
}
pour (int i = 0; i < nbRooms; i ++)
{
limite de [i] = 0 ; Initialisation des limites à 0
}
Série.begin(9600) ; Pour le débogage
Si (! driver.init()) / / si les modules RF n’a pas pu initialiser
Série.println ("init a échoué") ;
Cette partie du programme d’installation gère la configuration de Conseil Bluefruit. La fonction setupBluefruit sera expliquée plus tard. Le code suivant il change mode LED de la Commission (si la version du firmware est au moins 0.6.6) et définissez le jury en mode données, afin qu’il puisse communiquer avec le Smartphone.
setupBluefruit() ;Série.println(F("***")) ;
Commande de LED activité est pris en charge uniquement de 0.6.6
Si (ble.isVersionAtLeast(MINIMUM_FIRMWARE_VERSION))
{
Activité de changement Mode LED
Série.println (F (« Activité LED changement de » MODE_LED_BEHAVIOUR)) ;
ble.sendCommandCheckOK ("AT + HWModeLED = « MODE_LED_BEHAVIOUR) ;
}
Module de jeu données mode
.Println sérieF ("activation mode données!") ;
ble.setMode(BLUEFRUIT_MODE_DATA) ;
Série.println(F("***")) ;
}
Dans le cadre de la boucle , nous répondrons à la réception des données de l’émetteur Arduinos, la transmission de ces données vers le Smartphone et la réception des limites depuis le Smartphone.
La partie de collecte et de transmission de données se trouve dans un if expression afin que vous pouvez arrêter la diffusion de BLE si vous le souhaitez, dont je n’a pas fait.
Nous puis effectuer une boucle sur chaque pièce, l' gotResponse la valeur false et si vous envoyez une demande. Dans le même temps, nous commençons une minuterie en assignant une valeur à la variable de temps avec la fonction millis .
{
Si (envoi) / / pour l’arrêt de la diffusion de BLE
{
pour (int i = 0; i < nbRooms; i ++)
{
gotResponse = false ;
Envoyer la demande
temps = millis() ; Minuterie départ
sendRequest(i) ; Envoyer à l’émetteur Arduino
Alors que nous n’avons pas reçu de réponse de l’émetteur Arduino, nous stockons la valeur millis dans la variable currentTime afin de le comparer à temps. Si la différence est supérieure à 500 millisecondes, cela signifie que le message a été perdu et que nous devons envoyer une autre demande. Nous devons également de réinitialiser la variable temps .
Réception de réponsetandis que (! gotResponse) / / si aucune réponse n’a été reçue
{
currentTime = millis() ;
Si (currentTime - temps > 500) / / 0,5 secondes se soit écoulé sans recevoir aucune réponse, renvoyez la demande
{
temps = millis() ; Réinitialiser la minuterie
Série.println ("pas de réponse après 0,5 seconde, renvoyer la demande ») ;
sendRequest(i) ;
}
Une fois de plus, nous créons un tampon pour stocker les données reçues. A réception, nous stocker le message dans une variable chaîne et analyser les valeurs de données et de la salle . Si la chambre correspond à celui attendu, nous gotResponse la valeur true et stocker les données dans le tableau de valeurs .
uint8_t buf [4] ; Mémoire tampon utilisée pour stocker les données reçues, sa taille est égale à 3 octets, comme les données sont : String(room) + valeur (eg. 0555)uint8_t buflen = sizeof(buf) ;
Si (driver.recv (buf, & buflen)) / / au moment de la réception des données
{
Message de chaîne = (char *) buf ; Stockage des données dans une chaîne pour l’analyse
int salle = message.substring (0, 1).toInt() ; Numéro de la chambre d’analyse
données int = message.substring(1).toInt() ; L’analyse des données
Si (salle == i) / / si les données proviennent de la chambre correcte
{
gotResponse = true ;
les valeurs [salle] = données ; Conservation des données
Dans cette partie, nous traitons la foudre des LEDs. Ceci est optionnel.
Allumer/éteindre LEDsSi (valeurs [salle] > limit[room])
{
digitalWrite (LEDpin [i], élevé) ;
}
d’autre
{
digitalWrite (LEDpin [i], faible) ;
}
Pour le débogage
Série.print ("Data for room") ;
Série.print(room) ;
Série.print ("est") ;
Série.println(data) ;
Série.println("") ;
}
}
}
Delay(50) ;
}
Une fois que nous avons reçu et vérifié les données de chaque pièce, nous pouvons passer à la transmission de ces données vers le Smartphone. Le message commence par un « # » et se termine par un "*" afin d’analyser facilement dans l’application Smartphone. Nous nous séparons également les valeurs par un « / ».
dataToSend = « # » ; Commencer la chaîne de données par # pour easyier l’analyse de l’application Smartphonepour (int i = 0; i < nbRooms; i ++)
{
dataToSend.concat(String(values[i])) ;
Si (j’ai < nbRooms - 1)
{
dataToSend.concat("/") ; Séparez les valeurs avec un /
}
}
dataToSend.concat("*") ; Fin de la chaîne de données avec *
Série.print ("envoi:") ;
Série.println(dataToSend) ;
Série.println("") ;
}
Le message est alors stocké dans un tableau char et envoyé à la Pentecôte de Smartphone, la méthode ble.print .
char n, entrées [BUFSIZE + 1] ; Utilisé pour stocker des données à envoyer au SmartphonedataToSend.toCharArray (intrants, BUFSIZE + 1) ; Chaîne de données de la copie au tampon
ble.Print(inputs) ; Envoi de données
Vient ensuite la réception des limites envoyé par le Smartphone. Nous commençons par créer une variable de chaîne appelée valeurs (pas le même que le tableau int!) qui va stocker les caractères reçus par le biais de la connexion BLE. Une fois que nous avons lu le #, c'est-à-dire le point de départ du message, nous définir la variable d’enregistrement vrai qui permettra à la concaténation des caractères suivants pour la valeurs de variable, jusqu'à ce que le * est lu. Lorsque le message est terminé, nous analyser et stocker les limites à l’aide de la fonction cellesci qui est expliquée plus tard.
Les valeurs de chaîne = "" ; Chaîne de données de vidangeLecture des données reçues du Smartphone
enregistrement de bool = false ;
tandis que (ble.available()) / / alors que la donnée n’est disponible de BLE
{
int c = ble.read() ;
Série.println((char)c) ;
Si (enregistrement) / / si nous avons lu le #
{
Si ((char) c! = ' *')
{
values.Concat((Char)c) ; Tant que c se distingue par le caractère de fin *, ajoutez-le à la chaîne de données
}
d’autre
{
Série.println(values) ; setLimits(values) ;
enregistrement = false ; Définir les limites de ceux que nous venons de recevoir
valeurs = "" ;
}
}
Si ((char) c == « # ») / / démarrer l’enregistrement à la réception du début caractère #
{
enregistrement = true ;
}
}
}
Voici les fonctions utilisées dans le code.
La première affiche un message d’erreur et arrête l’exécution du programme.
void erreur (const __FlashStringHelper * err)
{
Série.println(err) ;
while (1) ;
}
Cette fonction configure le jury Bluefruit lorsqu’il démarre. Il effectue également une usine zéro si elle a été activée.
Sub setupBluefruit(){
/ * Initialiser le module * /
Série.print (F ("initialisation du module Bluefruit LE:")) ;
Si (! ble.begin(VERBOSE_MODE))
{
erreur (F ("ne pouvait pas trouver Bluefruit, assurez-vous qu’il est en mode commande et vérifiez le câblage?")) ;
}
Série.println (F("OK!")) ;
Si (FACTORYRESET_ENABLE)
{
/ * Effectuer un factory reset pour s’assurer que tout est dans un état connu * /
Série.println (F ("effectuant un factory reset:")) ;
Si (! ble.factoryReset()) {}
erreur (F ("ne pouvait pas réinitialisation d’usine")) ;
}
}
/ * Désactiver commande echo de Bluefruit * /
ble.Echo(false) ;
Série.println (« Bluefruit demande d’info: ") ;
/ * Imprimer les informations de Bluefruit * /
ble.info() ;
ble.Verbose(false) ;
}
Cette fonction est utilisée pour envoyer des demandes à l’émetteur Arduinos, portant le numéro d’identification de pièce en tant que paramètre.
Envoyer une demande à l’émetteur de chambre correspondant (i)Sub sendRequest(int i)
{
demande = demandes [i] ;
demande de ((uint8_t *) Driver.Send, strlen(request)) ;
driver.waitPacketSent() ;
Série.print ("requête au bureau") ;
Série.println(i) ;
Série.println (la « réponse en attente") ;
Série.println("") ;
}
Cette fonction analyse le message limite a reçu depuis le téléphone intelligent et stocke les limites du tableau de limite .
Stocker les limitesSub setLimits(String values)
{
pour (int i = 0; i < nbRooms; i ++)
{
Si (j’ai < nbRooms - 1)
{
limite de [i] = values.substring (4 * i, 3 + 4 * i).toInt() ; Pärsing les limites
}
d’autre
{
limite de [i] = values.substring (4 * i).toInt() ; L’analyse de la dernière limite
}
}
}