Arduino UNO R4 WiFi로 BLE ⑥ BME280의 BLE 주변기기와 연결되는 센트럴
지난번에 Arduino UNO R4 WiFi에 기압센서 BME280을 연결하여 BLE 주변기기를 만들었는데요, PC에서 동작하는 온세미컨덕터의 BLE인 RSL10 Bluetooth Low Energy Explorer를 연결하여 기압과 온도 데이터를받았습니다.
이 마이크로컴퓨터 보드 Arduino UNO R4 WiFi를 PC의 USB에서 분리하고 전원을 연결하여 단독으로 작동하도록 합니다.그리고 RSL10 Bluetooth Low Energy Explorer로 연결할 수 있음을 확인했습니다.
본 문서의 전체 리스트를 링크로 연결하였습니다. 참고하세요.
UNO R4 WiFi BLE ⑥ BME280의 BLE 주변기기와 연결되는 센트럴
UNO R4 WiFi BLE ⑤ BME280의 BLE peripheral
UNO R4 WiFi BLE ④ 기압 센서 BME280을 연결
UNO R4 WiFi BLE ③ LPS22의 BLE 주변기기와 연결되는 센트럴
UNO R4 WiFi BLE ② LPS22의 BLE 주변기기
UNO R4 WiFi BLE ① 기압 센서 LPS22 연결
● 두 번째 마이크로 컴퓨터 보드 Arduino UNO R4 WiFi 준비
또 다른 마이크로 컴퓨터 보드 Arduino UNO R4 WiFi를 준비하여 PC에 연결하고 BLE 센트럴의 스케치를 만듭니다.
● BLE의 각종 정의
BLE 주변기기란 localNAME으로 선택합니다.
#define localNAME "BME280_int"
연결이 완료되면 캐릭터스틱을 지정하여 읽어옵니다.
#define BME280_Temp_Characteristic_UUID "F000AA31-0452-4000-B000-000000000000" // BLE Characteristic
#define BME280_Press_Characteristic_UUID "F000AA32-0452-4000-B000-000000000000"
#define BME280_Humidity_Characteristic_UUID "F000AA33-0452-4000-B000-000000000000"
●setup - BLE
먼저 초기화합니다.
BLE.begin();
localNAME으로 찾습니다.
// start scanning for peripherals
BLE.scanForName(localNAME);
●loop-BLE
주변기기를 찾으면 주소, localNAME, 서비스 UUID를 출력합니다.
// check if a peripheral has been discovered
BLEDevice peripheral = BLE.available();
if (peripheral) {
// discovered a peripheral, print out address, local name, and advertised service
Serial.print("Found ");
Serial.print(peripheral.address());
Serial.print(" '");
Serial.print(peripheral.localName());
Serial.print("' ");
Serial.print(peripheral.advertisedServiceUuid());
Serial.println();
스캔을 중지합니다.
// stop scanning
BLE.stopScan();
읽기 함수를 실행합니다.
readData(peripheral);
읽기 함수에서는 먼저 connect를 수행합니다.
if (peripheral.connect()) {
다음으로 discover합니다.
if (peripheral.discoverAttributes()) {
온도와 기압, 습도의 UUID로 데이터를 가져옵니다.
// retrieve the characteristic
BLECharacteristic Temperature_Characteristic = peripheral.characteristic(BME280_Temp_Characteristic_UUID);
BLECharacteristic Pressure_Characteristic = peripheral.characteristic(BME280_Press_Characteristic_UUID);
BLECharacteristic Humidity_Characteristic = peripheral.characteristic(BME280_Humidity_Characteristic_UUID);
온도 데이터를 2바이트씩 읽어오는데, 2바이트(상위)와 1바이트(하위)에 정수 데이터가 들어있으므로 16비트 데이터로 수정한다.
Temperature_Characteristic.readValue(buffer,2);
uint16_t temperature = (uint8_t)buffer[1]*256 + (uint8_t)buffer[0];
측정한 실수를 100배하여 정수로 보내왔으므로 100으로 나눕니다.
Serial.println(temperature / 100.0);
기압과 습도 데이터도 마찬가지로 읽어들여 실수로 변환하여 출력한다.기압과 습도는 10배입니다.
전체 스케치입니다.
#include <ArduinoBLE.h>
#define localNAME "BME280_int"
#define BME280_Temp_Characteristic_UUID "F000AA31-0452-4000-B000-000000000000" // BLE Characteristic
#define BME280_Press_Characteristic_UUID "F000AA32-0452-4000-B000-000000000000"
#define BME280_Humidity_Characteristic_UUID "F000AA33-0452-4000-B000-000000000000"
void setup() {
Serial.begin(115200);
while (!Serial) delay(10);
BLE.begin();
Serial.println("\n start BLE peripherals - Temperature/Pressure/Humidity");
// start scanning for peripherals
BLE.scanForName(localNAME);
}
void loop() {
// check if a peripheral has been discovered
BLEDevice peripheral = BLE.available();
if (peripheral) {
// discovered a peripheral, print out address, local name, and advertised service
Serial.print("Found ");
Serial.print(peripheral.address());
Serial.print(" '");
Serial.print(peripheral.localName());
Serial.print("' ");
Serial.print(peripheral.advertisedServiceUuid());
Serial.println();
if (peripheral.localName() != localNAME) {
return;
}
// stop scanning
BLE.stopScan();
readData(peripheral);
// peripheral disconnected, start scanning again
BLE.scanForName(localNAME);
}
}
void readData(BLEDevice peripheral) {
byte buffer[2] ;
// connect to the peripheral
Serial.print("\nConnecting ...");
if (peripheral.connect()) {
Serial.println("Connected");
} else {
Serial.println("Failed to connect!");
return;
}
// discover peripheral attributes
Serial.print("Discovering attributes ...");
if (peripheral.discoverAttributes()) {
Serial.println("Attributes discovered\n");
} else {
Serial.println("Attribute discovery failed!");
peripheral.disconnect();
return;
}
// retrieve the characteristic
BLECharacteristic Temperature_Characteristic = peripheral.characteristic(BME280_Temp_Characteristic_UUID);
BLECharacteristic Pressure_Characteristic = peripheral.characteristic(BME280_Press_Characteristic_UUID);
BLECharacteristic Humidity_Characteristic = peripheral.characteristic(BME280_Humidity_Characteristic_UUID);
if (!Temperature_Characteristic) {
Serial.println("Peripheral does not have Temp characteristic!");
peripheral.disconnect();
return;
}
Serial.println("---Found CHARACTERISTIC_UUID");
while (peripheral.connected()) {
if (Temperature_Characteristic.canRead()) {
Serial.print("\ntemp = ");
Temperature_Characteristic.readValue(buffer,2);
uint16_t temperature = (uint8_t)buffer[1]*256 + (uint8_t)buffer[0];
Serial.println(temperature / 100.0);
}
if (Pressure_Characteristic.canRead()) {
Serial.print("Pressure = ");
Pressure_Characteristic.readValue(buffer,2);
uint16_t pressure = (uint8_t)buffer[1]*256 + (uint8_t)buffer[0];
Serial.println((pressure / 10.0),1);
}
if (Humidity_Characteristic.canRead()) {
Serial.print("Humidity = ");
Humidity_Characteristic.readValue(buffer,2);
uint16_t humidity = (uint8_t)buffer[1]*256 + (uint8_t)buffer[0];
Serial.println((humidity / 10.0),1);
}
delay(1000);
}
Serial.println("Peripheral disconnected");
}
실행 예시입니다.
● 그래픽 디스플레이에 수신된 데이터 표시
LPS22 때처럼 마이크로보드의 LED 매트릭스에 텍스트를 표시하려고 했지만, 온도, 기압, 습도를 표시하기에는 너무 좁아서 스크롤을 하면 보기가 매우 어려웠다.
Arduino UNO R4 WiFi로 BLE ③ LPS22의 BLE 주변기기와 연결되는 센트럴
그래서 BLE 주변기기와 마찬가지로 OLED 그래픽 디스플레이를 사용했다.아마존에서 구입할 수 있는 I2C 연결 타입이다.이 마이컴 보드에는 Qwiic 전용 커넥터가 준비되어 있지만, OLED 그래픽 디스플레이는 인식하지 못했습니다.
Spresense에서 Lchica로 시작하는 (5) Wire 라이브러리 그래픽 디스플레이
스케치입니다.제조사를 알 수 없는 OLED 그래픽 디스플레이이지만, 드라이버는 Adafruit의 ssd1306용 드라이버를 사용했습니다.슬레이브 주소는 0x3c입니다.
#include <ArduinoBLE.h>
#include <Adafruit_SSD1306.h>
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &Wire);
#define localNAME "BME280_int"
#define BME280_Temp_Characteristic_UUID "F000AA31-0452-4000-B000-000000000000" // BLE Characteristic
#define BME280_Press_Characteristic_UUID "F000AA32-0452-4000-B000-000000000000"
#define BME280_Humidity_Characteristic_UUID "F000AA33-0452-4000-B000-000000000000"
void setup() {
Serial.begin(115200);
while (!Serial) delay(10);
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3c)) { // Address 0x3C for 128x32
Serial.println(F("SSD1306 allocation failed"));
for (;;)
; // Don't proceed, loop forever
}
display.display();
delay(500); // Pause for 2 seconds
display.setTextSize(1);
display.setTextColor(WHITE);
display.setRotation(0);
display.clearDisplay();
BLE.begin();
Serial.println("\n start BLE peripherals - Temperature/Pressure/Humidity + ssd1306");
// start scanning for peripherals
BLE.scanForName(localNAME);
}
void loop() {
display.clearDisplay();
display.setCursor(0, 0);
// check if a peripheral has been discovered
BLEDevice peripheral = BLE.available();
if (peripheral) {
// discovered a peripheral, print out address, local name, and advertised service
Serial.print("Found ");
Serial.print(peripheral.address());
Serial.print(" '");
Serial.print(peripheral.localName());
Serial.print("' ");
Serial.print(peripheral.advertisedServiceUuid());
Serial.println();
if (peripheral.localName() != localNAME) {
return;
}
// stop scanning
BLE.stopScan();
readData(peripheral);
// peripheral disconnected, start scanning again
BLE.scanForName(localNAME);
}
}
void readData(BLEDevice peripheral) {
uint16_t temperature;
uint16_t pressure;
uint16_t humidity;
byte buffer[2] ;
// connect to the peripheral
Serial.print("\nConnecting ...");
if (peripheral.connect()) {
Serial.println("Connected");
} else {
Serial.println("Failed to connect!");
return;
}
// discover peripheral attributes
Serial.print("Discovering attributes ...");
if (peripheral.discoverAttributes()) {
Serial.println("Attributes discovered\n");
} else {
Serial.println("Attribute discovery failed!");
peripheral.disconnect();
return;
}
// retrieve the characteristic
BLECharacteristic Temperature_Characteristic = peripheral.characteristic(BME280_Temp_Characteristic_UUID);
BLECharacteristic Pressure_Characteristic = peripheral.characteristic(BME280_Press_Characteristic_UUID);
BLECharacteristic Humidity_Characteristic = peripheral.characteristic(BME280_Humidity_Characteristic_UUID);
if (!Temperature_Characteristic) {
Serial.println("Peripheral does not have Temp characteristic!");
peripheral.disconnect();
return;
}
Serial.println("---Found CHARACTERISTIC_UUID");
while (peripheral.connected()) {
if (Temperature_Characteristic.canRead()) {
Serial.print("\ntemp = ");
Temperature_Characteristic.readValue(buffer,2);
temperature = (uint8_t)buffer[1]*256 + (uint8_t)buffer[0];
Serial.println(temperature / 100.0);
}
if (Pressure_Characteristic.canRead()) {
Serial.print("Pressure = ");
Pressure_Characteristic.readValue(buffer,2);
pressure = (uint8_t)buffer[1]*256 + (uint8_t)buffer[0];
Serial.println((pressure / 10.0),1);
}
if (Humidity_Characteristic.canRead()) {
Serial.print("Humidity = ");
Humidity_Characteristic.readValue(buffer,2);
humidity = (uint8_t)buffer[1]*256 + (uint8_t)buffer[0];
Serial.println((humidity / 10.0),1);
}
display.clearDisplay();
display.setCursor(0, 0);
display.println("Temperature - `C");
display.print(temperature / 100.0, 2);
display.println("");
display.println("");
display.println("Pressure - hPa");
display.print(pressure / 10.0, 1);
display.println("");
display.println("");
display.println("Humidity - %");
display.print(humidity / 10.0, 1);
display.println("");
display.display();
delay(1000);
}
Serial.println("Peripheral disconnected");
}
실행 예시입니다.
'아두이노우노 R4' 카테고리의 다른 글
Bluetooth HM-10 BLE module 서로 통신하는 방법 (0) | 2024.11.12 |
---|---|
DIY 홈보안 시스템 Arduino Uno R4 Wi-Fi키패드 LCD 디스플레이 (2) | 2024.11.02 |
아두이노 OLED 메뉴 디스플레이 (2) | 2024.11.01 |
UNO R4 WiFi BLE ⑤ BME280의 BLE peripheral (2) | 2024.10.11 |
UNO R4 WiFi BLE ④ 기압 센서 BME280을 연결 (3) | 2024.10.11 |
UNO R4 WiFi BLE ③ LPS22의 BLE 주변기기와 연결되는 센트럴 (2) | 2024.10.11 |
Arduino를 사용한 스마트 주차 시스템 (7) | 2024.10.04 |
ADXL345 가속도계와 아두이노 UNO 연동하기 (5) | 2024.09.11 |
더욱 좋은 정보를 제공하겠습니다.~ ^^