forked from FOSS/BangleApps
Add Bluetooth multimeter support
parent
6b5cc8b536
commit
39598a2d1f
|
@ -0,0 +1 @@
|
|||
0.01: New App!
|
|
@ -0,0 +1,32 @@
|
|||
# Bluetooth Multimeter
|
||||
|
||||
Connect to compatible a Bluetooth Multimeters and display the result on your wrist!
|
||||
|
||||
## Compatible Bluetooth meters
|
||||
|
||||
Only the OWON is supported right now - feel free to add support for more!
|
||||
|
||||
### OWON OW18E
|
||||
|
||||
Available [on Amazon](https://www.amazon.co.uk/Bluetooth-Multimeter-Multimeters-Voltmeter-Resistance/dp/B08NJT38SF/ref=sr_1_1)
|
||||
|
||||
Turn the meter on, and long-press the Hz/Duty/Delta/Bluetooth button on the right hand side. Now run the app.
|
||||
|
||||
## Usage
|
||||
|
||||
The app currently only displays the current reading from the volt meter.
|
||||
|
||||
If the app fails to connect you'll need to reload it to reconnect.
|
||||
|
||||
To exit the app, long-press the button.
|
||||
|
||||
|
||||
## Future functionality...
|
||||
|
||||
* Logging
|
||||
* Graphs
|
||||
* More than one meter
|
||||
|
||||
## Creator
|
||||
|
||||
Gordon Williams (please file issues via GitHub)
|
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("mEw4kA///z3vy067fWlP7/t1r3f33vrU07tdxHKn1mnUEv92DgO75xUwmcziIAIiAWJgYXLiIuLC5dwC6xIJCwP/swAHsIXM5GZAA/HC4kCC42I7oAG3OXC4sgC4/e9v+939AQP7C40iC429C4Pu/wCC9YXHGAYXCzoXC3wCCC5AwDC4WZC4M+909AQM7C5AwCC4ef/tfn/dAQQXIDAQXDAA4XHJIYXBzNVAA9XC4K8CR4QwCC4Mzi93AA1xC4JBCC4QwCC4URABIXBCgaqDC5MWC4YRCI4hfC1VEmMX93u8MR/Pd6J3CCQJ3DR4YXF84XBR4ilDbAYXFagM3iP1R4YQBCwbXER4KHBRYaWBR4TWFYoQXCsKPKCIQuEC452BC6MxiPju8xiYZEI5gXBiLDHO5k+FgKSBCYM+C4inJAAMWmlEolDi8TC4jXJAAQWBAANBUoIXCCQQCBDgQXCn0z+gXDokRjwXCCIQXCDoQuHAAJlBC4ZBBC4kiC4ekC4lBI4ioDYQYXD1QXJXIR3DL4fjn4XBGIdBbQQXFYAYvE0gXEF5DXGC4IYBC4WhC5IFCC4dKC4QDB+KPDC4guCX4n6GAIXCmK/CuAXEAgQvEPAIXC14JDmAXDFwYXEeAKpCBAgXECwYXFeQVDC5AAFC400AwoXQAAwXJgYXWGBoWJAF4A==")
|
|
@ -0,0 +1,105 @@
|
|||
var decoded;
|
||||
var gatt;
|
||||
|
||||
|
||||
function decode(d) {
|
||||
var value = d.getUint16(4,1);
|
||||
if (value&32768)
|
||||
value = -(value&32767);
|
||||
var flags = d.getUint8(0);
|
||||
var flags2 = d.getUint8(1);
|
||||
// mv dc 27,240 "11xxx"
|
||||
// mv ac 95,240 "1011xxx"
|
||||
// v dc 36,240 "100xxx" 36(2dp) 35(20dp)
|
||||
// v ac 100,240 "1100xxx" 100(2dp) 99(20dp) 97(2000dp)
|
||||
// ohms 55,241 "110xxx"
|
||||
// beep 231,242 "11100xxx"
|
||||
// diode 167,242 "10100xxx"
|
||||
// capac 76,241 "1001xxx"
|
||||
// hz 162,241 "10100xxx"
|
||||
// temp 33,242 "100xxx"
|
||||
// ncv 96,243 "1100xxx"
|
||||
// uA 146,240 "10010xxx"
|
||||
// ma 155,240 "10011xxx"
|
||||
// A 163,240 "10100xxx"
|
||||
var dp = flags&7;
|
||||
var range = (flags>>3)&7;
|
||||
value *= Math.pow(10, -dp);
|
||||
var isAC = !!(flags&64);
|
||||
var mode = "?", units = "";
|
||||
if (flags2==240) {
|
||||
if (flags&128) {
|
||||
mode = "current";
|
||||
units = ["","nA","uA","mA","A","kA","MA",""][range];
|
||||
} else {
|
||||
mode = "voltage";
|
||||
units = ["","nV","uV","mV","V","kV","MV",""][range] + " " + (isAC?"AC":"DC");
|
||||
}
|
||||
} else if (flags2==241) {
|
||||
if (isAC) {
|
||||
mode = "capacitance";
|
||||
units = ["","nF","uF","mF","F","kF","MF",""][range];
|
||||
} else if (flags&128) {
|
||||
mode = "frequency";
|
||||
units = "Hz";
|
||||
} else {
|
||||
mode = "resistance";
|
||||
units = ["","nOhm","uOhm","mOhm","Ohm","kOhm","MOhm",""][range];
|
||||
}
|
||||
} else if (flags2==242) {
|
||||
if (flags&128) mode = isAC ? "continuity" : "diode";
|
||||
else {
|
||||
mode = "temperature";
|
||||
units = isAC ? "F" : "C";
|
||||
}
|
||||
} else if (flags2==243) mode = "ncv";
|
||||
//console.log(mode+" "+value+" "+units,new Uint8Array(d.buffer).slice());
|
||||
decoded = {
|
||||
value : value,
|
||||
mode : mode, // current/voltage/capacitance/frequency/resistance/temperature
|
||||
units : units, // eg 'mA'
|
||||
raw : new Uint8Array(d.buffer).slice(),
|
||||
};
|
||||
updateDisplay(decoded);
|
||||
}
|
||||
|
||||
function updateDisplay(d) {
|
||||
var mode = d.mode;
|
||||
mode = mode.substr(0,1).toUpperCase()+mode.substr(1);
|
||||
var s = d.value.toString();
|
||||
|
||||
var R = Bangle.appRect;
|
||||
g.reset().clearRect(R);
|
||||
g.setFont("12x20").setFontAlign(-1,-1).drawString(mode, R.x, R.y);
|
||||
g.setFont("12x20").setFontAlign(1,1).drawString(d.units, R.x+R.w-1, R.y+R.h-1);
|
||||
var fontSize = 80;
|
||||
g.setFont("Vector",fontSize).setFontAlign(0,0);
|
||||
while (g.stringWidth(s) > R.w-20) {
|
||||
fontSize -= 2;
|
||||
g.setFont("Vector", fontSize);
|
||||
}
|
||||
g.drawString(s, R.x+R.w/2, R.y+R.h/2);
|
||||
}
|
||||
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
E.showMessage(/*LANG*/"Connecting...");
|
||||
|
||||
NRF.requestDevice({ filters: [{ name: 'BDM' }] }).then(function(device) {
|
||||
return device.gatt.connect();
|
||||
}).then(function(g) {
|
||||
gatt = g;
|
||||
return gatt.getPrimaryService(0xFFF0);
|
||||
}).then(function(service) {
|
||||
return service.getCharacteristic(0xFFF4);
|
||||
}).then(function(c) {
|
||||
c.on('characteristicvaluechanged', function(event) {
|
||||
d = event.target.value;
|
||||
decode(d);
|
||||
});
|
||||
return c.startNotifications();
|
||||
}).then(function() {
|
||||
E.showMessage(/*LANG*/"Connected.");
|
||||
}).catch(function(e) {
|
||||
E.showMessage(e.toString());
|
||||
});
|
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
|
@ -0,0 +1,15 @@
|
|||
{ "id": "btmultimeter",
|
||||
"name": "Bluetooth Multimeter",
|
||||
"shortName":"BT Meter",
|
||||
"version":"0.01",
|
||||
"description": "Connect to compatible a Bluetooth Multimeters and display the result on your wrist!",
|
||||
"icon": "app.png",
|
||||
"tags": "bluetooth,tool",
|
||||
"screenshots" : [ { "url":"screenshot.png" } ],
|
||||
"supports" : ["BANGLEJS","BANGLEJS2"],
|
||||
"readme": "README.md",
|
||||
"storage": [
|
||||
{"name":"btmultimeter.app.js","url":"app.js"},
|
||||
{"name":"btmultimeter.img","url":"app-icon.js","evaluate":true}
|
||||
]
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 2.6 KiB |
Loading…
Reference in New Issue