Commit 555095fd authored by Sam Calisch's avatar Sam Calisch

added embedded firmware

parent 9e4df6a6
//adxl registers
const byte adxl_partid = 0x02;
const byte adxl_status = 0x04;
const byte adxl_status2 = 0x05;
const byte adxl_activity_status = 0x05;
const byte adxl_x_data = 0x08;
const byte adxl_y_data = 0x0A;
const byte adxl_z_data = 0x0C;
const byte adxl_offset_x = 0x20;
const byte adxl_offset_y = 0x21;
const byte adxl_offset_z = 0x22;
const byte adxl_act_x_l = 0x24;
const byte adxl_act_z_h = 0x27;
const byte adxl_act_z_l = 0x28;
const byte adxl_time_act = 0x29;
const byte adxl_hpf = 0x38;
const byte adxl_int1_map = 0x3B;
const byte adxl_int2_map = 0x3C;
const byte adxl_timing = 0x3D;
const byte adxl_measure = 0x3E;
const byte adxl_power_ctl = 0x3F;
const byte adxl_self_test = 0x40;
byte readbyte(byte address) {
byte result;
digitalWrite(SS_ADXL, LOW);
SPI.transfer( (address << 1) | 0b000000001 );
result = SPI.transfer(0x00);
digitalWrite(SS_ADXL, HIGH);
return (result);
}
void writebyte(byte address, byte value) {
digitalWrite(SS_ADXL, LOW);
SPI.transfer( (address << 1) & 0b11111110 );
SPI.transfer(value);
digitalWrite(SS_ADXL, HIGH);
}
bool init_adxl372(){
//ADXL372
// turn on full bandwidth measurement mode
writebyte(adxl_power_ctl, 0b00000011);
// enable low noise mode, 3200Hz output signal bandwidth
writebyte(adxl_measure, 0b00001100);
// configure ODR = 6400 Hz
writebyte(adxl_timing, 0b10000000);
// configure corner frequency 0 (30Hz at 6400Hz ODR)
writebyte(adxl_hpf, 0b00000000);
// set z trim
writebyte( adxl_offset_z, 0b00000110 );
delay(100); //start up
writebyte(adxl_self_test, 0b00000001); //assert self test
delay(300); //delay 300ms
byte st = readbyte(adxl_self_test); //read self test status bits
if ((st & 0b00000010) && (st & 0b00000100 )){
Serial.println("Self test passed!");
} else {
Serial.print(st);
Serial.println(", Self test failed!");
return 0;
}
writebyte(adxl_self_test, 0b00000000); //clear self test
// keep on full bandwidth measurement mode
// disable lpf and hpf
writebyte(adxl_power_ctl, 0b00001111);
//configure motion warning on z axis
writebyte(adxl_act_x_l, 0b00000010); //set referenced activity processing mode
writebyte(adxl_act_z_h, 0b00000011); //set msb of threshold
writebyte(adxl_act_z_l, 0b11100001); //enable z axis contribution to motion and set lsb of threshold
writebyte(adxl_time_act, 0b00000010); //set activity time counter threshold
writebyte(adxl_int1_map, 0b00100000 ); //map motion warning to int1 pin
//configure data ready on int2 pin
writebyte(adxl_int2_map, 0b00000001);
// give the sensor time to set up:
delay(100);
return 1;
}
void shutdown_adxl372(){
writebyte(adxl_power_ctl, 0b00000000);
}
#include <SPI.h>
#include <SD.h>
#define SS_ADXL 6 //slave select for adxl372
#define SPI_SPEED 10000000 //10MHz top speed for SCLK
#define debug 0 //if serial connection for debug
#include "adxl372.h"
#define adxl_int1_pin 19
#define adxl_int2_pin 15
#define samples_after_trigger 4000
#define samples_total 6000
#define frequency_debug_pin 11
#define VBATPIN A7
File logfile; //define a log file
#define cardSelect 4 //slave select for micro sd card
#include "sd_utils.h"
#define LED_RED 13
#define LED_GRN 8
int16_t z_accel[samples_total];
int8_t dt[samples_total];
uint32_t this_time, last_time;
uint32_t pointer = 0;
uint32_t data_start = 0;
void setup() {
if(debug){
Serial.begin(115200);
while (!Serial) {} //wait for serial connection
Serial.println("\r\nADXL372 logger");
}
pinMode(SS_ADXL, OUTPUT);
digitalWrite(SS_ADXL, HIGH); //unselect adxl, must do before talking to sd card
pinMode(adxl_int1_pin, INPUT); //impact detection
pinMode(adxl_int2_pin, INPUT); //data ready
pinMode(LED_RED,OUTPUT); pinMode(LED_GRN,OUTPUT);
digitalWrite(LED_RED,LOW); digitalWrite(LED_GRN,LOW);
SPI.begin(); //this gives about 100kHz sampling rate on z data.
//I couldn't get this to take my user defined clock speed for some reason...
if (!init_sd_card()){
while(1){
delay(100); digitalWrite(LED_GRN,LOW);
delay(100); digitalWrite(LED_GRN,HIGH);
}
}
if (!init_adxl372()){
while(1){
delay(100); digitalWrite(LED_RED,LOW);
delay(100); digitalWrite(LED_RED,HIGH);
}
}
//if debug, simply report values
if (debug){
while(1){
float average = 0;
for(int i=0; i<samples_total; ++i){
read_z_accel();
average += z_accel[pointer];
}
Serial.print("ADXL LSB: "); Serial.println( average/samples_total/16. );
Serial.print("g value: "); Serial.println( (200./4096)*average/samples_total/16. );
delay(10);
}
}
//else
//wake up in "armed" mode: writing into cyclic buffer as fast a possible.
//when trigger, continue writing for samples_after_trigger.
//when done, turn on green led, create file on SD card, and write out.
//then turn off adxl and wait.
digitalWrite(LED_RED,HIGH);
unsigned long last_read_time = 0;
readbyte(adxl_status2); //reset activity interrupt by reading status2
while(1){
read_z_accel();
//if impact detection, break out of loop.
if ( digitalRead( adxl_int1_pin ) ) {
data_start = pointer; //keep track of data starting point.
break;
}
}
for(int i=0; i<samples_after_trigger; i++){
read_z_accel();
}
shutdown_adxl372();
digitalWrite(LED_RED,LOW);
if (debug) Serial.println("Triggered");
int ind=0;
logfile.print("data_start,"); logfile.println(data_start);
logfile.print("battery_voltage,"); logfile.println( 2*(3.3/1024)*analogRead(VBATPIN) );
for(int i=0; i<samples_total; i++){
digitalWrite(LED_GRN,HIGH);
//start with oldest sample
ind = (i+data_start+samples_after_trigger+1)%samples_total;
logfile.print(dt[ind]);
//logfile.print(times[ind]-times[data_start]);
logfile.print(",");
logfile.println(z_accel[ind]);
if (i%100==0) logfile.flush();
digitalWrite(LED_GRN,LOW);
delay(1);
}
logfile.flush();
if (debug) Serial.println("Done Writing");
//Serial.println( ((float)z_accel[pointer])/40 );
}
void loop() {}
void read_z_accel() {
while(!digitalRead(adxl_int2_pin) ){} //wait for data ready
//digitalWrite( frequency_debug_pin, !digitalRead(frequency_debug_pin));
pointer = (pointer + 1)%samples_total;
digitalWrite(SS_ADXL, LOW);
SPI.transfer( (adxl_z_data << 1) | 0b000000001 );
z_accel[pointer] = ((SPI.transfer(0x00) << 8) | SPI.transfer(0x00));// >> 4;
this_time = micros();
dt[pointer] = this_time-last_time;
last_time = this_time;
digitalWrite(SS_ADXL, HIGH);
}
bool init_sd_card(){
// see if the card is present and can be initialized:
if (!SD.begin(cardSelect)) {
if (debug) Serial.println("Card init. failed!");
return 0;
}
char filename[15];
strcpy(filename, "ADXL00.TXT");
for (uint8_t i = 0; i < 100; i++) {
filename[4] = '0' + i/10;
filename[5] = '0' + i%10;
// create if does not exist, do not open existing, write, sync after write
if (! SD.exists(filename)) {
break;
}
}
logfile = SD.open(filename, FILE_WRITE);
if( ! logfile ) {
if (debug) {
Serial.print("Couldnt create ");
Serial.println(filename);
return 0;
}
}
if (debug) Serial.print("Writing to ");
if (debug) Serial.println(filename);
return 1;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment