ArduinoとBluetoothモジュールでスマホと通信
Arduino UnoとBluetoothモジュール(Bluefruit LE UART Friend)を使って、iPhoneとBluetooth通信してみた。この記事ではそのやり方を解説していく。
ArduinoとBluetoothモジュールの配線
Bluefruit | Arduino UNO |
---|---|
DFU | 未接続 |
GND | GND |
RTS | 未接続 |
VIN | 5V |
RXI | DIGITAL 9 |
TXO | DIGITAL 10 |
CTS | DIGITAL 11 |
MOD | 未接続 |
BluefruitのスイッチはUART側に設定する。
Bluetoothモジュールからのメッセージをスマホで受信
スマホからBluefruitに接続する専用のアプリがあるのでインストールする。Arduinoにプログラムを書き込まなくても電源を入れれば、Bluefruitとは接続できる。
iOS版
Android版
今度はArduinoのIDE側の設定、サンプルコード(Adafruit_BluefruitLE_nRF51)をこちらからダウンロードする。
解凍したらフォルダ名をAdafruit_BluefruitLE_nRF51にし、Arduinoのライブラリフォルダに取り入れる。Finderの場所は、Documents → Arduino → librariesとなっている。するとArduino IDEのスケッチ例の中にAdafruit_BluefruitLE_nRF51のサンプルコードが表示される。
Bluetooth動作テストのためのArduinoスケッチ
サンプルコードを元に改造していく。適当な文字を1秒間に1回、アプリへ送信するだけの簡単なプログラムを作ってみた。
/*
Created by Toshihiko Arai.
https://101010.fun/iot/arduino-bluetooth.html
*/
#include <Arduino.h>
#include <SPI.h>
#include "Adafruit_BLE.h"
#include "Adafruit_BluefruitLE_SPI.h"
#include "Adafruit_BluefruitLE_UART.h"
#if SOFTWARE_SERIAL_AVAILABLE
#include <SoftwareSerial.h>
#endif
// Arduino UNOの場合この設定でうまくいった
//
#define BLUEFRUIT_SWUART_RXD_PIN 9 // Required for software serial!
#define BLUEFRUIT_SWUART_TXD_PIN 10 // Required for software serial!
#define BLUEFRUIT_UART_CTS_PIN 11 // Required for software serial!
#define BLUEFRUIT_UART_RTS_PIN -1 // Optional, set to -1 if unused
#define BLUEFRUIT_UART_MODE_PIN -1 // Set to -1 if unused
#define VERBOSE_MODE true // If set to 'true' enables debug output
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);
void error(const __FlashStringHelper*err) {
Serial.println(err);
while (1);
}
void setup(void)
{
while (!Serial); // required for Flora & Micro
delay(500);
Serial.begin(9600);
if ( !ble.begin(VERBOSE_MODE) )
{
error(F("Couldn't find Bluefruit, make sure it's in CoMmanD mode & check wiring?"));
}
Serial.println( F("OK!") );
}
void loop(void)
{
delay(1000);
ble.write("debug\n");
}
プログラムをArduinoにアップロードし、アプリでArduinoに接続してみる。動画のようにArduinoからのメッセージをBluetooth通信で受信できた。
Bluefruit LE UART Friendの情報はこちら
iPhoneとArudinoのBluetooth通信
今度はiPhoneからArduinoへBluetoothでメッセージを送ってみよう。図のやりとりを、SwiftでCoreBlueToothを使ってプログラミングしていく。
iPhoneからArduinoへBluetoothでメッセージ送信
Bluetooth通信のSwiftプログラム
/*
Created by Toshihiko Arai.
https://101010.fun/iot/arduino-bluetooth.html
*/
import UIKit
import CoreBluetooth
class ViewController: UIViewController {
@IBOutlet weak var reciveTextView: UITextView!
let kUARTServiceUUID = "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UARTサービス
let kTXCharacteristicUUID = "6E400002-B5A3-F393-E0A9-E50E24DCCA9E" // ペリフェラルへ送信用
let kRXCharacteristicUUID = "6E400003-B5A3-F393-E0A9-E50E24DCCA9E" // ペリフェラルからの受信用
var centralManager: CBCentralManager!
var peripheral: CBPeripheral!
var serviceUUID : CBUUID!
var kTXCBCharacteristic: CBCharacteristic!
var kRXCBCharacteristic: CBCharacteristic!
// var charcteristicUUID: CBUUID!
var charcteristicUUIDs: [CBUUID]!
@IBOutlet weak var sendMessageTextField: UITextField!
@IBAction func clickedConnectButton(_ sender: Any) {
setup()
}
@IBAction func clickedWriteButton(_ sender: Any) {
let peripheral = self.peripheral
if(peripheral == nil) { return }
let writeData = sendMessageTextField.text!.data(using: .utf8)!
peripheral!.writeValue(writeData, for: kTXCBCharacteristic, type: .withResponse)
sendMessageTextField.text = ""
}
override func viewDidLoad() {
super.viewDidLoad()
}
/// セントラルマネージャー、UUIDの初期化
private func setup() {
centralManager = CBCentralManager()
centralManager.delegate = self as CBCentralManagerDelegate
// centralManager.scanForPeripherals(withServices: nil, options: nil)
serviceUUID = CBUUID(string: kUARTServiceUUID)
charcteristicUUIDs = [CBUUID(string: kTXCharacteristicUUID), CBUUID(string: kRXCharacteristicUUID)]
}
}
//MARK : - CBCentralManagerDelegate
extension ViewController: CBCentralManagerDelegate {
func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch central.state {
//電源ONを待って、スキャンする
case CBManagerState.poweredOn:
let services: [CBUUID] = [serviceUUID]
centralManager?.scanForPeripherals(withServices: services,
options: nil)
default:
break
}
}
/// ペリフェラルを発見すると呼ばれる
func centralManager(_ central: CBCentralManager,
didDiscover peripheral: CBPeripheral,
advertisementData: [String : Any],
rssi RSSI: NSNumber) {
self.peripheral = peripheral
centralManager?.stopScan()
//接続開始
central.connect(peripheral, options: nil)
}
/// 接続されると呼ばれる
func centralManager(_ central: CBCentralManager,
didConnect peripheral: CBPeripheral) {
peripheral.delegate = self
peripheral.discoverServices([serviceUUID])
}
}
//MARK : - CBPeripheralDelegate
extension ViewController: CBPeripheralDelegate {
/// サービス発見時に呼ばれる
func peripheral(_ peripheral: CBPeripheral,
didDiscoverServices error: Error?) {
if error != nil {
print(error.debugDescription)
return
}
//キャリアクタリスティク探索開始
peripheral.discoverCharacteristics(charcteristicUUIDs,
for: (peripheral.services?.first)!)
}
/// キャリアクタリスティク発見時に呼ばれる
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
if error != nil {
print(error.debugDescription)
return
}
for characteristics in service.characteristics! {
if(characteristics.uuid == CBUUID(string: kTXCharacteristicUUID)) {
// peripheral.setNotifyValue(true, for: (service.characteristics?[1])!)
self.kTXCBCharacteristic = characteristics
addMessageToTextView("Found TX characteristics !\n")
} else if(characteristics.uuid == CBUUID(string: kRXCharacteristicUUID)) {
self.kRXCBCharacteristic = characteristics
addMessageToTextView("Found RX characteristics !\n")
}
}
if(self.kRXCBCharacteristic != nil) {
startReciving()
}
}
private func startReciving() {
peripheral.setNotifyValue(true, for: kRXCBCharacteristic)
addMessageToTextView("Start monitoring the message from Arduino.\n\n")
}
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
print(#function)
if error != nil {
print(error.debugDescription)
return
}
}
/// データ更新時に呼ばれる
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
if error != nil {
print(error.debugDescription)
return
}
updateWithData(data: characteristic.value!)
}
private func updateWithData(data : Data) {
if let dataString = String(data: data, encoding: String.Encoding.utf8) {
addMessageToTextView(dataString)
}
}
private func addMessageToTextView(_ message:String) {
reciveTextView.text = reciveTextView.text + message
scrollToBottom(reciveTextView)
}
private func scrollToBottom(_ textView:UITextView) {
textView.selectedRange = NSRange(location: textView.text.count, length: 0)
textView.isScrollEnabled = true
let scrollY = textView.contentSize.height - textView.bounds.height
let scrollPoint = CGPoint(x: 0, y: scrollY > 0 ? scrollY : 0)
textView.setContentOffset(scrollPoint, animated: true)
}
}
Bluetooth通信のArduinoスケッチ
/*
Created by Toshihiko Arai.
https://101010.fun/iot/arduino-bluetooth.html
*/
#include <string.h>
#include <Arduino.h>
#include <SPI.h>
#include "Adafruit_BLE.h"
#include "Adafruit_BluefruitLE_SPI.h"
#include "Adafruit_BluefruitLE_UART.h"
#if SOFTWARE_SERIAL_AVAILABLE
#include <SoftwareSerial.h>
#endif
// Arduino UNOの場合この設定でうまくいった
//
#define BLUEFRUIT_SWUART_RXD_PIN 9 // Required for software serial!
#define BLUEFRUIT_SWUART_TXD_PIN 10 // Required for software serial!
#define BLUEFRUIT_UART_CTS_PIN 11 // Required for software serial!
#define BLUEFRUIT_UART_RTS_PIN -1 // Optional, set to -1 if unused
#define BLUEFRUIT_UART_MODE_PIN -1 // Set to -1 if unused
#define VERBOSE_MODE false // If set to 'true' enables debug output
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);
void error(const __FlashStringHelper*err) {
Serial.println(err);
while (1);
}
void setup(void)
{
while (!Serial); // required for Flora & Micro
delay(500);
Serial.begin(9600);
if ( !ble.begin(VERBOSE_MODE) )
{
error(F("Couldn't find Bluefruit, make sure it's in CoMmanD mode & check wiring?"));
}
Serial.println( F("OK!") );
}
void loop(void)
{
int n = 0;
int maxMessageLength = 50;
char recivedMessage[maxMessageLength];
while ( ble.available() ) {
int c = ble.read();
// 起動時に255(0xFF)の出力をスルー
if(c != 0xFF) {
if(maxMessageLength > (n - 1)) {
recivedMessage[n] = (char)c;
n++;
}
}
}
if(n > 0) {
recivedMessage[n] = '\0';
ble.write("Arduino got your message is...\n");
ble.write(recivedMessage);
ble.write("\n");
}
}
プログラムをそれぞれ実行すると、メッセージを送受信できる。
ArduinoとiPhone間のBluetooth通信に成功
参考サイト
Arduinoの参考書
本書では、開発者自らが、Arduinoの哲学、ハードウェア、ソフトウェアの基礎を解説、誰にでもできる簡単なチュートリアルを行います。
Amazon最後まで読んでいただきありがとうございました。
「この記事が参考になったよ」という方は、ぜひ記事をシェアをしていただけるととても嬉しいです。
今後も有益な記事を書くモチベーションにつながりますので、どうかよろしくお願いいたします。↓↓↓↓↓↓↓