Data Capture Board Part 2

By Sam Proctor, Smart Solutions Research & Development

Introduction

Now the board is assembled, we are going to use XCode to program it. It’s a step in the direction of high productivity.

Lets address why we want to use XCode to program the Arduino. The standard Arduino IDE is functionally fine, however it does lack in a few areas. XCode on the other hand is a really great IDE for writing iOS and OSX applications, the syntax highlighting is really great and autocompletion is also great.

When examining how we can use XCode to compile and upload to the Arduino we thankfully found the Embedxcode Project which has pre-built templates to use within XCode.

Continuing our aim to extend the life of racing motorcycle engines we need to be able to capture useful data that will ultimately allow us to achieve this goal.
Vibration analysis & Oil analysis are two keys tools within Condition Monitoring and in the context of Motorcycle engines, areas that are expected to yield the greatest chance for success.

The data capture board therefore will be used to acquire vibration data, not only this we also desire to do as much analysis as possible on-asset or as close to the point of data acquisition as possible.
Motivation for on asset analysis is in reducing the amount of data that needs to be transferred from the asset to another location for analysis.

This article describes getting Embedxcode up and running to utilize the Adafruit libraries and start recording vibration data to the SDCard.

Installation & Configuration

The first step naturally is the installation of embedxcode, this is easy enough, download and follow the instructions. Once installed, open XCode and start to create a new project, you should see the following new options

xcode1

 

Creating a New Project

Once the framework has been installed we can go ahead and create a new Project, since we are using a Arduino Mega this example will use this board as its target.
The first step therefore is to select the ’embedXcode Sketch’ template from the new options in XCode and click Next.

From the screen that appears we can fill out the required information and select the board, the result should look something like in the image below.
Click next and choose a location to store the project and then click ‘Create’

XCode2

 

 

Importing Libraies

If you are familiar with XCode and creating apps for iOS then you will know how easy it is to import libraries and frameworks into XCode. With the embedXcode it is a little bit tricker, but not to much so.
For this project we want to accomplish two primary goals; capture IMU data & Write it to SD Card, therefore we need the Adafruit libraries that will interface with the sensors.
They are downloaded from the Adafruit website, copied across to the project and included in the ‘test1.ino’ file for the Sketch. At this stage there is nothing much different from standard XCode based development.

As stated in the embedXCode website in order to use any libraries you first need to add them to the make file manually, this is what we do next to ensure that we can use them.

xcode3

 

 

Data Capture Code

This section now goes through the code we used to do initial data capture and storage

Classes and Variables

Since the ‘test1.ino’ file is laid out as a series of functions rather than a object oriented piece of code we declare some variables that will get used by these functions.

#include "SD.h"
#include "Wire.h"
#include "Adafruit_Sensor.h"
#include "Adafruit_LSM303_U.h"
#include "Adafruit_BMP085_U.h"
#include "Adafruit_10DOF.h"
// Define variables and constants
uint8_t myLED;
//++++++++++++++++++++++++++++++++++++++++++++++++
//++++ Vars and settings for inertial sensors ++++
//++++++++++++++++++++++++++++++++++++++++++++++++
Adafruit_LSM303_Accel_Unified accel = Adafruit_LSM303_Accel_Unified(30301);
Adafruit_LSM303_Mag_Unified mag = Adafruit_LSM303_Mag_Unified(30302);
Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(18001);
float seaLevelPressure = SENSORS_PRESSURE_SEALEVELHPA;
Adafruit_10DOF dof = Adafruit_10DOF();
Sd2Card card;
SdVolume volume;
SdFile root;
const int chipSelect = 53;
const bool printAttitude = false;
uint32_t timer = millis(); //Timer to use to print data to serial port
const int attitudeLogFreq = 1000;
uint32_t sampleCount = 0;

Sensor Initialization

Before we can start sampling from the sensors we need to get them into a working state, to do this we create a function ‘initSensors’. Most of this code is vanilla from the samples provided by Adafruit.

//--------------------------------------------
//Name: initSensors
//Desc: initializes the sensors
//--------------------------------------------
void initSensors()
{
    if(!accel.begin())
    {
        /* There was a problem detecting the LSM303 ... check your connections */
        Serial.println(F("Ooops, no LSM303 detected ... Check your wiring!"));
    }
    if(!mag.begin())
    {
        /* There was a problem detecting the LSM303 ... check your connections */
        Serial.println("Ooops, no LSM303 detected ... Check your wiring!");
    }
    if(!bmp.begin())
    {
        /* There was a problem detecting the BMP180 ... check your connections */
        Serial.println("Ooops, no BMP180 detected ... Check your wiring!");
    }
}

SD Card Initialization

Just like the sensors, we need to get the SD Card ready before we can write to it.

//--------------------------------------------
//Name: initSDCard
//Desc: initializes the SD card ready for use
//--------------------------------------------
void initSDCard()
{
    pinMode(53, OUTPUT); //Set the hardware SS pin to output - SPI won't work properly otherwise
    
    Serial.print("Initializing SD card...");
    
    // see if the card is present and can be initialized:
    if (!SD.begin(chipSelect))
    {
        Serial.println("Card failed, or not present");
    }
    else
    {
        Serial.println("card initialized.");
     
        String header;
        File dataFile;
        
        //Overwrite exisiting log files
        SD.remove("vibData.csv");
        dataFile = SD.open("vibData.csv", FILE_WRITE);
        if (dataFile)
        {
            String header = "Timestamp,X,Y,Z";
            dataFile.println(header);
            dataFile.close();
        }
        else
        {
            Serial.println("Could not open vibData.csv for writing the header");
        }
        
        
        SD.remove("attitudeLog.csv");
        dataFile = SD.open("attitudeLog.csv", FILE_WRITE);
        if (dataFile)
        {
            header = "Timestamp,Pitch,Roll,Yaw";
            dataFile.println(header);
            dataFile.close();
        }
        else
        {
            Serial.println("Could not open attitudeLog.csv for writing the header");
        }
        
        
    }
}

Main Setup() function

Just like the sensors, we need to get the SD Card ready before we can write to it.

//--------------------------------------------
//Name: setup
//Desc: use to do any setup required
//--------------------------------------------
void setup()
{
    //Get the serial port ready to use
    Serial.begin(115200);
    Serial.println(F("Adafruit 10 DOF Pitch/Roll/Heading Example"));
    Serial.println("");
    
    //Configure the LED
    myLED = 13;
    pinMode(myLED, OUTPUT);
    
    //Get the IMU sensors ready to use
    initSensors();
    
    //Get the SD Card ready to use
    initSDCard();
}

loop() function

The Arduino platform calls the loop function repeatedly once the sketch has been uploaded, the code below is that we are using to capture and store data.

//--------------------------------------------
//Name: loop
//Desc: function that gets called continually
//--------------------------------------------
void loop()
{
    sampleCount++;
    sensors_event_t accel_event;
    sensors_event_t mag_event;
    sensors_event_t bmp_event;
    sensors_vec_t   orientation;
    File dataFile;
    String dataString;
    
    digitalWrite(myLED, HIGH);
    //Read the accelerometer and magnetmeter
    accel.getEvent(&accel_event);
    mag.getEvent(&mag_event);
    //Log these bad boys to the SD card
    dataFile = SD.open("vibData.csv", FILE_WRITE);
    
    if (dataFile)
    {
        //Create the output string
        dataString = "";
        dataString += accel_event.timestamp;
        dataString += ",";
        dataString += accel_event.acceleration.x;
        dataString += ",";
        dataString += accel_event.acceleration.y;
        dataString += ",";
        dataString += accel_event.acceleration.z;
        
        
        dataFile.println(dataString);
        dataFile.close();
    }
    else
    {
        Serial.println("error opening vibData.csv");
    }
    
    digitalWrite(myLED, LOW);
}

Build and Deploy

In order to deploy the sketch we can either select the ‘All’ option from the targets in XCode or select and run the ‘Build’ & ‘Upload’ targets on their own.
Either will work, however if done individually then ‘Build’ must be run before ‘Upload’.

Summary

To conclude then, we have installed the embedXcode platform to extend the functionality of XCode to allow us to compile and upload sketches to the Arduino baord.
The reason for doing this was to take advantage of the superior editor and project management features of XCode that will allow us to build complex sketches as this project progresses.

Leave a Reply