はじめに
タイトルの通り、Wio Terminalの加速度センサ値を、MATLABに送ってそれをリアルタイムに可視化するやり方についてです。Wio TerminalとMATLABの入ったPCの間はBLEで接続し、ワイヤレスで動作します。
元ネタはSeeed公式サイトのこちらで、もともとPC側のアプリケーションがHTMLだったのをMATLABに記述しなおしました。
こんな感じの動きをします
Wio Terminalのセットアップ
Wio TerminalでBluetooth接続するにあたっては、ワイヤレス通信用CPU(RTL8720DN)のファームウェアアップデートを行う必要があります。公式ページはこちらで、日本語記事はこちらが参考になります。
コード
MATLAB側
MATLAB側コードを実行する前に、Wio Terminal側にファームウェアを書き込んだうえで電源を入れておいてください。
Wio Terminal側と問題なく接続できれば、
- Scanning for devices...
- Connecting to device...
- Receiving data...
のメッセージが出た後、加速度センサ値のグラフが表示されます。
ちなみに、ChatGPTで公式のhtmlからMATLABに変換させました。3,4か所ほどの手直しでかなり簡単にできました。
% Bluetooth Accelerometer Plotter for Wio Terminal
% 1. Upload the sketch to your Wio Terminal
% 2. Run this MATLAB script
clear;
close;
% Set up BLE
serviceUuid = "19B10000-E8F2-537E-4F6C-D104768A1214";
characteristicUuid = "19B10010-E8F2-537E-4F6C-D104768A1214";
% Connect to BLE device
disp("Scanning for devices...");
devices = blelist;
device = [];
numDevices = size(devices, 1);
for i = 1:numDevices
if any(strcmp(serviceUuid, devices.Advertisement(i).CompleteServiceUUIDs))
device = devices(i, :);
break;
end
end
if isempty(device)
error("No compatible device found.");
end
disp("Connecting to device...");
b = ble(device.Address{1});
c = characteristic(b, serviceUuid, characteristicUuid);
% Set up plot
xyz_color = ['r','g','b'];
figure;
for i = 1:3
h(i) = animatedline('Marker', 'o', 'Color', xyz_color(i), 'LineStyle', 'none');
end
title('Bluetooth Accelerometer Plotter for Wio Terminal');
xlabel('Time');
ylabel('Acceleration');
legend('X', 'Y', 'Z');
axis([0, 100, -2, 2]);
grid on;
dataPoints = 100;
accelData = zeros(dataPoints, 3);
% Read data and update plot
disp("Receiving data...");
tic;
i = 0;
while isvalid(b)
i = i + 1;
value = read(c, "latest");
accel = sscanf(native2unicode(value), "%f|%f|%f");
% Update data buffer
if i <= dataPoints
accelData(i, :) = accel';
else
accelData = [accelData(2:end, :); accel'];
end
% Update plot
for j = 1:3
clearpoints(h(j));
addpoints(h(j), 1:size(accelData, 1), accelData(:, j));
end
drawnow limitrate;
end
Wio Terminal側
Arduino IDEを使う場合には、適当にコードをIDEにコピペして使ってください。
ほぼ公式のサンプルコードのままですが、画面に加速度センサ値を表示するところだけ追加しました。
こちらの記事にある通り、「Seeed_Arduino_rpcBLE」、「Seeed_Arduino_rpcUnified」などのライブラリが必要です。
// Sample code to send Accelerometer values via Bluetooth.
// Original↓
// https://wiki.seeedstudio.com/Wio-Terminal-Web-Bluetooth/#arduino-set-up-1
#include <rpcBLEDevice.h>
#include <BLEServer.h>
#include <LIS3DHTR.h>
#define accelerometerService "19b10000-e8f2-537e-4f6c-d104768a1214"
#define firstCharacteristic "19b10010-e8f2-537e-4f6c-d104768a1214"
#define DESCRIPTOR_UUID "19b10010"
LIS3DHTR<TwoWire> lis;
#include"TFT_eSPI.h"
TFT_eSPI tft;
bool deviceConnected = false;
bool oldDeviceConnected = false;
BLEServer *pServer = NULL;
BLECharacteristic * pCharacteristic;
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
Serial.println("MyServerCallbacks onConnect ");
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
}
};
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string rxValue = pCharacteristic->getValue();
if (rxValue.length() > 0) {
Serial.println("*********");
Serial.print("Received Value: ");
for (int i = 0; i < rxValue.length(); i++)
Serial.print(rxValue[i]);
Serial.println();
Serial.println("*********");
}
}
};
void setup() {
Serial.begin(115200);
// while(!Serial){};
lis.begin(Wire1);
if (!lis) {
Serial.println("Accelerater Error!");
while(1);
}
lis.setOutputDataRate(LIS3DHTR_DATARATE_25HZ); //Data output rate
lis.setFullScaleRange(LIS3DHTR_RANGE_2G); //Scale range set to 2g
Serial.println("Accelerater Initialised!");
Serial.println("Starting BLE work!");
BLEDevice::init("Accelerometer");
pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
BLEService *pService = pServer->createService(accelerometerService);
pCharacteristic = pService->createCharacteristic(
firstCharacteristic,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setAccessPermissions(GATT_PERM_READ | GATT_PERM_WRITE);
BLEDescriptor *pDescriptor = pCharacteristic->createDescriptor(
DESCRIPTOR_UUID,
ATTRIB_FLAG_VOID | ATTRIB_FLAG_ASCII_Z,
GATT_PERM_READ | GATT_PERM_WRITE,
2
);
pCharacteristic->setCallbacks(new MyCallbacks());
pService->start();
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(accelerometerService);
pAdvertising->setScanResponse(true);
pAdvertising->setMinPreferred(0x06); // functions that help with iPhone connections issue
pAdvertising->setMinPreferred(0x12);
BLEDevice::startAdvertising();
Serial.println("Characteristic defined! Now you can read it in your phone!");
// setup for display
tft.begin();
tft.setRotation(3);
tft.fillScreen(TFT_BLACK); //Black background
tft.setTextColor(TFT_WHITE, TFT_BLACK); //White text color
}
void loop() {
if (deviceConnected) {
updateAcceleration();
}
// disconnecting
if (!deviceConnected && oldDeviceConnected) {
delay(500); // give the bluetooth stack the chance to get things ready
pServer->startAdvertising(); // restart advertising
Serial.println("start advertising");
oldDeviceConnected = deviceConnected;
}
// connecting
if (deviceConnected && !oldDeviceConnected) {
// do stuff here on connecting
oldDeviceConnected = deviceConnected;
}
}
void updateAcceleration() {
float x_values, y_values, z_values;
x_values = lis.getAccelerationX();
y_values = lis.getAccelerationY();
z_values = lis.getAccelerationZ();
String accelerometerData = String(x_values)+"|"+String(y_values)+"|"+String(z_values);
Serial.println(accelerometerData);
pCharacteristic->setValue(accelerometerData.c_str());
pCharacteristic->notify();
// show xyz values on the display
char x_str[100], y_str[100], z_str[100];
dtostrf(x_values, 6, 2, x_str);
dtostrf(y_values, 6, 2, y_str);
dtostrf(z_values, 6, 2, z_str);
tft.drawString(x_str, 70, 60, 6);
tft.drawString(y_str, 70,110, 6);
tft.drawString(z_str, 70,160, 6);
delay(20);
}
おわりに
Wio Terminalの加速度センサ値を、MATLABでリアルタイム可視化するやり方について書きました。間違い等ありましたらコメントお願いします。
Wio Terminal、最近あまり見かけなくなりましたが私は好きです。画面でかくてボタン多いところとか。
しばしばセールで4000円台で売ってたりするので、またブームになって欲しいです。