Arduino Microcontroller Code Reference

This page contains a verbosely commented example code for the Teensy microcontroller. This example makes use of three current sensors as well as one accelerometer.

Define Variables

First, we define all of the global variables that we will be using on the microcontroller


// Teensy Serial 1 (RX1 TX1 pins)
#define HWSERIAL Serial1

// Expected size of the serial input when receiving commands
#define INPUT_SIZE 30

const String ACCELEROMETER = "Accelerometer";
const String CURRENT = "Current";
const String CURRENT1 = "Current-1";
const String CURRENT2 = "Current-2";
const String CURRENT3 = "Current-3";

const String INTERVAL = "Interval";
const String START = "Start";
const String STOP = "Stop";
const String SET = "Set";

// Declare constants
uint16_t accelerometerSamplingRate = 2500; // Sample rate of the audio in hertz.
uint16_t accelerometerSize = 2500; // Size of the FFT
uint16_t accelerometerLineSize = 500;

// Time between accelerometer samples in Hz
float sensorSamplingPeriod = 0.1;

uint16_t currentSamplingRate = 100;
uint16_t currentSize = 1000;
uint16_t currentLineSize = 500;

const int accelerometerX = 1; // Input ADC pin: accelerometer axis 1. Corresponds to pin 15 on cape
const int accelerometerY = 0;

const int current1 = 8;
const int current2 = 7;
const int current3 = 9;

int intervalCount = 0;

const int ANALOG_READ_RESOLUTION = 8; // Bits of resolution for the ADC.
uint8_t accelerometerSample;
float currentSample;
uint8_t currentSample1;
uint8_t currentSample2;
uint8_t currentSample3;

bool sumCurrent = true;

const String SERIAL_DELIMITER = ","; // Delimeter between current values in uart string
const String SERIAL_START = ""; // First character in uart string

// The Teensy supports up to 4 concurrent instances of IntervalTimer
IntervalTimer accelerometerSamplingTimer;
IntervalTimer accelerometerTimer;
IntervalTimer currentSamplingTimer;
IntervalTimer currentTimer;
IntervalTimer sensorIntervalTimer;

String currentOut = CURRENT;
String currentOut1 = CURRENT1;
String currentOut2 = CURRENT2;
String currentOut3 = CURRENT3;
String accelerometerOut = ACCELEROMETER;

String serialInput;

// Keep track of the current position for the accelerometer
uint16_t accelerometerCount = 0;
uint16_t accelerometerLineNumber = 0;

uint16_t currentCount = 0;
uint16_t currentLineNumber = 0;

uint8_t sensorSampleNumber = 10;

char DELIMITER = '|';

// Used to parse serial input commands
String dataId;
int samplingFrequency;
int numPoints;

// Setup function.
void setup() {
HWSERIAL.begin(115200);
analogReadResolution(ANALOG_READ_RESOLUTION);
}

Wait for Serial Input

// Main loop.
void loop() {

while(HWSERIAL.available()) {

// Get next command from Serial (add 1 for final 0)
char input[INPUT_SIZE + 1];

byte size = HWSERIAL.readBytes(input, INPUT_SIZE);

// Add the final 0 to end the C string
input[size] = 0;

// Read each command pair
char* command = strtok(input, “|”);

int position = 0;

dataId = command;

if(dataId == “StartAccelerometer”){
accelerometerTimer.begin(sampleAccelerometer,1e6/accelerometerSamplingRate);
break;
}
else if(dataId == START + CURRENT){
currentTimer.begin(sampleCurrent,1e6/currentSamplingRate);
break;
}
else if(dataId == START + “All”){
accelerometerTimer.begin(sampleAccelerometer, 1e6/accelerometerSamplingRate);
delay(100);
currentTimer.begin(sampleCurrent,1e6/currentSamplingRate);
break;
}
else if(dataId == START + INTERVAL){
sensorIntervalTimer.begin(intervalCallback,1e6/sensorSamplingPeriod);
}
else if(dataId == STOP){
sensorIntervalTimer.end();
intervalCount = 0;
break;
}

// Parse the serial input
while (command != 0)
{
if(dataId == SET + ACCELEROMETER){
switch(position){
case 1:
accelerometerSamplingRate = atoi(command);
break;
case 2:
accelerometerSize = atoi(command);
break;
}
}
else if(dataId == SET + CURRENT){
switch(position){
case 1:
currentSamplingRate = atoi(command);
break;
case 2:
currentSize = atoi(command);
break;
}
}
else if(dataId == SET + INTERVAL){
switch(position){
case 1:
sensorSamplingPeriod = atof(command);
break;
case 2:
sensorSampleNumber = atoi(command);
break;
}
}
position++;
command = strtok(0, “|”);
}
}
}

Perform Periodic Samples

void intervalCallback(){
accelerometerTimer.begin(sampleAccelerometer, 1e6/accelerometerSamplingRate);
delay(10);
currentTimer.begin(sampleCurrent,1e6/currentSamplingRate);

intervalCount++;

if(intervalCount > sensorSampleNumber){
sensorIntervalTimer.end();
intervalCount = 0;
}
}

Map Values to Float

char* mapToFloat(uint8_t value){
// Using 5 Volts as the maximum ADC Value and 8 Bit ADC Resolution,
// The normalized value is multiplied by 5/255. This simplifies to 1/51
float returnVal = value / 51.0;
char returnString[6];
return dtostrf(returnVal,4,3,returnString);
}

Sample from the Accelerometer

// This callback is used to quickly grab a series of accelerometer data points
// After this function completes one cycle, the timer is ended.
void sampleAccelerometer() {

if (accelerometerCount + accelerometerLineNumber * accelerometerLineSize < accelerometerSize){ accelerometerSample = analogRead(accelerometerX); accelerometerOut += mapToFloat(accelerometerSample); if(accelerometerCount >= accelerometerLineSize){
HWSERIAL.println(accelerometerOut + SERIAL_DELIMITER);
accelerometerOut = ACCELEROMETER;
accelerometerLineNumber++;
accelerometerCount = 0;
}
else{
accelerometerOut += SERIAL_DELIMITER;
accelerometerCount++;
}
}
else{
HWSERIAL.println(accelerometerOut + “END”);
accelerometerCount = 0;
accelerometerLineNumber = 0;
accelerometerOut = ACCELEROMETER;
accelerometerTimer.end();
}
}

Sample from the Current Sensor

// samplingTimer callback function.
void sampleCurrent() {

if (currentCount + currentLineNumber * currentLineSize < currentSize){ currentSample1 = analogRead(current1); currentSample = currentSample1; currentOut += mapToFloat(currentSample); currentCount++; if(currentCount > currentLineSize){
HWSERIAL.println(currentOut + SERIAL_DELIMITER);
currentOut = CURRENT;
currentLineNumber++;
currentCount = 0;
}
else{
currentOut += SERIAL_DELIMITER;
}
}
else{
HWSERIAL.println(currentOut + “END”);
currentCount = 0;
currentLineNumber = 0;
currentOut = CURRENT;
currentTimer.end();
}
}