Hi everyone!
I wrote code in arduino IDE but wanted to use all potential of Xiao NRF52840 with use of Nordic SDK and Zephyr RTOS as well as zigbee on my small side project but I’m struggling with getting readings from UART. I’m successfully reading data from builtin IMU but cannot get anything from GPS (arduino code show results). I’ve attached my main.c file as well as prj.conf and .overlay file. Maybe it’s caused by connecting using USB? And my second question is: is there any way to synchronize GPS and IMU readings?
overlay
lsm6ds3tr-c-en {
compatible = "regulator-fixed-sync", "regulator-fixed";
enable-gpios = <&gpio1 8 (NRF_GPIO_DRIVE_S0H1 | GPIO_ACTIVE_HIGH)>;
regulator-name = "LSM6DS3TR_C_EN";
regulator-boot-on;
startup-delay-us = <3000>;
};
&i2c0 {
compatible = "nordic,nrf-twim";
/* Cannot be used together with spi0. */
status = "okay";
pinctrl-0 = <&i2c0_default>;
pinctrl-1 = <&i2c0_sleep>;
pinctrl-names = "default", "sleep";
clock-frequency = <I2C_BITRATE_FAST>;
lsm6ds3tr_c: lsm6ds3tr-c@6a {
compatible = "st,lsm6dsl";
reg = <0x6a>;
irq-gpios = <&gpio0 11 GPIO_ACTIVE_HIGH>;
status = "okay";
};
};
&pinctrl {
uart0_default: uart0_default {
group1 {
psels = <NRF_PSEL(UART_TX, 1, 11)>;
};
group2 {
psels = <NRF_PSEL(UART_RX, 1, 12)>;
bias-pull-up;
};
};
uart0_sleep: uart0_sleep {
group1 {
psels = <NRF_PSEL(UART_TX, 1, 11)>,
<NRF_PSEL(UART_RX, 1, 12)>;
low-power-enable;
};
};
};
&uart0 {
compatible = "nordic,nrf-uarte";
status = "okay";
current-speed = <9600>;
pinctrl-0 = <&uart0_default>;
pinctrl-1 = <&uart0_sleep>;
pinctrl-names = "default", "sleep";
};
prj.conf
CONFIG_STDOUT_CONSOLE=y
CONFIG_I2C=y
CONFIG_SPI=y
CONFIG_SENSOR=y
CONFIG_LSM6DSL_TRIGGER_GLOBAL_THREAD=y
CONFIG_CBPRINTF_FP_SUPPORT=y
# CONFIG_USB_DEVICE_STACK=y
# CONFIG_USB_DEVICE_PRODUCT="XIAO_GPS_IMU"
CONFIG_UART_0_ASYNC=y
CONFIG_UART_0_INTERRUPT_DRIVEN=y
Main.c
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/drivers/gnss.h>
#include <zephyr/logging/log.h>
#include <stdio.h>
#include <zephyr/sys/util.h>
// static int print_samples;
// static int lsm6dsl_trig_cnt;
// static struct sensor_value accel_x_out, accel_y_out, accel_z_out;
// static struct sensor_value gyro_x_out, gyro_y_out, gyro_z_out;
// // const struct device *uart = DEVICE_DT_GET(DT_NODELABEL(uart0));
// #ifdef CONFIG_LSM6DSL_TRIGGER
// static void lsm6dsl_trigger_handler(const struct device *dev,
// const struct sensor_trigger *trig)
// {
// static struct sensor_value accel_x, accel_y, accel_z;
// static struct sensor_value gyro_x, gyro_y, gyro_z;
// lsm6dsl_trig_cnt++;
// sensor_sample_fetch_chan(dev, SENSOR_CHAN_ACCEL_XYZ);
// sensor_channel_get(dev, SENSOR_CHAN_ACCEL_X, &accel_x);
// sensor_channel_get(dev, SENSOR_CHAN_ACCEL_Y, &accel_y);
// sensor_channel_get(dev, SENSOR_CHAN_ACCEL_Z, &accel_z);
// /* lsm6dsl gyro */
// sensor_sample_fetch_chan(dev, SENSOR_CHAN_GYRO_XYZ);
// sensor_channel_get(dev, SENSOR_CHAN_GYRO_X, &gyro_x);
// sensor_channel_get(dev, SENSOR_CHAN_GYRO_Y, &gyro_y);
// sensor_channel_get(dev, SENSOR_CHAN_GYRO_Z, &gyro_z);
// if (print_samples) {
// print_samples = 0;
// accel_x_out = accel_x;
// accel_y_out = accel_y;
// accel_z_out = accel_z;
// gyro_x_out = gyro_x;
// gyro_y_out = gyro_y;
// gyro_z_out = gyro_z;
// }
// }
// #endif
const struct device *gps_dev = DEVICE_DT_GET(DT_NODELABEL(uart0));
void gps_uart_callback(const struct device *dev, void *user_data) {
uint8_t byte;
if (!uart_irq_update(dev)) return;
while (uart_irq_rx_ready(dev)) {
if (uart_fifo_read(dev, &byte, 1) > 0) {
printk("0x%02x\n", byte);
}
}
}
int main(void)
{
const struct uart_config uart_cfg = {
.baudrate = 9600,
.parity = UART_CFG_PARITY_NONE,
.stop_bits = UART_CFG_STOP_BITS_1,
.data_bits = UART_CFG_DATA_BITS_8,
.flow_ctrl = UART_CFG_FLOW_CTRL_NONE
};
int err = uart_configure(gps_dev, &uart_cfg);
if (err < 0) {
return err;
}
printk("Setting up UART\n");
if (!device_is_ready(gps_dev)) {
printk("UART device not ready\n");
return 0;
}
uart_irq_callback_user_data_set(gps_dev, gps_uart_callback, NULL);
uart_irq_rx_enable(gps_dev);
// int cnt = 0;
// char out_str[64];
// struct sensor_value odr_attr;
// const struct device *const lsm6dsl_dev = DEVICE_DT_GET_ONE(st_lsm6dsl);
// if (!device_is_ready(lsm6dsl_dev)) {
// printk("sensor: device not ready.\n");
// return 0;
// }
// /* set accel/gyro sampling frequency to 104 Hz */
// odr_attr.val1 = 104;
// odr_attr.val2 = 0;
// if (sensor_attr_set(lsm6dsl_dev, SENSOR_CHAN_ACCEL_XYZ,
// SENSOR_ATTR_SAMPLING_FREQUENCY, &odr_attr) < 0) {
// printk("Cannot set sampling frequency for accelerometer.\n");
// return 0;
// }
// if (sensor_attr_set(lsm6dsl_dev, SENSOR_CHAN_GYRO_XYZ,
// SENSOR_ATTR_SAMPLING_FREQUENCY, &odr_attr) < 0) {
// printk("Cannot set sampling frequency for gyro.\n");
// return 0;
// }
// #ifdef CONFIG_LSM6DSL_TRIGGER
// struct sensor_trigger trig;
// trig.type = SENSOR_TRIG_DATA_READY;
// trig.chan = SENSOR_CHAN_ACCEL_XYZ;
// if (sensor_trigger_set(lsm6dsl_dev, &trig, lsm6dsl_trigger_handler) != 0) {
// printk("Could not set sensor type and channel\n");
// return 0;
// }
// #endif
// if (sensor_sample_fetch(lsm6dsl_dev) < 0) {
// printk("Sensor sample update error\n");
// return 0;
// }
while (1) {
printk("Waiting for getting UART signal...\n");
// /* Erase previous */
// printk("\0033\014");
// printf("LSM6DSL sensor samples:\n\n");
// /* lsm6dsl accel */
// sprintf(out_str, "accel x:%f ms/2 y:%f ms/2 z:%f ms/2",
// sensor_value_to_double(&accel_x_out),
// sensor_value_to_double(&accel_y_out),
// sensor_value_to_double(&accel_z_out));
// printk("%s\n", out_str);
// sprintf(out_str, "G-X: %d G-Y: %d G-Z: %d",
// sensor_ms2_to_g(&accel_x_out),
// sensor_ms2_to_g(&accel_y_out),
// sensor_ms2_to_g(&accel_z_out));
// printk("%s\n", out_str);
// /* lsm6dsl gyro */
// sprintf(out_str, "gyro x:%f dps y:%f dps z:%f dps",
// sensor_value_to_double(&gyro_x_out),
// sensor_value_to_double(&gyro_y_out),
// sensor_value_to_double(&gyro_z_out));
// printk("%s\n", out_str);
// printk("loop:%d trig_cnt:%d\n\n", ++cnt, lsm6dsl_trig_cnt);
// print_samples = 1;
k_sleep(K_MSEC(200));
k_sleep(K_SECONDS(2));
}
}