Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • card10/firmware
  • annejan/firmware
  • astro/firmware
  • fpletz/firmware
  • gerd/firmware
  • fleur/firmware
  • swym/firmware
  • l/firmware
  • uberardy/firmware
  • wink/firmware
  • madonius/firmware
  • mot/firmware
  • filid/firmware
  • q3k/firmware
  • hauke/firmware
  • Woazboat/firmware
  • pink/firmware
  • mossmann/firmware
  • omniskop/firmware
  • zenox/firmware
  • trilader/firmware
  • Danukeru/firmware
  • shoragan/firmware
  • zlatko/firmware
  • sistason/firmware
  • datenwolf/firmware
  • bene/firmware
  • amedee/firmware
  • martinling/firmware
  • griffon/firmware
  • chris007/firmware
  • adisbladis/firmware
  • dbrgn/firmware
  • jelly/firmware
  • rnestler/firmware
  • mh/firmware
  • ln/firmware
  • penguineer/firmware
  • monkeydom/firmware
  • jens/firmware
  • jnaulty/firmware
  • jeffmakes/firmware
  • marekventur/firmware
  • pete/firmware
  • h2obrain/firmware
  • DooMMasteR/firmware
  • jackie/firmware
  • prof_r/firmware
  • Draradech/firmware
  • Kartoffel/firmware
  • hinerk/firmware
  • abbradar/firmware
  • JustTB/firmware
  • LuKaRo/firmware
  • iggy/firmware
  • ente/firmware
  • flgr/firmware
  • Lorphos/firmware
  • matejo/firmware
  • ceddral7/firmware
  • danb/firmware
  • joshi/firmware
  • melle/firmware
  • fitch/firmware
  • deurknop/firmware
  • sargon/firmware
  • markus/firmware
  • kloenk/firmware
  • lucaswerkmeister/firmware
  • derf/firmware
  • meh/firmware
  • dx/card10-firmware
  • torben/firmware
  • yuvadm/firmware
  • AndyBS/firmware
  • klausdieter1/firmware
  • katzenparadoxon/firmware
  • xiretza/firmware
  • ole/firmware
  • techy/firmware
  • thor77/firmware
  • TilCreator/firmware
  • fuchsi/firmware
  • dos/firmware
  • yrlf/firmware
  • PetePriority/firmware
  • SuperVirus/firmware
  • sur5r/firmware
  • tazz/firmware
  • Alienmaster/firmware
  • flo_h/firmware
  • baldo/firmware
  • mmu_man/firmware
  • Foaly/firmware
  • sodoku/firmware
  • Guinness/firmware
  • ssp/firmware
  • led02/firmware
  • Stormwind/firmware
  • arist/firmware
  • coon/firmware
  • mdik/firmware
  • pippin/firmware
  • royrobotiks/firmware
  • zigot83/firmware
  • mo_k/firmware
106 results
Select Git revision
  • add_menu_vibration
  • blinkisync-as-preload
  • ch3/api-speed-eval2
  • ch3/dual-core
  • ch3/genapi-refactor
  • ch3/leds-api
  • ch3/splashscreen
  • dualcore
  • dx/flatten-config-module
  • dx/meh-bdf-to-stm
  • freertos-btle
  • genofire/ble-follow-py
  • koalo/bhi160-works-but-dirty
  • koalo/factory-reset
  • koalo/wip/i2c-for-python
  • master
  • msgctl/faultscreen
  • msgctl/textbuffer_api
  • plaetzchen/ios-workaround
  • rahix/bhi
  • rahix/bluetooth-app-favorite
  • rahix/bma
  • rahix/user-space-ctx
  • renze/hatchery_apps
  • renze/safe_mode
  • schleicher-test
  • schneider/212-reset-hardware-when-entering-repl
  • schneider/ancs
  • schneider/ble-buffers
  • schneider/ble-central
  • schneider/ble-ecg-stream-visu
  • schneider/ble-fixes-2020-3
  • schneider/ble-mini-demo
  • schneider/ble-stability
  • schneider/ble-stability-new-phy
  • schneider/bonding
  • schneider/bonding-fail-if-full
  • schneider/bootloader-update-9a0d158
  • schneider/deepsleep
  • schneider/deepsleep2
  • schneider/deepsleep4
  • schneider/default-main
  • schneider/freertos-list-debug
  • schneider/fundamental-test
  • schneider/iaq-python
  • schneider/ir
  • schneider/max30001
  • schneider/max30001-epicaridum
  • schneider/max30001-pycardium
  • schneider/maxim-sdk-update
  • schneider/mp-exception-print
  • schneider/mp-for-old-bl
  • schneider/png
  • schneider/schleicher-test
  • schneider/sdk-0.2.1-11
  • schneider/sdk-0.2.1-7
  • schneider/sleep-display
  • schneider/spo2-playground
  • schneider/stream-locks
  • schneider/v1.17-changelog
  • bootloader-v1
  • release-1
  • v0.0
  • v1.0
  • v1.1
  • v1.10
  • v1.11
  • v1.12
  • v1.13
  • v1.14
  • v1.15
  • v1.16
  • v1.17
  • v1.18
  • v1.2
  • v1.3
  • v1.4
  • v1.5
  • v1.6
  • v1.7
  • v1.8
  • v1.9
82 results
Show changes
Commits on Source (3)
...@@ -102,6 +102,7 @@ typedef _Bool bool; ...@@ -102,6 +102,7 @@ typedef _Bool bool;
#define API_LIGHT_SENSOR_RUN 0x80 #define API_LIGHT_SENSOR_RUN 0x80
#define API_LIGHT_SENSOR_GET 0x81 #define API_LIGHT_SENSOR_GET 0x81
#define API_LIGHT_SENSOR_STOP 0x82 #define API_LIGHT_SENSOR_STOP 0x82
#define API_LIGHT_SENSOR_READ 0x83
#define API_BUTTONS_READ 0x90 #define API_BUTTONS_READ 0x90
...@@ -1386,6 +1387,14 @@ API(API_LIGHT_SENSOR_GET, int epic_light_sensor_get(uint16_t* value)); ...@@ -1386,6 +1387,14 @@ API(API_LIGHT_SENSOR_GET, int epic_light_sensor_get(uint16_t* value));
*/ */
API(API_LIGHT_SENSOR_STOP, int epic_light_sensor_stop()); API(API_LIGHT_SENSOR_STOP, int epic_light_sensor_stop());
/**
* Get the light level directly. Each call has an intrinsic delay of about 240us, I recommend another 100-300us delay via utime.sleep_ms() between calls. Whether or not the IR LED is fast enough is another issue.
*
* :return: Light level
*/
API(API_LIGHT_SENSOR_READ, uint16_t epic_light_sensor_read(void));
/** /**
* File * File
* ==== * ====
......
...@@ -27,6 +27,13 @@ static int light_sensor_init() ...@@ -27,6 +27,13 @@ static int light_sensor_init()
return 0; return 0;
} }
uint16_t epic_light_sensor_read()
{
ADC_StartConvert(ADC_CH_7, 0, 0);
ADC_GetData(&last_value);
return last_value;
}
static void readAdcCallback() static void readAdcCallback()
{ {
if (hwlock_acquire(HWLOCK_ADC, 0) != 0) { if (hwlock_acquire(HWLOCK_ADC, 0) != 0) {
......
import display
import light_sensor
import utime
import buttons
import os
TRANSMISSION_RECEIVED_TXT = "blinki-received.txt"
TRANSMISSION_CALIBRATE = [1, 0, 1, 0, 1, 0, 1, 0]
TRANSMISSION_START_SIGNATURE = [0, 0, 0, 0, 0, 1, 0, 1]
TRANSMISSION_END_SIGNATURE = [0, 0, 0, 0, 0, 0, 0, 0]
TRANSMISSION_TIMING_SIGNATURE = [1, 0, 1, 1]
TIMING = 75
SCROLLSPEED = 20
def init():
if TRANSMISSION_RECEIVED_TXT not in os.listdir("/"):
with open("/" + TRANSMISSION_RECEIVED_TXT, "w") as f:
f.write("blinki transmissions")
def triangle(disp, x, y, left):
yf = 1 if left else -1
scale = 6
disp.line(x - scale * yf, int(y + scale / 2), x, y)
disp.line(x, y, x, y + scale)
disp.line(x, y + scale, x - scale * yf, y + int(scale / 2))
def save_transmission():
with open(TRANSMISSION_RECEIVED_TXT, "a") as myfile:
myfile.write("\n" + decoded_string)
def transmission_to_list(length=0):
global read_values_list
global read_values_current
read_values_current = light_sensor.read()
if length != 0:
while len(read_values_list) >= length:
read_values_list.pop(0)
read_values_list.append(read_values_current)
def transmission_list_to_byte_list():
global read_values_list_binary
global read_values_list_copy
global read_values_list
if read_values_list[0] <= read_values_mean:
read_values_list_binary.append(0)
read_values_list_copy.append(0)
else:
read_values_list_binary.append(1)
read_values_list_copy.append(1)
del read_values_list[:1]
if len(read_values_list_binary) == 2:
if read_values_list_binary[:2] == [0, 0]:
read_values_list_binary_filtered.append(0)
del read_values_list_binary[:2]
if read_values_list_binary[:2] == [1, 1]:
read_values_list_binary_filtered.append(1)
del read_values_list_binary[:2]
if read_values_list_binary[:2] == [0, 1]:
read_values_list_binary_filtered.append(0)
del read_values_list_binary[:1]
if read_values_list_binary[:2] == [1, 0]:
read_values_list_binary_filtered.append(1)
del read_values_list_binary[:1]
def get_transmission_mean():
global read_values_mean
transmission_to_list(8)
read_values_mean = sum(read_values_list) / len(read_values_list)
def detect_transmission_start():
global read_values_list_binary_filtered
global transmission_started
#print(read_values_list_binary_filtered)
if read_values_list_binary_filtered[-8:] == TRANSMISSION_START_SIGNATURE:
transmission_started = 1
def detect_transmission_end():
global transmission_ended
if read_values_list_binary_filtered[-8:] == TRANSMISSION_END_SIGNATURE:
transmission_ended = 1
def strip_timecode():
global read_values_list_binary_filtered
if read_values_list_binary_filtered[:len(TRANSMISSION_TIMING_SIGNATURE)] == TRANSMISSION_TIMING_SIGNATURE:
del read_values_list_binary_filtered[:len(TRANSMISSION_TIMING_SIGNATURE)]
elif read_values_list_binary_filtered[1:len(TRANSMISSION_TIMING_SIGNATURE)+1] == TRANSMISSION_TIMING_SIGNATURE:
del read_values_list_binary_filtered[:len(TRANSMISSION_TIMING_SIGNATURE)+1]
elif read_values_list_binary_filtered[:len(TRANSMISSION_TIMING_SIGNATURE)-1] == TRANSMISSION_TIMING_SIGNATURE[1:len(TRANSMISSION_TIMING_SIGNATURE)]:
del read_values_list_binary_filtered[:len(TRANSMISSION_TIMING_SIGNATURE)-1]
else:
del read_values_list_binary_filtered[:len(TRANSMISSION_TIMING_SIGNATURE)-1]
if read_values_list_binary_filtered[0] == 1:
del read_values_list_binary_filtered[:1]
def decode_byte():
global read_values_list_binary_filtered
global decoded_string
byte_string = ""
for item in read_values_list_binary_filtered[:8]:
byte_string += str(item)
del read_values_list_binary_filtered[:8]
decoded_string += chr(int(byte_string, 2))
def decode_transmission():
global decoded_string
del read_values_list_binary_filtered[0]
while len(read_values_list_binary_filtered) >= 8+len(TRANSMISSION_TIMING_SIGNATURE):
decode_byte()
strip_timecode()
def menu():
if app_state == 0:
disp.print("start", posy=0, fg=[255, 255, 255])
disp.print("receive", posy=20, fg=[255, 255, 255])
disp.print("calibration", posy=40, fg=[255, 255, 255])
disp.print("hold", posx=85, posy=60, fg=[0, 255, 255])
triangle(disp, 150, 66, False)
if app_state == 2:
disp.print("calibrating", posy=0, fg=[0, 255, 255])
disp.print(str(min(read_values_list)), posx=0, posy=20, fg=[255, 0, 0])
#disp.print(str(round(read_values_mean, 2)), posx=46, posy=40, fg=[0, 255, 255])
disp.print(str(max(read_values_list)), posx=50, posy=20, fg=[0, 255, 0])
disp.print("release", posx=36, posy=40, fg=[255, 255, 255])
disp.print("first", posx=36, posy=60, fg=[255, 255, 255])
triangle(disp, 150, 66, False)
if app_state == 1:
disp.print("waiting for", posy=0, fg=[255, 255, 255])
disp.print("transmission", posy=20, fg=[255, 255, 255])
printlist = ''.join(str(e) for e in read_values_list_binary_filtered[-22:])
disp.print(printlist, posx=0, posy=40, fg=[0, 255, 0])
disp.print("reset", posx=12, posy=60, fg=[255, 0, 0])
triangle(disp, 10, 66, True)
if app_state == 3:
disp.print("transmission", posy=0, fg=[255, 255, 255])
disp.print("started", posy=20, fg=[255, 255, 255])
printlist = ''.join(str(e) for e in read_values_list_binary_filtered[-22:])
disp.print(printlist, posx=0, posy=40, fg=[0, 255, 0])
if app_state == 5:
global offset_counter
linelength = len(decoded_string)
maxchars = 11
if linelength > maxchars:
offset = offset_counter//SCROLLSPEED
#print(offset)
#print(offset_counter)
disp.print(decoded_string[offset:maxchars+offset], posx=0, posy=20, fg=[0, 255, 0])
offset_counter += 1
if maxchars + offset > linelength:
offset_counter = 0
else:
disp.print(decoded_string, posx=0, posy=20, fg=[0, 255, 0])
disp.print("ended", posy=0, fg=[255, 255, 255])
disp.print("save", posx=85, posy=60, fg=[255, 255, 255])
disp.print("back", posx=15, posy=60, fg=[255, 255, 255])
triangle(disp, 10, 66, True)
triangle(disp, 150, 66, False)
def reset():
global app_state
global offset_counter
global read_values_current
global read_values_list
global read_values_list_binary
global read_values_list_binary_filtered
global read_values_list_binary_copy
global read_values_list_copy
global cycle_start_time
global cycle_time
global transmission_decoded
global transmission_started
global transmission_ended
global mean_calculation_started
global counter
global decoded_string
global synchronized
app_state = 0
offset_counter = 0
read_values_current = 0
read_values_list = [0]
read_values_list_binary = [0]
read_values_list_binary_filtered = []
read_values_list_binary_copy = []
read_values_list_copy = []
cycle_start_time = 0
cycle_time = 0
transmission_decoded = ""
transmission_started = 0
transmission_ended = 0
mean_calculation_started = 0
counter = 0
decoded_string = ""
synchronized = 0
app_state = 0
offset_counter = 0
read_values_current = 0
read_values_list = [0]
read_values_list_binary = [0]
read_values_list_binary_filtered = []
read_values_list_binary_copy = []
read_values_list_copy = []
cycle_start_time = 0
cycle_time = 0
transmission_decoded = ""
read_values_mean = sum(read_values_list) / len(read_values_list)
transmission_started = 0
transmission_ended = 0
mean_calculation_started = 0
button_pressed = False
disp = display.open()
counter = 0
decoded_string = ""
synchronized = 0
init()
while True:
v = buttons.read(buttons.BOTTOM_LEFT | buttons.BOTTOM_RIGHT | buttons.TOP_RIGHT)
if v == 0:
button_pressed = False
disp.clear()
if app_state == 0:
if v == 4:
mean_calculation_started = 1
app_state = 2
cycle_start_time = utime.time_ms()
decoded_string = ""
if app_state == 2:
get_transmission_mean()
if v == 0 and mean_calculation_started == 1:
app_state = 1
if app_state == 1:
mean_calculation_started = 0
transmission_to_list()
transmission_list_to_byte_list()
detect_transmission_start()
if not button_pressed and v & buttons.BOTTOM_LEFT != 0:
button_pressed = True
reset()
#print(read_values_list)
#print(read_values_list_binary)
#print(read_values_list_binary_filtered)
if transmission_started == 1:
read_values_list = []
read_values_list_copy = []
read_values_list_binary_copy = []
read_values_list_binary = []
read_values_list_binary_filtered = []
app_state = 3
if app_state == 3:
transmission_to_list()
transmission_list_to_byte_list()
#filter_binary_list()
detect_transmission_end()
if transmission_ended == 1:
app_state = 4
if app_state == 4:
decode_transmission()
app_state = 5
if app_state == 5:
if not button_pressed and v & buttons.BOTTOM_RIGHT != 0:
button_pressed = True
print(decoded_string)
save_transmission()
reset()
if not button_pressed and v & buttons.BOTTOM_LEFT != 0:
button_pressed = True
reset()
menu()
disp.update()
if app_state == 1 or app_state == 2 or app_state == 3:
while utime.time_ms() - cycle_start_time <= cycle_time:
wait = True
#print("wait")
#print(utime.time_ms())
#print(cycle_start_time)
#print(cycle_time)
#print("wait-end")
cycle_time += TIMING
{"name":"blinkisync-receive","description":"Transmit text over light. Firmware v1.8 required. https://card10.badge.events.ccc.de/blinkisync/","category":"utility","author":"torben","revision":1}
\ No newline at end of file
import leds
import utime
import buttons
import display
import os
TRANSMISSION_SEND_TXT = "blinki-transmission.txt"
TRANSMISSION_CALIBRATE = [1, 0, 1, 0, 1, 0, 1, 0]
TRANSMISSION_START_SIGNATURE = [0, 0, 0, 0, 0, 1, 0, 1]
TRANSMISSION_END_SIGNATURE = [0, 0, 0, 0, 0, 0, 0, 0]
#TRANSMISSION_END_SIGNATURE = [1, 1, 1, 1, 1, 1, 1, 1]
TRANSMISSION_TIMING_SIGNATURE = [1, 0, 1, 1]
TIMING = 150
def init():
global input_string
if TRANSMISSION_SEND_TXT not in os.listdir("/"):
with open("/" + TRANSMISSION_SEND_TXT, "w") as f:
f.write("hello world!")
with open("/" + TRANSMISSION_SEND_TXT, "r") as f:
input_string = f.readlines()[0]
def triangle(disp, x, y, left):
yf = 1 if left else -1
scale = 6
disp.line(x - scale * yf, int(y + scale / 2), x, y)
disp.line(x, y, x, y + scale)
disp.line(x, y + scale, x - scale * yf, y + int(scale / 2))
def get_transmission():
str_to_byte_list = []
for character in input_string:
str_to_byte_list_dirty = " ".join(map(bin, bytearray(character, "utf-8")))
while len(str_to_byte_list_dirty) <= 8:
str_to_byte_list_dirty = "0" + str_to_byte_list_dirty
for item in str_to_byte_list_dirty:
if item == "1" or item == "0":
str_to_byte_list.append(int(item))
transmission = []
transmission.extend(TRANSMISSION_START_SIGNATURE)
transmission.extend(TRANSMISSION_TIMING_SIGNATURE)
while len(str_to_byte_list) // 8 > 0:
transmission.extend(str_to_byte_list[:8])
del str_to_byte_list[:8]
transmission.extend(TRANSMISSION_TIMING_SIGNATURE)
transmission.extend(str_to_byte_list)
transmission.extend(TRANSMISSION_END_SIGNATURE)
return transmission
def send_stream():
global timing_test_list
global transmission
global app_state
if transmission[0] == 1:
print(transmission[1])
leds.set(13, [255, 255, 255])
elif transmission[0] == 0:
print(transmission[0])
leds.set(13, [0, 0, 0])
if len(transmission) == 1:
app_state = 3
del transmission[0]
def send_calibration():
leds.set(13, [255, 255, 255])
utime.sleep_ms(int(TIMING/2))
leds.set(13, [0, 0, 0])
def menu():
if app_state == 0:
disp.print("start", posy=0, fg=[255, 255, 255])
disp.print("transmit", posy=20, fg=[255, 255, 255])
disp.print("calibration", posy=40, fg=[255, 255, 255])
disp.print("hold", posx=85, posy=60, fg=[0, 255, 255])
triangle(disp, 150, 66, False)
if app_state == 1:
disp.print("calibrating", posy=0, fg=[0, 255, 255])
disp.print("release", posx=36, posy=40, fg=[255, 255, 255])
disp.print("second", posx=36, posy=60, fg=[255, 255, 255])
if app_state == 2:
disp.print(str("sending"), posy=20, fg=[255, 255, 255])
disp.print("reset", posx=70, posy=60, fg=[0, 255, 255])
triangle(disp, 150, 66, False)
if app_state == 3:
disp.print(str("done"), posy=20, fg=[255, 255, 255])
app_state = 0
input_string = ""
button_pressed = False
disp = display.open()
counter = 0
calibration_started = 0
counter = 0
start_time = 0
start_time_set = 0
cycle_time = 0
cycle_start_time = 0
init()
transmission = get_transmission()
while True:
if app_state == 2:
counter += 1
if app_state == 2 & start_time_set == 0:
start_time = utime.time()
start_time_set = 1
disp.clear()
v = buttons.read(buttons.BOTTOM_LEFT | buttons.BOTTOM_RIGHT | buttons.TOP_RIGHT)
if v == 0:
button_pressed = False
if not button_pressed and v & buttons.BOTTOM_RIGHT != 0:
button_pressed = True
app_state += 1
if app_state == 0:
if v == 4:
calibration_started = 1
app_state = 1
cycle_start_time = utime.time_ms()
if app_state == 1:
send_calibration()
if v == 0 and calibration_started == 1:
calibration_started = 0
app_state = 2
if app_state == 2:
send_stream()
if app_state == 3:
transmission = get_transmission()
app_state = 0
cycle_time = 0
menu()
disp.update()
if app_state == 2:
end_time = utime.time()
print(counter)
print(end_time-start_time)
if app_state == 3:
print(counter)
print(end_time-start_time)
if app_state == 1 or app_state == 2:
while utime.time_ms() - cycle_start_time <= cycle_time:
wait = True
print("wait")
print(utime.time_ms())
print(cycle_start_time)
print(cycle_time)
print("wait-end")
cycle_time += TIMING
{"name":"blinkisync-transmit","description":"Transmit text over light. Firmware v1.8 required. https://card10.badge.events.ccc.de/blinkisync/","category":"utility","author":"torben","revision":1}
\ No newline at end of file
...@@ -42,11 +42,18 @@ static mp_obj_t mp_light_sensor_stop() ...@@ -42,11 +42,18 @@ static mp_obj_t mp_light_sensor_stop()
} }
static MP_DEFINE_CONST_FUN_OBJ_0(light_sensor_stop_obj, mp_light_sensor_stop); static MP_DEFINE_CONST_FUN_OBJ_0(light_sensor_stop_obj, mp_light_sensor_stop);
static mp_obj_t mp_light_sensor_read()
{
return mp_obj_new_int_from_uint(epic_light_sensor_read());
}
static MP_DEFINE_CONST_FUN_OBJ_0(light_sensor_read_obj, mp_light_sensor_read);
static const mp_rom_map_elem_t light_sensor_module_globals_table[] = { static const mp_rom_map_elem_t light_sensor_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_light_sensor) }, { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_light_sensor) },
{ MP_ROM_QSTR(MP_QSTR_start), MP_ROM_PTR(&light_sensor_start_obj) }, { MP_ROM_QSTR(MP_QSTR_start), MP_ROM_PTR(&light_sensor_start_obj) },
{ MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&light_sensor_stop_obj) }, { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&light_sensor_stop_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_reading), MP_ROM_PTR(&light_sensor_get_obj) } { MP_ROM_QSTR(MP_QSTR_get_reading), MP_ROM_PTR(&light_sensor_get_obj) },
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&light_sensor_read_obj) },
}; };
static MP_DEFINE_CONST_DICT( static MP_DEFINE_CONST_DICT(
light_sensor_module_globals, light_sensor_module_globals_table light_sensor_module_globals, light_sensor_module_globals_table
......
...@@ -97,6 +97,7 @@ Q(light_sensor) ...@@ -97,6 +97,7 @@ Q(light_sensor)
Q(start) Q(start)
Q(get_reading) Q(get_reading)
Q(stop) Q(stop)
Q(read)
/* bme680 */ /* bme680 */
Q(bme680) Q(bme680)
......