0
\$\begingroup\$

I'm new to STM32 programming and am programming on a STM32F429 Microcontroller. My main goal is to integrate a Sparkfun UV sensor VEML6075 into the microcontroller as an external payload.

TLDR: Tried to send commands into the i2c line to initialise the sensor and take readings from its registers, code below utilising HAL_I2C library methods does not work at all.

To begin doing so, I researched on how to program and take readings directly from the UV sensor itself in Arduino without using the Sparkfun library provided. This was done easily enough, simply using the Wire library to write and read from the I2C line.

Now the hard part: translating this over to STM32, which was where I got stuck. The datasheet gets a little confusing as it only mentions commands and not register values, so I'm confused as to how the process goes.

From reading through the datasheet of the VEML6075 sensor, my understanding of how to initialise and take readings from this sensor is as such:

1) Set the base register, UV_CONF to set the desired functioning parameters as seen from the table: enter image description here

Where I perceive that I need to send a command of 0x10 to the CONF register 0x00 which initialises the sensor with timing 100ms.

2) Send commands to the registers to read from the values stored on the registers: enter image description here

To which I want to try a simple reading of UVA, so I should write(0x07) and read from the register 0x07??

The codes I came up with subsequently is as follows:

The slave device address is 0x10.

Init function:

    void VEML6075_init(uint8_t register_pointer, uint8_t register_value)
{
    HAL_StatusTypeDef status = HAL_OK;

    status = HAL_I2C_Mem_Write(&hi2c3, 0x10, (uint16_t)register_pointer, I2C_MEMADD_SIZE_8BIT,  (uint8_t*)(&register_value), 1, 10 );

    if(status != HAL_OK){
        fprintf(SYSCON, "UV sensor init not successful");
    }
}

Read from registers function:

    uint16_t VEML6075_Fetch_RawUV(uint8_t register_pointer)
{
    HAL_StatusTypeDef status = HAL_OK;
    uint16_t return_value = 0;

    status = HAL_I2C_Mem_Read(&hi2c3, 0x10, (uint16_t)register_pointer, I2C_MEMADD_SIZE_8BIT, &return_value, 2, 10);

    if(status == HAL_OK){
            fprintf(SYSCON, "UV sensor reading successful");
        }
    return return_value;
}

Overall main calling code:

// VEML6075 init variables
uint8_t register_pointer_init = 0x00;
uint8_t register_init_command = 0x10;
// VEML6075 read UVA variables
uint8_t register_pointer = 0x07;

  VEML6075_init(register_pointer_init,register_init_command);
  UVA_Combined = VEML6075_Fetch_RawUV(register_pointer);

The code doesnt work and the sensor never gets initialised. Could I know where I'm interpreting the i2c protocol or the HAL libraries' functions wrongly? Thanks!

\$\endgroup\$
  • 1
    \$\begingroup\$ Is the main snippet your whole main? Also, where are the GPIO pins being initialised? The I2C pins will needs to be initialised as the appropriate alternate function pins. \$\endgroup\$ – JCollins Mar 18 at 10:07
  • \$\begingroup\$ It's a part of the main code. Prior to these lines, the I2C lines have already been initialised : MX_I2C1_Init(); MX_I2C2_Init(); MX_I2C3_Init(); The GPIO pins are initialised within the above three functions. I dont get what you mean by function pins though. \$\endgroup\$ – Mack Mar 18 at 10:23
  • \$\begingroup\$ Have you tried stepping through with a debugger to see where things fall over? Do you have access to a scope to see what the clk and data lines are doing? Also the casting (uint8_t *) is not required, your variable register_value is already uint8_t, the & is all that is required. From the bit of a look at the datasheet that I've had, it looks like you've interpreted it correctly. If I were in your shoes I would have the scope and debugger out. \$\endgroup\$ – JCollins Mar 18 at 11:05
  • \$\begingroup\$ Ah, i haven't. I'll try that and report back here, I was wondering whether I perhaps made an error in the arguments of the function-calls for the HAL_I2C library or mis-interpreted the way i should be calling the registers on the sensor thru I2C line as I'm still new to this. \$\endgroup\$ – Mack Mar 18 at 11:18
  • \$\begingroup\$ I've tried debugging but to no avail, the code dives way too deep into the HAL_I2C libraries =/ \$\endgroup\$ – Mack Mar 19 at 3:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.