Nahtlose serielle Bluetooth-Kommunikation auf Raspberry Pi 2 mit Windows 10 IoT Core
Komponenten und Zubehör
| Raspberry Pi 2 Model B | × | 1 |
| Generischer Bluetooth-USB-Dongle | × | 1 |
| Arduino UNO | × | 1 |
| SparkFun Bluetooth Modem – BlueSMiRF Silver | × | 1 |
Apps und Online-Dienste
- Microsoft Windows 10 IoT Core
- Microsoft Visual Studio 2015
Projektbeschreibung
Dieses Projekt zeigt eine Universal Windows App (UWP), die einen Raspberry Pi 2 unter Windows 10 IoT Core per Bluetooth Serial Port Profile (SPP) mit einem eingebetteten Bluetooth-Gerät verbindet. Ein generischer Bluetooth-USB-Dongle dient als Schnittstelle. Die App wurde mit einem sehr alten Dongle entwickelt und sollte daher mit nahezu jedem Bluetooth-Dongle funktionieren.
Hintergrund: Bluetooth-Profile
Bluetooth ermöglicht Peer-to-Peer-Vernetzung über kurze Distanz. Im Gegensatz zu WLAN ist die Verbindung 1:1. Zwei Geräte können symmetrisch (z. B. OBEX) oder asymmetrisch (z. B. A2DP Audio-Streaming) kommunizieren.
Das Microsoft IoT-Core Bluetooth-Beispiel nutzt GATT (Generic Attribute Profile) für Bluetooth Low Energy. Dieses Projekt ist deutlich simpler: Es verwendet ausschließlich das Serial Port Profile (SPP) basierend auf RFCOMM – ideal für klassische serielle Datenübertragung zwischen Mikrocontrollern.
Die IoT-App (UWP)
Die App listet alle mit dem Pi gepairten Bluetooth-Geräte auf. Per Doppelklick wird eine Verbindung hergestellt. Texteingabe erfolgt per TextBox, Senden per Button. Empfangene Daten werden automatisch angezeigt. Beim Test-Endpunkt (Arduino mit Echo-Sketch) erscheint der gesendete Text wieder im Empfangsfeld.
Der Endpunkt (Arduino + Bluetooth-Modul)
Ein Arduino Uno mit BlueSMiRF Silver (oder vergleichbarem Modul) dient als Gegenstelle. Der Sketch echoed jeden empfangenen Character zurück.
Shield-Setup
void setup() {
Serial.begin(115200); // Baudrate des BT-Moduls (im Command Mode gesetzt)
delay(333);
while (!Serial);
delay(1000);
Serial.println("The quick brown fox jumps over the lazy dog!");
}
Shield-Loop (Echo)
void loop() {
char ch = Serial.read();
while (255 == (byte)ch) { ch = Serial.read(); } // Warten auf gültiges Byte
Serial.print(ch); // Zurücksenden
}
Wichtig: BT-Adapter zum Programmieren vom Arduino trennen (RX/TX-Konflikt).
Pairing (Kopplung)
Bluetooth-Geräte müssen vor der Verbindung gepairt werden. Da IoT-Core-Geräte oft „headless“ sind (kein Display, keine Popups), erfolgt Pairing über:
- IoT-Core Web-Portal (neuere Versionen unterstützen Passkey-Pairing)
- Kommandozeilen-Tool per SSH
Details zum Pairing finden sich im verlinkten Artikel „Win 10 IoT-Core: Bluetooth Universal Windows Serial App“ auf embedded101.com.
Projekt in Visual Studio 2015 erstellen
Neues Projekt → Visual C# → Windows → Blank App (Universal Windows)
UI in XAML erstellen
- Alle Textelemente:
TextBlock, außer Sende-Feld:TextBox(Multiline/Enter aktiviert) - Empfangsfeld:
TextBlockmitTextWrapping - Layout: Horizontale
StackPanels für Zeilen, diese in vertikalerStackPanelmit derListBox ListBox(ConnectDevices) mit Binding anPairedDevices, ItemTemplate zeigtName
<ListBox x:Name="ConnectDevices"
ItemsSource="{Binding Source={StaticResource PairedDevices}}"
Margin="10" DoubleTapped="ConnectDevices_DoubleTapped"
Width="Auto" Height="Auto">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
App-Konfiguration (Package.appxmanifest)
Da der UI-Editor die nötigen Capabilities nicht unterstützt: Rechtsklick → Open With → XML Editor. Im <Capabilities>-Bereich:
<Capabilities>
<Capability Name="internetClient" />
<DeviceCapability Name="bluetooth.rfcomm">
<Device Id="any">
<Function Type="name:serialPort"/>
</Device>
</DeviceCapability>
</Capabilities>
internetClient ist Standard, für dieses Projekt nicht zwingend nötig.
Gepairte Geräte ermitteln
Beim App-Start werden alle per SPP verfügbaren Geräte asynchron gesucht:
DeviceInformationCollection DeviceInfoCollection
= await DeviceInformation.FindAllAsync(
RfcommDeviceService.GetDeviceSelector(RfcommServiceId.SerialPort));
Die Collection wird in eine ObservableCollection<PairedDeviceInfo> überführt für die ListBox.
_pairedDevices = new ObservableCollection<PairedDeviceInfo>();
foreach (var item in DeviceInfoCollection) {
_pairedDevices.Add(new PairedDeviceInfo {
Name = item.Name,
Id = item.Id,
DeviceInfo = item
});
}
PairedDeviceInfo Klasse:
Name(string)Id(string)DeviceInfo(Windows.Devices.Enumeration.DeviceInformation)
Verbindung aufbauen
Per Doppelklick auf ListBox-Eintrag:
_service = await RfcommDeviceService.FromIdAsync(DeviceInfo.Id);
_socket = new StreamSocket();
await _socket.ConnectAsync(_service.ConnectionHostName, _service.ConnectionServiceName);
Erfolg: _socket ist nicht null. Fehlerbehandlung per try-catch.
Senden/Empfangen nutzt _socket.OutputStream / _socket.InputStream.
Text empfangen (asynchron, separater Thread)
private async void Listen() {
ReadCancellationTokenSource = new CancellationTokenSource();
if (_socket.InputStream != null) {
dataReaderObject = new DataReader(_socket.InputStream);
while (true) {
await ReadAsync(ReadCancellationTokenSource.Token);
}
}
}
private async Task ReadAsync(CancellationToken cancellationToken) {
uint ReadBufferLength = 1024;
cancellationToken.ThrowIfCancellationRequested();
dataReaderObject.InputStreamOptions = InputStreamOptions.Partial;
var loadAsyncTask = dataReaderObject.LoadAsync(ReadBufferLength).AsTask(cancellationToken);
UInt32 bytesRead = await loadAsyncTask;
if (bytesRead > 0) {
string recvdtxt = dataReaderObject.ReadString(bytesRead);
// UI-Update hier (Dispatcher nötig)
}
}
Text senden (synchon aus UI-Sicht)
private async void Send(string msg) {
DataWriter dataWriteObject = new DataWriter(_socket.OutputStream);
dataWriteObject.WriteString(msg);
var storeAsyncTask = dataWriteObject.StoreAsync().AsTask();
UInt32 bytesWritten = await storeAsyncTask;
}
Button-Zustände
Buttons (Senden, Empfang starten) sind nur aktiv, wenn verbunden. Entsprechende Enable/Disable-Logik im Code.
Fertig!
Die App ermöglicht serielle Bluetooth-Kommunikation zwischen Raspberry Pi 2 (IoT Core) und klassischen Bluetooth-Modulen (HC-05, BlueSMiRF, etc.) – basis für viele IoT-Projekte.
Quellcode: GitHub | Codeplex (Mirror)
Herstellungsprozess
- GoPiGo v2 auf Windows 10 IoT Core für Raspberry Pi 3 erweitern
- LED-Helligkeit per PWM und Taster am Arduino Mega steuern
- Präzise Druck- & Luftstrommessung mit analogem Sensor und Arduino
- Echtzeit-Gyroskop-Spiel mit Arduino Nano & MPU-6050
- ESP32-CAM Bewegungserkennungs-Kamera für Discord
- DHT11 Temperatur- & Feuchtesensor mit LED-Anzeige & Piezo-Summer
- Unopad: Nahtloser Arduino MIDI-Controller für Ableton Live
- Selbstbau TV-Fernbedienung: Arduino UNO, batteriebetrieben, 3D-gedrucktes Gehäuse
- LED per Bluetooth mit Arduino steuern – Einfache DIY-Anleitung
- Einfachen Hindernissensor mit Arduino bauen – IR-LED & Photodiode Tutorial