#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: ble.dart import 'package:flutter/material.dart'; import 'package:flutter_reactive_ble/flutter_reactive_ble.dart'; import 'dart:async'; class BLE{ BLE(); final frb = FlutterReactiveBle(); StreamSubscription? subscription; late StreamSubscription connection; late QualifiedCharacteristic tx; late QualifiedCharacteristic rx; String status = 'not connected'; static final String BASE = "-0000-1000-8000-00805f9b34fb"; static int response = 0; int value = 0; Future stopScan() async { await subscription?.cancel(); subscription = null;} String getStatus(){ return status;} void sendData() async { await frb.writeCharacteristicWithoutResponse(tx, value:[0x24,0x54]);} int readData() { return response; } void connectToBLE() async { subscription = frb.scanForDevices(withServices: [Uuid.parse("0000ffe0"+BASE)]).listen((device){ connection = frb.connectToDevice(id: device.id).listen((state){ if (state.connectionState == DeviceConnectionState.connected) { // get tx tx = QualifiedCharacteristic( serviceId: Uuid.parse("0000ffe0"+BASE), characteristicId: Uuid.parse("0000ffe1"+BASE), deviceId: device.id); // get rx rx = QualifiedCharacteristic( serviceId: Uuid.parse("0000ffe0"+BASE), characteristicId: Uuid.parse("0000ffe1"+BASE), deviceId: device.id); // 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'; stopScan();} }, onError: (Object e) { // connecting error print('error: $e\n'); }); }, onError:(Object e){ // scan 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: 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)]);}} /////////////// 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)) ]);}}