From f9941e23b7776ac8ade313e1596ffd53bd719ef6 Mon Sep 17 00:00:00 2001 From: Tinyu-Zhao Date: Mon, 9 Dec 2024 14:08:16 +0800 Subject: [PATCH] docs: Supplemental Unit Documentation and Examples. Signed-off-by: Tinyu-Zhao --- docs/en/base/index.rst | 2 +- docs/en/base/motion.rst | 4 +- docs/en/hats/heart.rst | 2 +- docs/en/hats/index.rst | 2 +- docs/en/hats/neoflash.rst | 2 +- docs/en/hats/servo.rst | 2 +- docs/en/module/dmx.rst | 4 +- docs/en/module/gps.rst | 2 +- docs/en/module/odrive.rst | 2 +- docs/en/module/pm25.rst | 2 +- docs/en/refs/unit.angle8.ref | 27 + docs/en/refs/unit.co2.ref | 37 ++ docs/en/refs/unit.co2l.ref | 36 ++ docs/en/refs/unit.envpro.ref | 28 + docs/en/refs/unit.rfid.ref | 24 + docs/en/refs/unit.tvoc.ref | 27 + docs/en/refs/unit.weight.ref | 25 + docs/en/software/dl.rst | 4 +- docs/en/units/adc_v11.rst | 4 +- docs/en/units/ain4.rst | 2 +- docs/en/units/angle8.rst | 144 +++++ docs/en/units/button.rst | 2 +- docs/en/units/bytebutton.rst | 4 +- docs/en/units/byteswitch.rst | 17 +- docs/en/units/catch.rst | 2 +- docs/en/units/co2.rst | 264 +++++++++ docs/en/units/co2l.rst | 263 +++++++++ docs/en/units/color.rst | 2 +- docs/en/units/dds.rst | 2 +- docs/en/units/digi_clock.rst | 2 +- docs/en/units/dmx.rst | 4 +- docs/en/units/envpro.rst | 143 +++++ docs/en/units/extio.rst | 22 +- docs/en/units/extio2.rst | 2 +- docs/en/units/fader.rst | 4 +- docs/en/units/flash_light.rst | 2 +- docs/en/units/glass.rst | 2 +- docs/en/units/glass2.rst | 2 +- docs/en/units/gps_v11.rst | 4 +- docs/en/units/grove2grove.rst | 2 +- docs/en/units/heart.rst | 2 +- docs/en/units/index.rst | 7 + docs/en/units/key.rst | 2 +- docs/en/units/minioled.rst | 2 +- docs/en/units/oled.rst | 2 +- docs/en/units/puzzle.rst | 2 +- docs/en/units/rca.rst | 2 +- docs/en/units/relay4.rst | 2 +- docs/en/units/rfid.rst | 103 ++++ docs/en/units/rollercan.rst | 2 +- docs/en/units/ssr.rst | 2 +- docs/en/units/tvoc.rst | 176 ++++++ docs/en/units/uwb.rst | 2 +- docs/en/units/watering.rst | 2 +- docs/en/units/weight.rst | 105 ++++ .../unit/angle8/angle8_cores3_example.m5f2 | 1 + examples/unit/angle8/angle8_cores3_example.py | 67 +++ examples/unit/co2/co2_cores3_example.m5f2 | 1 + examples/unit/co2/co2_cores3_example.py | 59 ++ examples/unit/co2l/co2l_cores3_example.m5f2 | 1 + examples/unit/co2l/co2l_cores3_example.py | 61 ++ .../unit/envpro/envpro_cores3_example.m5f2 | 1 + examples/unit/envpro/envpro_cores3_example.py | 58 ++ examples/unit/rfid/rfid_cores3_example.m5f2 | 1 + examples/unit/rfid/rfid_cores3_example.py | 50 ++ examples/unit/tvoc/tvoc_cores3_example.m5f2 | 1 + examples/unit/tvoc/tvoc_cores3_example.py | 60 ++ .../unit/weight/weight_cores3_example.m5f2 | 1 + examples/unit/weight/weight_cores3_example.py | 51 ++ m5stack/libs/driver/sgp30.py | 212 ++++++- m5stack/libs/unit/angle8.py | 161 ++++- m5stack/libs/unit/co2.py | 551 +++++++++++++++++- m5stack/libs/unit/envpro.py | 115 ++++ m5stack/libs/unit/rfid.py | 99 +++- m5stack/libs/unit/tvoc.py | 59 +- m5stack/libs/unit/weight.py | 77 +++ 76 files changed, 3107 insertions(+), 120 deletions(-) create mode 100644 docs/en/refs/unit.angle8.ref create mode 100644 docs/en/refs/unit.co2.ref create mode 100644 docs/en/refs/unit.co2l.ref create mode 100644 docs/en/refs/unit.envpro.ref create mode 100644 docs/en/refs/unit.rfid.ref create mode 100644 docs/en/refs/unit.tvoc.ref create mode 100644 docs/en/refs/unit.weight.ref create mode 100644 docs/en/units/angle8.rst create mode 100644 docs/en/units/co2.rst create mode 100644 docs/en/units/co2l.rst create mode 100644 docs/en/units/envpro.rst create mode 100644 docs/en/units/rfid.rst create mode 100644 docs/en/units/tvoc.rst create mode 100644 docs/en/units/weight.rst create mode 100644 examples/unit/angle8/angle8_cores3_example.m5f2 create mode 100644 examples/unit/angle8/angle8_cores3_example.py create mode 100644 examples/unit/co2/co2_cores3_example.m5f2 create mode 100644 examples/unit/co2/co2_cores3_example.py create mode 100644 examples/unit/co2l/co2l_cores3_example.m5f2 create mode 100644 examples/unit/co2l/co2l_cores3_example.py create mode 100644 examples/unit/envpro/envpro_cores3_example.m5f2 create mode 100644 examples/unit/envpro/envpro_cores3_example.py create mode 100644 examples/unit/rfid/rfid_cores3_example.m5f2 create mode 100644 examples/unit/rfid/rfid_cores3_example.py create mode 100644 examples/unit/tvoc/tvoc_cores3_example.m5f2 create mode 100644 examples/unit/tvoc/tvoc_cores3_example.py create mode 100644 examples/unit/weight/weight_cores3_example.m5f2 create mode 100644 examples/unit/weight/weight_cores3_example.py diff --git a/docs/en/base/index.rst b/docs/en/base/index.rst index ec1c7474..e5ee663a 100644 --- a/docs/en/base/index.rst +++ b/docs/en/base/index.rst @@ -3,7 +3,7 @@ Base .. toctree:: :maxdepth: 1 - + atom_can.rst atom_socket.rst motion.rst diff --git a/docs/en/base/motion.rst b/docs/en/base/motion.rst index 80b24a93..4c003f73 100644 --- a/docs/en/base/motion.rst +++ b/docs/en/base/motion.rst @@ -1,6 +1,6 @@ -Motion -====== +Motion Base +=========== .. include:: ../refs/base.motion.ref diff --git a/docs/en/hats/heart.rst b/docs/en/hats/heart.rst index b273287a..27d043fa 100644 --- a/docs/en/hats/heart.rst +++ b/docs/en/hats/heart.rst @@ -1,5 +1,5 @@ -HeartHat +Heart Hat ========= .. include:: ../refs/hat.heart.ref diff --git a/docs/en/hats/index.rst b/docs/en/hats/index.rst index ee0d2f20..b1aeb842 100644 --- a/docs/en/hats/index.rst +++ b/docs/en/hats/index.rst @@ -11,6 +11,7 @@ HAT dlight.rst env.rst finger.rst + heart.rst joyc.rst joystick.rst mini_encoder.rst @@ -23,4 +24,3 @@ HAT thermal.rst tof.rst vibrator.rst - heart.rst diff --git a/docs/en/hats/neoflash.rst b/docs/en/hats/neoflash.rst index 8f465c15..f3078d9a 100644 --- a/docs/en/hats/neoflash.rst +++ b/docs/en/hats/neoflash.rst @@ -1,5 +1,5 @@ NeoFlash Hat -=========== +============= .. include:: ../refs/hat.neoflash.ref diff --git a/docs/en/hats/servo.rst b/docs/en/hats/servo.rst index e3d296a1..bf5b7d05 100644 --- a/docs/en/hats/servo.rst +++ b/docs/en/hats/servo.rst @@ -1,5 +1,5 @@ Servo Hat -======== +========== .. include:: ../refs/hat.servo.ref diff --git a/docs/en/module/dmx.rst b/docs/en/module/dmx.rst index f234ebf8..e0f95d71 100644 --- a/docs/en/module/dmx.rst +++ b/docs/en/module/dmx.rst @@ -1,5 +1,5 @@ DMX512 Module -=========== +============= .. include:: ../refs/module.dmx.ref @@ -40,7 +40,7 @@ UIFLOW2 Slave Example: class DMX512Module ----------------- +------------------ Constructors ------------ diff --git a/docs/en/module/gps.rst b/docs/en/module/gps.rst index cb631d51..ea3965ae 100644 --- a/docs/en/module/gps.rst +++ b/docs/en/module/gps.rst @@ -1,6 +1,6 @@ GPS Module -========= +=========== .. include:: ../refs/module.gps.ref diff --git a/docs/en/module/odrive.rst b/docs/en/module/odrive.rst index ec289a16..b3287663 100644 --- a/docs/en/module/odrive.rst +++ b/docs/en/module/odrive.rst @@ -1,6 +1,6 @@ ODrive Module -============ +=============== .. include:: ../refs/module.odrive.ref diff --git a/docs/en/module/pm25.rst b/docs/en/module/pm25.rst index 334141e6..e2a5e58a 100644 --- a/docs/en/module/pm25.rst +++ b/docs/en/module/pm25.rst @@ -1,6 +1,6 @@ PM2.5 Module -=========== +============== .. include:: ../refs/module.pm25.ref diff --git a/docs/en/refs/unit.angle8.ref b/docs/en/refs/unit.angle8.ref new file mode 100644 index 00000000..8d583978 --- /dev/null +++ b/docs/en/refs/unit.angle8.ref @@ -0,0 +1,27 @@ + +.. |Angle8Unit| image:: https://static-cdn.m5stack.com/resource/docs/products/unit/8Angle/img-b698604d-29dd-4506-b662-4752e1f03a28.webp + :target: https://docs.m5stack.com/en/unit/8Angle + :height: 200px + :width: 200px + +.. |init.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/8angle/init.png +.. |get_adc12_raw.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/8angle/get_adc12_raw.png +.. |get_adc8_raw.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/8angle/get_adc8_raw.png +.. |get_switch_status.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/8angle/get_switch_status.png +.. |set_led_rgb.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/8angle/set_led_rgb.png +.. |set_led_rgb_from.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/8angle/set_led_rgb_from.png +.. |set_angle_sync_bright.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/8angle/set_angle_sync_bright.png +.. |get_device_spec.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/8angle/get_device_spec.png +.. |set_i2c_address.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/8angle/set_i2c_address.png + +.. |example.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/8angle/example.png + +.. |angle8unit_cores3_example.m5f2| raw:: html + + + angle8unit_cores3_example.m5f2 + + diff --git a/docs/en/refs/unit.co2.ref b/docs/en/refs/unit.co2.ref new file mode 100644 index 00000000..f8f3e9ee --- /dev/null +++ b/docs/en/refs/unit.co2.ref @@ -0,0 +1,37 @@ + +.. |CO2Unit| image:: https://static-cdn.m5stack.com/resource/docs/products/unit/co2/co2_01.webp + :target: https://docs.m5stack.com/en/unit/co2 + :height: 200px + :width: 200px + +.. |init.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2/init.png +.. |set_start_periodic_measurement.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2/set_start_periodic_measurement.png +.. |set_stop_periodic_measurement.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2/set_stop_periodic_measurement.png +.. |is_data_ready.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2/is_data_ready.png +.. |get_temperature_offset.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2/get_temperature_offset.png +.. |set_temperature_offset.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2/set_temperature_offset.png +.. |get_sensor_altitude.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2/get_sensor_altitude.png +.. |set_sensor_altitude.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2/set_sensor_altitude.png +.. |set_ambient_pressure.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2/set_ambient_pressure.png +.. |set_force_calibration.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2/set_force_calibration.png +.. |get_calibration_enabled.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2/get_calibration_enabled.png +.. |set_calibration_enabled.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2/set_calibration_enabled.png +.. |set_start_low_periodic_measurement.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2/set_start_low_periodic_measurement.png +.. |save_to_eeprom.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2/save_to_eeprom.png +.. |get_serial_number.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2/get_serial_number.png +.. |set_self_test.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2/set_self_test.png +.. |set_factory_reset.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2/set_factory_reset.png +.. |reinit.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2/reinit.png + +.. |example.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2/example.png + + + +.. |co2_cores3_example.m5f2| raw:: html + + + co2_cores3_example.m5f2 + \ No newline at end of file diff --git a/docs/en/refs/unit.co2l.ref b/docs/en/refs/unit.co2l.ref new file mode 100644 index 00000000..8e28c53c --- /dev/null +++ b/docs/en/refs/unit.co2l.ref @@ -0,0 +1,36 @@ + +.. |CO2LUnit| image:: https://static-cdn.m5stack.com/resource/docs/products/unit/CO2L/img-9d1ab7e5-8692-4652-8714-9300367c0d37.webp + :target: https://docs.m5stack.com/en/unit/co2l + :height: 200px + :width: 200px + +.. |init.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2l/init.png +.. |set_start_periodic_measurement.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2l/set_start_periodic_measurement.png +.. |set_stop_periodic_measurement.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2l/set_stop_periodic_measurement.png +.. |is_data_ready.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2l/is_data_ready.png +.. |get_temperature_offset.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2l/get_temperature_offset.png +.. |set_temperature_offset.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2l/set_temperature_offset.png +.. |get_sensor_altitude.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2l/get_sensor_altitude.png +.. |set_sensor_altitude.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2l/set_sensor_altitude.png +.. |set_ambient_pressure.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2l/set_ambient_pressure.png +.. |set_force_calibration.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2l/set_force_calibration.png +.. |get_calibration_enabled.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2l/get_calibration_enabled.png +.. |set_calibration_enabled.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2l/set_calibration_enabled.png +.. |set_start_low_periodic_measurement.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2l/set_start_low_periodic_measurement.png +.. |save_to_eeprom.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2l/save_to_eeprom.png +.. |get_serial_number.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2l/get_serial_number.png +.. |set_self_test.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2l/set_self_test.png +.. |set_factory_reset.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2l/set_factory_reset.png +.. |reinit.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2l/reinit.png + +.. |example.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/co2l/example.png + + +.. |co2l_cores3_example.m5f2| raw:: html + + + co2l_cores3_example.m5f2 + \ No newline at end of file diff --git a/docs/en/refs/unit.envpro.ref b/docs/en/refs/unit.envpro.ref new file mode 100644 index 00000000..a503dc4e --- /dev/null +++ b/docs/en/refs/unit.envpro.ref @@ -0,0 +1,28 @@ + +.. |ENVPROUnit| image:: https://static-cdn.m5stack.com/resource/docs/products/unit/ENV%20Pro%20Unit/img-2ba12134-9756-471a-b1a5-ba803a875e8f.webp + :target: https://docs.m5stack.com/en/unit/ENV%20Pro%20Unit + :height: 200px + :width: 200px + +.. |init.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/env_pro/init.png +.. |get_over_sampling_rate.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/env_pro/get_over_sampling_rate.png +.. |set_over_sampling_rate.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/env_pro/set_over_sampling_rate.png +.. |get_iir_filter_coefficient.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/env_pro/get_iir_filter_coefficient.png +.. |set_iir_filter_coefficient.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/env_pro/set_iir_filter_coefficient.png +.. |get_temperature.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/env_pro/get_temperature.png +.. |get_humidity.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/env_pro/get_humidity.png +.. |get_pressure.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/env_pro/get_pressure.png +.. |get_gas_resistance.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/env_pro/get_gas_resistance.png +.. |get_altitude.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/env_pro/get_altitude.png + +.. |example.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/env_pro/example.png + +.. |envpro_cores3_example.m5f2| raw:: html + + + envpro_cores3_example.m5f2 + + diff --git a/docs/en/refs/unit.rfid.ref b/docs/en/refs/unit.rfid.ref new file mode 100644 index 00000000..7c432324 --- /dev/null +++ b/docs/en/refs/unit.rfid.ref @@ -0,0 +1,24 @@ + +.. |RFIDUnit| image:: https://static-cdn.m5stack.com/resource/docs/products/unit/rfid/rfid_01.webp + :target: https://docs.m5stack.com/en/unit/rfid + :height: 200px + :width: 200px + +.. |init.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/rfid/init.png +.. |is_new_card_present.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/rfid/is_new_card_present.png +.. |read_card_uid.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/rfid/read_card_uid.png +.. |read.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/rfid/read.png +.. |write.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/rfid/write.png +.. |close.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/rfid/close.png + +.. |example.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/rfid/example.png + +.. |rfid_cores3_example.m5f2| raw:: html + + + rfid_cores3_example.m5f2 + + diff --git a/docs/en/refs/unit.tvoc.ref b/docs/en/refs/unit.tvoc.ref new file mode 100644 index 00000000..a1376f38 --- /dev/null +++ b/docs/en/refs/unit.tvoc.ref @@ -0,0 +1,27 @@ + +.. |TVOCUnit| image:: https://static-cdn.m5stack.com/resource/docs/products/unit/tvoc/tvoc_01.webp + :target: https://docs.m5stack.com/en/unit/tvoc + :height: 200px + :width: 200px + +.. |init.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/tvoc/init.png +.. |set_baseline_co2_tvoc.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/tvoc/set_baseline_co2_tvoc.png +.. |set_relative_humidity.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/tvoc/set_relative_humidity.png +.. |co2eq.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/tvoc/co2eq.png +.. |baseline_co2eq.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/tvoc/baseline_co2eq.png +.. |tvoc.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/tvoc/tvoc.png +.. |baseline_tvoc.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/tvoc/baseline_tvoc.png +.. |raw_h2.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/tvoc/raw_h2.png +.. |raw_ethanol.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/tvoc/raw_ethanol.png + +.. |example.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/tvoc/example.png + +.. |tvoc_cores3_example.m5f2| raw:: html + + + tvoc_cores3_example.m5f2 + + diff --git a/docs/en/refs/unit.weight.ref b/docs/en/refs/unit.weight.ref new file mode 100644 index 00000000..48dbb3df --- /dev/null +++ b/docs/en/refs/unit.weight.ref @@ -0,0 +1,25 @@ + +.. |WEIGHTUnit| image:: https://static-cdn.m5stack.com/resource/docs/products/unit/WEIGHT/img-a0113c8c-ed62-43b9-ad38-5cb934811d9e.webp + :target: https://docs.m5stack.com/en/unit/WEIGHT + :height: 200px + :width: 200px + +.. |init.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/weight/init.png +.. |get_raw_weight.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/weight/get_raw_weight.png +.. |get_scale_weight.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/weight/get_scale_weight.png +.. |set_tare.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/weight/set_tare.png +.. |set_calibrate_scale.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/weight/set_calibrate_scale.png +.. |is_ready_wait.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/weight/is_ready_wait.png +.. |set_channel.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/weight/set_channel.png + +.. |example.png| image:: https://static-cdn.m5stack.com/mpy_docs/unit/weight/example.png + +.. |weight_cores3_example.m5f2| raw:: html + + + weight_cores3_example.m5f2 + + diff --git a/docs/en/software/dl.rst b/docs/en/software/dl.rst index 0d79335b..4c3f3061 100644 --- a/docs/en/software/dl.rst +++ b/docs/en/software/dl.rst @@ -167,7 +167,7 @@ The HumanFaceRecognizer object is returned by `dl.HumanFaceRecognizer()`. |enrolled_id_num.png| class DetectionResult -- DetectionResult object ------------------------------- +----------------------------------------------- The line object is returned by `ObjectDetector.infer()`. @@ -234,7 +234,7 @@ The line object is returned by `ObjectDetector.infer()`. |get_keypoint.png| class RecognitionResult -- RecognitionResult object ------------------------------- +--------------------------------------------------- The ``RecognitionResult`` is returned by `HumanFaceRecognizer.recognize(img, keypoint)`. diff --git a/docs/en/units/adc_v11.rst b/docs/en/units/adc_v11.rst index f81e91b8..4861891a 100644 --- a/docs/en/units/adc_v11.rst +++ b/docs/en/units/adc_v11.rst @@ -1,6 +1,6 @@ -ADCV11 Unit -========== +ADC V1.1 Unit +============= .. sku:U013-V11 .. include:: ../refs/unit.adc_v11.ref diff --git a/docs/en/units/ain4.rst b/docs/en/units/ain4.rst index d191dd1a..bfdc1477 100644 --- a/docs/en/units/ain4.rst +++ b/docs/en/units/ain4.rst @@ -1,5 +1,5 @@ -AIN4_20mA Unit +AIN4-20mA Unit ============== .. include:: ../refs/unit.ain4.ref diff --git a/docs/en/units/angle8.rst b/docs/en/units/angle8.rst new file mode 100644 index 00000000..70598e9f --- /dev/null +++ b/docs/en/units/angle8.rst @@ -0,0 +1,144 @@ + +Angle8 Unit +=========== +.. sku:U154 +.. include:: ../refs/unit.angle8.ref + +UNIT 8Angle is an input unit integrating 8 adjustable potentiometers, internal STM32F030 microcomputer as acquisition and communication processor, and the host computer adopts I2C communication interface, each adjustable potentiometer corresponds to 1 RGB LED light, and there is also a physical toggle switch and its corresponding RGB LED light, containing 5V->3V3 DCDC circuit. + +Support the following products: + +|Angle8Unit| + +Micropython Example: + + .. literalinclude:: ../../../examples/unit/angle8/angle8_cores3_example.py + :language: python + :linenos: + + +UIFLOW2 Example: + + |example.png| + +.. only:: builder_html + + |angle8unit_cores3_example.m5f2| + +class Angle8Unit +---------------- + +Constructors +------------ + +.. class:: Angle8Unit(i2c, address) + + Initialize the Angle8Unit with the specified I2C interface and address. + + :param i2c: The I2C or PAHUBUnit instance for communication. + :param int address: The I2C address of the device (default is ANGLE8_ADDR). + + UIFLOW2: + + |init.png| + + +Methods +------- + +.. method:: Angle8Unit.available() + + Check if the device is available on the I2C bus. + +.. method:: Angle8Unit.get_adc12_raw(channel) + + Get the raw 12-bit ADC value from the specified channel. + + :param int channel: The channel number (1 to 8). + + UIFLOW2: + + |get_adc12_raw.png| + +.. method:: Angle8Unit.get_adc8_raw(channel) + + Get the raw 8-bit ADC value from the specified channel. + + :param int channel: The channel number (1 to 8). + + UIFLOW2: + + |get_adc8_raw.png| + +.. method:: Angle8Unit.get_switch_status() + + Get the status of the switch button. + + + UIFLOW2: + + |get_switch_status.png| + +.. method:: Angle8Unit.set_led_rgb(channel, rgb, bright) + + Set the RGB color and brightness of the specified LED channel. + + :param int channel: The LED channel number (0 to 8). + :param int rgb: The RGB color value (0x00 to 0xFFFFFF). + :param int bright: The brightness level (0 to 100, default is 50). + + UIFLOW2: + + |set_led_rgb.png| + +.. method:: Angle8Unit.set_led_rgb_from(begin, end, rgb, bright, per_delay) + + Set the RGB color and brightness for a range of LED channels. + + :param int begin: The starting LED channel (0 to 8). + :param int end: The ending LED channel (0 to 8). + :param int rgb: The RGB color value (0x00 to 0xFFFFFF). + :param int bright: The brightness level (0 to 100, default is 50). + :param int per_delay: The delay in milliseconds between setting each channel (default is 0). + + UIFLOW2: + + |set_led_rgb_from.png| + +.. method:: Angle8Unit.set_angle_sync_bright(channel, rgb) + + Set the LED brightness synchronized with the angle value. + + :param int channel: The LED channel number (0 to 8). + :param int rgb: The RGB color value (0x00 to 0xFFFFFF). + + UIFLOW2: + + |set_angle_sync_bright.png| + +.. method:: Angle8Unit.get_device_spec(mode) + + Get device specifications such as firmware version or I2C address. + + :param int mode: The register to read (FW_VER_REG or I2C_ADDR_REG). + + UIFLOW2: + + |get_device_spec.png| + +.. method:: Angle8Unit.set_i2c_address(address) + + Set a new I2C address for the device. + + :param int address: The new I2C address (1 to 127). + + UIFLOW2: + + |set_i2c_address.png| + +.. method:: Angle8Unit.readfrommem(reg, num) + + Read a specified number of bytes from a device register. + + :param reg: The register address to read from. + :param num: The number of bytes to read. \ No newline at end of file diff --git a/docs/en/units/button.rst b/docs/en/units/button.rst index 0355b5a1..7559e105 100644 --- a/docs/en/units/button.rst +++ b/docs/en/units/button.rst @@ -1,6 +1,6 @@ Button Unit -========== +============ .. include:: ../refs/unit.button.ref diff --git a/docs/en/units/bytebutton.rst b/docs/en/units/bytebutton.rst index 27422387..d3c05d00 100644 --- a/docs/en/units/bytebutton.rst +++ b/docs/en/units/bytebutton.rst @@ -1,6 +1,6 @@ -ByteButtonUnit -============== +ByteButton Unit +=============== .. sku:U192 .. include:: ../refs/unit.bytebutton.ref diff --git a/docs/en/units/byteswitch.rst b/docs/en/units/byteswitch.rst index 971b338b..b8233451 100644 --- a/docs/en/units/byteswitch.rst +++ b/docs/en/units/byteswitch.rst @@ -10,20 +10,21 @@ Support the following products: |ByteSwitchUnit| -Micropython Example: +.. + Micropython Example: - .. literalinclude:: ../../../examples/unit/byteswitch/byteswitch_cores3_example.py - :language: python - :linenos: + .. literalinclude:: ../../../examples/unit/byteswitch/byteswitch_cores3_example.py + :language: python + :linenos: + UIFLOW2 Example: -UIFLOW2 Example: + |example.png| - |example.png| + .. only:: builder_html -.. only:: builder_html + |byteswitch_cores3_example.m5f2| - |byteswitch_cores3_example.m5f2| class ByteSwitchUnit -------------------- diff --git a/docs/en/units/catch.rst b/docs/en/units/catch.rst index 55c1043e..14e1d967 100644 --- a/docs/en/units/catch.rst +++ b/docs/en/units/catch.rst @@ -1,5 +1,5 @@ Catch Unit -========= +========== .. include:: ../refs/unit.catch.ref diff --git a/docs/en/units/co2.rst b/docs/en/units/co2.rst new file mode 100644 index 00000000..93373856 --- /dev/null +++ b/docs/en/units/co2.rst @@ -0,0 +1,264 @@ + +CO2 Unit +========= +.. sku:U103 +.. include:: ../refs/unit.co2.ref + +CO2Unit is a hardware module designed for measuring CO2 concentration, temperature, and humidity. +It communicates via I2C and provides functions for calibration, measurement, and configuration. + +Support the following products: + +|CO2Unit| + +Micropython Example: + + .. literalinclude:: ../../../examples/unit/co2/co2_cores3_example.py + :language: python + :linenos: + +UIFLOW2 Example: + + |example.png| + +.. only:: builder_html + + |co2_cores3_example.m5f2| + + +class CO2Unit +------------- + +Constructors +------------ + +.. class:: CO2Unit(i2c, address) + + Initialize the CO2Unit with the I2C interface and address. + + :param i2c: I2C interface or PAHUBUnit instance for communication. + :param int address: I2C address of the CO2 sensor, default is 0x62. + + UIFLOW2: + + |init.png| + + +Methods +------- + +.. method:: CO2Unit.available() + + Check if the CO2 unit is available on the I2C bus. + + +.. method:: CO2Unit.set_start_periodic_measurement() + + Set the sensor into working mode, which takes about 5 seconds per measurement. + + + UIFLOW2: + + |set_start_periodic_measurement.png| + +.. method:: CO2Unit.set_stop_periodic_measurement() + + Stop the measurement mode for the sensor. + + + UIFLOW2: + + |set_stop_periodic_measurement.png| + +.. method:: CO2Unit.get_sensor_measurement() + + Get temperature, humidity, and CO2 concentration from the sensor. + + +.. method:: CO2Unit.is_data_ready() + + Check if the data (temperature, humidity, CO2) is ready from the sensor. + + + UIFLOW2: + + |is_data_ready.png| + +.. method:: CO2Unit.get_temperature_offset() + + Get the temperature offset to be added to the reported measurements. + + + UIFLOW2: + + |get_temperature_offset.png| + +.. method:: CO2Unit.set_temperature_offset(offset) + + Set the maximum value of 374°C temperature offset. + + :param int offset: The temperature offset to set, default is 0. + + UIFLOW2: + + |set_temperature_offset.png| + +.. method:: CO2Unit.get_sensor_altitude() + + Get the altitude value of the measurement location in meters above sea level. + + + UIFLOW2: + + |get_sensor_altitude.png| + +.. method:: CO2Unit.set_sensor_altitude(height) + + Set the altitude value of the measurement location in meters above sea level. + + :param int height: The altitude in meters to set. Must be between 0 and 65535 meters. + + UIFLOW2: + + |set_sensor_altitude.png| + +.. method:: CO2Unit.set_ambient_pressure(ambient_pressure) + + Set the ambient pressure in hPa at any time to adjust CO2 calculations. + + :param int ambient_pressure: The ambient pressure in hPa, constrained to the range [0, 65535]. + + UIFLOW2: + + |set_ambient_pressure.png| + +.. method:: CO2Unit.set_force_calibration(target_co2) + + Force the sensor to recalibrate with a given current CO2 level. + + :param int target_co2: The current CO2 concentration to be used for recalibration. + + UIFLOW2: + + |set_force_calibration.png| + +.. method:: CO2Unit.get_calibration_enabled() + + Get whether automatic self-calibration (ASC) is enabled or disabled. + + + UIFLOW2: + + |get_calibration_enabled.png| + +.. method:: CO2Unit.set_calibration_enabled(enabled) + + Enable or disable automatic self-calibration (ASC). + + :param bool enabled: Set to True to enable ASC, or False to disable it. + + UIFLOW2: + + |set_calibration_enabled.png| + +.. method:: CO2Unit.set_start_low_periodic_measurement() + + Set the sensor into low power working mode, with about 30 seconds per measurement. + + + UIFLOW2: + + |set_start_low_periodic_measurement.png| + +.. method:: CO2Unit.data_isready() + + Check if new data is available from the sensor. + +.. method:: CO2Unit.save_to_eeprom() + + Save temperature offset, altitude offset, and self-calibration enable settings to EEPROM. + + + UIFLOW2: + + |save_to_eeprom.png| + +.. method:: CO2Unit.get_serial_number() + + Get a unique serial number for this sensor. + + + UIFLOW2: + + |get_serial_number.png| + +.. method:: CO2Unit.set_self_test() + + Perform a self-test, which can take up to 10 seconds. + + + UIFLOW2: + + |set_self_test.png| + +.. method:: CO2Unit.set_factory_reset() + + Reset all configuration settings stored in the EEPROM and erase the FRC and ASC algorithm history. + + + UIFLOW2: + + |set_factory_reset.png| + +.. method:: CO2Unit.reinit() + + Reinitialize the sensor by reloading user settings from EEPROM. + + + UIFLOW2: + + |reinit.png| + +.. method:: CO2Unit.set_single_shot_measurement_all() + + Set the sensor to perform a single-shot measurement for CO2, humidity, and temperature. + +.. method:: CO2Unit.set_single_shot_measurement_ht() + + Set the sensor to perform a single-shot measurement for humidity and temperature. + +.. method:: CO2Unit.set_sleep_mode() + + Put the sensor into sleep mode to reduce current consumption. + +.. method:: CO2Unit.set_wake_up() + + Wake up the sensor from sleep mode into idle mode. + +.. method:: CO2Unit.write_cmd(cmd_wr, value) + + Write a command to the sensor. + + :param int cmd_wr: The command to write to the sensor. + :param int value: The value to send with the command, if any. + +.. method:: CO2Unit.read_response(num) + + Read the sensor's response. + + :param int num: The number of bytes to read from the sensor. + +.. method:: CO2Unit.check_crc(buf) + + Check the CRC of the received data to ensure it is correct. + + :param bytearray buf: The buffer of bytes to check the CRC. + +.. method:: CO2Unit.crc8(buffer) + + Calculate the CRC-8 checksum for a given buffer. + + :param bytearray buffer: The buffer of bytes to calculate the CRC for. + + + diff --git a/docs/en/units/co2l.rst b/docs/en/units/co2l.rst new file mode 100644 index 00000000..fd463bb6 --- /dev/null +++ b/docs/en/units/co2l.rst @@ -0,0 +1,263 @@ + +CO2L Unit +========= +.. sku:U104 +.. include:: ../refs/unit.co2l.ref + +UNIT CO2L is a digital air CO2 concentration detection unit with a single-measurement low-power mode, built-in Sensirion's SCD41 sensor and power buck circuitry, and I2C communication. The unit is suitable for the measurement of air ambient conditions with a typical accuracy of ± (40 ppm + 5 % reading) for CO2 measurements over a measuring range of 400 ppm – 5000 ppm while measuring ambient temperature and humidity. + +Support the following products: + +|CO2LUnit| + +Micropython Example: + + .. literalinclude:: ../../../examples/unit/co2l/co2l_cores3_example.py + :language: python + :linenos: + +UIFLOW2 Example: + + |example.png| + +.. only:: builder_html + + |co2l_cores3_example.m5f2| + + +class CO2LUnit +-------------- + +Constructors +------------ + +.. class:: CO2LUnit(i2c, address) + + Initialize the CO2LUnit with the I2C interface and address. + + :param i2c: I2C interface or PAHUBUnit instance for communication. + :param int address: I2C address of the CO2 sensor, default is 0x62. + + UIFLOW2: + + |init.png| + + +Methods +------- + +.. method:: CO2LUnit.available() + + Check if the CO2 unit is available on the I2C bus. + + +.. method:: CO2LUnit.set_start_periodic_measurement() + + Set the sensor into working mode, which takes about 5 seconds per measurement. + + + UIFLOW2: + + |set_start_periodic_measurement.png| + +.. method:: CO2LUnit.set_stop_periodic_measurement() + + Stop the measurement mode for the sensor. + + + UIFLOW2: + + |set_stop_periodic_measurement.png| + +.. method:: CO2LUnit.get_sensor_measurement() + + Get temperature, humidity, and CO2 concentration from the sensor. + + +.. method:: CO2LUnit.is_data_ready() + + Check if the data (temperature, humidity, CO2) is ready from the sensor. + + + UIFLOW2: + + |is_data_ready.png| + +.. method:: CO2LUnit.get_temperature_offset() + + Get the temperature offset to be added to the reported measurements. + + + UIFLOW2: + + |get_temperature_offset.png| + +.. method:: CO2LUnit.set_temperature_offset(offset) + + Set the maximum value of 374°C temperature offset. + + :param int offset: The temperature offset to set, default is 0. + + UIFLOW2: + + |set_temperature_offset.png| + +.. method:: CO2LUnit.get_sensor_altitude() + + Get the altitude value of the measurement location in meters above sea level. + + + UIFLOW2: + + |get_sensor_altitude.png| + +.. method:: CO2LUnit.set_sensor_altitude(height) + + Set the altitude value of the measurement location in meters above sea level. + + :param int height: The altitude in meters to set. Must be between 0 and 65535 meters. + + UIFLOW2: + + |set_sensor_altitude.png| + +.. method:: CO2LUnit.set_ambient_pressure(ambient_pressure) + + Set the ambient pressure in hPa at any time to adjust CO2 calculations. + + :param int ambient_pressure: The ambient pressure in hPa, constrained to the range [0, 65535]. + + UIFLOW2: + + |set_ambient_pressure.png| + +.. method:: CO2LUnit.set_force_calibration(target_co2) + + Force the sensor to recalibrate with a given current CO2 level. + + :param int target_co2: The current CO2 concentration to be used for recalibration. + + UIFLOW2: + + |set_force_calibration.png| + +.. method:: CO2LUnit.get_calibration_enabled() + + Get whether automatic self-calibration (ASC) is enabled or disabled. + + + UIFLOW2: + + |get_calibration_enabled.png| + +.. method:: CO2LUnit.set_calibration_enabled(enabled) + + Enable or disable automatic self-calibration (ASC). + + :param bool enabled: Set to True to enable ASC, or False to disable it. + + UIFLOW2: + + |set_calibration_enabled.png| + +.. method:: CO2LUnit.set_start_low_periodic_measurement() + + Set the sensor into low power working mode, with about 30 seconds per measurement. + + + UIFLOW2: + + |set_start_low_periodic_measurement.png| + +.. method:: CO2LUnit.data_isready() + + Check if new data is available from the sensor. + +.. method:: CO2LUnit.save_to_eeprom() + + Save temperature offset, altitude offset, and self-calibration enable settings to EEPROM. + + + UIFLOW2: + + |save_to_eeprom.png| + +.. method:: CO2LUnit.get_serial_number() + + Get a unique serial number for this sensor. + + + UIFLOW2: + + |get_serial_number.png| + +.. method:: CO2LUnit.set_self_test() + + Perform a self-test, which can take up to 10 seconds. + + + UIFLOW2: + + |set_self_test.png| + +.. method:: CO2LUnit.set_factory_reset() + + Reset all configuration settings stored in the EEPROM and erase the FRC and ASC algorithm history. + + + UIFLOW2: + + |set_factory_reset.png| + +.. method:: CO2LUnit.reinit() + + Reinitialize the sensor by reloading user settings from EEPROM. + + + UIFLOW2: + + |reinit.png| + +.. method:: CO2LUnit.set_single_shot_measurement_all() + + Set the sensor to perform a single-shot measurement for CO2, humidity, and temperature. + +.. method:: CO2LUnit.set_single_shot_measurement_ht() + + Set the sensor to perform a single-shot measurement for humidity and temperature. + +.. method:: CO2LUnit.set_sleep_mode() + + Put the sensor into sleep mode to reduce current consumption. + +.. method:: CO2LUnit.set_wake_up() + + Wake up the sensor from sleep mode into idle mode. + +.. method:: CO2LUnit.write_cmd(cmd_wr, value) + + Write a command to the sensor. + + :param int cmd_wr: The command to write to the sensor. + :param int value: The value to send with the command, if any. + +.. method:: CO2LUnit.read_response(num) + + Read the sensor's response. + + :param int num: The number of bytes to read from the sensor. + +.. method:: CO2LUnit.check_crc(buf) + + Check the CRC of the received data to ensure it is correct. + + :param bytearray buf: The buffer of bytes to check the CRC. + +.. method:: CO2LUnit.crc8(buffer) + + Calculate the CRC-8 checksum for a given buffer. + + :param bytearray buffer: The buffer of bytes to calculate the CRC for. + + + diff --git a/docs/en/units/color.rst b/docs/en/units/color.rst index bf8ae3b9..6edec6de 100644 --- a/docs/en/units/color.rst +++ b/docs/en/units/color.rst @@ -1,6 +1,6 @@ Color Unit -========= +=========== .. sku:U009 .. include:: ../refs/unit.color.ref diff --git a/docs/en/units/dds.rst b/docs/en/units/dds.rst index 31ed7f42..2a841f35 100644 --- a/docs/en/units/dds.rst +++ b/docs/en/units/dds.rst @@ -1,5 +1,5 @@ DDS Unit -======= +========= .. include:: ../refs/unit.dds.ref diff --git a/docs/en/units/digi_clock.rst b/docs/en/units/digi_clock.rst index f73702fd..bab372df 100644 --- a/docs/en/units/digi_clock.rst +++ b/docs/en/units/digi_clock.rst @@ -1,5 +1,5 @@ DigiClock Unit -============= +=============== .. include:: ../refs/unit.digi_clock.ref diff --git a/docs/en/units/dmx.rst b/docs/en/units/dmx.rst index 383a54ae..261ee309 100644 --- a/docs/en/units/dmx.rst +++ b/docs/en/units/dmx.rst @@ -109,7 +109,7 @@ Methods |read_data.png| -.. method:: DMX512.receive_none_block() -> None +.. method:: DMX512Unit.receive_none_block() -> None Starts non-blocking data reception for the specified channels with associated callbacks. @@ -128,7 +128,7 @@ Methods |receive_data_event.png| -.. method:: DMX512.stop_receive() -> None +.. method:: DMX512Unit.stop_receive() -> None Stops the non-blocking data reception task. diff --git a/docs/en/units/envpro.rst b/docs/en/units/envpro.rst new file mode 100644 index 00000000..7da3e412 --- /dev/null +++ b/docs/en/units/envpro.rst @@ -0,0 +1,143 @@ + +ENVPRO Unit +=========== +.. sku:U169 +.. include:: ../refs/unit.envpro.ref + +ENV Pro Unit is an environmental sensor that utilizes the BME688 sensor solution, supporting the measurement of various environmental parameters such as volatile organic compounds (VOCs), indoor air quality (IAQ), temperature, humidity, and atmospheric pressure. It features a compact size, wide operating range, simple communication interface (I2C), excellent performance, and low power consumption, making it suitable for weather stations, indoor environmental monitoring, and air quality detection applications. + +Support the following products: + +|ENVPROUnit| + +Micropython Example: + + .. literalinclude:: ../../../examples/unit/envpro/envpro_cores3_example.py + :language: python + :linenos: + + +UIFLOW2 Example: + + |example.png| + +.. only:: builder_html + + |envpro_cores3_example.m5f2| + +class ENVPROUnit +---------------- + +Constructors +------------ + +.. class:: ENVPROUnit(i2c, address) + + Initialize the ENVPROUnit with an I2C object and an optional address. + + :param i2c: The I2C interface or PAHUBUnit instance to communicate with the ENV PRO sensor. + :param int address: The I2C address of the ENV PRO sensor. Defaults to 0x77. + + UIFLOW2: + + |init.png| + + +Methods +------- + +.. method:: ENVPROUnit.get_over_sampling_rate(env) + + Retrieve the oversampling rate for the specified environment parameter. + + :param env: The environment parameter (TEMPERATURE, PRESSURE, HUMIDITY). + + UIFLOW2: + + |get_over_sampling_rate.png| + +.. method:: ENVPROUnit.set_over_sampling_rate(env, rate) + + Set the oversampling rate for the specified environment parameter. + + :param env: The environment parameter (TEMPERATURE, PRESSURE, HUMIDITY). + :param rate: The oversampling rate to be set. + + UIFLOW2: + + |set_over_sampling_rate.png| + +.. method:: ENVPROUnit.get_iir_filter_coefficient() + + Retrieve the IIR filter coefficient. + + + UIFLOW2: + + |get_iir_filter_coefficient.png| + +.. method:: ENVPROUnit.set_iir_filter_coefficient(value) + + Set the IIR filter coefficient. + + :param value: The IIR filter coefficient to be set. + + UIFLOW2: + + |set_iir_filter_coefficient.png| + +.. method:: ENVPROUnit.get_temperature() + + Retrieve the measured temperature. + + + UIFLOW2: + + |get_temperature.png| + +.. method:: ENVPROUnit.get_humidity() + + Retrieve the measured humidity. + + + UIFLOW2: + + |get_humidity.png| + +.. method:: ENVPROUnit.get_pressure() + + Retrieve the measured pressure. + + + UIFLOW2: + + |get_pressure.png| + +.. method:: ENVPROUnit.get_gas_resistance() + + Retrieve the measured gas resistance. + + + UIFLOW2: + + |get_gas_resistance.png| + +.. method:: ENVPROUnit.get_altitude() + + Retrieve the calculated altitude based on pressure readings. + + ``Note``: Altitude is calculated based on the difference between barometric pressure and sea level pressure + + + UIFLOW2: + + |get_altitude.png| + + + +Constants +--------- + + .. data:: ENVPROUnit.TEMPERATURE + .. data:: ENVPROUnit.PRESSURE + .. data:: ENVPROUnit.HUMIDITY \ No newline at end of file diff --git a/docs/en/units/extio.rst b/docs/en/units/extio.rst index 31a20eee..97ab8a16 100644 --- a/docs/en/units/extio.rst +++ b/docs/en/units/extio.rst @@ -1,5 +1,5 @@ EXTIO Unit -========= +=========== .. sku:U011 .. include:: ../refs/unit.extio.ref @@ -7,19 +7,21 @@ Support the following products: |EXTIOUnit| -.. Micropython Example: - -.. .. literalinclude:: ../../../examples/unit/extio/extio_core2_example.py -.. :language: python -.. :linenos: +.. + Micropython Example: + + .. literalinclude:: ../../../examples/unit/extio/extio_core2_example.py + :language: python + :linenos: + + UIFLOW2 Example: -.. UIFLOW2 Example: + |example.png| -.. |example.png| + .. only:: builder_html -.. .. only:: builder_html + |extio_core2_example.m5f2| -.. |extio_core2_example.m5f2| class EXTIOUnit --------------- diff --git a/docs/en/units/extio2.rst b/docs/en/units/extio2.rst index c8492c2b..193cbc61 100644 --- a/docs/en/units/extio2.rst +++ b/docs/en/units/extio2.rst @@ -1,6 +1,6 @@ EXTIO2 Unit -========== +=========== .. sku:U011-B .. include:: ../refs/unit.extio2.ref diff --git a/docs/en/units/fader.rst b/docs/en/units/fader.rst index 5fd3e054..aa77ebbb 100644 --- a/docs/en/units/fader.rst +++ b/docs/en/units/fader.rst @@ -1,6 +1,6 @@ -FaderUnit -========= +Fader Unit +=========== .. include:: ../refs/unit.fader.ref diff --git a/docs/en/units/flash_light.rst b/docs/en/units/flash_light.rst index e8ea80bf..58823419 100644 --- a/docs/en/units/flash_light.rst +++ b/docs/en/units/flash_light.rst @@ -1,6 +1,6 @@ FlashLight Unit -============== +================ .. include:: ../refs/unit.flash_light.ref diff --git a/docs/en/units/glass.rst b/docs/en/units/glass.rst index 89ce6d93..2eebdaab 100644 --- a/docs/en/units/glass.rst +++ b/docs/en/units/glass.rst @@ -1,6 +1,6 @@ Glass Unit -========= +=========== .. include:: ../refs/unit.glass.ref diff --git a/docs/en/units/glass2.rst b/docs/en/units/glass2.rst index 268bbe0a..c06d94b9 100644 --- a/docs/en/units/glass2.rst +++ b/docs/en/units/glass2.rst @@ -1,6 +1,6 @@ Glass2 Unit -========== +=========== .. include:: ../refs/unit.glass2.ref diff --git a/docs/en/units/gps_v11.rst b/docs/en/units/gps_v11.rst index bd3ae741..7cd833e1 100644 --- a/docs/en/units/gps_v11.rst +++ b/docs/en/units/gps_v11.rst @@ -1,6 +1,6 @@ -GPSV1.1(SMA) Unit -================= +GPS V1.1(SMA) Unit +================== .. include:: ../refs/unit.gps_v11.ref diff --git a/docs/en/units/grove2grove.rst b/docs/en/units/grove2grove.rst index f0f23184..687ecfef 100644 --- a/docs/en/units/grove2grove.rst +++ b/docs/en/units/grove2grove.rst @@ -1,5 +1,5 @@ Grove2Grove Unit -=============== +================ .. include:: ../refs/unit.grove2grove.ref diff --git a/docs/en/units/heart.rst b/docs/en/units/heart.rst index 927ba217..6f95053a 100644 --- a/docs/en/units/heart.rst +++ b/docs/en/units/heart.rst @@ -1,6 +1,6 @@ Heart Unit -========= +========== .. include:: ../refs/unit.heart.ref diff --git a/docs/en/units/index.rst b/docs/en/units/index.rst index 7481c7b1..dc26ea23 100644 --- a/docs/en/units/index.rst +++ b/docs/en/units/index.rst @@ -10,6 +10,7 @@ Unit adc_v11.rst ain4.rst angle.rst + angle8.rst bps.rst button.rst buzzer.rst @@ -17,6 +18,8 @@ Unit can.rst cardkb.rst catch.rst + co2.rst + co2l.rst color.rst dac.rst dac2.rst @@ -29,6 +32,7 @@ Unit earth.rst encoder.rst env.rst + envpro.rst extencoder.rst extio.rst extio2.rst @@ -73,6 +77,7 @@ Unit reflective_ir.rst relay.rst relay4.rst + rfid.rst rgb.rst roller485.rst rollercan.rst @@ -83,10 +88,12 @@ Unit timerpwr.rst tmos.rst tof.rst + tvoc.rst uhf_rfid.rst ultrasonic.rst uwb.rst vibrator.rst watering.rst + weight.rst weight_i2c.rst zigbee.rst diff --git a/docs/en/units/key.rst b/docs/en/units/key.rst index b7d9adc8..416fff58 100644 --- a/docs/en/units/key.rst +++ b/docs/en/units/key.rst @@ -1,5 +1,5 @@ Key Unit -======= +======== .. include:: ../refs/unit.key.ref diff --git a/docs/en/units/minioled.rst b/docs/en/units/minioled.rst index f4a1cbaa..01646e13 100644 --- a/docs/en/units/minioled.rst +++ b/docs/en/units/minioled.rst @@ -1,6 +1,6 @@ MiniOLED Unit -============ +============== .. include:: ../refs/unit.minioled.ref diff --git a/docs/en/units/oled.rst b/docs/en/units/oled.rst index 33ccde80..668471f2 100644 --- a/docs/en/units/oled.rst +++ b/docs/en/units/oled.rst @@ -1,6 +1,6 @@ OLED Unit -======== +========== .. include:: ../refs/unit.oled.ref diff --git a/docs/en/units/puzzle.rst b/docs/en/units/puzzle.rst index c7aac8d7..c8e8ae35 100644 --- a/docs/en/units/puzzle.rst +++ b/docs/en/units/puzzle.rst @@ -1,6 +1,6 @@ Puzzle Unit -========== +=========== .. include:: ../refs/unit.puzzle.ref diff --git a/docs/en/units/rca.rst b/docs/en/units/rca.rst index e63189b4..172817d6 100644 --- a/docs/en/units/rca.rst +++ b/docs/en/units/rca.rst @@ -1,6 +1,6 @@ RCA Unit -======= +========= .. include:: ../refs/unit.rca.ref diff --git a/docs/en/units/relay4.rst b/docs/en/units/relay4.rst index b71d7086..d210356f 100644 --- a/docs/en/units/relay4.rst +++ b/docs/en/units/relay4.rst @@ -1,5 +1,5 @@ Relay4 Unit -========== +=========== .. include:: ../refs/unit.relay4.ref diff --git a/docs/en/units/rfid.rst b/docs/en/units/rfid.rst new file mode 100644 index 00000000..5a7189ff --- /dev/null +++ b/docs/en/units/rfid.rst @@ -0,0 +1,103 @@ + +RFID Unit +========== +.. sku:U031 +.. include:: ../refs/unit.rfid.ref + +RFIDUnit is a hardware module designed for RFID card reading and writing operations. It extends the MFRC522 driver, supporting card detection, reading, writing, and advanced features like selecting and waking up RFID cards. + +Support the following products: + +|RFIDUnit| + +Micropython Example: + + .. literalinclude:: ../../../examples/unit/rfid/rfid_cores3_example.py + :language: python + :linenos: + + +UIFLOW2 Example: + + |example.png| + +.. only:: builder_html + + |rfid_cores3_example.m5f2| + +class RFIDUnit +-------------- + +Constructors +------------ + +.. class:: RFIDUnit(i2c, address) + + Initialize the RFIDUnit with I2C communication and an optional address. + + :param i2c: The I2C interface instance. + :param int address: The I2C address of the RFIDUnit. Default is 0x28. + + UIFLOW2: + + |init.png| + + +Methods +------- + +.. method:: RFIDUnit.is_new_card_present() + + Check if a new RFID card is present. + + + UIFLOW2: + + |is_new_card_present.png| + +.. method:: RFIDUnit.read_card_uid() + + Read the UID of the RFID card if available. + + + UIFLOW2: + + |read_card_uid.png| + +.. method:: RFIDUnit.read(block_addr) + + Read a specific block from the RFID card. + + :param block_addr: The block address to read data from. + + UIFLOW2: + + |read.png| + +.. method:: RFIDUnit.write(block_addr, buffer) + + Write data to a specific block on the RFID card. + + :param block_addr: The block address to write data to. + :param buffer: The data buffer to write to the block. + + UIFLOW2: + + |write.png| + +.. method:: RFIDUnit.close() + + Halt the PICC and stop the encrypted communication session. + + + UIFLOW2: + + |close.png| + +.. method:: RFIDUnit.wakeup_all() + + Wake up all RFID cards within range. + +.. method:: RFIDUnit.picc_select_card() + + Select the currently active RFID card. \ No newline at end of file diff --git a/docs/en/units/rollercan.rst b/docs/en/units/rollercan.rst index a65f45e5..95e6c809 100644 --- a/docs/en/units/rollercan.rst +++ b/docs/en/units/rollercan.rst @@ -1,6 +1,6 @@ RollerCAN Unit -============= +=============== .. include:: ../refs/unit.rollercan.ref diff --git a/docs/en/units/ssr.rst b/docs/en/units/ssr.rst index 07b52835..e362d169 100644 --- a/docs/en/units/ssr.rst +++ b/docs/en/units/ssr.rst @@ -1,6 +1,6 @@ SSR Unit -======= +========= .. include:: ../refs/unit.ssr.ref diff --git a/docs/en/units/tvoc.rst b/docs/en/units/tvoc.rst new file mode 100644 index 00000000..08157b11 --- /dev/null +++ b/docs/en/units/tvoc.rst @@ -0,0 +1,176 @@ + +TVOC Unit +========= +.. sku:U088 +.. include:: ../refs/unit.tvoc.ref + +TVOCUnit is a hardware module for measuring Total Volatile Organic Compounds (TVOC) and equivalent CO2 (eCO2). It is based on the SGP30 sensor and communicates via the I2C interface. The class supports configuration and measurement operations. + +Support the following products: + +|TVOCUnit| + +Micropython Example: + + .. literalinclude:: ../../../examples/unit/tvoc/tvoc_cores3_example.py + :language: python + :linenos: + + +UIFLOW2 Example: + + |example.png| + +.. only:: builder_html + + |tvoc_cores3_example.m5f2| + +class TVOCUnit +-------------- + +Constructors +------------ + +.. class:: TVOCUnit(i2c, address) + + Initialize the TVOCUnit with the specified I2C interface and address. + + :param i2c: The I2C interface or PAHUBUnit object for communication with the sensor. + :param int address: The I2C address of the TVOC unit. Defaults to 0x58. + + UIFLOW2: + + |init.png| + + +Methods +------- + +.. method:: TVOCUnit.available() + + Check whether the TVOC/eCO2 unit is available. + +.. method:: TVOCUnit.set_baseline_co2_tvoc(co2eq, tvoc) + + Set the baseline values for CO2 and TVOC measurements. + + :param int co2eq: The CO2 equivalent baseline value to be set. + :param int tvoc: The TVOC baseline value to be set. + + UIFLOW2: + + |set_baseline_co2_tvoc.png| + +.. method:: TVOCUnit.set_relative_humidity(humidity_per, temp_c) + + Set the relative humidity and temperature for accurate air quality measurement. + + :param float humidity_per: The relative humidity in percentage (%). + :param float temp_c: The ambient temperature in Celsius (°C). + + UIFLOW2: + + |set_relative_humidity.png| + +.. method:: TVOCUnit.iaq_init() + + Initialize the IAQ (Indoor Air Quality) algorithm for the sensor. + +.. method:: TVOCUnit.measure_iaq() + + Measure the CO2 equivalent (CO2eq) and TVOC values. + +.. method:: TVOCUnit.get_iaq_baseline() + + Retrieve the IAQ algorithm baseline values for CO2eq and TVOC. + +.. method:: TVOCUnit.set_iaq_baseline(co2eq, tvoc) + + Set the previously recorded IAQ algorithm baseline values for CO2eq and TVOC. + + :param co2eq: The CO2 equivalent baseline value. + :param tvoc: The TVOC baseline value. + +.. method:: TVOCUnit.set_absolute_humidity(absolute_humidity) + + Set the absolute humidity compensation for the sensor. To disable, set the value to 0. + + :param absolute_humidity: The absolute humidity value to set. + +.. method:: TVOCUnit.measure_test() + + Run the on-chip self-test. + +.. method:: TVOCUnit.get_feature_set() + + Retrieve the feature set of the sensor. + +.. method:: TVOCUnit.measure_raw() + + Return raw H2 and Ethanol signals for part verification and testing. + +.. method:: TVOCUnit.get_serial() + + Retrieve the sensor serial ID. + +.. method:: TVOCUnit.co2eq() + + Retrieve the Carbon Dioxide Equivalent (CO2eq) in parts per million (ppm). + + + UIFLOW2: + + |co2eq.png| + +.. method:: TVOCUnit.baseline_co2eq() + + Retrieve the baseline value for CO2eq. + + + UIFLOW2: + + |baseline_co2eq.png| + +.. method:: TVOCUnit.tvoc() + + Retrieve the Total Volatile Organic Compound (TVOC) in parts per billion (ppb). + + + UIFLOW2: + + |tvoc.png| + +.. method:: TVOCUnit.baseline_tvoc() + + Retrieve the baseline value for TVOC. + + + UIFLOW2: + + |baseline_tvoc.png| + +.. method:: TVOCUnit.raw_h2() + + Retrieve the raw H2 signal value. + + + UIFLOW2: + + |raw_h2.png| + +.. method:: TVOCUnit.raw_ethanol() + + Retrieve the raw Ethanol signal value. + + + UIFLOW2: + + |raw_ethanol.png| + +.. method:: TVOCUnit.convert_r_to_a_humidity(temp_c, r_humidity_perc, fixed_point) + + Convert relative humidity to absolute humidity based on the sensor's equation. + + :param temp_c: The ambient temperature in Celsius (°C). + :param r_humidity_perc: The relative humidity in percentage (%). + :param bool fixed_point: Whether to return the value in 8.8 fixed-point format. Defaults to True. \ No newline at end of file diff --git a/docs/en/units/uwb.rst b/docs/en/units/uwb.rst index c1ae5fde..b57f7b7e 100644 --- a/docs/en/units/uwb.rst +++ b/docs/en/units/uwb.rst @@ -1,6 +1,6 @@ UWB Unit -======= +======== .. include:: ../refs/unit.uwb.ref diff --git a/docs/en/units/watering.rst b/docs/en/units/watering.rst index fa660b96..27c07cdb 100644 --- a/docs/en/units/watering.rst +++ b/docs/en/units/watering.rst @@ -1,5 +1,5 @@ Watering Unit -============ +============= .. include:: ../refs/unit.watering.ref diff --git a/docs/en/units/weight.rst b/docs/en/units/weight.rst new file mode 100644 index 00000000..2f95d2eb --- /dev/null +++ b/docs/en/units/weight.rst @@ -0,0 +1,105 @@ + +Weight Unit +============ +.. sku:U030 +.. include:: ../refs/unit.weight.ref + +Weight unit integrates a HX711 24 bits A/D chip that is specifically designed for electronic weighing device. + +Support the following products: + +|WEIGHTUnit| + +Micropython Example: + + .. literalinclude:: ../../../examples/unit/weight/weight_cores3_example.py + :language: python + :linenos: + + +UIFLOW2 Example: + + |example.png| + +.. only:: builder_html + + |weight_cores3_example.m5f2| + +class WEIGHTUnit +---------------- + +Constructors +------------ + +.. class:: WEIGHTUnit(port) + + Initialize the WEIGHTUnit with specified port pins. + + :param port: A tuple containing data and clock pin numbers. + + UIFLOW2: + + |init.png| + + +Methods +------- + +.. method:: WEIGHTUnit.get_raw_weight() + + Read the raw weight value from the HX711. + + + UIFLOW2: + + |get_raw_weight.png| + +.. method:: WEIGHTUnit.get_scale_weight() + + Get the scaled weight value based on calibration. + + + UIFLOW2: + + |get_scale_weight.png| + +.. method:: WEIGHTUnit.set_tare() + + Set the tare weight to zero out the scale. + + + UIFLOW2: + + |set_tare.png| + +.. method:: WEIGHTUnit.set_calibrate_scale(weight) + + Calibrate the scale with a known weight. + + :param weight: The known weight used for calibration. + + UIFLOW2: + + |set_calibrate_scale.png| + +.. method:: WEIGHTUnit.is_ready_wait() + + Check if the HX711 is ready to provide data. + + + UIFLOW2: + + |is_ready_wait.png| + +.. method:: WEIGHTUnit.set_channel(chan) + + Set the channel for the HX711. + + :param int chan: The channel to set (1, 2, or 3). + + UIFLOW2: + + |set_channel.png| + + + diff --git a/examples/unit/angle8/angle8_cores3_example.m5f2 b/examples/unit/angle8/angle8_cores3_example.m5f2 new file mode 100644 index 00000000..87d28a1e --- /dev/null +++ b/examples/unit/angle8/angle8_cores3_example.m5f2 @@ -0,0 +1 @@ +{"version":"V2.0","versionNumber":"V2.1.9","type":"cores3","components":[{"name":"screen","type":"screen","layer":0,"screenId":"builtin","screenName":"","id":"__cores3_screen","createTime":1733454156732,"x":0,"y":0,"width":320,"height":240,"backgroundColor":"#222222","size":0,"isSelected":true},{"name":"title0","type":"title","layer":1,"screenId":"builtin","screenName":"","id":"u@uvkw3`EqlzAz7q","createTime":1733466734614,"x":0,"y":0,"color":"#ffffff","backgroundColor":"#0000FF","text":"8AngleUnit CoreS3 Example","textOffset":3,"font":"Widgets.FONTS.DejaVu18","isSelected":false},{"name":"label0","type":"label","layer":1,"screenId":"builtin","screenName":"","id":"uFXHA46k#^@aqD1R","createTime":1733708739708,"x":0,"y":58,"color":"#ffffff","backgroundColor":"#222222","text":"label0","engine":"gfx","font":"Widgets.FONTS.DejaVu18","rotation":0,"isSelected":false},{"name":"label1","type":"label","layer":2,"screenId":"builtin","screenName":"","id":"sHx7OFcRsA+76kwu","createTime":1733708741688,"x":0,"y":109,"color":"#ffffff","backgroundColor":"#222222","text":"label1","engine":"gfx","font":"Widgets.FONTS.DejaVu18","rotation":0,"isSelected":false},{"name":"label2","type":"label","layer":3,"screenId":"builtin","screenName":"","id":"qcnB+R1z**vo3&J$","createTime":1733708744055,"x":0,"y":160,"color":"#ffffff","backgroundColor":"#222222","text":"label2","engine":"gfx","font":"Widgets.FONTS.DejaVu18","rotation":0,"isSelected":false}],"resources":[{"hardware":["hardware_button","hardware_pin_button","imu","speaker","touch","als","mic","i2c"]},{"unit":["unit_angle8"]}],"units":[{"type":"unit_angle8","name":"angle8_0","portList":["A","PAHUB","Custom"],"portType":"A","userPort":[22,21],"id":"v8-J1rksiK6_rmc-","createTime":1733715996866,"bus":"i2c0","pahubPortList":[0,1,2,3,4,5],"pahubPort":0,"initBlockId":"i5RSrKuC9M?H+g9+VTjg"}],"hats":[],"bases":[],"i2cs":[{"id":"i2c0","portType":"A","userPort":[22,21],"freq":"100000"}],"blockly":"map_valuetrue010000012angle8_00x43angle8_019palette#33ff331000map_value0truemap_valueROUND3.10angle8_0802550100label0Pressure:Switch:angle8_0label1Data is ready.CH1 8bit:angle8_01label2Data is ready.CH8 map value:map_valueangle8_019palette#33ff3350map_value010","screen":[{"simulationName":"Built-in","type":"builtin","width":320,"height":240,"scale":0.78,"screenName":"","blockId":"","screenColorType":0,"id":"builtin","createTime":1733454156727}],"logicWhenNum":0,"customList":[]} \ No newline at end of file diff --git a/examples/unit/angle8/angle8_cores3_example.py b/examples/unit/angle8/angle8_cores3_example.py new file mode 100644 index 00000000..bfbb482e --- /dev/null +++ b/examples/unit/angle8/angle8_cores3_example.py @@ -0,0 +1,67 @@ +# SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD +# +# SPDX-License-Identifier: MIT + +import os, sys, io +import M5 +from M5 import * +from hardware import * +from unit import Angle8Unit +import m5utils +import time + + +title0 = None +label0 = None +label1 = None +label2 = None +i2c0 = None +angle8_0 = None + + +import math + +map_value = None + + +def setup(): + global title0, label0, label1, label2, i2c0, angle8_0, map_value + + M5.begin() + Widgets.fillScreen(0x222222) + title0 = Widgets.Title( + "8AngleUnit CoreS3 Example", 3, 0xFFFFFF, 0x0000FF, Widgets.FONTS.DejaVu18 + ) + label0 = Widgets.Label("label0", 0, 58, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18) + label1 = Widgets.Label("label1", 0, 109, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18) + label2 = Widgets.Label("label2", 0, 160, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18) + + i2c0 = I2C(0, scl=Pin(1), sda=Pin(2), freq=100000) + angle8_0 = Angle8Unit(i2c0, 0x43) + angle8_0.set_led_rgb_from(1, 9, 0x33FF33, 100, 0) + map_value = 0 + + +def loop(): + global title0, label0, label1, label2, i2c0, angle8_0, map_value + M5.update() + map_value = round(m5utils.remap(angle8_0.get_adc8_raw(8), 0, 255, 0, 100)) + label0.setText(str((str("Switch:") + str((angle8_0.get_switch_status()))))) + label1.setText(str((str("CH1 8bit:") + str((angle8_0.get_adc8_raw(1)))))) + label2.setText(str((str("CH8 map value:") + str(map_value)))) + angle8_0.set_led_rgb_from(1, 9, 0x33FF33, map_value, 0) + time.sleep(1) + + +if __name__ == "__main__": + try: + setup() + while True: + loop() + except (Exception, KeyboardInterrupt) as e: + try: + from utility import print_error_msg + + print_error_msg(e) + except ImportError: + print("please update to latest firmware") diff --git a/examples/unit/co2/co2_cores3_example.m5f2 b/examples/unit/co2/co2_cores3_example.m5f2 new file mode 100644 index 00000000..18a43c3d --- /dev/null +++ b/examples/unit/co2/co2_cores3_example.m5f2 @@ -0,0 +1 @@ +{"version":"V2.0","versionNumber":"V2.1.9","type":"cores3","components":[{"name":"screen","type":"screen","layer":0,"screenId":"builtin","screenName":"","id":"__cores3_screen","createTime":1733454156732,"x":0,"y":0,"width":320,"height":240,"backgroundColor":"#222222","size":0,"isSelected":true},{"name":"title0","type":"title","layer":1,"screenId":"builtin","screenName":"","id":"u@uvkw3`EqlzAz7q","createTime":1733466734614,"x":0,"y":0,"color":"#ffffff","backgroundColor":"#0000FF","text":"CO2Unit CoreS3 Example","textOffset":3,"font":"Widgets.FONTS.DejaVu18","isSelected":false},{"name":"label0","type":"label","layer":1,"screenId":"builtin","screenName":"","id":"uFXHA46k#^@aqD1R","createTime":1733708739708,"x":1,"y":44,"color":"#ffffff","backgroundColor":"#222222","text":"label0","engine":"gfx","font":"Widgets.FONTS.DejaVu18","rotation":0,"isSelected":false,"width":54,"height":20},{"name":"label1","type":"label","layer":2,"screenId":"builtin","screenName":"","id":"sHx7OFcRsA+76kwu","createTime":1733708741688,"x":1,"y":95,"color":"#ffffff","backgroundColor":"#222222","text":"label1","engine":"gfx","font":"Widgets.FONTS.DejaVu18","rotation":0,"isSelected":false,"width":54,"height":20},{"name":"label2","type":"label","layer":3,"screenId":"builtin","screenName":"","id":"qcnB+R1z**vo3&J$","createTime":1733708744055,"x":1,"y":146,"color":"#ffffff","backgroundColor":"#222222","text":"label2","engine":"gfx","font":"Widgets.FONTS.DejaVu18","rotation":0,"isSelected":false,"width":54,"height":20},{"name":"label3","type":"label","layer":4,"screenId":"builtin","screenName":"","id":"aDDf&z&atPbj2v_O","createTime":1733708747002,"x":1,"y":198,"color":"#ffffff","backgroundColor":"#222222","text":"label3","engine":"gfx","font":"Widgets.FONTS.DejaVu18","rotation":0,"isSelected":false,"width":54,"height":20}],"resources":[{"hardware":["hardware_button","hardware_pin_button","imu","speaker","touch","als","mic","i2c"]},{"unit":["unit_co2"]}],"units":[{"type":"unit_co2","name":"co2_0","portList":["A","PAHUB","Custom"],"portType":"A","userPort":[22,21],"id":"tyCOsIG5y&7A=WN9","createTime":1733476616242,"bus":"i2c0","pahubPortList":[0,1,2,3,4,5],"pahubPort":0,"initBlockId":"@+RIkBB.$v8T;f:xPHye"}],"hats":[],"bases":[],"i2cs":[{"id":"i2c0","portType":"A","userPort":[22,21],"freq":"100000"}],"blockly":"true010000012co2_0co2_0falseco2_0label0Data is ready.label1Data is ready.CO2 ppm:co2_0label2Data is ready.Humidity:co2_0label3Data is ready.Temperature:co2_0label0Data not ready.","screen":[{"simulationName":"Built-in","type":"builtin","width":320,"height":240,"scale":0.78,"screenName":"","blockId":"","screenColorType":0,"id":"builtin","createTime":1733454156727}],"logicWhenNum":0,"customList":[]} \ No newline at end of file diff --git a/examples/unit/co2/co2_cores3_example.py b/examples/unit/co2/co2_cores3_example.py new file mode 100644 index 00000000..df32e603 --- /dev/null +++ b/examples/unit/co2/co2_cores3_example.py @@ -0,0 +1,59 @@ +# SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD +# +# SPDX-License-Identifier: MIT + +import os, sys, io +import M5 +from M5 import * +from hardware import * +from unit import CO2Unit + + +title0 = None +label0 = None +label1 = None +label2 = None +label3 = None +i2c0 = None +co2_0 = None + + +def setup(): + global title0, label0, label1, label2, label3, i2c0, co2_0 + + M5.begin() + Widgets.fillScreen(0x222222) + title0 = Widgets.Title("CO2Unit CoreS3 Example", 3, 0xFFFFFF, 0x0000FF, Widgets.FONTS.DejaVu18) + label0 = Widgets.Label("label0", 1, 44, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18) + label1 = Widgets.Label("label1", 1, 95, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18) + label2 = Widgets.Label("label2", 1, 146, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18) + label3 = Widgets.Label("label3", 1, 198, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18) + + i2c0 = I2C(0, scl=Pin(1), sda=Pin(2), freq=100000) + co2_0 = CO2Unit(i2c0) + co2_0.set_start_periodic_measurement() + + +def loop(): + global title0, label0, label1, label2, label3, i2c0, co2_0 + if co2_0.is_data_ready(): + label0.setText(str("Data is ready.")) + label1.setText(str((str("CO2 ppm:") + str((co2_0.co2))))) + label2.setText(str((str("Humidity:") + str((co2_0.humidity))))) + label3.setText(str((str("Temperature:") + str((co2_0.temperature))))) + else: + label0.setText(str("Data not ready.")) + + +if __name__ == "__main__": + try: + setup() + while True: + loop() + except (Exception, KeyboardInterrupt) as e: + try: + from utility import print_error_msg + + print_error_msg(e) + except ImportError: + print("please update to latest firmware") diff --git a/examples/unit/co2l/co2l_cores3_example.m5f2 b/examples/unit/co2l/co2l_cores3_example.m5f2 new file mode 100644 index 00000000..ef75380b --- /dev/null +++ b/examples/unit/co2l/co2l_cores3_example.m5f2 @@ -0,0 +1 @@ +{"version":"V2.0","versionNumber":"V2.1.9","type":"cores3","components":[{"name":"screen","type":"screen","layer":0,"screenId":"builtin","screenName":"","id":"__cores3_screen","createTime":1733454156732,"x":0,"y":0,"width":320,"height":240,"backgroundColor":"#222222","size":0,"isSelected":true},{"name":"title0","type":"title","layer":1,"screenId":"builtin","screenName":"","id":"u@uvkw3`EqlzAz7q","createTime":1733466734614,"x":0,"y":0,"color":"#ffffff","backgroundColor":"#0000FF","text":"CO2LUnit CoreS3 Example","textOffset":3,"font":"Widgets.FONTS.DejaVu18","isSelected":false},{"name":"label0","type":"label","layer":1,"screenId":"builtin","screenName":"","id":"uFXHA46k#^@aqD1R","createTime":1733708739708,"x":1,"y":44,"color":"#ffffff","backgroundColor":"#222222","text":"label0","engine":"gfx","font":"Widgets.FONTS.DejaVu18","rotation":0,"isSelected":false},{"name":"label1","type":"label","layer":2,"screenId":"builtin","screenName":"","id":"sHx7OFcRsA+76kwu","createTime":1733708741688,"x":1,"y":95,"color":"#ffffff","backgroundColor":"#222222","text":"label1","engine":"gfx","font":"Widgets.FONTS.DejaVu18","rotation":0,"isSelected":false},{"name":"label2","type":"label","layer":3,"screenId":"builtin","screenName":"","id":"qcnB+R1z**vo3&J$","createTime":1733708744055,"x":1,"y":146,"color":"#ffffff","backgroundColor":"#222222","text":"label2","engine":"gfx","font":"Widgets.FONTS.DejaVu18","rotation":0,"isSelected":false},{"name":"label3","type":"label","layer":4,"screenId":"builtin","screenName":"","id":"aDDf&z&atPbj2v_O","createTime":1733708747002,"x":1,"y":198,"color":"#ffffff","backgroundColor":"#222222","text":"label3","engine":"gfx","font":"Widgets.FONTS.DejaVu18","rotation":0,"isSelected":false}],"resources":[{"hardware":["hardware_button","hardware_pin_button","imu","speaker","touch","als","mic","i2c"]},{"unit":["unit_co2l"]}],"units":[{"type":"unit_co2l","name":"co2l_0","portList":["A","PAHUB","Custom"],"portType":"A","userPort":[22,21],"id":"mzH%vZG6YGGme3P8","createTime":1733708999739,"bus":"i2c0","pahubPortList":[0,1,2,3,4,5],"pahubPort":0,"initBlockId":"WLk!)M,zAj;{wX;]O9S*"}],"hats":[],"bases":[],"i2cs":[{"id":"i2c0","portType":"A","userPort":[22,21],"freq":"100000"}],"blockly":"true010000012co2l_0co2l_0falseco2l_0label0Data is ready.label1Data is ready.CO2 ppm:co2l_0label2Data is ready.Humidity:co2l_0label3Data is ready.Temperature:co2l_0label0Data not ready.","screen":[{"simulationName":"Built-in","type":"builtin","width":320,"height":240,"scale":0.78,"screenName":"","blockId":"","screenColorType":0,"id":"builtin","createTime":1733454156727}],"logicWhenNum":0,"customList":[]} \ No newline at end of file diff --git a/examples/unit/co2l/co2l_cores3_example.py b/examples/unit/co2l/co2l_cores3_example.py new file mode 100644 index 00000000..cf18ba85 --- /dev/null +++ b/examples/unit/co2l/co2l_cores3_example.py @@ -0,0 +1,61 @@ +# SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD +# +# SPDX-License-Identifier: MIT + +import os, sys, io +import M5 +from M5 import * +from hardware import * +from unit import CO2LUnit + + +title0 = None +label0 = None +label1 = None +label2 = None +label3 = None +i2c0 = None +co2l_0 = None + + +def setup(): + global title0, label0, label1, label2, label3, i2c0, co2l_0 + + M5.begin() + Widgets.fillScreen(0x222222) + title0 = Widgets.Title( + "CO2LUnit CoreS3 Example", 3, 0xFFFFFF, 0x0000FF, Widgets.FONTS.DejaVu18 + ) + label0 = Widgets.Label("label0", 1, 44, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18) + label1 = Widgets.Label("label1", 1, 95, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18) + label2 = Widgets.Label("label2", 1, 146, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18) + label3 = Widgets.Label("label3", 1, 198, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18) + + i2c0 = I2C(0, scl=Pin(1), sda=Pin(2), freq=100000) + co2l_0 = CO2LUnit(i2c0) + co2l_0.set_start_periodic_measurement() + + +def loop(): + global title0, label0, label1, label2, label3, i2c0, co2l_0 + if co2l_0.is_data_ready(): + label0.setText(str("Data is ready.")) + label1.setText(str((str("CO2 ppm:") + str((co2l_0.co2))))) + label2.setText(str((str("Humidity:") + str((co2l_0.humidity))))) + label3.setText(str((str("Temperature:") + str((co2l_0.temperature))))) + else: + label0.setText(str("Data not ready.")) + + +if __name__ == "__main__": + try: + setup() + while True: + loop() + except (Exception, KeyboardInterrupt) as e: + try: + from utility import print_error_msg + + print_error_msg(e) + except ImportError: + print("please update to latest firmware") diff --git a/examples/unit/envpro/envpro_cores3_example.m5f2 b/examples/unit/envpro/envpro_cores3_example.m5f2 new file mode 100644 index 00000000..049c1902 --- /dev/null +++ b/examples/unit/envpro/envpro_cores3_example.m5f2 @@ -0,0 +1 @@ +{"version":"V2.0","versionNumber":"V2.1.9","type":"cores3","components":[{"name":"screen","type":"screen","layer":0,"screenId":"builtin","screenName":"","id":"__cores3_screen","createTime":1733454156732,"x":0,"y":0,"width":320,"height":240,"backgroundColor":"#222222","size":0,"isSelected":true},{"name":"title0","type":"title","layer":1,"screenId":"builtin","screenName":"","id":"u@uvkw3`EqlzAz7q","createTime":1733466734614,"x":0,"y":0,"color":"#ffffff","backgroundColor":"#0000FF","text":"ENVProUnit CoreS3 Example","textOffset":3,"font":"Widgets.FONTS.DejaVu18","isSelected":false},{"name":"label0","type":"label","layer":1,"screenId":"builtin","screenName":"","id":"uFXHA46k#^@aqD1R","createTime":1733708739708,"x":0,"y":58,"color":"#ffffff","backgroundColor":"#222222","text":"label0","engine":"gfx","font":"Widgets.FONTS.DejaVu18","rotation":0,"isSelected":false},{"name":"label1","type":"label","layer":2,"screenId":"builtin","screenName":"","id":"sHx7OFcRsA+76kwu","createTime":1733708741688,"x":0,"y":109,"color":"#ffffff","backgroundColor":"#222222","text":"label1","engine":"gfx","font":"Widgets.FONTS.DejaVu18","rotation":0,"isSelected":false},{"name":"label2","type":"label","layer":3,"screenId":"builtin","screenName":"","id":"qcnB+R1z**vo3&J$","createTime":1733708744055,"x":0,"y":160,"color":"#ffffff","backgroundColor":"#222222","text":"label2","engine":"gfx","font":"Widgets.FONTS.DejaVu18","rotation":0,"isSelected":false}],"resources":[{"hardware":["hardware_button","hardware_pin_button","imu","speaker","touch","als","mic","i2c"]},{"unit":["unit_envpro"]}],"units":[{"type":"unit_envpro","name":"envpro_0","portList":["A","PAHUB","Custom"],"portType":"A","userPort":[22,21],"id":"qKC3JK2KrA!`s9tK","createTime":1733713944573,"bus":"i2c0","pahubPortList":[0,1,2,3,4,5],"pahubPort":0,"initBlockId":"mERz^!-xVL35p#i$JAyv"}],"hats":[],"bases":[],"i2cs":[{"id":"i2c0","portType":"A","userPort":[22,21],"freq":"100000"}],"blockly":"true010000012envpro_0truelabel0Pressure:Pressure:envpro_0label1Data is ready.Humidity:envpro_0label2Data is ready.Temperature:envpro_01","screen":[{"simulationName":"Built-in","type":"builtin","width":320,"height":240,"scale":0.78,"screenName":"","blockId":"","screenColorType":0,"id":"builtin","createTime":1733454156727}],"logicWhenNum":0,"customList":[]} \ No newline at end of file diff --git a/examples/unit/envpro/envpro_cores3_example.py b/examples/unit/envpro/envpro_cores3_example.py new file mode 100644 index 00000000..8ade3d8d --- /dev/null +++ b/examples/unit/envpro/envpro_cores3_example.py @@ -0,0 +1,58 @@ +# SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD +# +# SPDX-License-Identifier: MIT + +import os, sys, io +import M5 +from M5 import * +from hardware import * +from unit import ENVPROUnit +import time + + +title0 = None +label0 = None +label1 = None +label2 = None +i2c0 = None +envpro_0 = None +co2_0 = None + + +def setup(): + global title0, label0, label1, label2, i2c0, envpro_0, co2_0 + + M5.begin() + Widgets.fillScreen(0x222222) + title0 = Widgets.Title( + "ENVProUnit CoreS3 Example", 3, 0xFFFFFF, 0x0000FF, Widgets.FONTS.DejaVu18 + ) + label0 = Widgets.Label("label0", 0, 58, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18) + label1 = Widgets.Label("label1", 0, 109, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18) + label2 = Widgets.Label("label2", 0, 160, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18) + + i2c0 = I2C(0, scl=Pin(1), sda=Pin(2), freq=100000) + envpro_0 = ENVPROUnit(i2c0) + + +def loop(): + global title0, label0, label1, label2, i2c0, envpro_0, co2_0 + M5.update() + label0.setText(str((str("Pressure:") + str((envpro_0.get_pressure()))))) + label1.setText(str((str("Humidity:") + str((envpro_0.get_humidity()))))) + label2.setText(str((str("Temperature:") + str((envpro_0.get_temperature()))))) + time.sleep(1) + + +if __name__ == "__main__": + try: + setup() + while True: + loop() + except (Exception, KeyboardInterrupt) as e: + try: + from utility import print_error_msg + + print_error_msg(e) + except ImportError: + print("please update to latest firmware") diff --git a/examples/unit/rfid/rfid_cores3_example.m5f2 b/examples/unit/rfid/rfid_cores3_example.m5f2 new file mode 100644 index 00000000..cb6d2e2e --- /dev/null +++ b/examples/unit/rfid/rfid_cores3_example.m5f2 @@ -0,0 +1 @@ +{"version":"V2.0","versionNumber":"V2.1.8","type":"cores3","components":[{"name":"screen","type":"screen","layer":0,"screenId":"builtin","screenName":"","id":"__cores3_screen","createTime":1733454156732,"x":0,"y":0,"width":320,"height":240,"backgroundColor":"#222222","size":0,"isSelected":true},{"name":"title0","type":"title","layer":1,"screenId":"builtin","screenName":"","id":"u@uvkw3`EqlzAz7q","createTime":1733466734614,"x":0,"y":0,"color":"#ffffff","backgroundColor":"#0000FF","text":"RFIDUnit CoreS3 Example","textOffset":3,"font":"Widgets.FONTS.DejaVu18","isSelected":false}],"resources":[{"hardware":["hardware_button","hardware_pin_button","imu","speaker","touch","als","mic","i2c"]},{"unit":["unit_rfid"]}],"units":[{"type":"unit_rfid","name":"rfid_0","portList":["A","PAHUB","Custom"],"portType":"A","userPort":[22,21],"id":"noA$inbITFBqlEfp","createTime":1733469241285,"bus":"i2c0","pahubPortList":[0,1,2,3,4,5],"pahubPort":0,"initBlockId":"v8{/gG}`U3FaGj1$E5k1"}],"hats":[],"bases":[],"i2cs":[{"id":"i2c0","portType":"A","userPort":[22,21],"freq":"100000","blockId":"%K:FZ@L5)c,m;}Z/G4F^"}],"blockly":"true010000012rfid_0falsehello M5rfid_0hello M5rfid_0hello M5rfid_01100","screen":[{"simulationName":"Built-in","type":"builtin","width":320,"height":240,"scale":0.78,"screenName":"","blockId":"","screenColorType":0,"id":"builtin","createTime":1733454156727}],"logicWhenNum":0,"customList":[]} \ No newline at end of file diff --git a/examples/unit/rfid/rfid_cores3_example.py b/examples/unit/rfid/rfid_cores3_example.py new file mode 100644 index 00000000..407ee68f --- /dev/null +++ b/examples/unit/rfid/rfid_cores3_example.py @@ -0,0 +1,50 @@ +# SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD +# +# SPDX-License-Identifier: MIT + +import os, sys, io +import M5 +from M5 import * +from hardware import * +from unit import RFIDUnit +import time + + +title0 = None +i2c0 = None +rfid_0 = None + + +def setup(): + global title0, i2c0, rfid_0 + + M5.begin() + Widgets.fillScreen(0x222222) + title0 = Widgets.Title( + "RFIDUnit CoreS3 Example", 3, 0xFFFFFF, 0x0000FF, Widgets.FONTS.DejaVu18 + ) + + i2c0 = I2C(0, scl=Pin(1), sda=Pin(2), freq=100000) + rfid_0 = RFIDUnit(i2c0) + + +def loop(): + global title0, i2c0, rfid_0 + print(rfid_0.is_new_card_present()) + print(rfid_0.read_card_uid()) + print(rfid_0.read(1)) + time.sleep_ms(100) + + +if __name__ == "__main__": + try: + setup() + while True: + loop() + except (Exception, KeyboardInterrupt) as e: + try: + from utility import print_error_msg + + print_error_msg(e) + except ImportError: + print("please update to latest firmware") diff --git a/examples/unit/tvoc/tvoc_cores3_example.m5f2 b/examples/unit/tvoc/tvoc_cores3_example.m5f2 new file mode 100644 index 00000000..e4a920fc --- /dev/null +++ b/examples/unit/tvoc/tvoc_cores3_example.m5f2 @@ -0,0 +1 @@ +{"version":"V2.0","versionNumber":"V2.1.9","type":"cores3","components":[{"name":"screen","type":"screen","layer":0,"screenId":"builtin","screenName":"","id":"__cores3_screen","createTime":1733454156732,"x":0,"y":0,"width":320,"height":240,"backgroundColor":"#222222","size":0,"isSelected":true},{"name":"title0","type":"title","layer":1,"screenId":"builtin","screenName":"","id":"u@uvkw3`EqlzAz7q","createTime":1733466734614,"x":0,"y":0,"color":"#ffffff","backgroundColor":"#0000FF","text":"TVOCUnit CoreS3 Example","textOffset":3,"font":"Widgets.FONTS.DejaVu18","isSelected":false},{"name":"label0","type":"label","layer":1,"screenId":"builtin","screenName":"","id":"uFXHA46k#^@aqD1R","createTime":1733708739708,"x":0,"y":44,"color":"#ffffff","backgroundColor":"#222222","text":"label0","engine":"gfx","font":"Widgets.FONTS.DejaVu18","rotation":0,"isSelected":false},{"name":"label1","type":"label","layer":2,"screenId":"builtin","screenName":"","id":"sHx7OFcRsA+76kwu","createTime":1733708741688,"x":0,"y":95,"color":"#ffffff","backgroundColor":"#222222","text":"label1","engine":"gfx","font":"Widgets.FONTS.DejaVu18","rotation":0,"isSelected":false},{"name":"label2","type":"label","layer":3,"screenId":"builtin","screenName":"","id":"qcnB+R1z**vo3&J$","createTime":1733708744055,"x":0,"y":146,"color":"#ffffff","backgroundColor":"#222222","text":"label2","engine":"gfx","font":"Widgets.FONTS.DejaVu18","rotation":0,"isSelected":false},{"name":"label3","type":"label","layer":null,"screenId":"builtin","screenName":"","id":"xaFtRp&pWK#jofxe","createTime":1733713850990,"x":0,"y":193,"color":"#ffffff","backgroundColor":"#222222","text":"label3","engine":"gfx","font":"Widgets.FONTS.DejaVu18","rotation":0,"isSelected":false}],"resources":[{"hardware":["hardware_button","hardware_pin_button","imu","speaker","touch","als","mic","i2c"]},{"unit":["unit_tvoc"]}],"units":[{"type":"unit_tvoc","name":"tvoc_0","portList":["A","PAHUB","Custom"],"portType":"A","userPort":[22,21],"id":"cfyVdX1l0k8C6stx","createTime":1733713984541,"bus":"i2c0","pahubPortList":[0,1,2,3,4,5],"pahubPort":0,"initBlockId":"0ic.~-PHT#yuxpgRZW=]"}],"hats":[],"bases":[],"i2cs":[{"id":"i2c0","portType":"A","userPort":[22,21],"freq":"100000"}],"blockly":"true010000012tvoc_0truelabel0Pressure:TVOC:tvoc_0label1Data is ready.CO2:tvoc_0label2Data is ready.Ethanol:tvoc_0label3Data is ready.H2:tvoc_01","screen":[{"simulationName":"Built-in","type":"builtin","width":320,"height":240,"scale":0.78,"screenName":"","blockId":"","screenColorType":0,"id":"builtin","createTime":1733454156727}],"logicWhenNum":0,"customList":[]} \ No newline at end of file diff --git a/examples/unit/tvoc/tvoc_cores3_example.py b/examples/unit/tvoc/tvoc_cores3_example.py new file mode 100644 index 00000000..46418950 --- /dev/null +++ b/examples/unit/tvoc/tvoc_cores3_example.py @@ -0,0 +1,60 @@ +# SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD +# +# SPDX-License-Identifier: MIT + +import os, sys, io +import M5 +from M5 import * +from hardware import * +from unit import TVOCUnit +import time + + +label3 = None +title0 = None +label0 = None +label1 = None +label2 = None +i2c0 = None +tvoc_0 = None + + +def setup(): + global label3, title0, label0, label1, label2, i2c0, tvoc_0 + + M5.begin() + Widgets.fillScreen(0x222222) + label3 = Widgets.Label("label3", 0, 193, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18) + title0 = Widgets.Title( + "TVOCUnit CoreS3 Example", 3, 0xFFFFFF, 0x0000FF, Widgets.FONTS.DejaVu18 + ) + label0 = Widgets.Label("label0", 0, 44, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18) + label1 = Widgets.Label("label1", 0, 95, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18) + label2 = Widgets.Label("label2", 0, 146, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18) + + i2c0 = I2C(0, scl=Pin(1), sda=Pin(2), freq=100000) + tvoc_0 = TVOCUnit(i2c0) + + +def loop(): + global label3, title0, label0, label1, label2, i2c0, tvoc_0 + M5.update() + label0.setText(str((str("TVOC:") + str((tvoc_0.tvoc()))))) + label1.setText(str((str("CO2:") + str((tvoc_0.co2eq()))))) + label2.setText(str((str("Ethanol:") + str((tvoc_0.raw_ethanol()))))) + label3.setText(str((str("H2:") + str((tvoc_0.raw_h2()))))) + time.sleep(1) + + +if __name__ == "__main__": + try: + setup() + while True: + loop() + except (Exception, KeyboardInterrupt) as e: + try: + from utility import print_error_msg + + print_error_msg(e) + except ImportError: + print("please update to latest firmware") diff --git a/examples/unit/weight/weight_cores3_example.m5f2 b/examples/unit/weight/weight_cores3_example.m5f2 new file mode 100644 index 00000000..5b678bb8 --- /dev/null +++ b/examples/unit/weight/weight_cores3_example.m5f2 @@ -0,0 +1 @@ +{"version":"V2.0","versionNumber":"V2.1.8","type":"cores3","components":[{"name":"screen","type":"screen","layer":0,"screenId":"builtin","screenName":"","id":"__cores3_screen","createTime":1733454156732,"x":0,"y":0,"width":320,"height":240,"backgroundColor":"#222222","size":0,"isSelected":true},{"name":"title0","type":"title","layer":1,"screenId":"builtin","screenName":"","id":"u@uvkw3`EqlzAz7q","createTime":1733466734614,"x":0,"y":0,"color":"#ffffff","backgroundColor":"#0000FF","text":"WeightUnit CoreS3 Example","textOffset":3,"font":"Widgets.FONTS.DejaVu18","isSelected":false},{"name":"label0","type":"label","layer":2,"screenId":"builtin","screenName":"","id":"atasONiLyrnuE3mX","createTime":1733466776859,"x":4,"y":113,"color":"#ffffff","backgroundColor":"#222222","text":"weight value:","engine":"gfx","font":"Widgets.FONTS.DejaVu18","rotation":0,"isSelected":false,"width":54,"height":20}],"resources":[{"hardware":["hardware_button","hardware_pin_button","imu","speaker","touch","als","mic","i2c"]},{"unit":["unit_weight"]}],"units":[{"type":"unit_weight","name":"weight_0","portList":["A","B","C","Custom"],"portType":"B","userPort":[22,21],"id":"omR%BMot6+Irhv*r","createTime":1733466374524,"initBlockId":"4dCh}Cjky2{t`d|#3X7q"}],"hats":[],"bases":[],"i2cs":[{"id":"i2c0","portType":"A","userPort":[22,21],"freq":"100000","blockId":"O2=v$Cx1:{g6~WTfl=7c"}],"blockly":"trueweight_0weight_0truelabel0Labelweight value:weight_0100","screen":[{"simulationName":"Built-in","type":"builtin","width":320,"height":240,"scale":0.78,"screenName":"","blockId":"","screenColorType":0,"id":"builtin","createTime":1733454156727}],"logicWhenNum":0,"customList":[]} \ No newline at end of file diff --git a/examples/unit/weight/weight_cores3_example.py b/examples/unit/weight/weight_cores3_example.py new file mode 100644 index 00000000..390d2b44 --- /dev/null +++ b/examples/unit/weight/weight_cores3_example.py @@ -0,0 +1,51 @@ +# SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD +# +# SPDX-License-Identifier: MIT + +import os, sys, io +import M5 +from M5 import * +from unit import WeightUnit +import time + + +title0 = None +label0 = None +weight_0 = None + + +def setup(): + global title0, label0, weight_0 + + M5.begin() + Widgets.fillScreen(0x222222) + title0 = Widgets.Title( + "WeightUnit CoreS3 Example", 3, 0xFFFFFF, 0x0000FF, Widgets.FONTS.DejaVu18 + ) + label0 = Widgets.Label( + "weight value:", 4, 113, 1.0, 0xFFFFFF, 0x222222, Widgets.FONTS.DejaVu18 + ) + + weight_0 = WeightUnit(port=(8, 9)) + weight_0.set_tare() + + +def loop(): + global title0, label0, weight_0 + M5.update() + label0.setText(str((str("weight value:") + str((weight_0.get_scale_weight))))) + time.sleep_ms(100) + + +if __name__ == "__main__": + try: + setup() + while True: + loop() + except (Exception, KeyboardInterrupt) as e: + try: + from utility import print_error_msg + + print_error_msg(e) + except ImportError: + print("please update to latest firmware") diff --git a/m5stack/libs/driver/sgp30.py b/m5stack/libs/driver/sgp30.py index f27ac67f..4dc58103 100644 --- a/m5stack/libs/driver/sgp30.py +++ b/m5stack/libs/driver/sgp30.py @@ -82,13 +82,28 @@ def __init__(self, i2c, addr=SGP30_DEFAULT_I2C_ADDR, measure_test=False, iaq_ini self.iaq_init() def iaq_init(self): - """Initialises the IAQ algorithm""" + """ + note: + en: Initialize the IAQ (Indoor Air Quality) algorithm for the sensor. + + params: + note: + """ self._i2c_read_words_from_cmd( SGP30_CMD_IAQ_INIT_HEX, SGP30_CMD_IAQ_INIT_MAX_MS, SGP30_CMD_IAQ_INIT_WORDS ) def measure_iaq(self): - """Measures the CO2eq and TVOC""" + """ + note: + en: Measure the CO2 equivalent (CO2eq) and TVOC values. + + params: + note: + + returns: + note: A tuple containing CO2eq and TVOC values. + """ return self._i2c_read_words_from_cmd( SGP30_CMD_MEASURE_IAQ_HEX, SGP30_CMD_MEASURE_IAQ_MS, @@ -96,7 +111,16 @@ def measure_iaq(self): ) def get_iaq_baseline(self): - """Retreives the IAQ algorithm baseline for CO2eq and TVOC""" + """ + note: + en: Retrieve the IAQ algorithm baseline values for CO2eq and TVOC. + + params: + note: + + returns: + note: A tuple containing baseline values for CO2eq and TVOC. + """ return self._i2c_read_words_from_cmd( SGP30_CMD_GET_IAQ_BASELINE_HEX, SGP30_CMD_GET_IAQ_BASELINE_MAX_MS, @@ -104,7 +128,16 @@ def get_iaq_baseline(self): ) def set_iaq_baseline(self, co2eq, tvoc): - """Sets the previously recorded IAQ algorithm baseline for CO2eq and TVOC""" + """ + note: + en: Set the previously recorded IAQ algorithm baseline values for CO2eq and TVOC. + + params: + co2eq: + note: The CO2 equivalent baseline value. + tvoc: + note: The TVOC baseline value. + """ if co2eq == 0 and tvoc == 0: raise ValueError("Invalid baseline values used") buffer = [] @@ -119,8 +152,14 @@ def set_iaq_baseline(self, co2eq, tvoc): ) def set_absolute_humidity(self, absolute_humidity): - """Sets absolute humidity compensation. To disable, - set 0.""" + """ + note: + en: Set the absolute humidity compensation for the sensor. To disable, set the value to 0. + + params: + absolute_humidity: + note: The absolute humidity value to set. + """ buffer = [] arr = [absolute_humidity >> 8, absolute_humidity & 0xFF] arr.append(generate_crc(arr)) @@ -132,7 +171,16 @@ def set_absolute_humidity(self, absolute_humidity): ) def measure_test(self): - """Runs on-chip self test""" + """ + note: + en: Run the on-chip self-test. + + params: + note: + + returns: + note: The result of the self-test. + """ return self._i2c_read_words_from_cmd( SGP30_CMD_MEASURE_TEST_HEX, SGP30_CMD_MEASURE_TEST_MAX_MS, @@ -140,7 +188,16 @@ def measure_test(self): )[0] def get_feature_set(self): - """Retrieves feature set of sensor""" + """ + note: + en: Retrieve the feature set of the sensor. + + params: + note: + + returns: + note: The feature set value. + """ return self._i2c_read_words_from_cmd( SGP30_CMD_GET_FEATURE_SET_HEX, SGP30_CMD_GET_FEATURE_SET_MAX_MS, @@ -148,7 +205,16 @@ def get_feature_set(self): )[0] def measure_raw(self): - """Returns raw H2 and Ethanol signals, used for part verification and testing""" + """ + note: + en: Return raw H2 and Ethanol signals for part verification and testing. + + params: + note: + + returns: + note: A tuple containing raw H2 and Ethanol signals. + """ return self._i2c_read_words_from_cmd( SGP30_CMD_MEASURE_RAW_HEX, SGP30_CMD_MEASURE_RAW_MAX_MS, @@ -160,8 +226,17 @@ def measure_raw(self): # TODO: Soft Reset (datasheet section 6.4) def get_serial(self): - """Retrieves sensor serial""" - serial = self.serial = self._i2c_read_words_from_cmd( + """ + note: + en: Retrieve the sensor serial ID. + + params: + note: + + returns: + note: The serial ID as a hexadecimal string. + """ + serial = self._i2c_read_words_from_cmd( SGP30_CMD_GET_SERIAL_ID_HEX, SGP30_CMD_GET_SERIAL_ID_MAX_MS, SGP30_CMD_GET_SERIAL_ID_WORDS, @@ -169,31 +244,99 @@ def get_serial(self): return hex(int.from_bytes(bytearray(serial), "large")) def co2eq(self): - """Carbon Dioxide Equivalent in parts per million (ppm)""" + """ + note: + en: Retrieve the Carbon Dioxide Equivalent (CO2eq) in parts per million (ppm). + + params: + note: + + returns: + note: The CO2eq value in ppm. + """ return self.measure_iaq()[0] def baseline_co2eq(self): - """Carbon Dioxide Equivalent baseline value""" + """ + note: + en: Retrieve the baseline value for CO2eq. + + params: + note: + + returns: + note: The baseline CO2eq value. + """ return self.get_iaq_baseline()[0] def tvoc(self): - """Total Volatile Organic Compound in parts per billion (ppb)""" + """ + note: + en: Retrieve the Total Volatile Organic Compound (TVOC) in parts per billion (ppb). + + params: + note: + + returns: + note: The TVOC value in ppb. + """ return self.measure_iaq()[1] def baseline_tvoc(self): - """Total Volatile Organic Compound baseline value""" + """ + note: + en: Retrieve the baseline value for TVOC. + + params: + note: + + returns: + note: The baseline TVOC value. + """ return self.get_iaq_baseline()[1] def raw_h2(self): - """Raw H2 signal""" + """ + note: + en: Retrieve the raw H2 signal value. + + params: + note: + + returns: + note: The raw H2 signal value. + """ return self.measure_raw()[0] def raw_ethanol(self): - """Raw Ethanol signal""" + """ + note: + en: Retrieve the raw Ethanol signal value. + + params: + note: + + returns: + note: The raw Ethanol signal value. + """ return self.measure_raw()[1] def _i2c_read_words_from_cmd(self, command, delay, reply_size): - """Runs an SGP command query, gets a reply and CRC results if necessary""" + """ + note: + en: Execute an I2C command query and retrieve the response, including CRC validation. + + params: + command: + note: The command to send to the sensor. + delay: + note: The delay in milliseconds before reading the response. + reply_size: + note: The size of the expected response in words. + + returns: + note: A list of response words from the sensor. + """ self._i2c.writeto(self.addr, bytes(command)) sleep_ms(delay) if not reply_size: @@ -210,24 +353,43 @@ def _i2c_read_words_from_cmd(self, command, delay, reply_size): return result def convert_r_to_a_humidity(self, temp_c, r_humidity_perc, fixed_point=True): - """Converts relative to absolute humidity as per the equation - found in datasheet""" + """ + note: + en: Convert relative humidity to absolute humidity based on the sensor's equation. + + params: + temp_c: + note: The ambient temperature in Celsius (°C). + r_humidity_perc: + note: The relative humidity in percentage (%). + fixed_point: + note: Whether to return the value in 8.8 fixed-point format. Defaults to True. + + returns: + note: The absolute humidity value, either in g/m³ or fixed-point format. + """ a_humidity_gm3 = 216.7 * ( (r_humidity_perc / 100 * 6.112 * exp(17.62 * temp_c / (243.12 + temp_c))) / (273.15 + temp_c) ) - # Return in 8.8 bit fixed point format (for setting humidity compensation), if not - # simply return the calculated value in g/m^3 if fixed_point: a_humidity_gm3 = (int(a_humidity_gm3) << 8) + (int(a_humidity_gm3 % 1 * 256)) return a_humidity_gm3 def generate_crc(data): - """8-bit CRC algorithm for checking data. - Calculation described in section 6.6 of SGP30 datasheet""" + """ + note: + en: Calculate an 8-bit CRC checksum based on the sensor's specified algorithm. + + params: + data: + note: The data array for which to calculate the CRC checksum. + + returns: + note: The calculated 8-bit CRC checksum. + """ crc = SGP30_CRC8_INIT - # Calculates 8-Bit CRC checksum with given polynomial for byte in data: crc ^= byte for _ in range(8): diff --git a/m5stack/libs/unit/angle8.py b/m5stack/libs/unit/angle8.py index 86c7df44..318b8797 100644 --- a/m5stack/libs/unit/angle8.py +++ b/m5stack/libs/unit/angle8.py @@ -24,10 +24,32 @@ class Angle8Unit: + """ + note: + en: UNIT 8Angle is an input unit integrating 8 adjustable potentiometers, internal STM32F030 microcomputer as acquisition and communication processor, and the host computer adopts I2C communication interface, each adjustable potentiometer corresponds to 1 RGB LED light, and there is also a physical toggle switch and its corresponding RGB LED light, containing 5V->3V3 DCDC circuit. + + details: + link: https://docs.m5stack.com/en/unit/8Angle + image: https://static-cdn.m5stack.com/resource/docs/products/unit/8Angle/img-b698604d-29dd-4506-b662-4752e1f03a28.webp + category: Unit + + example: + - ../../../examples/unit/angle8unit/angle8unit_cores3_example.py + + m5f2: + - unit/angle8unit/angle8unit_cores3_example.m5f2 + """ + def __init__(self, i2c: I2C | PAHUBUnit, address: int = ANGLE8_ADDR) -> None: - """! angle 8 channel initialize function - set I2C port - address : 1 to 127 + """ + note: + en: Initialize the Angle8Unit with the specified I2C interface and address. + + params: + i2c: + note: The I2C or PAHUBUnit instance for communication. + address: + note: The I2C address of the device (default is ANGLE8_ADDR). """ self._i2c = i2c if address >= 1 and address <= 127: @@ -35,11 +57,25 @@ def __init__(self, i2c: I2C | PAHUBUnit, address: int = ANGLE8_ADDR) -> None: self.available() def available(self) -> None: + """ + note: + en: Check if the device is available on the I2C bus. + + params: + note: + """ if self._i2c_addr not in self._i2c.scan(): raise UnitError("Angle 8 unit maybe not connect") def get_adc12_raw(self, channel: int = 0) -> int: - """! get adc12 raw data.""" + """ + note: + en: Get the raw 12-bit ADC value from the specified channel. + + params: + channel: + note: The channel number (1 to 8). + """ channel -= 1 if not ((channel * 2) >= ADC12_START_REG and (channel * 2) <= ADC12_END_REG): channel = ADC12_START_REG @@ -47,7 +83,14 @@ def get_adc12_raw(self, channel: int = 0) -> int: return struct.unpack(" int: - """! get adc8 raw data.""" + """ + note: + en: Get the raw 8-bit ADC value from the specified channel. + + params: + channel: + note: The channel number (1 to 8). + """ channel -= 1 channel += ADC8_START_REG if not (channel >= ADC8_START_REG and channel <= ADC8_END_REG): @@ -55,14 +98,27 @@ def get_adc8_raw(self, channel: int = 0) -> int: return self.readfrommem(channel, 1)[0] def get_switch_status(self) -> bool: - """! get switch status.""" + """ + note: + en: Get the status of the switch button. + + params: + note: + """ return bool(self.readfrommem(BUTTON_REG, 1)[0]) def set_led_rgb(self, channel: int, rgb: int, bright: int = 50) -> None: - """! set rgb led color. - channel: 0 ~ 8 - rgb: 0x00 ~ 0xffffff - brightness: 0 ~ 100 + """ + note: + en: Set the RGB color and brightness of the specified LED channel. + + params: + channel: + note: The LED channel number (0 to 8). + rgb: + note: The RGB color value (0x00 to 0xFFFFFF). + bright: + note: The brightness level (0 to 100, default is 50). """ channel -= 1 channel = RGB_START_REG + (channel * 4) @@ -77,12 +133,21 @@ def set_led_rgb(self, channel: int, rgb: int, bright: int = 50) -> None: def set_led_rgb_from( self, begin: int, end: int, rgb: int, bright: int = 50, per_delay: int = 0 ) -> None: - """! set rgb led color. - begin: 0 ~ 8 - end: 0 ~ 8 - rgb: 0x00 ~ 0xffffff - brightness: 0 ~ 100 - per_delay:0~ + """ + note: + en: Set the RGB color and brightness for a range of LED channels. + + params: + begin: + note: The starting LED channel (0 to 8). + end: + note: The ending LED channel (0 to 8). + rgb: + note: The RGB color value (0x00 to 0xFFFFFF). + bright: + note: The brightness level (0 to 100, default is 50). + per_delay: + note: The delay in milliseconds between setting each channel (default is 0). """ begin = min(TOTAL_LED, max(begin, 1)) end = min(TOTAL_LED, max(end, 1)) @@ -93,23 +158,39 @@ def set_led_rgb_from( time.sleep_ms(per_delay) def set_angle_sync_bright(self, channel: int, rgb: int) -> None: - """! set angle sync bright. - channel: 0 ~ 8 - rgb: 0x00 ~ 0xffffff + """ + note: + en: Set the LED brightness synchronized with the angle value. + + params: + channel: + note: The LED channel number (0 to 8). + rgb: + note: The RGB color value (0x00 to 0xFFFFFF). """ bright = self._map(self.get_adc12_raw(channel), 0, 4095, 0, 100) self.set_led_rgb(channel, rgb, bright) def get_device_spec(self, mode: int) -> int: - """! get firmware version and i2c address. - mode: 0xFE and 0xFF + """ + note: + en: Get device specifications such as firmware version or I2C address. + + params: + mode: + note: The register to read (FW_VER_REG or I2C_ADDR_REG). """ if mode >= FW_VER_REG and mode <= I2C_ADDR_REG: return self.readfrommem(mode, 1)[0] def set_i2c_address(self, address: int) -> None: - """! set i2c address. - address : 1 to 127 + """ + note: + en: Set a new I2C address for the device. + + params: + address: + note: The new I2C address (1 to 127). """ if address >= 1 and address <= 127: if address != self._i2c_addr: @@ -119,6 +200,16 @@ def set_i2c_address(self, address: int) -> None: time.sleep_ms(200) def readfrommem(self, reg, num) -> bytearray: + """ + note: + en: Read a specified number of bytes from a device register. + + params: + reg: + note: The register address to read from. + num: + note: The number of bytes to read. + """ buf = bytearray(1) buf[0] = reg time.sleep_ms(1) @@ -128,10 +219,34 @@ def readfrommem(self, reg, num) -> bytearray: return buf def _convert_12_to_24(self, val: int) -> int: + """ + note: + en: Convert a 12-bit RGB value to a 24-bit RGB value. + + params: + val: + note: The 12-bit RGB value to convert. + """ red = (val >> 8) * 17 green = ((val & 0xF0) >> 4) * 17 blue = (val & 0x0F) * 17 return red << 16 | green << 8 | blue def _map(self, val, in_min, in_max, out_min, out_max) -> int: + """ + note: + en: Map a value from one range to another. + + params: + val: + note: The input value to map. + in_min: + note: The minimum value of the input range. + in_max: + note: The maximum value of the input range. + out_min: + note: The minimum value of the output range. + out_max: + note: The maximum value of the output range. + """ return int((val - in_min) * (out_max - out_min) / (in_max - in_min) + out_min) diff --git a/m5stack/libs/unit/co2.py b/m5stack/libs/unit/co2.py index df77e8a1..22c40d04 100644 --- a/m5stack/libs/unit/co2.py +++ b/m5stack/libs/unit/co2.py @@ -10,7 +10,554 @@ CO2_I2C_ADDR = const(0x62) +REINIT = const(0x3646) +FACTORYRESET = const(0x3632) +FORCEDRECAL = const(0x362F) +SELFTEST = const(0x3639) +DATAREADY = const(0xE4B8) +STARTPERIODICMEASUREMENT = const(0x21B1) +STOPPERIODICMEASUREMENT = const(0x3F86) +STARTLOWPOWERPERIODICMEASUREMENT = const(0x21AC) +READMEASUREMENT = const(0xEC05) +SERIALNUMBER = const(0x3682) +GETTEMPOFFSET = const(0x2318) +SETTEMPOFFSET = const(0x241D) +GETALTITUDE = const(0x2322) +SETALTITUDE = const(0x2427) +SETPRESSURE = const(0xE000) +PERSISTSETTINGS = const(0x3615) +GETASCE = const(0x2313) +SETASCE = const(0x2416) +SINGLESHOTMEASUREALL = const(0x219D) +SINGLESHOTMEASUREHT = const(0x2196) +POWERDOWN = const(0x36E0) +WAKEUP = const(0x36F6) + + +class CO2Unit: + """ + note: + en: CO2Unit is a hardware module designed for measuring CO2 concentration, temperature, and humidity. + It communicates via I2C and provides functions for calibration, measurement, and configuration. + + details: + link: https://docs.m5stack.com/en/unit/co2unit + image: https://static-cdn.m5stack.com/resource/docs/products/unit/co2unit/co2unit_01.webp + category: Unit + + example: + - ../../../examples/unit/co2unit/co2unit_cores3_example.py + + m5f2: + - unit/co2unit/co2unit_cores3_example.m5f2 + """ -class CO2Unit(SCD40): def __init__(self, i2c: I2C | PAHUBUnit, address: int = CO2_I2C_ADDR) -> None: - super().__init__(i2c, address) + """ + note: + en: Initialize the CO2Unit with the I2C interface and address. + + params: + i2c: + note: I2C interface or PAHUBUnit instance for communication. + address: + note: I2C address of the CO2 sensor, default is 0x62. + """ + self.co2_i2c = i2c + self.unit_addr = address + self.available() + self.co2 = 0 + self.temperature = 0 + self.humidity = 0 + + def available(self) -> None: + """ + note: + en: Check if the CO2 unit is available on the I2C bus. + + params: + note: + """ + if self.unit_addr not in self.co2_i2c.scan(): + raise UnitError("CO2 unit may not be connected") + + def set_start_periodic_measurement(self) -> None: + """ + note: + en: Set the sensor into working mode, which takes about 5 seconds per measurement. + + params: + note: + """ + try: + self.write_cmd(STARTPERIODICMEASUREMENT) + time.sleep_ms(1) + except: + raise OSError( + "Indicates that the block cannot be executed while a periodic measurement is running" + ) + + def set_stop_periodic_measurement(self) -> None: + """ + note: + en: Stop the measurement mode for the sensor. + + params: + note: + """ + self.write_cmd(STOPPERIODICMEASUREMENT) + time.sleep(0.5) + + def get_sensor_measurement(self) -> None: + """ + note: + en: Get temperature, humidity, and CO2 concentration from the sensor. + + params: + note: + """ + self.write_cmd(READMEASUREMENT) + time.sleep_ms(1) + buf = self.read_response(9) + self.co2 = (buf[0] << 8) | buf[1] + temp = (buf[3] << 8) | buf[1] + self.temperature = round((-45 + 175 * (temp / (2**16 - 1))), 2) + humi = (buf[6] << 8) | buf[7] + self.humidity = round((100 * (humi / (2**16 - 1))), 2) + + def is_data_ready(self) -> bool: + """ + note: + en: Check if the data (temperature, humidity, CO2) is ready from the sensor. + + params: + note: + + returns: + note: True if data is ready, otherwise False. + """ + if self.data_isready(): + self.get_sensor_measurement() + return True + else: + return False + + def get_temperature_offset(self) -> float: + """ + note: + en: Get the temperature offset to be added to the reported measurements. + + params: + note: + + returns: + note: The temperature offset in degrees Celsius. + """ + try: + self.write_cmd(GETTEMPOFFSET) + buf = self.read_response(3) + temp = (buf[0] << 8) | buf[1] + time.sleep_ms(1) + return 175.0 * temp / 2**16 + except: + raise OSError( + "Indicates that the block cannot be executed while a periodic measurement is running" + ) + + def set_temperature_offset(self, offset: int = 0) -> None: + """ + note: + en: Set the maximum value of 374°C temperature offset. + + params: + offset: + note: The temperature offset to set, default is 0. + """ + try: + offset = min(374, offset) + temp = int(offset * (2**16 / 175)) + self.write_cmd(SETTEMPOFFSET, temp) + time.sleep_ms(1) + except: + raise OSError( + "Indicates that the block cannot be executed while a periodic measurement is running" + ) + + def get_sensor_altitude(self) -> int: + """ + note: + en: Get the altitude value of the measurement location in meters above sea level. + + params: + note: + + returns: + note: The altitude value in meters. + """ + try: + self.write_cmd(GETALTITUDE) + time.sleep_ms(1) + buf = self.read_response(3) + return (buf[0] << 8) | buf[1] + except: + raise OSError( + "Indicates that the block cannot be executed while a periodic measurement is running" + ) + + def set_sensor_altitude(self, height: int) -> None: + """ + note: + en: Set the altitude value of the measurement location in meters above sea level. + + params: + height: + note: The altitude in meters to set. Must be between 0 and 65535 meters. + """ + try: + height = min(65535, max(height, 0)) + self.write_cmd(SETALTITUDE, int(height)) + time.sleep_ms(1) + except: + raise OSError( + "Indicates that the block cannot be executed while a periodic measurement is running" + ) + + def set_ambient_pressure(self, ambient_pressure: int) -> None: + """ + note: + en: Set the ambient pressure in hPa at any time to adjust CO2 calculations. + + params: + ambient_pressure: + note: The ambient pressure in hPa, constrained to the range [0, 65535]. + """ + ambient_pressure = min(65535, max(ambient_pressure, 0)) + self.write_cmd(SETPRESSURE, int(ambient_pressure)) + time.sleep_ms(1) + + def set_force_calibration(self, target_co2: int) -> None: + """ + note: + en: Force the sensor to recalibrate with a given current CO2 level. + + params: + target_co2: + note: The current CO2 concentration to be used for recalibration. + """ + try: + self.set_stop_periodic_measurement() + self.write_cmd(FORCEDRECAL, int(target_co2)) + time.sleep(0.5) + buf = self.read_response(3) + correction = struct.unpack_from(">h", buf[0:2])[0] + if correction == 0xFFFF: + raise RuntimeError( + "Forced recalibration failed. Make sure sensor is active for 3 minutes first" + ) + except: + raise OSError( + "Indicates that the block cannot be executed while a periodic measurement is running" + ) + + def get_calibration_enabled(self) -> bool: + """ + note: + en: Get whether automatic self-calibration (ASC) is enabled or disabled. + + params: + note: + + returns: + note: True if ASC is enabled, otherwise False. + """ + try: + self.write_cmd(GETASCE) + time.sleep_ms(1) + buf = self.read_response(3) + return buf[1] == 1 + except: + raise OSError( + "Indicates that the block cannot be executed while a periodic measurement is running" + ) + + def set_calibration_enabled(self, enabled: bool) -> None: + """ + note: + en: Enable or disable automatic self-calibration (ASC). + + params: + enabled: + note: Set to True to enable ASC, or False to disable it. + """ + try: + enabled = min(1, max(enabled, 0)) + self.write_cmd(SETASCE, enabled) + time.sleep_ms(1) + except: + raise OSError( + "Indicates that the block cannot be executed while a periodic measurement is running" + ) + + def set_start_low_periodic_measurement(self) -> None: + """ + note: + en: Set the sensor into low power working mode, with about 30 seconds per measurement. + + params: + note: + """ + try: + self.write_cmd(STARTLOWPOWERPERIODICMEASUREMENT) + except: + raise OSError( + "Indicates that the block cannot be executed while a periodic measurement is running" + ) + + def data_isready(self) -> bool: + """ + note: + en: Check if new data is available from the sensor. + + params: + note: + + returns: + note: True if new data is available, otherwise False. + """ + try: + self.write_cmd(DATAREADY) + time.sleep_ms(1) + buf = self.read_response(3) + return not ((buf[0] & 0x07 == 0) and (buf[1] == 0)) + except: + raise OSError( + "Indicates that the block cannot be executed while a periodic measurement is running" + ) + + def save_to_eeprom(self) -> None: + """ + note: + en: Save temperature offset, altitude offset, and self-calibration enable settings to EEPROM. + + params: + note: + """ + try: + self.write_cmd(PERSISTSETTINGS) + time.sleep(0.8) + except: + raise OSError( + "Indicates that the block cannot be executed while a periodic measurement is running" + ) + + def get_serial_number(self) -> tuple: + """ + note: + en: Get a unique serial number for this sensor. + + params: + note: + + returns: + note: A tuple representing the unique serial number of the sensor. + """ + try: + self.write_cmd(SERIALNUMBER) + time.sleep_ms(1) + buf = self.read_response(9) + return (buf[0], buf[1], buf[3], buf[4], buf[6], buf[7]) + except: + raise OSError( + "Indicates that the block cannot be executed while a periodic measurement is running" + ) + + def set_self_test(self) -> None: + """ + note: + en: Perform a self-test, which can take up to 10 seconds. + + params: + note: + """ + try: + self.set_stop_periodic_measurement() + self.write_cmd(SELFTEST) + time.sleep(10) + buf = self.read_response(3) + if (buf[0] != 0) or (buf[1] != 0): + raise RuntimeError("Self test failed") + except: + raise OSError( + "Indicates that the block cannot be executed while a periodic measurement is running" + ) + + def set_factory_reset(self) -> None: + """ + note: + en: Reset all configuration settings stored in the EEPROM and erase the FRC and ASC algorithm history. + + params: + note: + """ + try: + self.set_stop_periodic_measurement() + self.write_cmd(FACTORYRESET) + time.sleep(1.2) + except: + raise OSError( + "Indicates that the block cannot be executed while a periodic measurement is running" + ) + + def reinit(self) -> None: + """ + note: + en: Reinitialize the sensor by reloading user settings from EEPROM. + + params: + note: + """ + try: + self.set_stop_periodic_measurement() + self.write_cmd(REINIT) + time.sleep_ms(20) + except: + raise OSError( + "Indicates that the block cannot be executed while a periodic measurement is running" + ) + + def set_single_shot_measurement_all(self) -> None: + """ + note: + en: Set the sensor to perform a single-shot measurement for CO2, humidity, and temperature. + + params: + note: + """ + try: + self.write_cmd(SINGLESHOTMEASUREALL) + time.sleep(5) + except: + raise OSError( + "Indicates that the block cannot be executed while a periodic measurement is running" + ) + + def set_single_shot_measurement_ht(self) -> None: + """ + note: + en: Set the sensor to perform a single-shot measurement for humidity and temperature. + + params: + note: + """ + try: + self.write_cmd(SINGLESHOTMEASUREHT) + time.sleep_ms(50) + except: + raise OSError( + "Indicates that the block cannot be executed while a periodic measurement is running" + ) + + def set_sleep_mode(self) -> None: + """ + note: + en: Put the sensor into sleep mode to reduce current consumption. + + params: + note: + """ + try: + self.write_cmd(POWERDOWN) + time.sleep_ms(1) + except: + raise OSError( + "Indicates that the block cannot be executed while a periodic measurement is running" + ) + + def set_wake_up(self) -> None: + """ + note: + en: Wake up the sensor from sleep mode into idle mode. + + params: + note: + """ + try: + self.write_cmd(WAKEUP) + time.sleep_ms(20) + except: + raise OSError( + "Indicates that the block cannot be executed while a periodic measurement is running" + ) + + def write_cmd(self, cmd_wr: int, value: int = None) -> None: + """ + note: + en: Write a command to the sensor. + + params: + cmd_wr: + note: The command to write to the sensor. + value: + note: The value to send with the command, if any. + """ + if value is not None: + byte_val = struct.pack(">h", value) + crc8 = self.crc8(byte_val) + self.co2_i2c.writeto(self.unit_addr, struct.pack(">hhb", cmd_wr, value, crc8)) + else: + self.co2_i2c.writeto(self.unit_addr, struct.pack(">h", cmd_wr)) + + def read_response(self, num: int) -> bytearray: + """ + note: + en: Read the sensor's response. + + params: + num: + note: The number of bytes to read from the sensor. + + returns: + note: The read response as a bytearray. + """ + buff = self.co2_i2c.readfrom(self.unit_addr, num) + self.check_crc(buff) + return buff + + def check_crc(self, buf: bytearray) -> bool: + """ + note: + en: Check the CRC of the received data to ensure it is correct. + + params: + buf: + note: The buffer of bytes to check the CRC. + + returns: + note: True if the CRC check passes, otherwise raises an error. + """ + for i in range(0, len(buf), 3): + if self.crc8(buf[i : (i + 2)]) != buf[i + 2]: + raise RuntimeError("CRC check failed while reading data") + return True + + def crc8(self, buffer: bytearray) -> int: + """ + note: + en: Calculate the CRC-8 checksum for a given buffer. + + params: + buffer: + note: The buffer of bytes to calculate the CRC for. + + returns: + note: The CRC-8 checksum as an integer. + """ + crc = 0xFF + for byte in buffer: + crc ^= byte + for _ in range(8): + if crc & 0x80: + crc = (crc << 1) ^ 0x31 + else: + crc = crc << 1 + return crc & 0xFF # Return the bottom 8 bits diff --git a/m5stack/libs/unit/envpro.py b/m5stack/libs/unit/envpro.py index 5a35a7f1..0d5dfde9 100644 --- a/m5stack/libs/unit/envpro.py +++ b/m5stack/libs/unit/envpro.py @@ -9,16 +9,53 @@ class ENVPROUnit(BME68X_I2C): + """ + note: + en: ENV Pro Unit is an environmental sensor that utilizes the BME688 sensor solution, supporting the measurement of various environmental parameters such as volatile organic compounds (VOCs), indoor air quality (IAQ), temperature, humidity, and atmospheric pressure. It features a compact size, wide operating range, simple communication interface (I2C), excellent performance, and low power consumption, making it suitable for weather stations, indoor environmental monitoring, and air quality detection applications. + + details: + link: https://docs.m5stack.com/en/unit/ENV%20Pro%20Unit + image: https://static-cdn.m5stack.com/resource/docs/products/unit/ENV%20Pro%20Unit/img-2ba12134-9756-471a-b1a5-ba803a875e8f.webp + category: Unit + + example: + - ../../../examples/unit/envpro/envpro_cores3_example.py + + m5f2: + - unit/envpro/envpro_cores3_example.m5f2 + """ + TEMPERATURE = 1 PRESSURE = 2 HUMIDITY = 3 def __init__(self, i2c: I2C | PAHUBUnit, address: int | list | tuple = 0x77): + """ + note: + en: Initialize the ENVPROUnit with an I2C object and an optional address. + + params: + i2c: + note: The I2C interface or PAHUBUnit instance to communicate with the ENV PRO sensor. + address: + note: The I2C address of the ENV PRO sensor. Defaults to 0x77. + """ if address not in i2c.scan(): raise UnitError("ENV PRO unit maybe not connect") super().__init__(i2c, address) def get_over_sampling_rate(self, env): + """ + note: + en: Retrieve the oversampling rate for the specified environment parameter. + + params: + env: + note: The environment parameter (TEMPERATURE, PRESSURE, HUMIDITY). + + returns: + note: The oversampling rate for the specified parameter. + """ if env == self.TEMPERATURE: return self.temperature_oversample elif env == self.PRESSURE: @@ -27,6 +64,16 @@ def get_over_sampling_rate(self, env): return self.humidity_oversample def set_over_sampling_rate(self, env, rate): + """ + note: + en: Set the oversampling rate for the specified environment parameter. + + params: + env: + note: The environment parameter (TEMPERATURE, PRESSURE, HUMIDITY). + rate: + note: The oversampling rate to be set. + """ if env == self.TEMPERATURE: self.temperature_oversample = rate elif env == self.PRESSURE: @@ -35,22 +82,90 @@ def set_over_sampling_rate(self, env, rate): self.humidity_oversample = rate def get_iir_filter_coefficient(self): + """ + note: + en: Retrieve the IIR filter coefficient. + + params: + note: + + returns: + note: The current IIR filter coefficient. + """ return self.filter_size def set_iir_filter_coefficient(self, value): + """ + note: + en: Set the IIR filter coefficient. + + params: + value: + note: The IIR filter coefficient to be set. + """ self.filter_size = value def get_temperature(self): + """ + note: + en: Retrieve the measured temperature. + + params: + note: + + returns: + note: The temperature value in degrees Celsius. + """ return self.temperature def get_humidity(self): + """ + note: + en: Retrieve the measured humidity. + + params: + note: + + returns: + note: The humidity value as a percentage. + """ return self.humidity def get_pressure(self): + """ + note: + en: Retrieve the measured pressure. + + params: + note: + + returns: + note: The pressure value in hPa. + """ return self.pressure def get_gas_resistance(self): + """ + note: + en: Retrieve the measured gas resistance. + + params: + note: + + returns: + note: The gas resistance value in kOhms. + """ return round(self.gas / 1000, 3) def get_altitude(self): + """ + note: + en: Retrieve the calculated altitude based on pressure readings. + + params: + note: + + returns: + note: The altitude value in meters. + """ return round(self.altitude, 2) diff --git a/m5stack/libs/unit/rfid.py b/m5stack/libs/unit/rfid.py index 393650d4..48cf0940 100644 --- a/m5stack/libs/unit/rfid.py +++ b/m5stack/libs/unit/rfid.py @@ -6,11 +6,47 @@ class RFIDUnit(MFRC522): + """ + note: + en: RFIDUnit is a hardware module designed for RFID card reading and writing operations. It extends the MFRC522 driver, supporting card detection, reading, writing, and advanced features like selecting and waking up RFID cards. + + details: + link: https://docs.m5stack.com/en/unit/rfid + image: https://static-cdn.m5stack.com/resource/docs/products/unit/rfid/rfid_01.webp + category: Unit + + example: + - ../../../examples/unit/rfid/rfid_cores3_example.py + + m5f2: + - unit/rfid/rfid_cores3_example.m5f2 + """ + def __init__(self, i2c, address: int | list | tuple = 0x28) -> None: + """ + note: + en: Initialize the RFIDUnit with I2C communication and an optional address. + + params: + i2c: + note: The I2C interface instance. + address: + note: The I2C address of the RFIDUnit. Default is 0x28. + """ super().__init__(i2c, address) self.pcd_init() def is_new_card_present(self) -> bool: + """ + note: + en: Check if a new RFID card is present. + + params: + note: + + returns: + note: True if a new card is detected, False otherwise. + """ buffer_atqa = bytearray(2) result = self.picc_request_a(buffer_atqa) if result == self.STATUS_OK or result == self.STATUS_COLLISION: @@ -19,10 +55,31 @@ def is_new_card_present(self) -> bool: return result == self.STATUS_OK def read_card_uid(self): + """ + note: + en: Read the UID of the RFID card if available. + + params: + note: + + returns: + note: The UID of the RFID card as a bytearray, or None if unavailable. + """ if self.picc_read_card_serial(): return self._uid.uid def read(self, block_addr): + """ + note: + en: Read a specific block from the RFID card. + + params: + block_addr: + note: The block address to read data from. + + returns: + note: A bytearray of 16 bytes from the specified block, or None if the operation fails. + """ buffer = bytearray(16) self.pcd_authenticate(0x60, block_addr, bytearray(b"\xff\xff\xff\xff\xff\xff"), self._uid) if self.mifare_read(block_addr, buffer) == self.STATUS_OK: @@ -31,6 +88,19 @@ def read(self, block_addr): return None def write(self, block_addr, buffer) -> int: + """ + note: + en: Write data to a specific block on the RFID card. + + params: + block_addr: + note: The block address to write data to. + buffer: + note: The data buffer to write to the block. + + returns: + note: The number of bytes written, or 0 if the operation fails. + """ buffer16 = bytearray(16) self.pcd_authenticate(0x60, block_addr, bytearray(b"\xff\xff\xff\xff\xff\xff"), self._uid) self.mifare_read(block_addr, buffer16) @@ -45,12 +115,39 @@ def write(self, block_addr, buffer) -> int: return 0 def close(self) -> None: - self.picc_halt_a() # Halt the PICC before stopping the encrypted session. + """ + note: + en: Halt the PICC and stop the encrypted communication session. + + params: + note: + """ + self.picc_halt_a() self.pcd_stop_crypto1() def wakeup_all(self) -> bool: + """ + note: + en: Wake up all RFID cards within range. + + params: + note: + + returns: + note: True if successful, False otherwise. + """ buffer_atqa = bytearray() return self.picc_wakeup_a(buffer_atqa) == self.STATUS_OK def picc_select_card(self) -> bool: + """ + note: + en: Select the currently active RFID card. + + params: + note: + + returns: + note: True if the card selection is successful, False otherwise. + """ return self.picc_select(self._uid) == self.STATUS_OK diff --git a/m5stack/libs/unit/tvoc.py b/m5stack/libs/unit/tvoc.py index 49465ec5..aad348bb 100644 --- a/m5stack/libs/unit/tvoc.py +++ b/m5stack/libs/unit/tvoc.py @@ -12,9 +12,32 @@ class TVOCUnit(SGP30): + """ + note: + en: TVOCUnit is a hardware module for measuring Total Volatile Organic Compounds (TVOC) and equivalent CO2 (eCO2). It is based on the SGP30 sensor and communicates via the I2C interface. The class supports configuration and measurement operations. + + details: + link: https://docs.m5stack.com/en/unit/tvoc + image: https://static-cdn.m5stack.com/resource/docs/products/unit/tvoc/tvoc_01.webp + category: Unit + + example: + - ../../../examples/unit/tvoc/tvoc_cores3_example.py + + m5f2: + - unit/tvoc/tvoc_cores3_example.m5f2 + """ + def __init__(self, i2c: I2C | PAHUBUnit, address: int = SGP30_I2C_ADDR) -> None: - """! initialize Function - set I2C Pins, SGP30 Address + """ + note: + en: Initialize the TVOCUnit with the specified I2C interface and address. + + params: + i2c: + note: The I2C interface or PAHUBUnit object for communication with the sensor. + address: + note: The I2C address of the TVOC unit. Defaults to 0x58. """ self._i2c = i2c self._i2c_addr = address @@ -22,13 +45,39 @@ def __init__(self, i2c: I2C | PAHUBUnit, address: int = SGP30_I2C_ADDR) -> None: super().__init__(i2c=i2c, addr=address) def available(self) -> None: - """! Is there available or Not? Check.""" + """ + note: + en: Check whether the TVOC/eCO2 unit is available. + + params: + note: + """ if self._i2c_addr not in self._i2c.scan(): raise UnitError("TVOC/eCO2 unit not found in Grove") - def set_baseline_co2_tvoc(self, co2eq, tvoc): + def set_baseline_co2_tvoc(self, co2eq: int, tvoc: int) -> None: + """ + note: + en: Set the baseline values for CO2 and TVOC measurements. + + params: + co2eq: + note: The CO2 equivalent baseline value to be set. + tvoc: + note: The TVOC baseline value to be set. + """ self.set_iaq_baseline(co2eq, tvoc) - def set_relative_humidity(self, humidity_per, temp_c): + def set_relative_humidity(self, humidity_per: float, temp_c: float) -> None: + """ + note: + en: Set the relative humidity and temperature for accurate air quality measurement. + + params: + humidity_per: + note: The relative humidity in percentage (%). + temp_c: + note: The ambient temperature in Celsius (°C). + """ abs_humi = self.convert_r_to_a_humidity(temp_c, humidity_per) self.set_absolute_humidity(abs_humi) diff --git a/m5stack/libs/unit/weight.py b/m5stack/libs/unit/weight.py index 4ec9d14f..f562f227 100644 --- a/m5stack/libs/unit/weight.py +++ b/m5stack/libs/unit/weight.py @@ -16,7 +16,31 @@ class WEIGHTUnit: + """ + note: + en: WEIGHT integrates a HX711 24 bits A/D chip that is specifically designed for electronic weighing device. + + details: + link: https://docs.m5stack.com/en/unit/WEIGHT + image: https://static-cdn.m5stack.com/resource/docs/products/unit/WEIGHT/img-a0113c8c-ed62-43b9-ad38-5cb934811d9e.webp + category: Unit + + example: + - ../../../examples/unit/weight/weight_cores3_example.py + + m5f2: + - unit/weight/weight_cores3_example.m5f2 + """ + def __init__(self, port) -> None: + """ + note: + en: Initialize the WEIGHTUnit with specified port pins. + + params: + port: + note: A tuple containing data and clock pin numbers. + """ self.hx711data = Pin(port[0], Pin.IN) self.hx711clk = Pin(port[1], Pin.OUT) self.zero_value = 0 @@ -26,6 +50,16 @@ def __init__(self, port) -> None: @property def get_raw_weight(self) -> int: + """ + note: + en: Read the raw weight value from the HX711. + + params: + note: + + returns: + note: The raw weight value as an integer. + """ count = 0 if self.is_ready_wait(): for i in range(24): @@ -51,15 +85,50 @@ def get_raw_weight(self) -> int: @property def get_scale_weight(self) -> int: + """ + note: + en: Get the scaled weight value based on calibration. + + params: + note: + + returns: + note: The scaled weight value as an integer. + """ return int((self.get_raw_weight - self.zero_value) * self._scale) def set_tare(self) -> None: + """ + note: + en: Set the tare weight to zero out the scale. + + params: + note: + """ self.zero_value = self.get_raw_weight def set_calibrate_scale(self, weight): + """ + note: + en: Calibrate the scale with a known weight. + + params: + weight: + note: The known weight used for calibration. + """ self._scale = (1.0 * weight) / (self.get_raw_weight - self.zero_value) def is_ready_wait(self) -> bool: + """ + note: + en: Check if the HX711 is ready to provide data. + + params: + note: + + returns: + note: True if the HX711 is ready, False otherwise. + """ times = 0 while self.hx711data.value(): times += 1 @@ -69,6 +138,14 @@ def is_ready_wait(self) -> bool: return not self.hx711data.value() def set_channel(self, chan: int) -> None: + """ + note: + en: Set the channel for the HX711. + + params: + chan: + note: The channel to set (1, 2, or 3). + """ self._channel = chan for i in range(self._channel): self.hx711clk.value(1)