2026-04-13 9:34 AM - last edited on 2026-04-13 9:50 AM by Andrew Neil
Hello everyone,
I want to develop an IoT application based on STM32L496 and I am working with the BG96 modem that is embedded on P-L496-CELL02 board. The exchange of AT commands with the modem is succesfull, but, even though i insert a plastic microsim (I have actually tried two of them), i keep getting an error message "Sim Not inserted". I have enabled the simselect0 (PC2) and simselect1 (PI3) pins in CubeMX, as it is indicated by the manual (set to 0 and 1, respectively) and verify their value with my code. The board is powered with an external supply source, through Arduino Vin. The BG96 firmware version is BG96MAR02A08M1G. I have inspected soldering, short-circuits between the sim socket and contacts and everything seems to be alright. I cannot understand what could possibly be the problem, does anyone have a clue? I would be grateful.
Here is my code. All AT commands return OK and seem to work.
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_I2C1_Init();
MX_USB_DEVICE_Init();
MX_USART2_UART_Init();
MX_USART3_UART_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
/* USER CODE BEGIN 2 */
uint8_t response[256];
uint8_t byte;
uint16_t idx = 0;
#define SEND_AT(cmd) do { \
memset(response, 0, sizeof(response)); \
idx = 0; \
HAL_UART_Transmit(&huart1, (uint8_t*)cmd, strlen(cmd), 1000); \
while(idx < sizeof(response)-1) { \
if(HAL_UART_Receive(&huart1, &byte, 1, 500) == HAL_OK) \
response[idx++] = byte; \
else break; \
} \
HAL_UART_Transmit(&huart2, response, idx, 1000); \
HAL_Delay(1000); \
} while(0)
// Select microsim and power on modem
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET);
HAL_Delay(2000);
HAL_GPIO_WritePin(GPIOI, GPIO_PIN_3, GPIO_PIN_SET);
HAL_Delay(2000);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_3, GPIO_PIN_SET);
HAL_Delay(5000);
HAL_UART_Receive(&huart1, (uint8_t *)response, sizeof(response) - 1, 1000);
memset(response, 0, sizeof(response));
// Wait for RDY from modem instead of fixed delay
//uint8_t rdyBuf[64];
//uint8_t rdyByte;
//uint16_t rdyIdx = 0;
uint8_t val;
//memset(rdyBuf, 0, sizeof(rdyBuf));
/*while(rdyIdx < sizeof(rdyBuf) - 1)
{
if(HAL_UART_Receive(&huart1, &rdyByte, 1, 10000) == HAL_OK)
{
rdyBuf[rdyIdx++] = rdyByte;
// Check if we received RDY
if(strstr((char*)rdyBuf, "RDY") != NULL)
{
HAL_UART_Transmit(&huart2, (uint8_t*)"Modem Ready!\r\n", 14, 1000);
break;
}
}
else
{
break;
}
}*/
// Now send AT commands
SEND_AT("AT+CMEE=2\r\n");
HAL_Delay(2000);
SEND_AT("AT+CFUN?\r\n");
HAL_Delay(2000);
SEND_AT("AT+CGMR\r\n");
HAL_Delay(2000);
SEND_AT("AT+QSIMSTAT?\r\n");
HAL_Delay(2000);
SEND_AT("AT+QSIMDET=0,0\r\n");
HAL_Delay(2000);
SEND_AT("AT&W\r\n");
HAL_Delay(2000);
//SEND_AT("AT+QCFG=?\r\n");
//HAL_Delay(8000);
SEND_AT("AT+CFUN=1,1\r\n");
HAL_Delay(10000);
HAL_UART_Receive(&huart1, (uint8_t *)response, sizeof(response) - 1, 1000);
memset(response, 0, sizeof(response));
val = (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_2) == GPIO_PIN_RESET) ? '0' : '1';
HAL_Delay(2000);
if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_2) == GPIO_PIN_RESET){
val = '0';
}
else{
val = '1';
}
HAL_UART_Transmit(&huart2, &val, 1, 1000);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET);
HAL_Delay(2000);
val = (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_2) == GPIO_PIN_RESET) ? '0' : '1';
HAL_Delay(2000);
if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_2) == GPIO_PIN_RESET){
val = '0';
}
else{
val = '1';
}
HAL_UART_Transmit(&huart2, &val, 1, 1000);
val = (HAL_GPIO_ReadPin(GPIOI, GPIO_PIN_3) == GPIO_PIN_SET) ? '1' : '0';
HAL_Delay(2000);
if (HAL_GPIO_ReadPin(GPIOI, GPIO_PIN_3) == GPIO_PIN_SET){
val = '1';
}
else{
val = '0';
}
HAL_UART_Transmit(&huart2, &val, 1, 1000);
SEND_AT("AT+QSIMDET?\r\n");
HAL_Delay(2000);
SEND_AT("AT+QSIMSTAT?\r\n");
HAL_Delay(2000);
SEND_AT("AT+CPIN?\r\n");Edited to apply source code formatting - please see How to insert source code for future reference.
2026-04-13 10:00 AM
Welcome to the forum.
Please see How to write your question to maximize your chances to find a solution for best results;
In particular: How to insert source code
@achilleastheo wrote:All AT commands return OK and seem to work. .
How do you know that? Your code doesn't seem to handle the responses?
Blind delays are not a good way to manage AT command sequences - you must pay attention to the responses!
Have you tried the AT commands directly with the modem - without any STM32 to complicate the issue?
@achilleastheo wrote:i keep getting an error message "Sim Not inserted".
Where, exactly, do you get that message?
I think your code would be a lot easier to follow if you used a proper function - rather than a macro - for sending your commands.
Should also be easier to debug...
Some more tips on debugging this sort of thing here.
2026-04-13 10:10 AM
Thanks for the response!
I inspect the modem responses with TeraTerm on my laptop. I agree with your comments about the code, however i wanted something quick and dirty just to verify connectivity. The only thing i havent checked is whether i need to upgrade the firmware on BG96. However, the version (which the modem responds to the relative AT command) seems to be the right one, based on my search on the internet.
2026-04-14 1:08 AM
@achilleastheo wrote:i wanted something quick and dirty just to verify connectivity. .
Best way to do that is just to drive it "manually" from a terminal.
@achilleastheo wrote:i keep getting an error message "Sim Not inserted".
You didn't answer where, exactly, do you get that message?
2026-04-14 2:55 AM
"Sim not Inserted" appears as a response to SEND_AT("AT+CPIN?\r\n");