-
Notifications
You must be signed in to change notification settings - Fork 237
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding SEN0322 O2 Sensor Driver Support #1075
base: public
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import Sensor from "embedded:sensor/OxygenGasSensor-OSensor/SEN0322"; | ||
import Timer from "timer"; | ||
|
||
const knownOxygenVal = 20.9; // Known concentration of oxygen in the air, for calibration | ||
const oxygenMV = 0; // The value marked on the sensor, set to 0 unless otherwise required | ||
|
||
const sensor = new Sensor({ | ||
sensor: { | ||
...device.I2C.default, | ||
io: device.io.I2C | ||
} | ||
}); | ||
|
||
sensor.configure({ | ||
vol: knownOxygenVal, | ||
mv: oxygenMV | ||
}); | ||
|
||
Timer.repeat(() => | ||
{ | ||
const sample = sensor.sample(); | ||
trace(`O2: ${sample.O} ppm\n`); | ||
}, 500); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"include": [ | ||
"$(MODDABLE)/modules/io/manifest.json", | ||
"$(MODDABLE)/modules/drivers/sensors/sen0322/manifest.json" | ||
], | ||
"modules": { | ||
"*": "./main" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"modules": { | ||
"embedded:sensor/OxygenGasSensor-OSensor/SEN0322": "$(MODDABLE)/modules/drivers/sensors/sen0322/sen0322" | ||
}, | ||
"preload": [ | ||
"embedded:sensor/OxygenGasSensor-OSensor/SEN0322" | ||
] | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/* | ||
* Copyright 2023 Moddable Tech, Inc. | ||
* Revised: March 27, 2023 | ||
* | ||
* This file is part of the Moddable SDK. | ||
* | ||
* This work is licensed under the | ||
* Creative Commons Attribution 4.0 International License. | ||
* To view a copy of this license, visit | ||
* <https://creativecommons.org/licenses/by/4.0>. | ||
* or send a letter to Creative Commons, PO Box 1866, | ||
* Mountain View, CA 94042, USA. | ||
* | ||
*/ | ||
|
||
/* | ||
SEN0322 - Oxygen Sensors | ||
https://www.dfrobot.com/product-2052.html | ||
Datasheet: https://wiki.dfrobot.com/Gravity_I2C_Oxygen_Sensor_SKU_SEN0322 | ||
Reference Driver: https://github.com/DFRobot/DFRobot_OxygenSensor/blob/master/DFRobot_OxygenSensor.cpp | ||
*/ | ||
|
||
|
||
import Timer from "timer"; | ||
|
||
const Register = Object.freeze({ | ||
OXYGEN_DATA: 0x03, ///< register for oxygen data | ||
USER_SET: 0x08, ///< register for users to configure key value manually | ||
AUTUAL_SET: 0x09, ///< register that automatically configure key value | ||
GET_KEY: 0x0A ///< register for obtaining key value | ||
}); | ||
|
||
const I2C_ADDR = 0x73; | ||
|
||
class SEN0322 | ||
{ | ||
#io; | ||
#key; | ||
|
||
constructor(options) { | ||
this.#io = new options.sensor.io({ | ||
address: I2C_ADDR, | ||
hz: 100_000, | ||
...options.sensor | ||
}); | ||
} | ||
|
||
configure(options) | ||
{ | ||
if (undefined !== options.vol) | ||
{ | ||
const vol = options.vol; | ||
const mv = options.mv ?? 0; | ||
if (0 > vol || vol > 25) | ||
throw new RangeError("invalid O2 concentration (must be 0-25)"); | ||
|
||
const io = this.#io; | ||
let keyValue = vol * 10; | ||
|
||
if (-0.000001 < mv && mv < 0.000001) | ||
io.write(Uint8Array.of(Register.USER_SET, keyValue)); | ||
else | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The throw above will always, so the content of this else clause can be directly inline below. |
||
{ | ||
keyValue = vol / mv * 1000; | ||
io.write(Uint8Array.of(Register.AUTUAL_SET, keyValue)); | ||
} | ||
} | ||
} | ||
#setKey() | ||
{ | ||
const io = this.#io; | ||
io.write(Uint8Array.of(Register.GET_KEY)); | ||
const curKey = (new Uint8Array(io.read(1)))[0]; | ||
if (curKey) | ||
this.#key = curKey / 1000.0; | ||
else | ||
this.#key = 20.9 / 120.0; | ||
} | ||
close() | ||
{ | ||
this.#io?.close(); | ||
this.#io = undefined; | ||
} | ||
sample() | ||
{ | ||
const io = this.#io; | ||
this.#setKey(); | ||
io.write(Uint8Array.of(Register.OXYGEN_DATA)); | ||
Timer.delay(100); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, this pauses the VM. I would not use this driver for this alone. Would be nice to find a different way to code this. At the very least document it at the top or readme. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed. A simple solution would be to have a timer in the driver to poll the value every 100ms. The driver would store the most recent value and return it from Because |
||
const rxbuf = new Uint8Array(io.read(3)); | ||
const oxygenPercent = this.#key * (rxbuf[0] + (rxbuf[1] / 10.0) + (rxbuf[2] / 100.0)); | ||
return { O: oxygenPercent * 10_000 }; // O2 concentration in PPM | ||
} | ||
|
||
} | ||
export default SEN0322; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Our ECMA-419 sensor drivers usually include a header with: