Introduction: Connect Open Loger and Accelerometer

About: Married to Domestic_Engineer (but I call her Meghan).

I am writing this so I can remember how to do this latter. This is a hack I did a few years ago and just pulled out of the closet to use again.

BACKROUND

It is common that you would want to save the data from an accelerometer with a device that is small. I am using two boards from Spark fun; Open Log, and MMA8452 Breakout (ie accelerometer, like in your smartphone).

The MMA8452 breakout board is a low cost 3-axis accelerometer mounted on a small printed circuit board. The header includes the communication pins (I2C (I think)). There are examples of how to connect and use this with an arduino development board.

IDEA

The Open Log boards is basically an arduino with an microSD card slot attached. The arduino receives serial data from the TX/RX lines and saves this to the microSD card. The pins brought out the header are just what you need to attach to an arduino mini - so the intended use is to use this to read some output from another arduino circuit.

WIRES

So if you only want to read and save the accelerometer data, it makes sense to wire it directly to the data logger. You just have to figure out which pins go where.....

MMA8452: OpenLog(atmega328) Equivalent pin using Arduino IDE

3.3v-------------------Vcc on header

SDA----------------Pin 27 atmega 328 --------- A4 (yellow wire in photo)

SCL----------------Pin 28 on atmega 328---------- A5 (white wire in photo)

GND--------------GND

NOTE: arduino pinout diagram http://forum.arduino.cc/index.php?topic=132130.0

atmegaTQFP

http://www.hobbytronics.co.uk/image/data/tutorial/...

Program the open log with a 3.3V FTDI Basic. Most of the pins connect straight from header to header --EXCEPT you need to swap the TX/RX lines. So OpenLogTXO goes to FTDI_RXI.

Here is the wiring

OpenLog FTDI Basic

BLK-------------------BLK

GND-----------------GND

VCC-----------------3.3V

TXO----------------RXI (not straight across)

RXI-----------------TXO (not strait across)

GND ------------- GND

not used---------BLK

CODE - library needed

You need the library for the accelerometer:

https://github.com/sparkfun/MMA8452_Accelerometer/...

Put the file in the the libraries file in sketchbook directory. To find the sketchbook, on arduino IDE, select file->preferences and it is right at the top. Then close arduino IDE and reopen.

(lots of info here:)

https://learn.sparkfun.com/tutorials/mma8452q-acce...

CODE - writes accelerometer output to SD card.

There is some very good code for use with the open logger, it will let you change parameters and make new files, I am not using that right now. Simply added the SD card writing to the basic accelerometer example. This has catch - There MUST BE FILE CALLED datalog.txt ON THE SD CARD. That is the file the data will go to.

The code should be attached.

It is called: MMA8452_Plus_SDLogger

LINKS:

https://github.com/sparkfun/MMA8452_Accelerometer

https://github.com/sparkfun/OpenLog

NOTE:

the code does not seem to be uploading... so here it is as text.

//////////////////accelerometer plus data logger code/////////

///////////////modified by MPC Marc Cryan ///////////

/*  MMA8452Q Basic Example Code Nathan Seidle SparkFun Electronics November 5, 2012 License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license). This example code shows how to read the X/Y/Z accelerations and basic functions of the MMA5842. It leaves out all the neat features this IC is capable of (tap, orientation, and inerrupts) and just displays X/Y/Z. See  the advanced example code to see more features. Hardware setup: MMA8452 Breakout ------------ Arduino 3.3V --------------------- 3.3V SDA -------^^(330)^^------- A4 SCL -------^^(330)^^------- A5 GND ---------------------- GND The MMA8452 is 3.3V so we recommend using 330 or 1k resistors between a 5V Arduino and the MMA8452 breakout. The MMA8452 has built in pull-up resistors for I2C so you do not need additional pull-ups. */

#include <Wire.h> // Used for I2C// The SparkFun breakout board defaults to 1, set to 0 if SA0 jumper on the bottom of the board is set
#define MMA8452_ADDRESS 0x1D  // 0x1D if SA0 is high, 0x1C if low//Define a few of the registers that we will be accessing on the MMA8452
#define OUT_X_MSB 0x01
#define XYZ_DATA_CFG  0x0E
#define WHO_AM_I   0x0D
#define CTRL_REG1  0x2A

#define GSCALE 2 // Sets full-scale range to +/-2, 4, or 8g. Used to calc real g values./////////datalogger
#include <SD.h>

// On the Ethernet Shield, CS is pin 4. Note that even if it's not// used as the CS pin, the hardware CS pin (10 on most Arduino boards,// 53 on the Mega) must be left as an output or the SD library// functions will not work.constint chipSelect = 10;
/////////////////voidsetup()
{
  Serial.begin(57600);
  Serial.println("MMA8452 Basic Example");

  Wire.begin(); //Join the bus as a master

  initMMA8452(); //Test and intialize the MMA8452////////////SDLoggerSerial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to// output, even if you don't use it:pinMode(10, OUTPUT);
  
  // see if the card is present and can be initialized:if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:return;
  }
  Serial.println("card initialized.");
/////////////////////
}

voidloop()
{  
  int accelCount[3];  // Stores the 12-bit signed value
  readAccelData(accelCount);  // Read the x/y/z adc values// Now we'll calculate the accleration value into actual g'sfloat accelG[3];  // Stores the real accel value in g'sfor (int i = 0 ; i < 3 ; i++)
  {
    accelG[i] = (float) accelCount[i] / ((1<<12)/(2*GSCALE));  // get actual g value, this depends on scale being set
  }

  // Print out valuesfor (int i = 0 ; i < 3 ; i++)
  {
    Serial.print(accelG[i], 4);  // Print g valuesSerial.print("\t");  // tabs in between axes
  }
  Serial.println();
  
  ///////////data to SD card// open the file. note that only one file can be open at a time,// so you have to close this one before opening another.File dataFile = SD.open("datalog.txt", FILE_WRITE);
   // if the file is available, write to it:if (dataFile) {
    
      for (int i = 0 ; i < 3 ; i++)
  {
    dataFile.print(accelG[i], 4);  // Print g values
    dataFile.print("\t");  // tabs in between axes
    dataFile.close();
  }  
  }
  // if the file isn't open, pop up an error:else {
    Serial.println("error opening datalog.txt");
  } 
  
 //////////////delay(10);  // Delay here for visibility
}

void readAccelData(int *destination)
{
  byte rawData[6];  // x/y/z accel register data stored here

  readRegisters(OUT_X_MSB, 6, rawData);  // Read the six raw data registers into data array// Loop to calculate 12-bit ADC and g value for each axisfor(int i = 0; i < 3 ; i++)
  {
    int gCount = (rawData[i*2] << 8) | rawData[(i*2)+1];  //Combine the two 8 bit registers into one 12-bit number
    gCount >>= 4; //The registers are left align, here we right align the 12-bit integer// If the number is negative, we have to make it so manually (no 12-bit data type)if (rawData[i*2] > 0x7F)
    {  
      gCount = ~gCount + 1;
      gCount *= -1;  // Transform into negative 2's complement #
    }

    destination[i] = gCount; //Record this gCount into the 3 int array
  }
}

// Initialize the MMA8452 registers // See the many application notes for more info on setting all of these registers:// http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=MMA8452Qvoid initMMA8452()
{
  byte c = readRegister(WHO_AM_I);  // Read WHO_AM_I registerif (c == 0x2A) // WHO_AM_I should always be 0x2A
  {  
    Serial.println("MMA8452Q is online...");
  }
  else
  {
    Serial.print("Could not connect to MMA8452Q: 0x");
    Serial.println(c, HEX);
    while(1) ; // Loop forever if communication doesn't happen
  }

  MMA8452Standby();  // Must be in standby to change registers// Set up the full scale range to 2, 4, or 8g.byte fsr = GSCALE;
  if(fsr > 8) fsr = 8; //Easy error check
  fsr >>= 2; // Neat trick, see page 22. 00 = 2G, 01 = 4A, 10 = 8G
  writeRegister(XYZ_DATA_CFG, fsr);

  //The default data rate is 800Hz and we don't modify it in this example code

  MMA8452Active();  // Set to active to start reading
}

// Sets the MMA8452 to standby mode. It must be in standby to change most register settingsvoid MMA8452Standby()
{
  byte c = readRegister(CTRL_REG1);
  writeRegister(CTRL_REG1, c & ~(0x01)); //Clear the active bit to go into standby
}

// Sets the MMA8452 to active mode. Needs to be in this mode to output datavoid MMA8452Active()
{
  byte c = readRegister(CTRL_REG1);
  writeRegister(CTRL_REG1, c | 0x01); //Set the active bit to begin detection
}

// Read bytesToRead sequentially, starting at addressToRead into the dest byte arrayvoid readRegisters(byte addressToRead, int bytesToRead, byte * dest)
{
  Wire.beginTransmission(MMA8452_ADDRESS);
  Wire.write(addressToRead);
  Wire.endTransmission(false); //endTransmission but keep the connection activeWire.requestFrom(MMA8452_ADDRESS, bytesToRead); //Ask for bytes, once done, bus is released by defaultwhile(Wire.available() < bytesToRead); //Hang out until we get the # of bytes we expectfor(int x = 0 ; x < bytesToRead ; x++)
    dest[x] = Wire.read();    
}

// Read a single byte from addressToRead and return it as a bytebyte readRegister(byte addressToRead)
{
  Wire.beginTransmission(MMA8452_ADDRESS);
  Wire.write(addressToRead);
  Wire.endTransmission(false); //endTransmission but keep the connection activeWire.requestFrom(MMA8452_ADDRESS, 1); //Ask for 1 byte, once done, bus is released by defaultwhile(!Wire.available()) ; //Wait for the data to come backreturnWire.read(); //Return this one byte
}

// Writes a single byte (dataToWrite) into addressToWritevoid writeRegister(byte addressToWrite, byte dataToWrite)
{
  Wire.beginTransmission(MMA8452_ADDRESS);
  Wire.write(addressToWrite);
  Wire.write(dataToWrite);
  Wire.endTransmission(); //Stop transmitting
}

Step 1: Put Both Circuits on One Board

Get

Go to sparkfun and get the schematics and board files (I only used the schematic files). They are made with Eagle from Cadsoft -- use that. Also get the sparkfun eagle libraries and design rule checks.

Schematics

Put both boards on one schematic in eagle. If you can import them, you have to watch out for repeated net and part names. I made a mess of this. So next time, add a suffix to all the names in one of the schematics before you combine them. Then use the name function to merge the nets one at a time. Adding suffixes to the part designations (ie U1_A, R2_A) to keep the circuits separate (not really needed).

Connect the circuits in the schematic just like the you did in real life. Put a jucntion (green dot) where wires should be connected.

Run the ERC (error rule check). This will check the schematic for weird stuff (like wires that are not really connected).

Board

Then generate a board drawing from the schematic. Arrange the components so everything fits nicely. Route the wires. Note the axises (axii ?) of the accelerometer.

Run DRC (design rule check) (use sparkfun or osh rules (open->job)).

Fix the errors in this order: hole size, overlap, clearance, everything else. I let vias overlap pads they are connected to, check those carefully then approve. Dont take chances with clearances and hole sizes.

Run DRC again (at this point I go around in circles checking things until I am tired, then I go to sleep and check again when I wake up).

Generate gerber files

Gerber files are what are used to make the boards, they are pretty universal and difficult to edit. Think of them as PDFs.

Open CAMjob, then load sparkfun or osh job file. And generate the gerbers. This makes a whole bunch of files.

Immediately go to your eagle folder and get the gerber files (sort by time modified). Put these in a zip file and upload to OSHPark. It will take a little while, then it will show you a preview and price. If the price is very high and the board looks very small, then the board size is probably way to big. This is usually from a stray something or other in the board files. Go back to the board files. Make sure you have an outline on the MILL or Dimensions layer. Turn on all the layers and zoom out. There should be nothing outside the outline (like the filename or a tiny dot) -- once you find the tiny dot (or the letter á´or whatever) either put it inside the outline or delete it.

Make gerbers and upload and check again.

Order boards:

Boards from OSHPark are a great price, get extras. It will take maybe two weeks to get them in the mail.

Order Components:

Go back to eagle and make a bill of materials (Tools -> bom). Group by part (not by designator). Go to digikey or mouser or sparkfun to get all the parts. Make sure they are the right size (sizes have names like: 0401,0603,TQFP,SOT).

Each piece will be very cheap, but it does add up. For low cost things (Like $0.008 resistors) get 100 for $0.80, or get more, it is easier then having to re-order.

Parts will probably come before the boards, look at all the parts when you get them and think about all the different places they come from, and how the hell you are going to solder them, dont sneeze and keep everything together.