3-Axis Accelerometer and Processing _ Robot is Happy

Embed Size (px)

DESCRIPTION

3-Axis Accelerometer and Processing _ Robot is Happy

Citation preview

  • 3/27/2014 3-Axis Accelerometer and Processing | Robot is Happy

    https://web.archive.org/web/20120418104603/http://www.robotishappy.com/2010/08/part-1-visualizing-3-axis-accelerometer-readings-in-processing 1/4

    Part 1) Visualizing 3-Axis Accelerometer Readings in Processingby Christopher Hazlett

    It's been a while since I've had the chance to do anything vaguely electronic. Sure, I've painted rooms in my house,installed ceiling fans, added insulation to my attic, but that's a far cry from programming in Wiring or Processing. So,thankfully, after getting my new workspace all put together, I got the chance to play with some of the parts I've had waitingin a few SparkFun boxes.

    So I started playing around with a 3-Axis Accelerometer in the hopes of dreaming up some project or other. So I hooked itup to my Arduino and my Arduino to my computer and wrote a little Processing code to graph it all into pretty colors. Aswith all of my projects, the first step for me is understanding and since I didn't have much experience with Accelerometersa little crash course was in order. As it turns out, it's a fairly simple sensor to use (or collection of 3 sensors: x, y, z, Ishould say). Simply plug the VCC connector into the Arduino 3V pin (not the 5V pin. The ADXL3305 chip is only rated to3.3V), the ground into ground and the x, y, and z pins into 0,1,2 analog pins. The code for the Arduino is simple:

    The Arduino Code

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    #define X_AXIS 0

    #define Y_AXIS 1

    #define Z_AXIS 2

    void setup() {

    Serial.begin(9600);

    }

    void loop() {

    int x = analogRead(X_AXIS);

    int y = analogRead(Y_AXIS);

    int z = analogRead(Z_AXIS);

    Serial.print(x);

    Serial.print('|');

    Serial.print(y);

    Serial.print(':');

    Serial.println(z);

    }

    It takes the readings in and outputs them into a formatted string '[x]|[y]:[z]'. That's it. This is just for outputting data rightnow, so nothing special. It gets more interesting when we look at the processing.

    The Processing Code in Action

    The code that makes the sweet, sweet video above isn't necessarily complicated, but there may be a few things you haven't

    Post Categories

    Arduino

    Beacon Locating Robot

    Light-Seeking Robot

    Message Queue Monitor

    News

    Other People's Robots

    Processing

    Projects

    Radio Control

    Stuff I'm Researching

    Uncategorized

    Recent Machines

    Robotic Curtain Not necessarily

    effective, but definitely awesome.

    Sign Language Translator

    Evil Mad Scientist Disects the

    Venerable Nixie Tube

    Arduino Something New!!

    Evil Mad Scientists Release Egg-Bot Kit

    Blogroll

    Adafruit

    Electrical What Schematic Symbols

    Evil Mad Scientist

    Flight 404

    Hack A Day

    Make

    NYC Resistor

    Parallax

    Pololu

    Sparkfun

    Tags

    Accelerometer Arduinoethernet shield Infrared international

    robot expo irex japan japanesegirls library message queue NewsPhysical Computing pick and place POV

    Processing service robotshield tokyo toy Tutorial videoWorkbench

    ROBOT IS HAPPYCREATING OUR ROBOT OVERLORDS ONE DAY AT A TIME Subscribe via RSS

    OTHER PEOPLE'S ROBOTS PROCESSING PROJECTS STUFF I'M RESEARCHING

    AUG/10

    http://w w w .robotishappy.com/2010/08/part-1-visualizing-3-axis-accelerometer-readings-in-processingGo FEB APR DEC

    182011 2012 2013

    13 captures

    24 Nov 10 - 20 Dec 12

    Close

    Help

  • 3/27/2014 3-Axis Accelerometer and Processing | Robot is Happy

    https://web.archive.org/web/20120418104603/http://www.robotishappy.com/2010/08/part-1-visualizing-3-axis-accelerometer-readings-in-processing 2/4

    The code that makes the sweet, sweet video above isn't necessarily complicated, but there may be a few things you haven'tused in Processing before.

    map(value, low1, high1, low2, high2) - converts a value from one range into a corresponding value into another

    range.

    norm(value, low, high) - converts a value into a value from 0.0 to 1.0 based on the supplied range.

    pushMatrix() / popMatrix() - the pushMatrix() and popMatrix() methods allow you to apply rotation, translation, and

    other methods to a specific style. By issuing the pushMatrix() then calling the translate(), and rotateX, rotateY

    methods, you can then call popMatrix so those methods don't affect other elements being rendered by Processing.

    The Processing Code

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61

    62

    63

    64

    65

    66

    67

    68

    69

    70

    71

    72

    73

    74

    75

    76

    77

    78

    79

    import processing.serial.*;

    import processing.opengl.*;

    Serial myPort;

    int baudRate = 9600;

    int lf = 10;

    PFont font;

    int[] xAxis;

    int[] yAxis;

    int[] zAxis;

    int currentX = 0;

    int currentY = 0;

    int currentZ = 0;

    //these value were determined by taking readings from a resting position

    int oneGSensorValue = 400;

    float oneGMillivolt = oneGSensorValue * 4.9;

    int totalReadings = 400;

    int readingPos = 0; // the reading position in the array

    void setup(){

    smooth();

    size(600, 300, OPENGL);

    font = createFont(PFont.list()[270], 24);

    smallFont();

    xAxis = new int[totalReadings];

    yAxis = new int[totalReadings];

    zAxis = new int[totalReadings];

    for (int i=0; i < totalReadings; i++){

    xAxis[i] = oneGSensorValue;

    yAxis[i] = oneGSensorValue;

    zAxis[i] = oneGSensorValue;

    }

    myPort = new Serial(this, Serial.list()[0], baudRate);

    myPort.bufferUntil(lf);

    noLoop();

    }

    void serialEvent(Serial p){

    String inString;

    try{

    inString = (myPort.readString());

    currentX = xValue(inString);

    currentY = yValue(inString);

    currentZ = zValue(inString);

    xAxis = insertValueIntoArray(xAxis, currentX, readingPos, totalReadings);

    yAxis = insertValueIntoArray(yAxis, currentY, readingPos, totalReadings);

    zAxis = insertValueIntoArray(zAxis, currentZ, readingPos, totalReadings);

    readingPos = readingPos + 1; // increment the array position

    }catch(Exception e){

    println(e);

    }

    redraw();

    }

    void draw()

    {

    background(#FEFFFC);

    drawGraph(xAxis, 100, color(#519050), "X - Axis");

    drawGraph(yAxis, 200, color(#708CDE), "Y - Axis");

    drawGraph(zAxis, 300, color(#D38031), "Z - Axis");

    draw3d(currentX, currentY, currentZ);

    }

    void drawGraph(int[] arrToDraw, int yPos, color graphColor, String name){

    int arrLength = arrToDraw.length;

    stroke(graphColor);

    for (int x=0; x

  • 3/27/2014 3-Axis Accelerometer and Processing | Robot is Happy

    https://web.archive.org/web/20120418104603/http://www.robotishappy.com/2010/08/part-1-visualizing-3-axis-accelerometer-readings-in-processing 3/4

    79

    80

    81

    82

    83

    84

    85

    86

    87

    88

    89

    90

    91

    92

    93

    94

    95

    96

    97

    98

    99

    100

    101

    102

    103

    104

    105

    106

    107

    108

    109

    110

    111

    112

    113

    114

    115

    116

    117

    118

    119

    120

    121

    122

    123

    124

    125

    126

    127

    128

    129

    130

    131

    132

    133

    134

    135

    136

    137

    138

    139

    140

    141

    142

    143

    144

    145

    146

    147

    148

    149

    150

    151

    152

    153

    154

    155

    156

    157

    158

    159

    160

    161

    162

    163

    164

    165

    166

    167

    }

    pushStyle();

    smallFont();

    stroke(#FFFFFF);

    fill(#FFFFFF);

    String gString = nfc(gFromSensorValue(arrToDraw[arrLength - 2]), 2);

    text(name + " : " + gString + " Gs", 10, yPos - 10);

    popStyle();

    }

    void draw3d(int currentX, int currentY, int currentZ){

    float normalizedX = norm(currentX, 0.0, 700.0);

    float normalizedY = norm(currentY, 0.0, 700.0);

    float normalizedZ = norm(currentZ, 0.0, 700.0);

    float finalZ = map(normalizedZ, 0.0, 1.0, 300.00, 0.0);

    float finalY = map(normalizedY, 0.0, 1.0, -3.5, 3.5);

    float finalX = map(normalizedX, 0.0, 1.0, -3.5, 3.5);

    pushMatrix();

    ambientLight(102, 102, 102);

    lightSpecular(204, 204, 204);

    directionalLight(102, 102, 102, -1, -1, -1);

    shininess(1.0);

    translate(500, finalZ);

    rotateY(finalY + 1.0);

    rotateZ(finalX);

    fill(#E2E8D5);

    noStroke();

    fill(#B76F6F);

    float heightWidth = finalX * 1.8;

    box(65, 65, 50);

    popMatrix();

    }

    int xValue(String inString){

    int pipeIndex = inString.indexOf('|');

    return int(inString.substring(0,pipeIndex));

    }

    int yValue(String inString){

    int pipeIndex = inString.indexOf('|');

    int colonIndex = inString.indexOf(':');

    return int(inString.substring(pipeIndex+1, colonIndex));

    }

    int zValue(String inString){

    int colonIndex = inString.indexOf(':');

    return int(inString.substring(colonIndex + 1, inString.length() - 2));

    }

    /*

    This little method creates a running tally of all the incoming sensor readings

    and then, when it reaches the end of the array, it pops the first one of the beginning

    and inserts a new value in at the end...thus keeping a running tally of the last 400

    readings (it can be for any length array, that's just what it's set to for this project).

    This works a lot like an RRD graph where my inspiration came from.

    */

    int[] insertValueIntoArray(int[] targetArray, int val, int pos, int maxLength){

    if(pos > (maxLength-1)){

    // if the pos == maxSize, shift the array to retain the original value

    int[] returnArray = subset(targetArray, 1, maxLength-1);

    returnArray = expand(returnArray, maxLength);

    returnArray[maxLength-2] = val;

    return returnArray;

    }else{

    targetArray[pos] = val;

    return targetArray;

    }

    }

    /*

    This conversion will vary from project to project

    and if you're project is relying on battery power

    the reading may need to be adjusted to give you true

    one G as your battery power decreases. All of this is due to

    the output of the X,Y, and Z sensors and their coorelation to the incoming voltage at VCC

    Check out the specs for the ADXL335 (part of the break out board from Sparkfun.com) here:

    http://www.analog.com/en/sensors/inertial-sensors/adxl335/products/product.html

    */

    float gFromSensorValue(int sensorValue){

    //convert analog value into millivolts

    float mvValue = sensorValue * 4.9;

    return mvValue/oneGMillivolt;

    }

    void smallFont(){ textFont(font, 24); }

    void mediumFont(){ textFont(font, 30); }

    void largeFont(){ textFont(font, 40); }

    This is just the first step of a larger project to create a DIY radio control using an xBee and this 3-axis accelerometer.

  • 3/27/2014 3-Axis Accelerometer and Processing | Robot is Happy

    https://web.archive.org/web/20120418104603/http://www.robotishappy.com/2010/08/part-1-visualizing-3-axis-accelerometer-readings-in-processing 4/4

    About Christopher HazlettChris has been programming for almost a decade, and thinks programming is even more fun whenit makes a robot do stuff...even if that stuff is just a bunch of blinking lights. Chris's GIT repos:http://github.com/chazlett.

    Tagged as: Accelerometer, Arduino, Processing Leave a comment

    RichardFebruary 11th, 2011 - 14:02

    Thanks for the code and video got it working!Cheers!

    DanOctober 17th, 2011 - 12:46

    Hmm cant seem to get the code to work.Is the code specific for running on a MAC or will it work for Windows XP as well?

    DanOctober 19th, 2011 - 12:09

    Got it working! I finally realized I need to tell it what COM port to use inside the [].Anyway thanks for the code. This is a great learning resource!

    Stuff Im Researching for a Project Finally, Back to Work

    This is just the first step of a larger project to create a DIY radio control using an xBee and this 3-axis accelerometer.

    Happy Coding.- Chris

    TweetShare

    Leave a comment

    Name (required)

    Mail (will not be published) (required)

    Website

    Submit

    Powered by WP Hashcash

    Copyright 2012 Robot is Happy Powered by WordPress

    Lightword Theme by Andrei Luca

    Podcast powered by podPress (v8.8 / v8.8.5.3)

    Enjoy this article?Consider subscribing to our rss feed!

    Comments (3) Trackbacks (0) ( subscribe to comments on this post )

    Go to top