Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some questions about the RTIMUHal class #12

Open
brightproject opened this issue Jun 13, 2024 · 11 comments
Open

Some questions about the RTIMUHal class #12

brightproject opened this issue Jun 13, 2024 · 11 comments

Comments

@brightproject
Copy link

brightproject commented Jun 13, 2024

Hello @HongshiTan
I'm using code from another repo written for teensy, and I rewrote it for Arduino and compiling it for stm32f411.

https://github.com/uutzinger/RTIMULib2-Teensy/

Unfortunately for me, there is no way to discuss code and stuff in this repo.
In the repository

https://github.com/HongshiTan/RTIMULib2/

there is such a possibility, but the RTIMUHal class is a little different, or rather more functional and advanced, but the meaning is the same.
I'm wondering what the case-insensitive read functionality is used for?

 bool HALRead(unsigned char slaveAddr, unsigned char regAddr, unsigned char length,
 unsigned char *data, const char *errorMsg); // normal read with register select
 bool HALRead(unsigned char slaveAddr, unsigned char length,
 unsigned char *data, const char *errorMsg); // read without register select

Actually, I had a problem with compilation when the code had such a strange reading initialization:
I2Cdev::readBytes(slaveAddr, regAddr, length, data, 10)
which I replaced with:
I2Cdev::readBytes(slaveAddr, regAddr, length, data)
And also had to add a new function to the library
I2Cdev.h and I2Cdev.cpp
static int8_t readBytes(uint8_t devAddr, uint8_t length, uint8_t *data, uint16_t timeout=I2Cdev::readTimeout, void *wireObj=0);
But this is not used anywhere in the code, which is why it caused strangeness.
Can someone tell me what this is used for?
I mean, when is regAddr not needed?
P.S. Perhaps this issue can be converted into discussions?

@HongshiTan
Copy link
Owner

HongshiTan commented Jun 14, 2024

Hello,

HALRead without register is a work around for some specific sensors, such as the HTU21D, etc., that do not need to specify the register address to read the measurement:

if (!m_settings->HALRead(m_humidityAddr, 3, rawData, "Failed to read HTU21D temperature"))

By the way, is the I2Cdev.cpp from RTIMULib2-Teensy? you can put the source code here

@brightproject
Copy link
Author

brightproject commented Jun 14, 2024

Hello.
Thanks for your reply.
I'm used this code

https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/I2Cdev

Only it copied and started working.
In general, the add-on in the form of HAL libraries

RTIMUHal.h
RTIMUHal.cpp

is quite inconvenient, and my I2C bus and microcontroller freeze after 5-10 seconds of operation.
I will rewrite the work with the I2C bus as it was done in RTIMULib-Arduino

https://github.com/jordandcarter/RTIMULib-Arduino/blob/cac4454680dd6798f1f4d7fa61ab465e960dd570/libraries/RTIMULib/RTIMUGD20M303DLHC.cpp#L52

@brightproject
Copy link
Author

Hello @HongshiTan

Can I ask you some more questions, not on the same topic, but partly on HAL and working with the RTIMULib2 code?

  1. In version 2 of this library, an external *ini settings file was added, which was supposed to simplify working with the library.
    But this method is convenient for those who work with the library on Linux or on RPI, who load the code into the microcontroller, this creates problems.
    Could you tell me how to configure the code with the desired sensor, without the RTIMULib.ini file?
  2. I have a MEMS gyroscope and accelerometer sensor, which I connected via SPI.
    But all the examples, except for the MPU9250, are connected via I2C.
    But this sensor, with the code here

Still, it uses the SPI bus in a strange way, configuring it through the I2C parameters.
In general, I'm still confused and trying to run the code with a new sensor ... but so far without results.
The code I'm compiling is not yours, but taken from here.
The code is compiled via platformio, the assembly is error-free.
I'm flashing the ESP32 microcontroller, and when I run the code I get the following messages in the serial port:

IMU Starting
Settings file not found. Using defaults and creating settings file

I would be grateful for your help.

@HongshiTan
Copy link
Owner

Hello, sorry for the late reply.

In your case on embedded platform, I think you can directly change the default setting in void RTIMUSettings::setDefaults() function, line 475 of RTIMUSettings.cpp

@HongshiTan
Copy link
Owner

The code is not designed for microcontrollers because the driver and controller of SPI/I2C can be very different from vendors, and there is no standard abstract layer, like POSIX, for ease of porting.

@brightproject
Copy link
Author

brightproject commented Sep 16, 2024

The code is not designed for microcontrollers because the driver and controller of SPI/I2C can be very different from vendors, and there is no standard abstract layer, like POSIX, for ease of porting.

Thank you @HongshiTan for responding to the request for help.
I appreciate your participation🙂
So it seems to be C++ code, and it is cross-platform.
And everything is assembled for me under ESP32S3, the problem is that I do not physically have an *ini file on the flash drive.
Earlier in the RTIMULib library I used such a construction for setting up in the main.c file

RTIMU *imu; // the IMU object
RTIMUSettings *settings; // the settings object

void setup()
{

    settings = new RTIMUSettings();

    settings->m_imuType = RTIMU_TYPE_GD20M303DLHC;

    settings->m_fusionType = RTFUSION_TYPE_KALMANSTATE4;
    // settings->m_fusionType = RTFUSION_TYPE_RTQF;
    // settings->m_fusionType = RTFUSION_TYPE_AHRS;

    // settings->m_fusionDebug = true;

    // settings->m_temperatureCalValid = true;

    // settings->m_compassCalValid = true;
    // settings->m_compassCalEllipsoidValid = true;

    // settings->m_accelCalValid = true;
    // settings->m_accelCalEllipsoidValid = true;

    settings->m_gyroBiasValid = true;

    imu = RTIMU::createIMU(settings);
    ...
    }

The code compiles fine, I wrote a python script that parses the RTIMUDefs.h file and displays the name of the sensor for which the program is compiled.

AHRS_IMU_COMPILE_OK

File code sensors.py

import re
import time
Import('env')

# ANSI escape codes for colors
RED = "\033[31m"
BLUE = "\033[34m"
GREEN = "\033[32m"
YELLOW = "\033[33m"
RESET = "\033[0m"

print(f"{YELLOW}Running sensors.py...{RESET}")  # Debugging line

def get_sensor_types():
    with open('lib/RTIMULib/IMUDrivers/RTIMUDefs.h', 'r') as file:
        content = file.read()

    # Search for sensor sections between // Start parser and // End parser
    section_pattern = r'// Start parser(.*?)// End parser'
    match = re.search(section_pattern, content, re.DOTALL)

    results = {}
    if match:
        # Find lines with sensor types and uncommented definitions
        type_matches = re.findall(r'// Type of (.*?):', match.group(1))
        define_matches = re.findall(r'^\s*#define\s+(\w+)', match.group(1), re.MULTILINE)

        # Combine results into a dictionary
        for i, type_name in enumerate(type_matches):
            if i < len(define_matches):
                results[type_name.strip()] = define_matches[i]

    return results

def version_printer(source, target, env):
    sensor_types = get_sensor_types()
    for type_name, sensor in sensor_types.items():
        print(f"{BLUE}Change in HERE: {YELLOW}RTIMUDefs.h{RESET}")
        print(f"{BLUE}Type of {type_name}: {GREEN}{sensor}{RESET}")

# Force execution on every build
env.AddPreAction("buildprog", version_printer)
env.AlwaysBuild("buildprog")

File code platformio.ini

; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

; .platformio\platforms\espressif32\boards

[platformio]
description = AHRS on RTIMULib2-Arduino for STM32/ESP32
; default_envs = genericSTM32F103CB
default_envs = AHRS_IMU

[env:genericSTM32F103CB]
platform = ststm32
board = genericSTM32F103CB
framework = arduino
upload_protocol = serial

[env:AHRS_IMU]
platform =
espressif32@^6.7.0
; https://github.com/pioarduino/platform-espressif32

board = esp32dev
framework = arduino
extra_scripts = post:sensors.py

monitor_speed = 115200
monitor_port = COM3
; monitor_port = COM22
upload_speed = 921600
upload_port = COM3
monitor_filters = esp32_exception_decoder

Even when I explicitly specify the IMU type in the code

m_imuType = RTIMU_TYPE_BNO055;

I still get a message in the serial port

IMU Starting
Settings file not found. Using defaults and creating settings file

I will continue to figure it out and add my files.

void RTIMUSettings::setDefaults()
{
    //  preset general defaults

    // m_imuType = RTIMU_TYPE_AUTODISCOVER;
    m_imuType = RTIMU_TYPE_BNO055;
    m_I2CSlaveAddress = 0;
    m_busIsI2C = true;
    m_I2CBus = 1;
    m_SPIBus = 0;
    m_SPISelect = 0;
    m_SPISpeed = 500000;
    m_fusionType = RTFUSION_TYPE_RTQF;
    m_axisRotation = RTIMU_XNORTH_YEAST;
    m_pressureType = RTPRESSURE_TYPE_AUTODISCOVER;
    m_I2CPressureAddress = 0;
    m_humidityType = RTHUMIDITY_TYPE_AUTODISCOVER;
    m_I2CHumidityAddress = 0;
    m_compassCalValid = false;

Well, the second task is to find a way to connect sensors via SPI, now the library only works via I2C.

Does the second version of the library have the ability to choose between an *ini file for settings and specifying settings "hard" in the firmware?
It seems to me that only the first option is possible now, and for the second one, the code needs to be somehow added so that it is possible to choose which option to use.
When running on RPI, yes, it is better to have the settings on a flash drive.
But for a microcontroller, either in the firmware or in FLASH or EEPROM memory.

@brightproject
Copy link
Author

A few more experiments with the RTIMULib2 library code.
First, I figured out why there was a ESP-WROOM-32 core 1 panic, all because of the framework version:

PLATFORM: Espressif 32 (6.8.1)
framework-arduinoespressif32 @ 3.20017.0 (2.0.17)

The code compilation itself is without errors and problems, but after a hardware reset, the MCU starts rebooting according to the code rst:0x10

rst:0x1 (POWERON_RESET),boot:0x12 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:13232
load:0x40080400,len:3028
entry 0x400805e4
ets Jun 8 2016 00:22:57

rst:0x10 (RTCWDT_RTC_RESET),boot:0x12 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:13232
load:0x40080400,len:3028
entry 0x400805e4

But this is a problem of the MCU itself, and even the manufacturer hints at simply changing the microcontroller, supposedly the Arduino framework version from 1 to 2 has undergone many changes and now many codes need to be rewritten, apparently RTIMULib2 was written during the development of the old version of ESP32-D0WDQ6 (revision v1.0).

I had to use version, and I don't have the problems that were above:

PLATFORM: Espressif 32 (3.5.0)
framework-arduinoespressif32 @ 3.10006.210326 (1.0.6)

Also, I divided the code into two parts to compile without using the *ini file:

// #define INI_SETUP
#define NO_INI_SETUP

RTIMU *imu;                                           // the IMU object

#ifdef INI_SETUP
RTIMUSettings *settings;                              // the settings object
#endif

#ifdef NO_INI_SETUP
RTIMUSettings settings;                              // the settings object
#endif

void setup()
{
    delay(5000);

    Serial.begin(SERIAL_PORT_SPEED);
    delay(1000);

    Serial.println("IMU Starting");

    #ifdef INI_SETUP
    settings = new RTIMUSettings();
    #endif

    #ifdef INI_SETUP
    imu = RTIMU::createIMU(settings);                 // create the imu object
    #endif

    #ifdef NO_INI_SETUP
    imu = RTIMU::createIMU(&settings);                 // create the imu object
    #endif

}

Please note that in some places I use a link to settings, and in others I don't.
I took the example of settings from the first version of RTIMULib.
In the case when I compile the code and flash the microcontroller with the preprocessor directive

#define NO_INI_SETUP

I get the following output to the serial port:

clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:10124
load:0x40080400,len:5828
entry 0x400806a8
IMU Starting
Using fusion algorithm %s
RTQF
Device(s): MPU-9150 min/max compass calibration not in use

Ellipsoid compass calibration not in use

Accel calibration not in use

I2C write failed - Failed to initiate MPU9150 reset
Failed to init IMU: I2C read failed - Failed to read fifo count
I2C read failed - Failed to read fifo count
I2C read failed - Failed to read fifo count
I2C read failed - Failed to read fifo count

This is a completely different conclusion, indicating that the code is working, but there is no connection established with the sensors via the I2C bus.
I hope @HongshiTan haven't completely confused you with my texts?
Perhaps, with joint efforts, we can figure out the code and in the future adapt it to esp32s3 and framework espressif32 version 6.8.1 or better yet, to esp-idf version 3.

@HongshiTan
Copy link
Owner

Hello, brightproject

It should be fine to hardcode the IMU settings by modifying the default configuration directly. You can likely ignore the log output about the missing ini file. As for the ESP32-related issues, sorry, but I’m unable to assist—both because I don’t have the hardware to reproduce the problem and I’m not get into the details with the specifics of their driver code. I hope you understand.

@brightproject
Copy link
Author

It should be fine to hardcode the IMU settings by modifying the default configuration directly.

Could you suggest a solution for working in this library with sensors via the SPI bus🙂?

@HongshiTan
Copy link
Owner

The HAL class abstract spidev is over the POSIX device interface. If you want it to work in the microcontroller, you need either replace all SPI operations in the HAL with those specified by your driver. or ensure that your SPI driver supports all POSIX operations, including the ioctl command.

@brightproject
Copy link
Author

I managed to compile firmware for both ESP32 and STM32.

https://github.com/orgs/stm32duino/discussions/2523#discussioncomment-10766584

I also managed to start the SPI bus and I can use the BNO055 sensor via the SPI bus. I also have a BNO08x sensor, have you ever worked with it, do you have library files for working with this sensor in RTIMULib2?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants