L’Internet des Objets
2.7 Le Bluetooth
La carte est équipée d’un composant Bluetooth (BLE). C’est un SPBTLE-RF (Very low power module for Bluetooth Smart v4.1). La description se trouve sur : https://www.st.com/en/wireless-transceivers-mcus-and-modules/spbtle-rf.html.
Pour l’utiliser, il faut commencer par les déclarations :
#include#include #define PIN_BLE_SPI_MOSI (PC12) #define PIN_BLE_SPI_MISO (PC11) #define PIN_BLE_SPI_SCK (PC10) #define PIN_BLE_SPI_nCS (PD13) #define PIN_BLE_SPI_RESET (PA8) #define PIN_BLE_SPI_IRQ (PE6) #define PIN_BLE_LED (LED4) // Configure BTLE_SPI SPIClass BTLE_SPI(PIN_BLE_SPI_MOSI, PIN_BLE_SPI_MISO, PIN_BLE_SPI_SCK); // Configure BTLE pins SPBTLERFClass BTLE(&BTLE_SPI, PIN_BLE_SPI_nCS, PIN_BLE_SPI_IRQ,\\ PIN_BLE_SPI_RESET, PIN_BLE_LED); const char *name = "AFbleST"; // pourquoi 7 characatères ?
Le nom semble utiliser 7 caractères, je ne sais pas pourquoi.
Ensuite, il faut initialiser le Bluetooth :
// -------------- Init BLE ----------------------------------------//
if(BTLE.begin() == SPBTLERF_ERROR)
{
Serial.println("Bluetooth module configuration error!");
while(1);
}
if(SensorService.begin(name, SERVER_BDADDR))
{
Serial.println("Sensor service configuration error!");
while(1);
}
Serial.println("Ble ok...");
Et la boucle qui émet les données environnementales :
void loop() {
BTLE.update();
...
SensorService.Update_Time_Characteristics();
...
hts221();
SensorService.Temp_Update(temperature*100);
SensorService.Press_Update(12);
SensorService.Humidity_Update(humidity);
...
SensorService.setConnectable();
C’est récupéré par un programme python sur GNU/Linux (voir : ??.
#! /bin/python
from bluepy import btle
import time
import binascii
import datetime
#print "Connecting..."
dev = btle.Peripheral("02:AF:E1:00:34:12")
Sensor1 = btle.UUID("42821a40-e477-11e2-82d0-0002a5d5c51b")
Service1 = dev.getServiceByUUID(Sensor1)
ch=Service1.getCharacteristics()[0]
v=ch.read()
ch=Service1.getCharacteristics()[2]
v=ch.read()
Et le programme complet pour référence :
// ================================================================== //
// //
// Communication environnement (température...) en BT. //
// Réception gatttool sur Linux //
// ================================================================== //
//
// Lit des valeurs environnementales et les tient à disposition en BT
// ================================================================== //
// //
// Paramètres de controle (nb de boucles...) //
// //
// ================================================================== //
int boucle =0 ; // le nombre de fois dans la boucle pour afficher les boucles
int T = 0;
uint32_t previousSecond = 0;
int M;
uint32_t MCU_Id;
uint8_t SERVER_BDADDR[] = {0x12, 0x34, 0x00, 0xE1, 0xaf, 0x02};
// =============================================== //
// Diode sur la carte
#define Led1 LED1
#define Led2 LED2
// ================================================================== //
// //
// Général SPI //
// //
// ================================================================== //
#include
#define I2C2_SCL PB10
#define I2C2_SDA PB11
// ================================================================== //
// //
// Configuration BLE //
// //
// ================================================================== //
#include
#include
#define PIN_BLE_SPI_MOSI (PC12)
#define PIN_BLE_SPI_MISO (PC11)
#define PIN_BLE_SPI_SCK (PC10)
#define PIN_BLE_SPI_nCS (PD13)
#define PIN_BLE_SPI_RESET (PA8)
#define PIN_BLE_SPI_IRQ (PE6)
#define PIN_BLE_LED (LED4)
// Configure BTLE_SPI
SPIClass BTLE_SPI(PIN_BLE_SPI_MOSI, PIN_BLE_SPI_MISO, PIN_BLE_SPI_SCK);
// Configure BTLE pins
SPBTLERFClass BTLE(&BTLE_SPI, PIN_BLE_SPI_nCS, PIN_BLE_SPI_IRQ, PIN_BLE_SPI_RESET, PIN_BLE_LED);
const char *name = "AFbleST"; // pourquoi 7 characatères ?
// ================================================================== //
// //
// HS221 Température, Humidité //
// //
// ================================================================== //
#include
HTS221Sensor *HumTemp;
float humidity, temperature;
TwoWire *dev_i2c; // doit être appelé *après* HTS221Sensor.h
// ================================================================== //
// //
// Accéléromètre, pour l'instant simulé //
// //
// ================================================================== //
AxesRaw_t axes_data;
// ================================================================== //
// //
// Offset en fonction de l'id du MCU //
// //
// ================================================================== //
float offsetTHTS221;
void offsetT()
{
switch (MCU_Id) {
case 1835064:
offsetTHTS221 = -5;
// SERVER_BDADDR[] = {0x38, 0x00, 0x1C, 0xE1, 0xaf, 0x02};
break;
case 2424886:
offsetTHTS221 = -4.2 ;
// SERVER_BDADDR[] = {0x36, 0x00, 0x25, 0xE1, 0xaf, 0x02};
break;
default:
offsetTHTS221 = 0;
// L'adresse Bluetooth, à l'envers apparaît comme 02:AF:E1:00:34:12]
// Le premier chiffre est devenu un zéro, alors j'ai changé le code...
//SERVER_BDADDR[] = {0x12, 0x34, 0x00, 0xE1, 0xaf, 0x02};
break;
}
Serial.print(" ::::::::: OFFSETS : ");
Serial.println(offsetTHTS221);
delay(10100);
}
// ================================================================== //
// //
// Setup //
// //
// ================================================================== //
void setup() {
int ret;
// initialize digital pin LED_BUILTIN as an output.
pinMode(Led2, OUTPUT);
pinMode(Led1, OUTPUT);
// Vitesse relativment élevée, mais faible pour éviter les erreurs //
Serial.begin(57600);
MCU_Id=HAL_GetUIDw0();
Serial.print("AF BLE tests MCU: "); Serial.println(MCU_Id);
offsetT();
// ================================================================== //
// HTS221 //
// Initialize I2C bus. pour HTS221 et LPS22HB
dev_i2c = new TwoWire(I2C2_SDA, I2C2_SCL);
dev_i2c->begin();
// Initialize HTS221
HumTemp = new HTS221Sensor (dev_i2c);
HumTemp->Enable();
Serial.println("HTS221");
// -------------- Init BLE ----------------------------------------//
if(BTLE.begin() == SPBTLERF_ERROR)
{
Serial.println("Bluetooth module configuration error!");
while(1);
}
if(SensorService.begin(name, SERVER_BDADDR))
{
Serial.println("Sensor service configuration error!");
while(1);
}
Serial.println("Ble ok...");
/* Configure the User Button in GPIO Mode */
pinMode(USER_BTN, INPUT);
// -- Accéléromètre
ret = SensorService.Add_Acc_Service();
if(ret == BLE_STATUS_SUCCESS)
{
Serial.print("Acc service added successfully.");
}
else
Serial.println("Error while adding Acc service.");
// -- Environnement
ret = SensorService.Add_Environmental_Sensor_Service();
if(ret == BLE_STATUS_SUCCESS)
Serial.println("Environmental Sensor service added successfully.");
else
Serial.println("Error while adding Environmental Sensor service.");
// -- Temps ??
/* Instantiate Timer Service with two characteristics:
* - seconds characteristic (Readable only)
* - minutes characteristics (Readable and Notifiable )
* la fonction millis() retourne le nombre de millisecondes depuis
l'initialisation
*/
ret = SensorService.Add_Time_Service();
if(ret == BLE_STATUS_SUCCESS)
Serial.println("Time service added successfully.");
else
Serial.println("Error while adding Time service.");
}
// =================================================================== //
// //
// Interroge le HTS221 et affiche le résultat sur le lien série //
// //
// =================================================================== //
void hts221(){
HumTemp->GetHumidity(&humidity);
HumTemp->GetTemperature(&temperature);
temperature=temperature+offsetTHTS221;
// Output data.
Serial.print("HTS221 Hum[%]: ");
Serial.print(humidity, 2);
Serial.print(" | Temp[C]: ");
Serial.println(temperature, 2);
}
// ================================================================== //
// //
// Boucle principale //
// //
// ================================================================== //
void loop() {
BTLE.update();
// Chaque tour on affiche un o si la connexion est établie un point sinon
// Au bout de 90 tours, on passe à a ligne
boucle = boucle +1 ;
if (boucle > 90)
{
boucle = 0; Serial.println("/");
}
if(SensorService.isConnected() == TRUE)
{
Serial.print("o");
digitalWrite(Led2, HIGH); // Allume la deux ...
digitalWrite(Led1, HIGH); // Allume la un
//Update accelerometer values
User_Process(&axes_data);
//Update time
SensorService.Update_Time_Characteristics();
if((millis() - previousSecond) >= 1000)
{
//Update environnemental data
previousSecond = millis();
hts221();
T = temperature; Serial.println(T);T=12;
SensorService.Temp_Update(temperature*100);
SensorService.Press_Update(12);
SensorService.Humidity_Update(humidity);
}
else {Serial.println("pas mili");
delay(100);}
}
else
{
Serial.print(".");
digitalWrite(Led2, LOW); // et éteint la deux
digitalWrite(Led1, LOW); // et éteint la un
//Keep the Bluetooth module in discoverable mode
SensorService.setConnectable();
}
delay(1000);
}
// ================================================================== //
// //
// //
// //
// ================================================================== //
/**
* @brief Process user input (i.e. pressing the USER button on Nucleo board)
* and send the updated acceleration data to the remote client.
*
* @param AxesRaw_t* p_axes
* @retval None
*/
void User_Process(AxesRaw_t* p_axes)
{
/* Check if the user has pushed the button */
if(digitalRead(USER_BTN) == RESET)
{
while (digitalRead(USER_BTN) == RESET);
/* Update acceleration data */
p_axes->AXIS_X += 100;
p_axes->AXIS_Y += 100;
p_axes->AXIS_Z += 100;
SensorService.Acc_Update(p_axes);
}
}
// ================================================================== //
// //
// //
// //
// ================================================================== //