hero-image
HOME
hero-image
project-highlight-image

Sensor Data Management System Simulation in C++

hero-image
Arjun

Project Timeline

Nov 2025 - Nov-2025

OVERVIEW

Developed a modular C++ program that simulates how robotic systems collect, store, and process sensor data. The system uses templates and smart pointers to manage multiple sensor types (temperature, distance) dynamically and safely. Each reading is timestamped and organized in a queue to ensure data is processed in the order received, accurately modeling real world sensor operations.

HighlightS

  • Designed a generic SensorData<T> template class to handle readings of various data types.
  • Used std::unique_Ptr for safe and automatic memory management.
  • Implemented specialized Sensor<T> classes to simulate temperature and distance sensors
  • Simulated data collection using randomized inputs and displayed readings in FIFO order

SKILLS

C++Object Oriented Programming (OOP)Templates, Smart PointersSTL Queues

SUPPORTING MATERIALS

Additional Details

Code Used for Project

Sensor Header File

#pragma once
#include <iostream>
#include <queue>
#include <memory>
#include "SensorData.h"

// Template class to manage the queue of sensor readings
template <typename T>
class Sensor
{

private:
    // This queue holds unique pointers to objects of SensorData.
    std::queue<std::unique_ptr<SensorData<T>>> dataQueue;
    unsigned int nextTimestamp = 1;

public:
    Sensor() = default;

    // This will add a new sensor reading into the queue
    void collectData(T value)
    {
        // This will create a new SensorData object and then assign it into the next timestamp

        auto newData = std::make_unique<SensorData<T>>(value, nextTimestamp);
        dataQueue.push(std::move(newData));
        ++nextTimestamp;
        std::cout << "Data has been collected successfully. \n"
                  << std::endl;
    }

    // Processes the oldest reading in the queue, prints it, and then removes it.
    void processData()
    {
        if (dataQueue.empty())
        {
            std::cout << "There is no Data to Process" << std::endl;
            return;
        }

        const auto &data = dataQueue.front();

        std::cout << "Data being processed..." << std::endl;
        std::cout << "Value: " << data->getValue() << ", Timestamp: " << data->getTimestamp() << std::endl;

        dataQueue.pop();
    }
};

SensorData Header File

#pragma once
#include <utility>

template <typename T>
class SensorData
{

private:
    T value;
    unsigned int timestamp;

public:
    SensorData() = default;
    SensorData(T v, unsigned int ts) : value(std::move(v)), timestamp(ts) {}

    const T &getValue() const noexcept { return value; }
    unsigned int getTimestamp() const noexcept { return timestamp; }
};

specificSensors Header File

#pragma once
#include "Sensor.h"

// Create the specific sensor for float readings

class TemperatureSensor
{
private:
    Sensor<float> sensor;

public:
    void collectData(float value)
    {
        sensor.collectData(value);
    }

    void processData()
    {
        sensor.processData();
    }
};

// Make the specific sensor for int readings
class DistanceSensor
{
private:
    Sensor<int> sensor;

public:
    void collectData(int value)
    {

        sensor.collectData(value);
    }

    void processData()
    {
        sensor.processData();
    }
};

Main File

#include <iostream>
#include <memory>
#include <string>
#include "Sensor.h"          //Part2
#include "SensorData.h"      //Part1
#include "specificSensors.h" //Part 3
#include <random>

// Part 4

int main()
{

    std::random_device rd;
    // Mersenne Twister and State Size
    std::mt19937 gen(rd());

    // Create a range for Temperature Sensor value Generation
    std::uniform_real_distribution<float> tempDist(5.0f, 45.0f);

    // Create a range for distance sensor value generation

    std::uniform_real_distribution<float> distDist(5, 999);

    const int READINGS = 5;

    std::cout << "----- Temperature Sensor Readings -----" << std::endl;

    TemperatureSensor tempSensor;

    // collecting random temp readings
    for (int i = 0; i < READINGS; ++i)
    {
        float value = tempDist(gen);
        tempSensor.collectData(value);
    }

    // process the temp values in the order it was collected
    std::cout << "Temperature Sensor Queue is being Processed: " << std::endl;
    for (int i = 0; i < READINGS; i++)
    {
        tempSensor.processData();
    }

    std::cout << "\n ----- Distance Sensor Readings -----" << std::endl;

    DistanceSensor distanceSensor;

    // collect randomn values for the distance readsings

    for (int i = 0; i < READINGS; i++)
    {
        int value = distDist(gen);
        distanceSensor.collectData(value);
    }

    // Process the distance values in the order it was collected
    std::cout << "Distance Sensor Queue is being processed: " << std::endl;
    for (int i = 0; i < READINGS; i++)
    {
        distanceSensor.processData();
    }
    return 0;
}
lowinertia
Portfolio Builder for Engineers
Created by Aram Lee
© 2025 Low Inertia. All rights reserved.