2020-11-09 10:57 AM
Hello.
I'm trying to design an RF controller for a drone with STM32F103RBT using FREERTOS CMSIS_V2.
The idea is: I have a hardware with some potentiometers, joysticks etc connected to the ADC channels. I have an NRF24L01 as RF transmitter using SPI communication. Finally I wanted to display the data on an OLED display using I2C.
The ADC is triggered using a Timer with 1ms sampling time and the values are stored using DMA.
I have 3 tasks and 2 queues.
Task1 : filters the 6 ADC values, and puts them in the queues - this is tested, and it's working as intended.
Task2: reads the 6 values from queue 1 serialises the data and pushed it to the RF module using SPI.
Task3: reads the 6 values from queue 2 bulds the strings and pushes the values to the OLED.
The communication is working. The threads are working as expected. The problem is with the queues.
Suppose that I put the array {123, 123, 0, 175, 125, 125} into the queue.
On the receiving ends I have {123, 123, 0, 175, 113, 85} and {123, 123, 0, 165, 165}, meaning the last two values won't go through the queue. Also, these two values will never change.
The size of the queues
#define DATA_T sizeof(uint8_t)*6
The first thread:
void StartDataProcessing(void *argument)
{
/* USER CODE BEGIN 5 */
uint8_t y_n[6], y_n_1[6] = {0};
/* Infinite loop */
for(;;)
{
// Get the new data
// Filter the data
y_n[0] = (ADC_Data[0]>> 5) + (y_n_1[0]>>1);
y_n[1] = (ADC_Data[1]>> 5) + (y_n_1[1]>>1);
y_n[2] = (ADC_Data[2]>> 5) + (y_n_1[2]>>1);
y_n[3] = (ADC_Data[3]>> 5) + (y_n_1[3]>>1);
y_n[4] = (ADC_Data[4]>> 5) + (y_n_1[4]>>1);
y_n[5] = (ADC_Data[5]>> 5) + (y_n_1[5]>>1);
// Store the data
y_n_1[0] = y_n[0];
y_n_1[1] = y_n[1];
y_n_1[2] = y_n[2];
y_n_1[3] = y_n[3];
y_n_1[4] = y_n[4];
y_n_1[5] = y_n[5];
// Send the data to the thread-safe queue
osMessageQueuePut(smoothDataQueueHandle, y_n, 0U, 0U);
osMessageQueuePut(nrfQueueHandle, y_n, 0U, 0U);
osDelay(1);
}
/* USER CODE END 5 */
}
The second thread:
void StartSender(void *argument)
{
/* USER CODE BEGIN StartSender */
uint8_t y_n[6];
osStatus_t status;
struct reference_params p;
uint8_t tx_buffer[20] = {0};
/* Infinite loop */
for(;;)
{
status = osMessageQueueGet(nrfQueueHandle, y_n, NULL, 0);
if(status == osOK){
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);
p.mode = 1;
p.alt = y_n[0];
p.pitch = y_n[1];
p.roll = y_n[2];
p.yaw = y_n[3];
memcpy(tx_buffer, &p, sizeof(p));
nrf_send(tx_buffer);
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);
}
osDelay(3);
}
/* USER CODE END StartSender */
}
And the third thread:
void StartDisplayData(void *argument)
{
/* USER CODE BEGIN StartDisplayData */
osStatus_t status;
uint8_t y_n[6];
char display_num[4] = "000\0";
/* Infinite loop */
for(;;)
{
status = osMessageQueueGet(smoothDataQueueHandle, y_n, NULL, 0);
if(status == osOK){
for(uint16_t i= 0; i < 6; ++i){
display_num[0] = (y_n[i]/100) + '0';
display_num[1] = (y_n[i]/10)%10 + '0';
display_num[2] = y_n[i]%10 + '0';
if(i < 3){
SSD1306_GotoXY(45, 10*(i+1));
SSD1306_Puts(display_num, &Font_7x10, 1);
}
else{
SSD1306_GotoXY(103, 10*(i-2));
SSD1306_Puts(display_num, &Font_7x10, 1);
}
}
SSD1306_UpdateScreen();
}
osDelay(30);
}
For good measures I've attached the whole main.c file.
Maybe it's something simple, but I can't figure out the problem.
Any help would be appreciated.
2020-11-10 02:58 AM
Short update here. I couldn't sleep so I've downloaded the OpenRTOS Viewer and found out that although the size of the queues was defined as sizeof(uint8_t)*6 the size in the queue viewer remained 4. This explains why I had garbage in the memory after the 4th element.
The solution was to hard-code the byte number as #define DATA_T 6.
I feel a little bit dumb after this one.