En el previo artículo se describió la instalación del sistema operativo Zephyr en la raspberry Pico 2 (Linux) Parte 1. Por favor antes de seguir los próximos pasos de este artículo realize el proceso previamente descrito aquí. La Raspberry Pico 2 será conectada a la plataforma de evaluación TDK ICM 20984 via Qwiic de Sparkfun dentro del sistema operativo Zephyr.
Estaremos usando el sistema operativo Zephyr vía el terminal minicom. El primer paso consiste en construir el “shell” del sistema operativo Zephyr. Se procede como se muestra a continuación para programar el Raspberry Pico 2 para incluir el “shell” del sistema operativo Zephyr,
(venv) $ west build -p always -b rpi_pico2/rp2350a/m33 -S cdc-acm-console ../samples/sensor/sensor_shell -DCONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=y -DCONFIG_SENSOR_INFO=y -DCONFIG_I2C_SHELL=y -DCONFIG_I2C=y
.....
.....
(venv) $west flash --runner uf2
-- west flash: rebuilding
ninja: no work to do.
-- west flash: using runner uf2
-- runners.uf2: Copying UF2 file to '/media/digikey/RP2350'
Comienze la sesion del terminal minicom,
$ minicom -D /dev/ttyACM0
Welcome to minicom 2.8
OPTIONS: I18n
Port /dev/ttyACM0, 12:41:43
.....
[00:00:01.211,000] <inf> usbd_ch9: Handle control 0x200061cc ep 0x80, len 0, s:0 d:0 s:1
[00:00:01.211,000] <inf> usbd_ch9: s-(out)-status finished
uart:~$
El sistema operativo Zephyr shell uart~$ surge despues del proceso de instalación. Ahora use la interfaz I2C de la Raspberry Pico 2 para conectar al TDK ICM 20984 de Sparkfun. La próxima foto muestra como esta conectado el Raspberry Pico 2 al sensor vía I2C en la “breadboard” disponible en DigiKey y también usando estos cables Qwiic.
Se procede a rastrear la interfaz I2C en la Raspberry Pico 2 como sigue. Primeramente, se identifican los puertos correspondientes en el sistema,
uart:~$ i2c scan
scan: wrong parameter count
scan - Scan I2C devices
Usage: scan <device>
Subcommands:
i2c@40098000
i2c@40090000
En este punto la Raspberry Pico 2 usando el shell del sistema operativo Zephyr se muestra que detecta el artefacto dependiendo de la interfaz conectada.
En este caso el TDK ICM 20984 via Qwiic de Sparkfun esta conectado a la interfaz i2c@4009000. Para autodetectar la dirección del artefacto en la interfaz I2C. Se emite el siguiente comando y va a escanear todas las direcciones posibles en la interfaz I2C,
uart:~$ i2c scan i2c@40090000
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- 69 -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
1 devices found on i2c@40090000
El TDK ICM 20984 Sensor MEMS vía Qwiic de Sparkfun con la dirección de la interfaz I2C detectada apropiadamente como 0x69. Ahora proceda a usar la interfaz I2C para leer el registro WHOAMI que identifica el TDK ICM 20984 Sensor MEMS vía Qwiic de Sparkfun como sigue,
uart:~$ i2c read_byte i2c@40090000 0x69 0x00
Output: 0xea
El valor correcto del sensor ICM-20948 se registra en el “shell” del sistema operativo Zephyr dentro de la Raspberry Pico 2 registrado como 0xEA. Como un ejemplo, ahora se procede a leer la función de baja potencia dentro del “ASIC” como sigue,
uart:~$ i2c read_byte i2c@40090000 0x69 0x05
Output: 0x40
Esta lectura demuestra que esta activado, entonces se procede a desactivar este modo de baja potencia como sigue,
uart:~$ i2c write_byte i2c@40090000 0x69 0x06 0x00
uart:~$ i2c read_byte i2c@40090000 0x69 0x06
Output: 0x0
En este momento, se ha demonstrado como como coordinar las transaciones de I2C con el “ASIC”.
Un sensor de imitación real se puede usar para demostrar la forma en que se puede referirse en el “shell” del sistema operativo de tiempo real Zephyr. Esto se logra usando ```
-DEXTRA_DTC_OVERLAY_FILE=fake_sensor.overlay como se muestra en el siguiente proceso de “build”
(venv) $ west build -p always -b rpi_pico2/rp2350a/m33 -S cdc-acm-console ../samples/sensor/sensor_shell -DCONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=y -DCONFIG_SENSOR_INFO=y -DCONFIG_I2C_SHELL=y -DCONFIG_I2C=y -DCONFIG_SENSOR_INFO=y -DEXTRA_DTC_OVERLAY_FILE=fake_sensor.overlay
(venv) $ west flash --runner uf2
entonces use minicom para encontrar el sensor de imitación como sigue,
uart:~$ sensor info
device name: sensor@0, vendor: A stand-in for a real vendor which can be used in examples and tests, model: fake-sensor, friendly name: Fake sensor 0
device name: sensor@1, vendor: A stand-in for a real vendor which can be used in examples and tests, model: fake-sensor, friendly name: Fake sensor 1
si se requiere el sensor@0 entonces, use el siguiente comando en el “shell”,
uart:~$ sensor get sensor@0
channel type=0(accel_x) index=0 shift=7 num_samples=1 value=46582103665ns (0.000000)
channel type=1(accel_y) index=0 shift=7 num_samples=1 value=46582103665ns (1.000000)
channel type=2(accel_z) index=0 shift=7 num_samples=1 value=46582103665ns (2.000000)
channel type=3(accel_xyz) index=0 shift=7 num_samples=1 value=46582103665ns, (0.000000, 1.000000, 2.000000)
channel type=4(gyro_x) index=0 shift=7 num_samples=1 value=46582103665ns (4.000000)
channel type=5(gyro_y) index=0 shift=7 num_samples=1 value=46582103665ns (5.000000)
channel type=6(gyro_z) index=0 shift=7 num_samples=1 value=46582103665ns (6.000000)
channel type=7(gyro_xyz) index=0 shift=7 num_samples=1 value=46582103665ns, (4.000000, 5.000000, 6.000000)
channel type=8(magn_x) index=0 shift=7 num_samples=1 value=46582103665ns (8.000000)
channel type=9(magn_y) index=0 shift=7 num_samples=1 value=46582103665ns (9.000000)
channel type=10(magn_z) index=0 shift=7 num_samples=1 value=46582103665ns (10.000000)
channel type=11(magn_xyz) index=0 shift=7 num_samples=1 value=46582103665ns, (8.000000, 9.000000, 10.000000)
channel type=12(die_temp) index=0 shift=7 num_samples=1 value=46582103665ns (12.000000)
channel type=13(ambient_temp) index=0 shift=7 num_samples=1 value=46582103665ns (13.000000)
channel type=14(press) index=0 shift=7 num_samples=1 value=46582103665ns (14.000000)
channel type=15(prox) index=0 num_samples=1 value=46850604664ns (is_near = 0)
channel type=16(humidity) index=0 shift=7 num_samples=1 value=46582103665ns (16.000000)
channel type=17(light) index=0 shift=7 num_samples=1 value=46582103665ns (17.000000)
channel type=18(ir) index=0 shift=7 num_samples=1 value=46582103665ns (18.000000)
channel type=19(red) index=0 shift=7 num_samples=1 value=46582103665ns (19.000000)
channel type=20(green) index=0 shift=7 num_samples=1 value=46582103665ns (20.000000)
channel type=21(blue) index=0 shift=7 num_samples=1 value=46582103665ns (21.000000)
channel type=22(altitude) index=0 shift=7 num_samples=1 value=46582103665ns (22.000000)
channel type=23(pm_1_0) index=0 shift=7 num_samples=1 value=46582103665ns (23.000000)
channel type=24(pm_2_5) index=0 shift=7 num_samples=1 value=46582103665ns (24.000000)
channel type=25(pm_10) index=0 shift=7 num_samples=1 value=46582103665ns (25.000000)
channel type=26(distance) index=0 shift=7 num_samples=1 value=46582103665ns (26.000000)
channel type=27(co2) index=0 shift=7 num_samples=1 value=46582103665ns (27.000000)
channel type=28(o2) index=0 shift=7 num_samples=1 value=46582103665ns (28.000000)
channel type=29(voc) index=0 shift=7 num_samples=1 value=46582103665ns (29.000000)
channel type=30(gas_resistance) index=0 shift=7 num_samples=1 value=46582103665ns (30.000000)
channel type=31(flow_rate) index=0 shift=7 num_samples=1 value=46582103665ns (31.000000)
channel type=32(voltage) index=0 shift=7 num_samples=1 value=46582103665ns (32.000000)
channel type=33(vshunt) index=0 shift=7 num_samples=1 value=46582103665ns (33.000000)
channel type=34(current) index=0 shift=7 num_samples=1 value=46582103665ns (34.000000)
channel type=35(power) index=0 shift=7 num_samples=1 value=46582103665ns (35.000000)
channel type=36(resistance) index=0 shift=7 num_samples=1 value=46582103665ns (36.000000)
channel type=37(rotation) index=0 shift=7 num_samples=1 value=46582103665ns (37.000000)
channel type=38(pos_dx) index=0 shift=7 num_samples=1 value=46582103665ns (38.000000)
channel type=39(pos_dy) index=0 shift=7 num_samples=1 value=46582103665ns (39.000000)
channel type=40(pos_dz) index=0 shift=7 num_samples=1 value=46582103665ns (40.000000)
channel type=41(pos_dxyz) index=0 shift=7 num_samples=1 value=46582103665ns, (38.000000, 39.000000, 40.000000)
channel type=42(rpm) index=0 shift=7 num_samples=1 value=46582103665ns (42.000000)
channel type=43(frequency) index=0 shift=7 num_samples=1 value=46582103665ns (43.000000)
channel type=44(gauge_voltage) index=0 shift=7 num_samples=1 value=46582103665ns (44.000000)
channel type=45(gauge_avg_current) index=0 shift=7 num_samples=1 value=46582103665ns (45.000000)
channel type=46(gauge_stdby_current) index=0 shift=7 num_samples=1 value=46582103665ns (46.000000)
channel type=47(gauge_max_load_current) index=0 shift=7 num_samples=1 value=46582103665ns (47.000000)
channel type=48(gauge_temp) index=0 shift=7 num_samples=1 value=46582103665ns (48.000000)
channel type=49(gauge_state_of_charge) index=0 shift=7 num_samples=1 value=46582103665ns (49.000000)
channel type=50(gauge_full_cap) index=0 shift=7 num_samples=1 value=46582103665ns (50.000000)
channel type=51(gauge_remaining_cap) index=0 shift=7 num_samples=1 value=46582103665ns (51.000000)
channel type=52(gauge_nominal_cap) index=0 shift=7 num_samples=1 value=46582103665ns (52.000000)
channel type=53(gauge_full_avail_cap) index=0 shift=7 num_samples=1 value=46582103665ns (53.000000)
channel type=54(gauge_avg_power) index=0 shift=7 num_samples=1 value=46582103665ns (54.000000)
channel type=55(gauge_state_of_health) index=0 shift=7 num_samples=1 value=46582103665ns (55.000000)
channel type=56(gauge_time_to_empty) index=0 shift=7 num_samples=1 value=46582103665ns (56.000000)
channel type=57(gauge_time_to_full) index=0 shift=7 num_samples=1 value=46582103665ns (57.000000)
channel type=58(gauge_cycle_count) index=0 shift=7 num_samples=1 value=46582103665ns (58.000000)
channel type=59(gauge_design_voltage) index=0 shift=7 num_samples=1 value=46582103665ns (59.000000)
channel type=60(gauge_desired_voltage) index=0 shift=7 num_samples=1 value=46582103665ns (60.000000)
channel type=61(gauge_desired_charging_current) index=0 shift=7 num_samples=1 value=46582103665ns (61.000000)
channel type=62(game_rotation_vector) index=0 shift=7 num_samples=1 value=46582103665ns (62.000000)
channel type=63(gravity_vector) index=0 shift=7 num_samples=1 value=46582103665ns (63.000000)
channel type=64(gbias_xyz) index=0 shift=7 num_samples=1 value=46582103665ns (64.000000)
Se puede observar distintos tipos de sensores (humedad relativa, altitud, proximidad, etc) con sus parámetros correspondientes. Se filtran los parametros como se muestra a continuación,
uart:~$ sensor get sensor@1 accel_z current
channel type=2(accel_z) index=0 shift=6 num_samples=1 value=94184102299ns (2.000000)
channel type=34(current) index=0 shift=6 num_samples=1 value=94184102299ns (34.000000)
Este artículo está en idioma inglés aqui.
This article is also available in english language here.
