Modular Data Acquisition System

I made a system for signal data acquisition that had to be modular and also work standalone without a connected PC. It should be powered by battery or usb and communication should be done by Bluetooth or USB. The memory had to be absurdly large or else I had to implement a trigger and sample profile that should be able to handle various situations. The later was the better solution. I did the PCB HW and firmware plus demo PC software that held all the functions/classes needed for another guy that did the final PC software, mechanic parts and HW installation.
So this is what I did.

HW Part

Base (Medium)

The system is based on a hub module (in the plastic case), a sensor module (aluminum case) and a sensor package (lower left corner).
Multiple sensor modules can be connected to the hub trough daisy chain.



The sensor module holds two differential input channels that are used for strain gauge measurement (Instrumentation Amplifiers), and six analog (12bit) or digital inputs. Each differential channel has a settable offset trough the 12bit DAC, so the offset can be adjusted while the profile is running. The module also holds one 3 axis accelerometer and one The RGB led is for status indication. The board on the picture is not fully populated. I used “no delay SPI flash memory” that enables me to sample and save data at a high rate. I made four flash memory footprints so it can be populated with 4 to 16MBit storage memory.  I use two SPI channels so I can write/read to two memories at the same time. The module also holds a regulator for the 10v that is used for the strain gauge sensors. This voltage can also be recorded if the user wants to check supply variations.

20131029_115618 (Medium)

The module is divided into two sections, analog and digital. This is to reduce noise.


The hub holds the USB and Bluetooth (v3.0) connection to the PC. It is using a step-up converter to step 5v (battery or USB) up to 12v for the strain gauge supply.
The empty footprint below the Bluetooth is for another Bluetooth module type, but the one from ST electronics was better suited for speed reasons. This module
also holds a global trigger input that is used in this application for absolute positioning of the cylindrical assembly it is mounted on.

Both Hub and Sensor module has power saving functionality to reduce power consumption when the system runs on battery .

SW Part


This is the demo software that I did for the other programmer and for my own debugging purpose.

The main structure of a data acquisition profile is that each sensor module has it’s own profile of how it will run –  independent of the other modules on the system.

Each Sensor module has n number of Sessions, each Session holds x number of cycles, each cycle holds period samples.
Lets say the module monitors two pressure sensitive cables that are placed on a road (almost everyone has seen this some time on some road).
A session holds the period settings. For each session trigger we get a cycle that contains data for each car. In that cycle we get a number of periods. Each period holds data for each wheel pair that are sensed by the cables.
If we have specified that we only want to record 100 cars that meet the first Session profile, we can set cycle length to 100, and the create a second Session for another profile settings that detects hay que ser mayor de edad para comprar viagra trucks instead.

Session Settings


Each module can hold multiple different Sessions, and each can be used multiple times or until the memory is full.
For each Session we can adjust the Differential channel offset (Vref). This is used for an increased range on ether the positive or negative signal side. If Vref is set to zero mV we have 12bit ADC resolution on the positive side of the strain gauge.  or if Vref is set to (max signal)/2, we have 11bit ADC resolution on both side of the strain gauge. And the same thing if you like better resolution on the negative side only.
The rest of the settings have the same functionality as in Period.

Period Settings


Start Trigger sets on what signal or property you like the period to start on.

  • External Signal is coupled directly to the global trigger (a trigger signal that is sent to all sensor modules).
  • ADC is used when you like to trigger on an analog signal from a selected channel.
  • Time is what it sounds like –  time from the last Period ended or Session started.
  • Percentage can be used when you have a repetitive global trigger signal. The module calculates the time between triggers and you can set a percentage so the trigger time can vary and you still get the same point between trigger signals.
  • Direct means that the Period starts directly.
  • Number of samples can be used if you like to wait n numbers of ADC samples before Period should start recording signal data.


Start Flank sets whether the trigger should activate on positive, negative or any flank.

Filter Time

Start Filter Time sets how long the trigger flank has to be steady before it is valid. The module starts recording data at the trigger moment, but if the filter shows that the trigger signal is not valid after n time it will delete recorded data and wait until next trigger. The value is X * 0.1mS, so a value of 100 equals 10mS.


Start ADC channel is where you set the channel that should be used if the Start Trigger is set to ADC.


Number of Triggers Before Start can be set if you know that there is n number of signal triggers before the data that should be recorded.

ADC TriggerValue

Start Value holds the value the ADC should trigger on in mV.


And there is the same settings for the end trigger. So you can set start trigger to an analog signal and set end trigger to time or number of samples as an example.


For each period we can set different ADC settings based on what we want so sample. The Sensor module has three ADC units, each 12-Bit resolution. Total sampling speed (ADC1 + ADC2 + ADC3) while storing data to flash is about 60KHz. It’s mostly dependent on number of channels per ADC, flash write time and filter settings. In this window the user can set average (Filter) and wanted sampling frequency. Not every sampling speed can be met however, so the closest frequency is displayed (Selected Freq). The lowest sampling frequency is 40Hz / Average. In the window ADC3 has a sample frequency of one sample per second, but it takes 10000 samples and makes an average of those over one second.


The ADC settings are then saved in the period profile. Each ADC can hold multiple channels.


If  ADC1 is set to 1KHz it does not matter if you select one or two channels, the sampling frequency is still 1Khz

  1. ADC1_CH1        DIFF_CH1_SIGNAL_PIN.    <- Strain gage
  2. ADC1_CH2       DIFF_CH2_SIGNAL_PIN.
  4. ADC2_CH2      ACC_Z_SIGNAL_PIN.     <- Internal Accelerometer
  5. ADC2_CH3      ACC_X_SIGNAL_PIN.
  6. ADC2_CH4      ACC_Y_SIGNAL_PIN.
  7. ADC3_CH1       AIN_CH1_PIN.       <- Analog inputs
  8. ADC3_CH2      AIN_CH2_PIN.
  9. ADC3_CH3      AIN_CH3_PIN.
  10. ADC3_CH4      AIN_CH4_PIN.
  11. ADC3_CH5      AIN_CH5_PIN.
  12. ADC3_CH6      AIN_CH6_PIN.

Profile setup.


To setup the Profile, the tree view holds the settings. Here we can get current status, Download profile to selected module, upload sample data, add and remove content.


For each Session.


For each Period.


Main control to run each or all modules. Using Send trigger the user can manually trig each module and upload sample data.


After the module has sampled the data it can be viewed and exported.

This project was fun to create. I had to think a lot about timings and squeeze as much functionality in the MCU as possible without loosing sampling speed.


Get every new post delivered to your Inbox

Join other followers: