After much struggle, I have come up with a working java file for use with the ADXL345. I'm posting here in hope someone may find it helpful. It does not adress board connections or i2c setup, but those topics seem well covered on the web. Please comment, criticize constructivley.
It uses Maven - I haven't shared a POM, but can if anyone is interested. I highly recommend installing Frank Delporte's template from git hub.
Google Frank delporte github Pi4J. Without it I would have not gotten this to work in Java.
It uses Maven - I haven't shared a POM, but can if anyone is interested. I highly recommend installing Frank Delporte's template from git hub.
Google Frank delporte github Pi4J. Without it I would have not gotten this to work in Java.
Code:
// This java file can be used to collect data from an ADXL345 accelerometer on Rapberry Pi// not discussed here - connecting device to Pi, setting up i2c connection// Recommend installing Frank Delporte's Pi4J template - this java file was used with it// see Frank DelPorte git hub to dload a template for creating a pi4j application - follow his instructions// google 'adxl345 data sheet', and study the adxl345 data sheet // code below sets values in three key registers of the adxl345 device: 0x2C, 0x2D, 0x31 to set up the device// Writing to Register 0x31 sets format of data coming from the accelerometer// - bits D3,D1, and D0 are used to set the format - D3 sets resolution 1000 = high res, 0000 = low res// - bits D1 and D0 set max g value: 00= +/- 2g, 01= +/- 4g, 10 = +/- 8g, 11 = +/- 16 g// - ex: 1011 = decimal 11 (8+0+2+1)= hex 0x0B is high resolution and +/- 16g - used in code below (write to register 0x31)// - in hi res, values received are 13 bit. in low res: 10bit for 2g, 11bit for 4g, 12bit for 8g, 13 bit for 16g// code below reads values from 0x32-0x37 to collect acceleration data for three axes// the data comes in 6 bytes, 2 bytes for each axis, the two bytes for each axis must be combined to get accel value for that axis// ---- data manipulation:// values are received as as 16 bit (two bytes) "twos complement" for each axis// twos complement breaks the measured value into two parts. one byte for the leftmost 8 bits, one byte for the right 8 bits // the more significant byte must moved to the left by 8 bits, then added to the less signif byte to reconstruct the measured value// this can be done with a bit shift <<8 (move the byte left 8 bits into the position of higher values) or by multiplying it by 256// &0x1F in code below is a 'bitwise AND' that will cause only 5 right bits of this byte to be used (0x1f=00011111) -google 'bitwise AND'// &0x1F keeps only 5 rightmost bits- appropriate for this example using a 13 bit value (full res, 16g). use different & 0xXX for different bit length// ---- dealing with signed values:// Since this a 13 bit value, max positive value is 0111111111111=4095. (13th bit is reserved, if 1 it would say value is negative)// The 13th bit = 4096, if total value is above 4095, the value needs to be processed as a negative number// If statement determines whether the data value implies a 1 in the 13th bit, if true converts it to a negative value// 4095 and 8192 below are appropriate for a 13 bit value (12, 11, 10 bit values need diff numbers here)// - bit size of received data determines proper AND mask, and negative value check// - 10 bit &03 with if >511, accel-=1024; 11 bit &07 with if >1023, accel-=2048; 12bit &0F with if >2047, accel-=4096 // ---- Printing results to file// this java file will print the results to a csv file if not desired delete or comment out where shown
Code:
import com.pi4j.Pi4J;import com.pi4j.context.Context;import com.pi4j.io.i2c.I2C;import com.pi4j.io.i2c.I2CConfig;import com.pi4j.io.i2c.I2CProvider;import java.io.File;import java.io.FileWriter;import java.util.Calendar; import java.text.SimpleDateFormat ;public class Ocala{ public static void main(String args[]) throws Exception{ boolean firstPass = true ;SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yy hh:mm:ss") ; int busid = 1 ; int i2cAddress = 0x53 ; // address for adxl345 Context pi4j = Pi4J.newAutoContext(); I2CProvider i2cProvider = pi4j.provider("linuxfs-i2c"); I2CConfig i2CConfig = com.pi4j.io.i2c.I2C.newConfigBuilder(pi4j).id(busid+": device "+i2cAddress).bus(busid).device(i2cAddress).build(); try { I2C device = i2cProvider.create(i2CConfig); device.writeRegister(0x2C, (byte)0x0A); // 0x2C is register address for data rate 0x0A is default 100 Hz device.writeRegister(0x2D, (byte)0x08); // 0x2D is register address for power control, bit D3 = value of 8 = 'turn on measurement' device.writeRegister(0x31, (byte)0x0B); // 0x31 is register address for data format, here full res 16g - see header while (true) {//---- following write to file - don't remove sleep File fil = new File("javadata.csv") ; FileWriter filWrit = new FileWriter(fil, true) ; if (firstPass){ String printString = "---------- New Java Run ----------\n" ; filWrit.append(printString); firstPass = false ; } // if firstpass Thread.sleep(250); //---- ADXL345 datasheet recomends reading all 6 bytes at same time for data consistency byte[] data = new byte[6]; data[0] = (byte)device.readRegister(0x32); data[1] = (byte)device.readRegister(0x33); data[2] = (byte)device.readRegister(0x34); data[3] = (byte)device.readRegister(0x35); data[4] = (byte)device.readRegister(0x36); data[5] = (byte)device.readRegister(0x37); //---- special processing of the values received from the adxl345 is required before they can be used - see notes in header int xAccl = ((data[1] & 0x1F) * 256 + (data[0])); if(xAccl > 4095){ xAccl -= 8192; } //if xaccl int yAccl = ((data[3] & 0x1F) * 256 + (data[2])); if(yAccl > 4095){ yAccl -= 8192; } //if yaccl int zAccl = ((data[5] & 0x1F) * 256 + (data[4])); if(zAccl > 4095){ zAccl -= 8192; } //if zaccl System.out.printf("X: %d Y: %d Z: %d %n ", xAccl, yAccl, zAccl);//---- following statements write to file - don't remove closing brace Calendar cal = Calendar.getInstance() ; filWrit.append(sdf.format(cal.getTime())) ; filWrit.append(", "); filWrit.append(String.valueOf(xAccl)); filWrit.append(", "); filWrit.append(String.valueOf(yAccl)); filWrit.append(", " ); filWrit.append(String.valueOf(zAccl)); filWrit.append("\r\n"); filWrit.flush() ; filWrit.close() ; } // while }catch(Exception e){ System.out.printf("some stupid error by jd"); } // catch } // main} // class
Statistics: Posted by JMDFlorida — Sat Aug 03, 2024 10:26 pm