KoreaTech

[Arduino] Arduino BLE Example

졸려질려 2020. 4. 22. 16:45
반응형

원문 링크 : https://rootsaid.com/arduino-ble-example/

Arduino BLE Example Code Explained

이번 글에서는 BLE(Bluetooth Low Energy)에 대한 기초 지식을 알고, Arduino BLE 칩셋과 다른 기기들 사이에 무선으로 데이터를 주고받는 방법을 알아보자.


Arduino Nano 33 BLE Sense

Arduino Nano 33 BLE Sense는 IoT 환경에서 BLE 연결성이 강조된 Arduino Nano 모델의 최신 버전이다. 해당 제품은 9축 관성(Inertial) 측정 장치부터 압력, 빛, 제스처 센서 그리고 마이크까지 포함된 다양한 센서들을 가지고 있다.

전원은 BLE 뿐만 아니라 Bluetooth 5 연결도 지원하는 Nina B306 모듈에 의해서 인가된다. 내장된 Bluetooth 모듈은 매우 낮은 에너지를 소모하고** Arduino 라이브러리를 사용해서 쉽게 접근 가능하다. 때문에 **프로그래밍이 쉽고, 어느 프로젝트에도 무선 연결이 가능하다. 따라서 프로젝트에 Bluetooth 기능을 추가하기 위해서 외부 Bluetooth 모듈을 따로 사용할 필요가 없을 것이다. 공간과 파워를 절약한다.


Arduino BLE - Bluetooth Low Energy Introduction

BLE는 Bluetooth의 버전들 중 하나로, 낮은 데이터 전송률을 가지고 매우 적은 파워를 소비해야하는 상황을 위해 최적화 되어있다. 우리는 1개의 Coin Cell(단추형 전지)로 몇주부터 심지어 몇달까지 여러 장치들을 동작할 수 있다.

Arduino는 Introduction to BLE를 잘 만들어두었지만, 이번 글에서는 독자가 BLE 통신을 바로 시작할 수 있도록 짧게 소개를 하려고 한다.

기본적으로, 우리가 BLE 통신 영역을 구성하려고 할 때 2가지 유형의 기기가 있다.

  • The Peripheral Device(주변 장치)
  • The Central Device(중앙 장치)

주변 장치는 공지 게시판(Notice board) 같이 다양한 공지(Notice)들로부터 데이터를 읽을 수 있고 새로운 공지들을 게시판에 등록(Pin)하는 기능을 한다. 이러한 정보가 필요한 모든 기기들을 위해 데이터를 게시한다.

중앙 장치는 공지 게시판에서 공지를 읽는 사람과 같다. 다수의 사용자들은 동시에 공지 게시판으로부터 데이터를 읽고 얻을 수 있다. 이와 비슷하게 다수의 중앙 장치들은 동시에 주변 장치로부터 데이터를 읽을 수 있다.

가속도계(Accelerometer)가 서비스인 경우 X,Y 및 Z 값은 세 가지 특성이 될 수 있다.

이제 간단한 Arduino BLE 예제를 보도록 하자.


Arduino BLE Example 1 - Battery Level Indicator

이번 예제에서 BLE를 통해 스마트폰을 사용하여 Arduino의 A0 핀과 연결된 배터리 레벨을 읽는 방법을 알아보자.

먼저 library manager를 통해 ArduinoBLE 라이브러리를 설치 해야한다.


Arduino BLE Tutorial Battery Level Indicator Code

# include <ArduinoBLE.h>
BLEService batteryService("1101");
BLEUnsignedCharCharacteristic batteryLevelChar("2101", BLERead | BLENotify);

void setup() {
  Serial.begin(9600);
  while(!Serial);

  pinMode(LED_BUILTIN, OUTPUT);
  if(!BLE.begin()) {
    Serial.println("Starting BLE Failed!");
    while(1);
  }

  BLE.setLocalName("BatteryMonitor");
  BLE.setAdvertisedService(batteryService);
  batteryService.addCharacteristic(batteryLevelChar);
  BLE.addService(batteryService);

  BLE.advertise();
  Serial.println("Bluetooth Device Active, Waiting for Connections...");
}

void loop() {
  BLEDevice central = BLE.central();

  if(central) {
    Serial.print("Connected to Central: ");
    Serial.println(central.address());
    digitalWrite(LED_BUILTIN, HIGH);

    while(central.connected()) {
      int battery = analogRead(A0);
      int batteryLevel = map(battery, 0, 1023, 0, 100);

      Serial.print("Battery Level % is now : ");
      Serial.println(batteryLevel);
      batteryLevelChar.writeValue(batteryLevel);
      delay(200);
    }
  }

  digitalWrite(LED_BUILTIN, LOW);
  Serial.print("Disconnected from Central: ");
  Serial.println(central.address());
}

Arduino BLE Tutorial Battery Level Indicator Code Explained

# include <ArduinoBLE.h>
BLEService batteryService("1101");
BLEUnsignedCharCharacteristic batteryLevelChar("2101", BLERead | BLENotify);

코드의 첫번째는 ArduinoBLE.h 파일을 include 하는 것이다. 그런 다음 Battery ServiceBattery Level Characteristics도 여기에 선언한다. 이곳에서 우리는 두 권한(BLERead, BLENotify)을 부여한다.

BLERead는 중앙 장치(Mobile Phone)가 주변 장치(Arduino)로부터 데이터를 읽을 수 있게 해준다. 그리고 BLENotify는 원격 Client가 특성(Characteristic)이 바뀌었는지 공지를 받을 수 있게 해준다.

Setup 함수로 넘어가보자.

Serial.begin(9600);
while(!Serial);

pinMode(LED_BUILTIN, OUTPUT);
if(!BLE.begin()) {
  Serial.println("Starting BLE Failed!");
  while(1);
}

여기서는 Serial 통신과 BLE를 초기화하고, Serial Monitor가 열리기를 기다린다.

이제 BLE 장치에 로컬 이름을 설정한다. 그 이름은 홍보 패킷(Advertising Packet)에 나타날 것이고 원격 기기들이 BLE 기기를 식별하기 위해 사용될 수 있다.

BLE.setLocalName("BatteryMonitor");
BLE.setAdvertisedService(batteryService);
batteryService.addCharacteristic(batteryLevelChar);
BLE.addService(batteryService);

이 부분에서는 Service UUID와 그 특징에 대한 값을 추가하고 설정한다.

BLE.advertise();
Serial.println("Bluetooth Device Active, Waiting for Connections...");

그리고 여기서는, BLE 홍보를 시작한다. 계속해서 BLE 홍보 패킷들을 보낼 것이고 원격 BLE 중앙 기기들이 새 연결을 받을 때까지 보여지게 된다.

LEDevice central = BLE.central();

if(central) {
  Serial.print("Connected to Central: ");
  Serial.println(central.address());
  digitalWrite(LED_BUILTIN, HIGH);

이제 loop 함수이다. 모든 것이 설정되고 홍보가 시작되면, 해당 기기는 중앙 기기를 기다린다. 그리고 연결되는 순간, 연결된 기기의 MAC 주소를 보여주고 내장된 LED에 불이 들어올 것이다.

while(central.connected()) {
  int battery = analogRead(A0);
  int batteryLevel = map(battery, 0, 1023, 0, 100);

  Serial.print("Battery Level % is now : ");
  Serial.println(batteryLevel);
  batteryLevelChar.writeValue(batteryLevel);
  delay(200);
}

지금, A0로부터 아날로그 전압을 읽기 시작할 것이다. 실제로 0에서 1023 사이에 값이지만 0부터 100 사이에 값으로 매핑되어 보여질 것이다. Serial Monitor에서 Battery Level을 보여줄 것이고 그 값은 batteryLevelChar 특성에 쓰여질 것이다. 그리고 200 ms를 대기한다. 그 후에는 중앙 기기가 주변 기기와 연결된 시간만큼 loop는 계속 실행될 것이다.

digitalWrite(LED_BUILTIN, LOW);
Serial.print("Disconnected from Central: ");
Serial.println(central.address());

연결이 끊기면, 중앙 기기를 보여주는 메시지가 나오고 LED가 꺼질 것이다.


Installing the App for Android

Android 스마트폰에서 "nRF Connect" 앱을 설치한다.

앱을 실행하고 스캔을 시작한다. 그럼 기기 목록에서 "Battery Monitor" 라는 기기를 볼 수 있다. 그것을 누르면 연결이 되면서 새 화면이 열린다.

해당 화면에서 기기의 서비스들과 특성들을 볼 수 있다. "Battery Service"를 누르면 Arduino로부터 읽고 있는 Battery Level을 확인할 수 있다.

반응형