← Back

Data Acquisition System

See on GitHub:

Note: this project is still in progress.

As part of Rowan University’s Baja SAE 2025-2027 team, I had the opportunity to lead the Data Acquisition (DAQ) subsystem. This subsystem focuses mainly on designing and implementing a network of sensors (i.e., engine RPM, transmission temperature, ride height, suspension travel, etc.) throughout the vehicle and collecting + processing the data. The data can be used for safety purposes (i.e., detecting an overheating transmission early before failure) but can also be used for improving the performance of the vehicle (i.e., are the shocks reacting as expected when coming down from a jump?).

High-Level Design

I wanted to base the overall design of this subsystem on how an actual modern road vehicle could be wired. Upon doing research, I decided that creating a decentralized network of sensors using one shared CAN Bus would be optimal, since it comes with a few benefits:

So, with this, I decided to go with an architecture like the graphic below. The main building block of the design is the CAN Module PCB, which features a PIC32 microcontroller and a CAN transceiver (among some other things for power filtering etc).

The CAN Module PCB has 8x GPIO pins that can be attached to an arbitrary sensor or other device (i.e., accelerometer, micro SD card, etc.), and also exposes pins to be attached to the shared CAN bus that is routed throughout the vehicle. Similarly, a shared power bus (+5V and GND) is present, but not pictured in the graphic.

---
config:
    theme: 'neutral'
---
flowchart LR
    bus@{ shape: docs, label: "Other CAN Modules" }

    subgraph unit[Sensor Unit]
        peripheral[Arbitrary Sensor]

        subgraph can-module[CAN Module PCB]
            direction LR

            mcu[PIC32 MCU]
            transceiver[CAN Bus\nTransceiver]

            mcu <--> transceiver
        end
    end

    mcu <--8x GPIO--> peripheral
    transceiver <--CAN Bus--> bus

Hardware

PCB Design

I used KiCad to design the PCB for this project, with a screenshot shown below. As mentioned, it features two main chips: a PIC32 microcontroller (U1), and an ATA6560 CAN transceiver (U3). You can find more details on my GitHub.

PCB Assembly

To save on costs (tariffs are not exactly making ordering PCBA from China cheap right now!) and also because I just wanted to, I opted to assemble the circuit boards by hand (I would later curse myself for this decision, but it ended up okay 😉)

I’ve done plenty of soldering before, but since this had many surface-mount components (including some with pads on the bottom), I needed to pick a new method. Now, I could have used the university’s pick & place machine and reflow oven, but that’s boring… so I decided to place the components by hand and use a hot plate.

The graphic below shows an overview of the assembly process (click an image to see it up close):

---
config:
    theme: 'neutral'
---
flowchart LR
    blank-board[<a href='/assets/projects/rowan-baja-daq/assembly/blank-board.png' target='_blank'><img src='/assets/projects/rowan-baja-daq/assembly/blank-board.png' /></a> Blank board] -->
    spread-paste[<a href='/assets/projects/rowan-baja-daq/assembly/spread-paste.png' target='_blank'><img src='/assets/projects/rowan-baja-daq/assembly/spread-paste.png' /></a> Spread solder paste] -->
    placed-components[<a href='/assets/projects/rowan-baja-daq/assembly/placed-components.png' target='_blank'><img src='/assets/projects/rowan-baja-daq/assembly/placed-components.png' /></a> Placed components] -->
    melt-solder[<a href='/assets/projects/rowan-baja-daq/assembly/melt-solder.png' target='_blank'><img src='/assets/projects/rowan-baja-daq/assembly/melt-solder.png' /></a> Melted solder paste] -->
    finished[<a href='/assets/projects/rowan-baja-daq/assembly/finished.png' target='_blank'><img src='/assets/projects/rowan-baja-daq/assembly/finished.png' /></a> Removed solder blobs]

Finally, after a crap-ton of 0402 components later (19x 0402 R’s and C’s per board, to be exact), we get the finished product… (nickel for scale)

Software

I was originally thinking of using an RTOS like FreeRTOS or Zephyr, but I decided it was a bit overkill. So, I opted to just write the software bare-metal in C.

Since the design would require lots of separate CAN Modules, and thus lots of separate software running, I decided to create a compilation scheme using CMake that would make it easy to write different software targets.

A visualization is shown below. The setup is abstracted through a Hardware Abstraction Layer (HAL) that allows for multiple hardware targets, which also allows for simulated tests to be written. Then, the HAL interface is used by custom libraries (i.e., a library for a particular temp sensor chip) and custom targets (approx one per board). CMake takes in all of these files and automatically compiles a simulated test program and also compiles the firmware for each target. More detail is available at my GitHub.

---
config:
    theme: 'neutral'
---
flowchart LR
    subgraph src[Source Code]
        direction TD
        vendor[Vendor Files]
        sim[Simulation Files]
        hal[Hardware Abstraction\nLayer]
        libs[Custom Library\nSource Code]
        targets[Custom Target\nSource Code]
        tests[Tests\nSource Code]
    end

    cmake_conf[CMake Configuration]
    cmake[CMake]

    subgraph output[Output Files]
        firmware[Compiled Firmware]
        test_prog[Compile Test Program]
    end


    vendor --> hal
    sim --> hal

    libs --> targets
    libs --> tests

    hal --> libs
    hal --> targets

    targets --> tests

    src --> cmake
    cmake_conf --> cmake

    cmake --> firmware
    cmake --> test_prog