// version 2 of pico ble flutter using flutter_reactive_ble // no scan needed, assume you know the id of the device #filename:uart_test.py #uses hm19 ble module - amazon item #8541588324 #pico pin4 - hm-19 rxd #pico pin5 - hm-19 txd #pico pin40 - hm-19 vcc from machine import UART,Pin,ADC import time uart=UART(1,9600) led = Pin(25,Pin.OUT) temp = ADC(4) while 1: time.sleep_ms(500) uart.write(str(temp.read_u16())) if uart.any() > 0: try: a,b = uart.read() if int(a) == 36 and int(b) == 84: led.toggle() except Exception as error: pass ////////////////////filename: main.dart // ble demo // flutter: // change minsdk to 21 // make sure bluetooth is on // give location permission to app import 'package:flutter/material.dart'; import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; import 'ble.dart'; import 'sendbutton.dart'; import 'connectbutton.dart'; import 'readbutton.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', home: MyHomePage(title: 'BLE demo'),);}} class MyHomePage extends StatefulWidget { MyHomePage({Key? key, required this.title}) : super(key: key); final String title; @override MyHomePageState createState() => MyHomePageState();} class MyHomePageState extends State with TickerProviderStateMixin { late TabController tabController; BLE ble = BLE(); String status = 'not connected'; @override void initState(){ super.initState(); ble.connectToBLE(); tabController = TabController(length: 3, vsync: this); tabController.addListener((){ setState((){ status = ble.getStatus(); }); }); } @override Widget build(BuildContext context) { status = ble.getStatus(); return Scaffold( appBar: AppBar( title: Text(widget.title), backgroundColor: Colors.black, bottom: TabBar( controller: tabController, indicator: BoxDecoration( borderRadius: BorderRadius.circular(50), color: Colors.greenAccent), tabs: const [ Tab(icon: Icon(Icons.home)), Tab(icon: Icon(Icons.light_mode)), Tab(icon: Icon(Icons.thermostat)),],),), body: TabBarView( controller: tabController, children: [ ConnectButton(ble, status), SendButton(ble), ReadButton(ble) ]));}} //////////////////// filename: g.dart class G { static final String myId = 'A4:DA:32:55:06:1E'; static final String BASE = "-0000-1000-8000-00805f9b34fb"; static final String service = "0000ffe0"+BASE; static final String tx = "0000ffe1"+BASE; static final String rx = "0000ffe1"+BASE; } //////////////////// filename: ble.dart import 'package:flutter/material.dart'; import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; import 'dart:async'; import 'g.dart'; class BLE{ BLE(); final frb = FlutterReactiveBle(); late StreamSubscription connection; late QualifiedCharacteristic tx; late QualifiedCharacteristic rx; String status = 'not connected'; static int response = 0; int value = 0; String getStatus(){ return status;} void sendData() async { await frb.writeCharacteristicWithoutResponse(tx, value:[0x24,0x54]);} int readData() { return response; } void connectToBLE() async { connection = frb.connectToDevice(id: G.myId).listen((state){ if (state.connectionState == DeviceConnectionState.connected) { // get tx tx = QualifiedCharacteristic( serviceId: Uuid.parse(G.service), characteristicId: Uuid.parse(G.tx), deviceId: G.myId ); // get rx rx = QualifiedCharacteristic( serviceId: Uuid.parse(G.service), characteristicId: Uuid.parse(G.tx), deviceId: G.myId); // subscribe to rx frb.subscribeToCharacteristic(rx).listen((data){ value = 0; value += (data[0] - 48).toUnsigned(8) * 10000; value += (data[1] - 48).toUnsigned(8) * 1000; value += (data[2] - 48).toUnsigned(8) * 100; value += (data[3] - 48).toUnsigned(8) * 10; value += (data[4] - 48).toUnsigned(8) * 1; response = value; }, onError:(Object e){ print('subscribe error: $e\n'); }); status = 'connected'; } }, onError: (Object e) { // connecting error print('error: $e\n'); });}} ///////////////////////////// filename: connectbutton.dart import 'package:flutter/material.dart'; import 'ble.dart'; class ConnectButton extends StatelessWidget { final BLE ble; final String status; ConnectButton(this.ble, this.status); @override Widget build(BuildContext c){ return Column( children: [ SizedBox(height:50), Text('status: $status'), SizedBox(height:50), Text('make sure bluetooth is on\ngive location permission to the app\nchange build.gradle minSkVersion to 21\ndemo uses flutter_reactive_ble 3.1.1', style: TextStyle(fontSize:35, fontWeight:FontWeight.bold)), SizedBox(height:50), Text('flutter_reactive_ble 3.1.1', style: TextStyle(fontSize:30))]);}} //////////////////// filename: readbutton.dart import 'package:flutter/material.dart'; import 'ble.dart'; class ReadButton extends StatefulWidget { final BLE ble; ReadButton(this.ble); @override ReadButtonState createState() => ReadButtonState();} class ReadButtonState extends State { int value = 0; double farenheit = 0.0; String s = ' '; @override Widget build(BuildContext c){ return Column( children: [ SizedBox(height:70), ElevatedButton( child: Text('read picos temp'), onPressed:() { value = widget.ble.readData(); farenheit = value.toDouble(); farenheit *= 3.3 / (65535); farenheit = 27 - (farenheit - 0.706) / 0.001721; farenheit = farenheit * (9 / 5) + 32; farenheit = double.parse((farenheit).toStringAsFixed(2)); setState((){ s = farenheit.toString(); }); },), SizedBox(height:70), Text('pico temp: $s', style: TextStyle(fontSize:40, fontWeight: FontWeight.bold, color: farenheit > 72.00 ? Colors.red : Colors.green)) ]);}} //////////////////// filename: sendbutton.dart import 'package:flutter/material.dart'; import 'ble.dart'; class SendButton extends StatelessWidget { final BLE ble; SendButton(this.ble); @override Widget build(BuildContext c){ return Column(children: [ SizedBox(height:70), ElevatedButton( child: Text('toggle led',style:TextStyle(fontSize:40,fontWeight:FontWeight.bold)), onPressed: ble.sendData)]);}}