Some of my students had some troubles when using the PmodACL accelerometer sensor with the I2C protocol to communicate with Processing. Basically, from time to time the accelerometer sends some extra information concerning the state of the I2C channel. From the Processing side, we need to clean up and ignore these extra data before parsing the information. Also, from time to time, it seams that not all the values are transmitted by the accelerometer. Here a possible solution.
PmodACL | Arduino |
SCL | A5 |
SDA | A4 |
GND | GND |
VCC | 3.3V |
#include "Wire.h" // I2Cdev and ADXL345 must be installed as libraries, or else the .cpp/.h files // for both classes must be in the include path of your project #include "I2Cdev.h" #include "ADXL345.h" // class default I2C address is 0x53 // specific I2C addresses may be passed as a parameter here // ALT low = 0x53 (default for SparkFun 6DOF board) // ALT high = 0x1D ADXL345 accel; int16_t ax, ay, az; #define LED_PIN 13 // (Arduino is 13, Teensy is 6) bool blinkState = false; void setup() { // join I2C bus (I2Cdev library doesn't do this automatically) Wire.begin(); // initialize serial communication // (38400 chosen because it works as well at 8MHz as it does at 16MHz, but // it's really up to you depending on your project) Serial.begin(9600); // initialize device Serial.println("Initializing I2C devices..."); accel.initialize(); // verify connection Serial.println("Testing device connections..."); Serial.println(accel.testConnection() ? "ADXL345 connection successful" : "ADXL345 connection failed"); // configure LED for output pinMode(LED_PIN, OUTPUT); } void loop() { // read raw accel measurements from device accel.getAcceleration(&ax, &ay, &az); // display tab-separated accel x/y/z values //Serial.print("accel:\t"); Serial.print('#'); Serial.print(ax); Serial.print(':'); Serial.print(ay); Serial.print(':'); Serial.println(az); // blink LED to indicate activity blinkState = !blinkState; digitalWrite(LED_PIN, blinkState); }
import processing.serial.*; Serial myPort; float xmag, ymag, zmag = 0; float newXmag, newYmag, newZmag = 0; float x, y, z = 0; void setup(){ size(400,400,P3D); myPort = new Serial(this, Serial.list()[3], 9600); myPort.bufferUntil('\n'); noStroke(); colorMode(RGB, 1); } void draw() { background(0.5); pushMatrix(); translate(width/2, height/2, 0); float diff = xmag-newXmag; if (abs(diff) > 0.01) { xmag -= diff/4.0; } diff = ymag-newYmag; if (abs(diff) > 0.01) { ymag -= diff/4.0; } diff = zmag-newZmag; if (abs(diff) > 0.01) { zmag -= diff/4.0; } rotateX(-ymag); rotateY(-xmag); rotateZ(-zmag); scale(90); beginShape(QUADS); fill(0, 1, 1); vertex(-1, 1, 1); fill(1, 1, 1); vertex( 1, 1, 1); fill(1, 0, 1); vertex( 1, -1, 1); fill(0, 0, 1); vertex(-1, -1, 1); fill(1, 1, 1); vertex( 1, 1, 1); fill(1, 1, 0); vertex( 1, 1, -1); fill(1, 0, 0); vertex( 1, -1, -1); fill(1, 0, 1); vertex( 1, -1, 1); fill(1, 1, 0); vertex( 1, 1, -1); fill(0, 1, 0); vertex(-1, 1, -1); fill(0, 0, 0); vertex(-1, -1, -1); fill(1, 0, 0); vertex( 1, -1, -1); fill(0, 1, 0); vertex(-1, 1, -1); fill(0, 1, 1); vertex(-1, 1, 1); fill(0, 0, 1); vertex(-1, -1, 1); fill(0, 0, 0); vertex(-1, -1, -1); fill(0, 1, 0); vertex(-1, 1, -1); fill(1, 1, 0); vertex( 1, 1, -1); fill(1, 1, 1); vertex( 1, 1, 1); fill(0, 1, 1); vertex(-1, 1, 1); fill(0, 0, 0); vertex(-1, -1, -1); fill(1, 0, 0); vertex( 1, -1, -1); fill(1, 0, 1); vertex( 1, -1, 1); fill(0, 0, 1); vertex(-1, -1, 1); endShape(); popMatrix(); } void serialEvent (Serial myPort) { // get the ASCII string: String inString = myPort.readStringUntil('\n'); float rate = 0.01; if (inString != null) { println(inString); String temp[] = split(inString,":"); //check if the string starts with # and there are at least 3 values if(inString.charAt(0) == '#' && temp.length==3){ println("OK"); x = float(temp[0]); y = float(temp[1]); z = float(temp[2]); newXmag = x/float(width) * TWO_PI; newYmag = y/float(height) * TWO_PI; newZmag = z/float(width) * TWO_PI; rotateX(newXmag); rotateY(newYmag); rotateY(newZmag); } } }