Search code examples
embeddedstm32sensorslorawanmcu

How to read the WhoAmI register of an ST-sensor during both initialization of the program (works) and repeatedly during LoRaWAN duty cycle (doesn't)?


I have been trying to program an STM32WL55JC1 microcontroller on a LoRa-E5-Mini from Seeed studio to be a LoRaWAN endnode and relay airpressure data from an ST LPS22HH sensor to The Things Network.

I think the problem I seem to be having must be in the code. The reason is that upon initialization, reading out the WhoAmI register of the sensor yields results. But every time afterwards, per the duty cycle of the LoRaWAN node, calling the function yields no results and I can't connect to the sensor. This stays the same, every Tx event the WhoAmI register can't be read.

Every time I reset the MCU, upon Sensor_Init() the register is read (once, twice or with a delay in between). But calling the same function from the Tx timer event yields no results. I have tried calling the I2C_id() function directly, or the same Sensor_Init() function that gets called at startup.

The sensornode has worked before, as in I have gotten a few uplinks with seemingly correct data from the sensor, but this is occasional at best and I can't reproduce it.

Below a typical serial read output. It starts after a reset. Duty cycle is set to one minute. Might be good to mention that joining often takes several tries and that what seems like succesful transmits often don't show up in TTN console.

13:46:11.479 -> APP_VERSION:        V1.1.0
13:46:11.479 -> MW_LORAWAN_VERSION: V2.3.0
13:46:11.479 -> MW_RADIO_VERSION:   V1.1.0
13:46:11.479 -> ###### OTAA ######
13:46:11.479 -> ###### AppKey:      F1:06:29:B9:4E:43:E4:98:**:**:**:**:**:**:**:**
13:46:11.479 -> ###### NwkKey:      F2:62:58:D1:C9:0C:89:F4:**:**:**:**:**:**:**:**
13:46:11.479 -> ###### ABP  ######
13:27:48.576 -> ###### AppSKey:     00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
13:27:48.576 -> ###### NwkSKey:     00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
13:27:48.576 -> ###### DevEui:  70:B3:D5:7E:D0:04:AB:31
13:27:48.576 -> ###### AppEui:  87:65:43:21:12:34:56:78
13:27:48.576 -> ###### DevAddr: 00:1F:28:32
13:27:48.576 -> 0s040:TX on freq 868500000 Hz at DR 0
13:27:48.576 -> Sensor_Init------------------------
13:27:48.576 -> WhoAmI ID: 0xB3
13:27:50.027 -> 1s527:MAC txDone
13:27:53.583 -> WhoAmI ID: 0xB3
13:27:58.595 -> 10s079:RX_1 on freq 868500000 Hz at DR 0
13:27:58.784 -> 10s277:IRQ_RX_TX_TIMEOUT
13:27:58.784 -> 10s277:MAC rxTimeOut
13:27:58.784 -> 
13:27:58.784 -> ###### = JOIN FAILED
13:28:49.519 -> Kan geen verbinding maken met de sensor (read)!
13:28:49.519 -> WhoAmI ID: 0x0
13:28:49.519 -> Sensor_Init------------------------
13:28:50.505 -> Kan geen verbinding maken met de sensor (read)!
13:28:50.505 -> WhoAmI ID: 0x0
13:28:56.511 -> Kan geen verbinding maken met de sensor (read)!
13:28:56.511 -> WhoAmI ID: 0x0
13:28:56.511 -> 67s977:temp= 21
13:28:56.511 -> 
67s977:VDDA= 254
13:28:56.511 -> 67s982:TX on freq 868500000 Hz at DR 0
13:28:56.511 -> Sensor_Init------------------------
13:28:57.450 -> Kan geen verbinding maken met de sensor (read)!
13:28:57.450 -> WhoAmI ID: 0x0
13:28:57.967 -> 69s469:MAC txDone
13:29:03.451 -> Kan geen verbinding maken met de sensor (read)!
13:29:03.451 -> WhoAmI ID: 0x0
13:29:08.472 -> 79s975:RX_1 on freq 868500000 Hz at DR 0
13:29:08.663 -> 80s173:IRQ_RX_TX_TIMEOUT
13:29:08.663 -> 80s173:MAC rxTimeOut
13:29:08.663 -> 
13:29:08.663 -> ###### = JOIN FAILED
.
.
.

Custom file:

void Sensor_Init(void){

        APP_LOG(TS_OFF, VLEVEL_M, "Sensor_Init------------------------\r\n")
        I2C_id();                       //both of these work
        HAL_Delay(5000);
        I2C_id();                       //both of these work

    return;
}


uint8_t I2C_id(void){

    static const uint8_t WhoAmI = 0x0F;             // WhoAmI register
    HAL_StatusTypeDef ret;
    ret=8;
    uint8_t var[1];
    var[0]=0x0;

    ret=platform_read(&hi2c2, WhoAmI, var, 1);

    APP_LOG(TS_OFF, VLEVEL_M, "WhoAmI ID: 0x%X\n",var[0]);
}

static int32_t platform_read(void *handle, uint8_t Reg, uint8_t *Bufp, uint16_t len){
    HAL_StatusTypeDef ret;
    uint8_t reg[1];
    reg[0]=Reg;

    ret=HAL_I2C_Master_Transmit(&hi2c2, addr_write, reg, 1, 1000);
    if(len>0 && !ret){
        ret=HAL_I2C_Master_Receive(&hi2c2, addr_read, Bufp, len, 1000);
    }
    else if(ret){
      // error
    }
    return ret;
}

lora_app.c:

LoRaWAN_Init(void){
.
.
.
  UTIL_SEQ_RegTask((1 << CFG_SEQ_Task_ApplicatieInit), UTIL_SEQ_RFU, Sensor_Init);
  UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_ApplicatieInit), CFG_SEQ_Prio_0);         //this calls Sensor_Init() and succesfully runs I2C_id()
.
.
.
}



static void OnTxTimerEvent(void *context)
{
  /* USER CODE BEGIN OnTxTimerEvent_1 */

    I2C_id();                       //this does not work

    //==================================================================
      UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_ApplicatieInit), CFG_SEQ_Prio_0);         //this calls Sensor_Init() but doesn't succesfully run I2C_id()
    //==================================================================

  /* USER CODE END OnTxTimerEvent_1 */
  UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_LoRaSendOnTxTimerOrButtonEvent), CFG_SEQ_Prio_0);

  /*Wait for next tx slot*/
  UTIL_TIMER_Start(&TxTimer);

}

Hoping someone might point me in the right direction.


Solution

  • It seems that the comment of @kkrambo was pointing in the right direction. Instead of calling my function from within the OnTxTimerEvent() function, I called it rather in the software, where the sensordata is encoded into a LoRaWAN message.