2019-07-18 06:28 AM
Hello,
I am struggling to understand how i would set up my uart to receive data until it sees a carriage return (\n) then to check this the rx and then to act on it. For example if i sent " on\r" it would turn an LED on
I am using the STM32Cube, Nucleo-103RB and Keil IDE
I have set up HAL_UART_Receive_IT so i can see the data being stored from the Tx, once 5 characters it will call HAL_UART_RxCpltCallback where this will toggle my LED and restart the interrupt reception. i did try and use strcmp() to compare strings but i couldn't get this to work.
i did read about setting up a idle line interrupt but ,again, i didn't understand it.
is there a simple way for receiving uart messages without knowing the length?
(im looking to use the HAL Drivers)
any help or guidance would be appreciated!
Kind regards,
Mike
2019-07-18 06:45 AM
Got to receive one byte at a time. STM32F1 going to interrupt for every byte any how, callback can be done in a decimated form.
Make a simple line parser/accumulator that buffers until CR or LF, and then copy to a holding buffer, and dispatch for processing.
2019-07-18 07:13 AM
Hi, Thank you for your fast response. Would i put this in my HAL_UART_RxCpltCallback?
Do you have an example of this or a webpage i could follow?
Kind Regards,
Mike
2019-07-18 08:06 AM
I guess you could, I prefer just to put such things in the interrupt handler. Have posted code previously showing capture of ASCII NMEA sentences from a GPS receiver.
Callbacks occur under interrupt context, one needs to be quick processing anything within a single byte time so you don't miss subsequent bytes.
2019-07-18 08:46 AM
Hello,
I really appreciate your help! I did find your code previously but i don't quite understand it. I'm sure that your code below is what I'm after.
From what i can understand you're storing the received data in and array called rx_buffer which gets stored into line_buffer[rx_index]. i don't understand how rx_index gets incremented nor how i would implement this into my own.
#define LINEMAX 200 // Maximal allowed/expected line length
volatile char line_buffer[LINEMAX + 1]; // Holding buffer with space for terminating NUL
volatile int line_valid = 0;
//****************************************************************************
void USART_GPS_IRQHandler(void) // Sync and Queue NMEA Sentences
{
static char rx_buffer[LINEMAX]; // Local holding buffer to build line
static int rx_index = 0;
if (USART_GPS->ISR & USART_ISR_RXNE) // Received character?
{
char rx = (char)(USART_GPS->RDR & 0xFF); //** i dont understand this line**//
if ((rx == '\r') || (rx == '\n')) // Is this an end-of-line condition, either will suffice?
{
if (rx_index != 0) // Line has some content
{
memcpy((void *)line_buffer, rx_buffer, rx_index); // Copy to static line buffer from dynamic receive buffer
line_buffer[rx_index] = 0; // Add terminating NUL
line_valid = 1; // flag new line valid for processing
rx_index = 0; // Reset content pointer
}
}
else
{
if ((rx == '$') || (rx_index == LINEMAX)) // If resync or overflows pull back to start
rx_index = 0;
rx_buffer[rx_index++] = rx; // Copy to buffer and increment
}
}
}
Kind Regards,
Mike
2019-07-18 09:44 AM
rx_index gets incremented in the collection of characters, that aren't CR/LF.
rx is loaded ONCE, with the current character in the USART's Received Data Register. I'm masking it because it's 16-bit wide, and I'm only interested in the lower 8-bits. The RXNE bit in the ISR says there's data available in the RDR.
A GPS NMEA sentence takes the form
$GPGLL,...,..,....,....,......*XX<CR><LF>
I'm interested in the content of the line once the delimiting character(s) are encountered. We don't know how long the line is going in, you have to inspect the stream as it arrives, a character at a time.
2019-07-18 10:32 AM
You are a legend! Thank you so much for your help! i have implemented some of your code and modified it slightly to my template but overall it works.
i just have to figure out how to put in actions when I've received a specific string. but thank you!
Kind Regards,
Mike
2019-07-18 11:23 AM
In this case the processing of the line is handled in the main() loop, and the data is in a secondary buffer so you have a complete-line-time in which to process it. In other types of system you could queue it for processing in another thread. But main point is to avoid doing processing of indeterminate duration while being bounded by reception-byte-time.