Challenge

Project 1 - Implement a fully functional Queue in C language using Linked lists

Project 1:- Implement a fully functional queue in C language using linked list

An IMU has two sensors:

  • Accelerometer
  • Gyroscope

Integrate the IMU to the development board; classify the data coming from Accelerometer and Gyroscope. Send the data of respective sensors on “Separate Queues” to a particular task. This task will identify which source is sending the data using “Queue Sets” and transfer the data to the respective UART Channel.

Introduction:

Integrating an Inertial Measurement Unit (IMU) to a development board and handling its accelerometer and gyroscope data via separate queues involves a few broad steps.Finally, the project transfers the data to the appropriate UART channel for monitoring and analysis.To implement the described functionality in an embedded system, you'd typically use a real-time operating system (RTOS) or a bare-metal approach, depending on the capabilities of your development board

Step 1: IMU Integration.

Initialize the IMU: This step involves initializing I2C or SPI on development boar, also initialize the IMU sensor, setting up its configuration for the accelerometer and gyroscope.
Read Sensor Data: Implement functions to read data from the accelerometer and gyroscope. This generally involves reading specific registers of the IMU chipset over I2C or SPI.

Step 2: RTOS Setup

Create Queues: In FreeRTOS, you'd create two queues – one for accelerometer data and another for gyroscope data.

Create Queue Set: A queue set allows a task to wait for messages to become available on any one of multiple queues

Create Tasks: At least one task that's responsible for reading IMU data and enqueuing it in the respective queues. Another task will wait on the queue set and process data accordingly.

Step 3: Sensor Data Handling Task

This task waits on the queue set. Once it receives data, it determines whether the data came from the accelerometer or gyroscope queue. Subsequently, it processes and routes data to the appropriate UART channel.

Step 4: Sending Data Over UART

After identifying the source of the data and performing any necessary processing, we can route the data to different UART channels based on the source. This would typically involve calling a UART transmission function while specifying the target UART channel and passing the data to be transmitted.

Overview of the project: RTOS concepts, C programming, and embedded systems basics. Depending on your development board and IMU model, specific initialization steps and configurations might vary. Always refer to hardware documentation and APIs available for precise implementation details

The difference between IMU sensor and accelerometer?
Accelerometers, Gyros, and IMUs: The Basics – ITP Physical ...
Introduction. Inertial Motion Units (IMUs) are sensors that measure movement in multiple axes. Accelerometers measure a changing acceleration on the sensor. They can be used to measure the tilt of the sensor with respect of the Earth, or the force of a hit.

CODE:

#include <FreeRTOS.h>
#include <task.h>
#include <queue.h>
#include <semphr.h>
// header files

// Define the data structure for the Inertial measurement unit reading
typedef struct

{
int accelerometerData;
int gyroscopeData;
} IMUData;

// Queues for accelerometer and gyroscope data
QueueHandle_t accelerometerQueue;
QueueHandle_t gyroscopeQueue;

// Queue Set to handle both accelerometer and gyroscope queues
QueueSetHandle_t sensorQueueSet;

// UART channels for accelerometer and gyroscope data
int accelerometerUARTChannel = 1;
int gyroscopeUARTChannel = 2;

// Task to read data from the sensor and classify it
void sensorTask(void *pvParameters)

{
IMUData imuData;

while (1)

{
// Simulate reading data from the accelerometer and gyroscope
// Replace this with actual sensor reading code
imuData.accelerometerData = readAccelerometer();
imuData.gyroscopeData = readGyroscope();

// Determine the source (Accelerometer or Gyroscope) and send to the respective queue
if (sourceIsAccelerometer())

{
xQueueSendToBack(accelerometerQueue, &imuData, portMAX_DELAY);
}

else

{
xQueueSendToBack(gyroscopeQueue, &imuData, portMAX_DELAY);
}

// Wait for a short interval before reading again


vTaskDelay(pdMS_TO_TICKS(100));
}
}

// Task to identify the source and send data to the respective UART channel
void communicationTask(void *pvParameters)

{
IMUData imuData;

while (1)

{
// Wait for data from either accelerometer or gyroscope queue


QueueSetMemberHandle_t triggeredQueue = xQueueSelectFromSet(sensorQueueSet, portMAX_DELAY);

// Identify the source and read data from the respective queue
if (triggeredQueue == accelerometerQueue) {
xQueueReceive(accelerometerQueue, &imuData, 0);
sendToUART(accelerometerUARTChannel, imuData.accelerometerData);
}

else

{
xQueueReceive(gyroscopeQueue, &imuData, 0);
sendToUART(gyroscopeUARTChannel, imuData.gyroscopeData);
}
}
}

int main()

{
// Initialize the queues
accelerometerQueue = xQueueCreate(10, sizeof(IMUData));
gyroscopeQueue = xQueueCreate(10, sizeof(IMUData));

// Create a Queue Set to monitor both accelerometer and gyroscope queues
sensorQueueSet = xQueueCreateSet(10 * sizeof(IMUData));

// Add both queues to the set
xQueueAddToSet(accelerometerQueue, sensorQueueSet);
xQueueAddToSet(gyroscopeQueue, sensorQueueSet);

// Create tasks for sensor and communication
xTaskCreate(sensorTask, "SensorTask", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
xTaskCreate(communicationTask, "CommunicationTask", configMINIMAL_STACK_SIZE, NULL, 2, NULL);

// Start the FreeRTOS scheduler
vTaskStartScheduler();

// Execution should not reach here
return 0;
}

.

Your portfolio, next

Ship work like this
in your own course.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.