All the designed code and written reports created for Lab Embedded Design 1 at KULeuven Technologiecampus Gent - Master's Electronics Engineering are gathered here. Chris Thoen helped with the research and reports but I mostly focussed on developing the code.
The main code is developed for use on the Silicion Labs Happy Gecko EFM32 board (EFM32HG322 -- TQFP48)
and was developed on Simplicity Studio v4
on Ubuntu 18.04 LTS
. It uses the ADXL362
accelerometer from Analog Devices on a breakout board from Sparkfun.
This is an un-optimized blink example which was created at the start of the lab sessions to get to know Simplicity Studio. The code created here is referenced in this report (Dutch).
This is an optimized blink example which was created at the start of the lab sessions to get to know Simplicity Studio. The code created here is referenced in this report (Dutch).
This is the main code developed for the project for the lab sessions. This is where the rest of this readme is about. This code is also talked about in more detail in this report (Dutch).
UPDATE (17-03-2019): Fixed too high sleep current (>30 µA) caused by the accelerometer sitting on the unused SPI bus. The solution was to disable the SPI pins before going to sleep. This was fixed in the code but the sleep-current-values in the report are wrong. The new sleep current is less than 4 µA.
The following documentation is all about code/SLSTK3400A_ADXL362/
.
The corresponding header
(.h
) and source
(.c
) files are placed in the respective folders inc
and src
.
In the header files we've put:
- All other includes to other libraries/code we need
- REGISTER definitions (PORT and PIN definitions are located in
pin_mapping.h
) - Public variable declararions
- Method prototypes
In the source files we've put:
- A single include to the corresponding header file
- The (public) variable instantiations
- All of the documentation
- The function implementations
These are all of the files we've created to make the project more readable:
-
main.c
- Here is the main method where everything starts from. We've also added two initialisation methods that configure the
EMF32
to wakeup from pin interrupts and/or it'sRTC compare
ability.
- Here is the main method where everything starts from. We've also added two initialisation methods that configure the
-
pin_mapping.h
- Here we put all the PORT and PIN definitions.
-
debugging.h
- Here we can enable or disable debugging over UART by (un)commenting one
#define
line. This file is called in every other file where there are UART (dbprint
) calls. Because these calls are surrounded by#ifdef DEBUGGING ... #endif
tags, the statements are included/excluded in the uploaded code.
- Here we can enable or disable debugging over UART by (un)commenting one
-
util.c
(&util.h
)- Here we have some utility functionality like:
- A Delay method with it's interrupt handler and a function to enable or disable
systicks
. - A method to initialize the LED's and to turn on or off LED0.
- A method to stop code execution when an
error
occured and flash the LED's to indicate this.
- A Delay method with it's interrupt handler and a function to enable or disable
- Here we have some utility functionality like:
-
handlers.c
(&handlers.h
)- Here we've gathered the interrupt handlers for
RTC compare
and odd and even pin interrupts.
- Here we've gathered the interrupt handlers for
-
accel.c
(&accel.h
)- Here we've gathered all the methods that have something to do with the accelerometer:
void initADXL_VCC (void)
: Initialize and enable the GPIO pin wich powers the accelerometer.void powerADXL (bool enabled)
: Enable or disable the GPIO pin wich powers the accelerometer.void enableSPIpinsADXL (bool enabled)
: Enable or disable the SPI pins to the accelerometer.void initADXL_SPI (void)
: Initialize the SPI pins and settings to communicate with the accelerometer.void testADXL (void)
: Test all the ODR (Output Data Rate) settings to see the effect they have on power.void readValuesADXL (void)
: Read and display the X-Y-Z g-values on UART.void resetHandlerADXL (void)
: This method tries to read the sensor ID. If this fails it tries to soft reset it and tries to read the ID again after a delay of one second. If this fails again the power to the sensor is turned off for one second. If the ID check fails again after this, the code stops executing and theerror
method is called.uint8_t readADXL (uint8_t address)
: Read one byte of data from a given register address. This method is called by other methods likereadADXL_XYZDATA
.void writeADXL (uint8_t address, uint8_t data)
: Write one byte of data to a given register address. This method is called by other methods likeconfigADXL_ODR
,configADXL_range
, ... .void readADXL_XYZDATA (void)
: Read the X-Y-Z data registers using burst reads and put the response data in the global array.void configADXL_ODR (uint8_t givenODR)
: Configure the Output Data Rate (ODR).void configADXL_range (uint8_t givenRange)
: Configure the measurement range and store the selected one in a global variable.void configADXL_activity (uint8_t gThreshold)
: Configure the accelerometer to work in activity threshold mode with a given g-value. This way the accelerometer generates an interrupt to wakeup the microcontroller if a value higher than the given threshold is detected.void measureADXL (bool enabled)
: Enable or disable measurement mode.void softResetADXL (void)
: Write'R'
to the soft reset register to soft-reset the accelerometer. This method is called byresetHandlerADXL
.bool checkID_ADXL (void)
: Check if the ID is correct. This method is called byresetHandlerADXL
.int32_t convertGRangeToGValue (int8_t sensorValue)
: Convert sensor readout-value in +-g range to mg value. This method is called byreadADXL_XYZDATA
.
- Here we've gathered all the methods that have something to do with the accelerometer:
-
dbprint.c
(&dbprint.h
)- Here a lot of debugging methods are implemented. For more info see dbprint GIT repo.
Extra notes on the flowchart:
- (*1): Every minute the RTC compare function will give an interrupt to wakeup the microcontroller.
- (*2): This handler tries to read the sensor ID. If this fails it tries to soft reset it and tries to read the ID again after a delay of one second. If this fails again the power to the sensor is turned off for one second. If the ID check fails again after this, the code stops executing and the
error
method is called. - (*3): Every minute an interrupt gets generated by the Real Time Counter Compare functionality.
- (*4): This can be a button (
PB0
orPB1
) interrupt or an interrupt generated by the accelerometer if the activity threshold is surpassed.
The following two figures are output examples in the UART console. The first one depicts using the method readValuesADXL();
, the second one depicts waking up from an interrupt when the threshold is exceeded, a button is pushed or the RTC compare functionality triggered an interrupt.
Right now data doesn't really get read in by the sensor, only the LED is turned on and the interrupt on the accelerometer is cleared if necessary. In the future this could change.
The accelerometer can be put in a wakeup-mode
where he only consumes about 270 nA (@2.0V) and measures the acceleration about six times per second to determine whether motion is present or absent. If motion is detected, the accelerometer can respond autonomously in the following ways:
- Switch into full bandwidth measurement mode.
- Signal an interrupt to a microcontroller.
- Wake up downstream circuitry, depending on the configuration.
In wake-up mode, all accelerometer features are available with the exception of the activity timer. All registers can be accessed, and real-time data can be read and/or stored in the FIFO.
This was not (yet) implemented since it would be very hard to measure these very small current differences. Therefor it would be hard to check if the accelerometer behaves like it should, and the time to get this working would perhaps better be used somewhere else...
We can perhaps use the FIFO
to store measurements at an optimal ODR
(Output Data Rate) so the wave frequency can be calculated using FFT functionality available in CMSIS
libraries. The accelerometer could fill this FIFO on it's own and signal to the microcontroller when it is filled by using an interrupt (there is still one pin unused). Then the microcontroller can read all these values at once and calculate the frequency, after which he again goes to sleep. We also need to look into the amount of samples we need for this to work.