1
\$\begingroup\$

I'm trying to connect Simcom SIM900 to Nucleo-F411RE using the following configuration for USART1:

void MX_USART1_UART_Init(void)
{

  huart1.Instance = USART1;
  huart1.Init.BaudRate = 9600;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  HAL_UART_Init(&huart1);

}

Also the GPIO initialization is as follows:

        GPIO_InitStruct.Pin       = GPIO_PIN_9 | GPIO_PIN_10;
        GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull      = GPIO_PULLUP;
        GPIO_InitStruct.Speed     = GPIO_SPEED_FAST;
        GPIO_InitStruct.Alternate = GPIO_AF7_USART1;

        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

Now I'm trying to send "AT\r" command and receive the "OK" or "ERROR" from the modem but it seems that I get nothing from it. I've tried sending "AT\n" "AT\n\r" too but neither was giving the proper result.

I use the oscilloscope to see if the binary bits are transmitted to the modem and it works fine. What can be the potential issue?

I think there's a configuration mismatch between Nucleo and the modem but couldn't figure it out yet.

Edit: My main function looks like this:

#define TXATMESSAGESIZE       (COUNTOF(Message) - 1)
#define RXBUFFERSIZE          10

#define COUNTOF(__BUFFER__)   (sizeof(__BUFFER__) / sizeof(*(__BUFFER__)))

uint8_t Message[] = "AT\r\n";
uint8_t aRxSIM900Buffer[RXBUFFERSIZE];
UART_HandleTypeDef huart1;

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_USART1_UART_Init();

  /* UART TX and RX */
  HAL_UART_Transmit(&huart1, (uint8_t*) Message, TXATMESSAGESIZE, 1);

  if( HAL_UART_Receive(&huart1, (uint8_t*) aRxSIM900Buffer, RXBUFFERSIZE, 10) != HAL_OK)
  {
      while(1){

      }
  }
}

Edit 2:

When I step into the HAL_UART_Receive function in debug mode, I see the program stuck inside static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout() function. To be exact, it goes inside this first if and waits for the next character to be received:

/* Wait until flag is set */
  if(Status == RESET)
  {
    while(__HAL_UART_GET_FLAG(huart, Flag) == RESET)
    {
      /* Check for the Timeout */
      if(Timeout != HAL_MAX_DELAY)
      {
        if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
        ...(otherstuff)
  }
\$\endgroup\$
  • \$\begingroup\$ I've also connected the Tx pin of SIM900 (Pin08) to the oscilloscope. When I power off the modem I don't see any bits in oscilloscope display, which means that the modem isn't sending "NORMAL POWER DOWN" message? I'm really confused about it. Any help will be appreciated. \$\endgroup\$ – bex Dec 8 '15 at 8:55
  • \$\begingroup\$ I'm assuming you have right hardware connection i.e Rx(Nucleo)-Tx(SIM900) and vice versa. I see you have an Oversampling var in struct? Care to explain why? and to clean your code a little bit in GPIO init. I would initialize both pins like this. GPIO_InitStruct.Pin= GPIO_Pin_9|GPIO_Pin_10; and remove the last 3 lines from the code. \$\endgroup\$ – ammar.cma Dec 8 '15 at 8:58
  • \$\begingroup\$ and another thing, did you check that PA9 and PA10 are multiplexed for USART1 on the hardware?. Just in case. A good start towards debugging. \$\endgroup\$ – ammar.cma Dec 8 '15 at 8:59
  • \$\begingroup\$ Another thought; It may be a circuit issue, since your SIM900 seems to be irresponsive. From my experience biggest issue with SIM modules is the power supply. Can you share a bit more? Also, is the sim module used before? Maybe the default baud rate had been changed. But this does not explain the fact that it gives no response while shutting down. Still, try sending AT+IPR=9600 just in case. \$\endgroup\$ – Batu Yıldız Dec 8 '15 at 9:03
  • 1
    \$\begingroup\$ I've added the results in the question above (under Edit 2). @BenceKaulics \$\endgroup\$ – bex Dec 8 '15 at 12:58
1
\$\begingroup\$

I am using a SIM900 myself with a different MCU. I can't comment on your code as such, but as others have mentioned the SIM900 is very picky about power supply. Make sure you are giving 4.5V. Throw in some bypass capacitors for good measure. We had an inductor on the input power which caused some problems. Not quite sure what was going on but once that inductor was replaced with a short we got much better results.

Are you monitoring the status lights from the SIM900? It is designed to have two LEDs, one on pin 66 - STATUS, and one on pin 52 - NETLIGHT. The status light should be on continuously, and the netlight LED should be blinking (slow if there's network, fast if there isn't). If you are not properly powering up the SIM900 you'll get nothing back (except for maybe some gibberish every now and then).

\$\endgroup\$
1
\$\begingroup\$

First I want to say thanks for all the contributions towards finding the right answer and I've tried every solution you suggested.

After spending a lot of time on reading SIM900 documentation, I found out that the problem is in I/O Pins of the modem. I was using the Arduino GSM shield with Nucleo board and 07 pin of SIM900 modem turned out to be the Tx pin. I thought it's 08 pin that should be used for Tx but it's the opposite.

In other words, (Rx) 07 in the modem means that 07 is a transmit pin and must be connected to the receive pin of the other device.

\$\endgroup\$
0
\$\begingroup\$

Okay. This is the code which i used for USART Receive only mode at 9600 Baud Rate. Make sure your grounds are common, or else it won't work.

void USART1_Init(void)
{



RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE);

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB , ENABLE);


  /* Configure USART1 pins:  Rx * - PB7 Alternative as TIM1 uses 4 channel PWM generation */

  GPIO_RX_Pin.GPIO_Pin =  GPIO_Pin_7;
  GPIO_RX_Pin.GPIO_Speed = GPIO_Speed_Level_1;
  GPIO_RX_Pin.GPIO_Mode = GPIO_Mode_AF;
  GPIO_RX_Pin.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOB, &GPIO_RX_Pin);

  GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_0);
    /* Configure USART1 */

UART1_BT.USART_BaudRate = 9600;
UART1_BT.USART_WordLength = USART_WordLength_8b;
UART1_BT.USART_StopBits = USART_StopBits_1;
UART1_BT.USART_Parity = USART_Parity_No ;
UART1_BT.USART_Mode = USART_Mode_Rx;
UART1_BT.USART_HardwareFlowControl = USART_HardwareFlowControl_None;


USART_Init(USART1, &UART1_BT);

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);  // ONLY RX mode config
NVIC_EnableIRQ(USART1_IRQn);    //NVIC enables the IRQ
USART_Cmd(USART1, ENABLE);


}

Here i am using CooCox with inbuilt libraries for fast code implementation I was using STM32F0 Discovery board, so the pins and functions are different. Especially the Alternate Function assignment. I used a handler to receive from RX pin. Here it goes.

void USART1_IRQHandler(void)
{

if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) /* RXNE if set, then data is received in DR register.*/
{
    USART_ClearITPendingBit(USART1, USART_IT_RXNE);
    char a;


    a = USART_ReceiveData(USART1);
}
\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.