2016-12-07 03:59 AM
Hi all,
I am working for a project which is having 5 interfacing modules out of this one module needs to interface quectel M95 GSM modem to stm32f030C8. From PCB side and Hardware all was done working fine modem Responding to AT Commands.USART1 is used for interfacing M95 module. STM32 cube MX tool is used for generate code for TrueStudio.
Here is my problem,when i sent AT command modem responding with OK and reading messages also.For that i am using USART2 to display received message on PC terminal using MAX3232 converter.
If i want read the message which is received , in that received message some part of message is missing.i tried to increase the buffer size & receive length in the HAL_UART_Receive_IT function but not worked out.
I am using usart1 receive interrupt .Receiving uart message are not exact what we need to receive some of sending characters also received.
uint8_t uart1_aRxBuffer[150],
send_Buf[100];
HAL_UART_Transmit(&huart1,(uint8_t *)send_Buf,len,1000);
HAL_UART_Receive_IT(&huart1,(uint8_t *)uart1_aRxBuffer,len1);
please help on this it is need to submit to the client ASAP.
#no-hablo-halSolved! Go to Solution.
2016-12-15 12:05 PM
The response you are seeing makes perfect sense because your logic is completely confused.
Regardless of the command, this is the way your logic is currently working:
1. You transmit a string (command) to the M95 like AT+GSM.....
2. You delay 2 seconds, during which time the M95 sends a response
3. you THEN enable the UART to receive data, using interrupts (and I still don't see your interrupt handling code)
4. the result of (2) above is that the response from the M95 happens while you are sitting in a 2 second delay. As a result you get whatever was received by the hardware before it overflowed because you are not emptying the Rx buffer as characters are coming in. So you get the first 2 characters '+C' which is the beginning of '+CPMS....' but since nobody is looking at the receiver, after the first two characters are buffered in the hardware peripheral (in the Rx register and the CPU interface register) it drops all subsequent characters on the floor. The whole message was sent back by the M95 while you are sitting in a delay loop and ignoring what is coming back for 2 seconds. So when you finally enable the Receiver with your HAL call it gives you the two characters it had stuck in the peripheral's registers.
What you need to do is enable the Receiver BEFORE you send a command so that you get back anything that the M95 sends you. Including the command you sent if you have Echo enabled. YOU need to figure out what to expect back based on whether echo is on or not, etc etc etc, and throw out any extraneous information and extract the useful response. You can't use delays to hope that the bad stiff gets ignored and you'll get the good stuff because you don't know how long it will be before the M95 responds.
By waiting 2 seconds to look at the receiver after sending a command, you are ignoring the response from the M95.
And as a side note, setting a receive buffer 5 characters bigger than the size of the buffer you were passed is dangerous at best. (assuming this will even know what the size is since what is passed to the function is pointer to an arbitrary array)
If you would like me to write the code for you, let me know.
2016-12-07 11:11 AM
It's a little hard to understand what your problem is. It sound like you are receiving some of the characters you sent out, which causes you a problem? You show that you are using the Rx channel in Interrupt mode but you do not talk about or show the code you use to respond to the received character interrupt. I will assume you have the capability to correctly buffer what is being received back from your external device.
The first thing I would suspect is that the device you are communicating with is in ECHO mode, so that every character you send to it, is sent back to you on your Rx line. This is useful when you are using a terminal emulator program on a PC to talk to the device, not necessarily helpful when you are connecting with your microcontroller. If you have an AT command to turn off ECHO , like ATE=0, you might send this first. And then clear your receive buffers.
Next, by using the non-interrupt call to Txmit your message, the program will block until all of the characters are transferred to the UART before moving on to the next statement that starts the Rx channel. With that the case, and if echo is on, what I would expect is the following:
There are a number of ways to deal with the situation. One is to run the Tx in interrupt mode, which will let you immediately enable the receiver and get back all of the echoed characters and throw out what you know to expect. Also you could just enable the receiver before you send the message and it will have the same effect. Alternately you can turn off echo on the peripheral as mentioned above.
In any case, you need to make sure you flush the receiver in some controlled way to ensure you only return meaning ful outputs from the device.
2016-12-07 12:11 PM
You'll need to manage or suppress the echo back from the modem, and resync depending on the OK, ERROR, NO CARRIER, etc responses the modem might provide. Arbitrary delays should also be avoided, network interaction may take several minutes to complete, and sending characters before completion might result in a command being aborted.
Turn Echo Off
ATE0
Turn Echo On
ATE1
With the HAL stuff make sure you are not creating some blocking code within a call-back (via IRQ Handler). Review how much data was received or transmitted, and if the request timed-out.
#no%20hablo%20hal
>>
please help on this it is need to submit to the client ASAP.
Nobody here cares, your client isn't paying us.
http://www.catb.org/~esr/faqs/smart-questions.html#urgent
2016-12-10 10:19 AM
If the second UART is only for debug, try to program the baudrate of the debug uart to be higher than the one going to the Quectel device. Then do not use buffer. When a byte is received from Quectel, directly write the DR of the debug UART TX. Good luck!
2016-12-15 04:53 AM
This is the source code what is running for GSM COM,
UART1 for Quectel M95,UART2 is for Hyper terminal.UART not receiving full reply message.
uint8_t test_commands()
{ send_cmnd((char *)''AT\r'',''OK''); send_cmnd((char *)''ATE0\r'',''OK''); send_cmnd((char *)''AT+CPMS=\''SM\'',\''SM\'',\''SM\''\r'',(''+CPMS: SM,0,50,SM,0,50,SM,0,50'')); send_cmnd((char *)''AT+CMGF=1\r'',''OK''); send_cmnd((char *)''AT+CNMI=2,0,0,0,0\r'',''OK''); send_cmnd((char *)''AT+CMEE=1\r'',''OK''); send_cmnd((char *)''AT+CSCS=\''GSM\''\r'',''OK'');return 0;
}void send_cmnd(char *AT_cmd_string,char *response_string)
{char send_Buf[50]={0};//added
sprintf(send_Buf,AT_cmd_string);uint8_t len = strlen(AT_cmd_string);
printf(''\r\nGSM Tx: %s\r\n'',(int8_t*)AT_cmd_string);
if(len)
{HAL_UART_Transmit_IT(&huart1,(uint8_t *)send_Buf,len);
}HAL_Delay(2000);reponse_read(response_string);}
void reponse_read(char *response_string)
{ uint8_t len1; len1=sizeof(response_string);HAL_UART_Receive_IT(&huart1,(uint8_t *)uart1_aRxBuffer,(len1+5));
HAL_Delay(500);
printf(''\r\n UART1 Rx:%s\r'',uart1_aRxBuffer); len1=0;}And the hyper terminal Displays below :
At the red mark we are expecting result :
''+CPMS: SM,0,50,SM,0,50,SM,0,50'' but not sucesses
Is UART1 & UART2 use the same buffer for writing & reading?
2016-12-15 05:06 AM
For the Above code is there any changes needed for receiving uart data from quectel M95.
Is there any problem with receiving data on uart2 and printing it on uart1 with ms delay?
By using these responses i need to check weather modem initialized correctly or not.
please help me on this issue.
2016-12-15 05:27 AM
I'm guessing how long does it take to send 'UART1 RX:' and how many bytes I may received in this time?
Try this: inside the interrupt of receiving a byte from Quectel, directly send and write the debug UART the same byte, and make sure the debug UART baud rate is higher (so you don't need extra buffering). When you write your 'GSM....' string,
send_cmnd((char *)'AT+CPMS=\'SM\',\'SM\',\'SM\'\r',('+CPMS: SM,0,50,SM,0,50,SM,0,50')); anticipate and add immediately the UART1 Rx: string before sending. Then it might work better. Let us know.
2016-12-15 12:05 PM
The response you are seeing makes perfect sense because your logic is completely confused.
Regardless of the command, this is the way your logic is currently working:
1. You transmit a string (command) to the M95 like AT+GSM.....
2. You delay 2 seconds, during which time the M95 sends a response
3. you THEN enable the UART to receive data, using interrupts (and I still don't see your interrupt handling code)
4. the result of (2) above is that the response from the M95 happens while you are sitting in a 2 second delay. As a result you get whatever was received by the hardware before it overflowed because you are not emptying the Rx buffer as characters are coming in. So you get the first 2 characters '+C' which is the beginning of '+CPMS....' but since nobody is looking at the receiver, after the first two characters are buffered in the hardware peripheral (in the Rx register and the CPU interface register) it drops all subsequent characters on the floor. The whole message was sent back by the M95 while you are sitting in a delay loop and ignoring what is coming back for 2 seconds. So when you finally enable the Receiver with your HAL call it gives you the two characters it had stuck in the peripheral's registers.
What you need to do is enable the Receiver BEFORE you send a command so that you get back anything that the M95 sends you. Including the command you sent if you have Echo enabled. YOU need to figure out what to expect back based on whether echo is on or not, etc etc etc, and throw out any extraneous information and extract the useful response. You can't use delays to hope that the bad stiff gets ignored and you'll get the good stuff because you don't know how long it will be before the M95 responds.
By waiting 2 seconds to look at the receiver after sending a command, you are ignoring the response from the M95.
And as a side note, setting a receive buffer 5 characters bigger than the size of the buffer you were passed is dangerous at best. (assuming this will even know what the size is since what is passed to the function is pointer to an arbitrary array)
If you would like me to write the code for you, let me know.
2016-12-15 11:28 PM
Thanks for your helpful reply,below is the interrupt handle code for UART receiving ,even after removing increment buffer size same result was seen from the device.
/**
* @brief Receive an amount of data in interrupt mode. * @param huart: UART handle. * @param pData: pointer to data buffer. * @param Size: amount of data to be received. * @retval HAL status */HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size){ if((huart->State == HAL_UART_STATE_READY) || (huart->State == HAL_UART_STATE_BUSY_TX)) { if((pData == NULL ) || (Size == 0)) { return HAL_ERROR; }/* Process Locked */
__HAL_LOCK(huart);huart->pRxBuffPtr = pData;
huart->RxXferSize = Size; huart->RxXferCount = Size;/* Computation of UART mask to apply to RDR register */
UART_MASK_COMPUTATION(huart);huart->ErrorCode = HAL_UART_ERROR_NONE;
/* Check if a transmit process is ongoing or not */ if(huart->State == HAL_UART_STATE_BUSY_TX) { huart->State = HAL_UART_STATE_BUSY_TX_RX; } else { huart->State = HAL_UART_STATE_BUSY_RX; }/* Enable the UART Parity Error Interrupt */
__HAL_UART_ENABLE_IT(huart, UART_IT_PE);/* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
__HAL_UART_ENABLE_IT(huart, UART_IT_ERR);/* Process Unlocked */
__HAL_UNLOCK(huart);/* Enable the UART Data Register not empty Interrupt */
__HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);return HAL_OK;
} else { return HAL_BUSY; }}if possible please send me the code for this interface.
2016-12-16 02:51 AM
Using the Above application stm32 need to read the text messages which are stored in the SIM card.
In these messages are some are lengthy(120 characters) for this how to define a receive buffer?
what is the maximum byte buffer size that uart can receive ?
Can i use
HAL_UART_Receive_IT(&huart1,(uint8_t *)uart1_aRxBuffer,150);?
is there any problem for using lengthy receive buffer?