Konstantin Dorohov
Published © GPL3+

Pistol Slide Acceleration Measurements

Not just 'bang!' - a lot of things happens.

IntermediateShowcase (no instructions)407
Pistol Slide Acceleration Measurements

Things used in this project

Hardware components

Arduino Mega 2560 & Genuino Mega 2560
Arduino Mega 2560 & Genuino Mega 2560
×1
Adafruit data logger
×1
Quadram 512 Kb Memory Shield
×1
SparkFun Serial Enabled 16x2 LCD (retired)
×1
SparkFun Single Axis Accelerometer Breakout - ADXL193
×1
SparkFun Arduino Project Enclosure
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

Block Diagram

Code

Arduino code

Arduino
All this is quite lame, but has a single advantage: it works and satisfied my needs.
//work with adafruit SD card
//prints file write bar on LCD
//works with ADXL193 on 3 pin
//improved LCD information
#define DEBUG 0
#define D_RTC 1

//http://arduino.cc/forum/index.php/topic,6549.0.html
#define FASTADC 1 //25965.5/sec
//from http://www.atmel.com/Images/doc2503.pdf
//Table 85. ADC Prescaler Selections
//ADPS2 ADPS1 ADPS0 Division Factor
//0     0     0     2
//0     0     1     2
//0     1     0     4
//0     1     1     8
//1     0     0     16
//1     0     1     32
//1     1     0     64
//1     1     1     128

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

//#include <Wire.h>  //seems like we don't need it?
#include <SD.h>
#include <I2cMaster.h>
//for MEGA
#define SDA_PIN 58
#define SCL_PIN 59

// ?
SoftI2cMaster i2c(SDA_PIN, SCL_PIN);
#if D_RTC
#include <SoftRTClib.h>
RTC_DS1307 RTC(&i2c);
#endif
                             // we use digital pin 10 for the SD cs line
const int chipSelect=10;                               
// the logging file
File f_file;
int n_filenum;
String s_filenum=String();
String filename=String()="ARDDUMMY.LOG";
char c = 0;  // placeholder for bits read from file
char s_filelist[]="FILELIST.TXT";
char buf[6];
char ch_filename[13];

//#include <xmem.h>  //use or remove!
//button handling
#define STATE_ON  0
#define STATE_CREATE_FILE   1
#define STATE_OFF 2
byte state = STATE_OFF;
boolean btnReleased=false;
boolean dataSent=false;
int CounterLimit=100;//debouncing wait time
int loopCounter = 0;
int16_t x,y,z,total;
int16_t *ptr;  //  unsigned int
unsigned long n_points, read_points ,start_time, end_time, bar;
boolean ram_full=false;
const int redLEDpin= 2;
const int greenLEDpin=3;
const int acc_pin= 3;  //analog! cannot be pin 5 - is used by SD shield for I2C
const int buttonPin = 5;     //extra button
#define mem_blocks 7
byte b_block_counter=0;
void setup()
{
  pinMode(greenLEDpin, OUTPUT);  
  pinMode(redLEDpin, OUTPUT);  
  pinMode(10,OUTPUT);  
  pinMode(buttonPin, INPUT); 
  state=STATE_OFF;
  digitalWrite(greenLEDpin, LOW);    
  digitalWrite(redLEDpin, LOW);      

  // set prescale to 16
#if FASTADC
  // set prescale to 16
  sbi(ADCSRA,ADPS2) ;
  cbi(ADCSRA,ADPS1) ;
  cbi(ADCSRA,ADPS0) ;  //ADC clock pre-scale 16 25965.5/sec
//  sbi(ADCSRA,ADPS0) ;  //pre-scale 32 18990/sec
#endif


//  xmem::begin(true);
//  xmem:setMemoryBank(1,true);
  XMCRA = _BV(SRE); // Enable external memory interface
  pinMode(38, OUTPUT); digitalWrite(38, LOW); // Enable RAM device
  pinMode(42, OUTPUT); digitalWrite(42, LOW); // Make the bank selection bits 
  pinMode(43, OUTPUT); digitalWrite(43, LOW); 
  pinMode(44, OUTPUT); digitalWrite(44, LOW); 
  setBank(b_block_counter);
  
  Serial1.begin(9600);
  backlightOn();
  clearLCD();

#if D_RTC
  DateTime now = RTC.now();  
  SdFile::dateTimeCallback(dateTime); 
#endif  
  if (!SD.begin(chipSelect)) 
  {
//   blink(redLEDpin,5,300);
   Serial1.print("No SD card  ");
   selectLineTwo();
   Serial1.print("Stopped");
   
   while(1);
  }
  

   Serial.begin(115200);

#if DEBUG     
   Serial.println("card initialized.");
   Serial.print(now.hour(), DEC);
   Serial.print(':');
   Serial.print(now.minute(), DEC);
   Serial.print(':');
   Serial.print(now.second(), DEC);
   Serial.println();  
#endif    
  // create a new file storing current file number
   clearLCD();
   delay(500);
   if (!SD.exists(s_filelist)) 
   {
     
     Serial1.print("New Control file...");
  //   blink(redLEDpin,2,200);
     f_file = SD.open(s_filelist, FILE_WRITE);
     f_file.print("0");
     f_file.close();
    }  
   Serial1.print("Ready        ");
 //  blink(greenLEDpin,3,300); 

}

void loop()
{
  check_button(); 
  if (state==STATE_ON)
  {
    if (ptr!=0) 
    {
      x=analogRead(acc_pin);
     *ptr=x;
      ptr++;
      n_points++;      
    }
   else if (b_block_counter<mem_blocks)  //switch memory block
   {b_block_counter++;    
    setBank(b_block_counter);
    ptr=(int16_t *)0x2200U;
   }
   else
   {
     digitalWrite(greenLEDpin, LOW);
     end_time=millis(); 
     ram_full=true;
//     clearLCD();
     selectLineOne();
     Serial1.print("RAM full        ");
   } 
  }
 else 
 if (dataSent==false)
     while ((read_points<n_points)&&(dataSent==false))
     {
       if (ptr!=0)     //read from RAM  write to SD
       {
        x=*ptr;
#if DEBUG        
        Serial.print("D!");
        Serial.println(x); 
#endif    
        if ((read_points+1)%bar==0)
        Serial1.write(0xFF);
    
        f_file.println(x);
        ptr++;
        read_points++;
        if (read_points==n_points)
        {
          dataSent=true;
          blink(redLEDpin,2,200);
          digitalWrite(redLEDpin, LOW);
          f_file.close();        
          selectLineTwo();        
          Serial1.print("Completed       ");          
        }
       }
       else if (b_block_counter<mem_blocks)  //switch memory block
       {
        b_block_counter++;    
        setBank(b_block_counter);
        ptr=(int16_t *)0x2200U;
        }
        else
        {
         dataSent=true;
         f_file.close();
         digitalWrite(redLEDpin, LOW); 
         selectLineTwo();        
         Serial1.print("Completed       ");          
        } 
     }  //end while  
}  

// Write lower 3 bits of bank to upper 3 bits of Port L

void setBank(uint8_t bank)
{
  PORTL = (PORTL & 0x1F) | ((bank & 0x7) << 5);
}


void check_button(){
 //turn off
 if (btnReleased==true && digitalRead(buttonPin)==HIGH)
 { 
   if (state==STATE_ON) 
   {  if (ram_full==false)
      end_time=millis();
      state=STATE_OFF;
      digitalWrite(greenLEDpin, LOW);
      digitalWrite(redLEDpin, HIGH);  
      ptr = (int16_t *)0x2200U; 
      b_block_counter=0; 
      setBank(b_block_counter); 
      read_points=0;
      createDataFile();
      bar=floor(n_points/16);  //for  bar printing
      clearLCD();
      selectLineOne();
      Serial1.print(ch_filename);
      selectLineTwo();      
      f_file.print("# Number of points: "); f_file.println(n_points);
      f_file.print("# Start_time: ");f_file.print(start_time);f_file.print("; End time: ");
      f_file.println(end_time);  
   }
 //turn on
   else 
   {
      clearLCD();
      selectLineOne();
      Serial1.print("Reading sensor..");
      state=STATE_ON;
      ram_full=false;
      digitalWrite(greenLEDpin, HIGH);
      digitalWrite(redLEDpin, LOW);    
      ptr = (int16_t *)0x2200U;
      b_block_counter=0;   
      dataSent=false;
      start_time=millis();
      n_points=0;
      x=0;
      setBank(b_block_counter);      
     }        
   btnReleased=false; 
 }  //remove contact bounce
 else if (btnReleased==false && digitalRead(buttonPin)==HIGH) 
 {
  loopCounter=0;}
 else if (btnReleased==false &&digitalRead(buttonPin)==LOW)
 {
   if (loopCounter<CounterLimit) loopCounter++;
   else {btnReleased=true; loopCounter=0;}
 }  
} 


void createDataFile() {
  s_filenum="";
#if D_RTC  
  SdFile::dateTimeCallback(dateTime);
#endif  
  //read current file number
  f_file=SD.open(s_filelist);
   while (f_file.available()) {
      c=f_file.read(); 
      s_filenum+=c;
   }
   f_file.close();
   s_filenum+=0; //must be '0' terminated for proper work of atoi

//increment current file number   
   s_filenum.toCharArray(buf, s_filenum.length()); 
   n_filenum=atoi(buf);
   n_filenum++;

   f_file = SD.open(s_filelist, O_CREAT|O_TRUNC|O_WRITE);      
   f_file.print(n_filenum);
   f_file.close();
  
   int n=sprintf(buf,"%05d",n_filenum);
   filename="DAT"+String(buf)+".txt"+0;

    filename.toCharArray(ch_filename, filename.length());
#if DEBUG
    Serial.print("file name: ");
    Serial.println(ch_filename);
#endif    

   f_file = SD.open(ch_filename, (O_WRITE | O_CREAT)); 
}  

#if D_RTC
void dateTime(uint16_t* date, uint16_t* time) 
{
  DateTime now = RTC.now();
  *date = FAT_DATE(now.year(), now.month(), now.day());
  *time = FAT_TIME(now.hour(), now.minute(), now.second());
}
#endif

void blink( int v_pin, byte n, int v_delay){
  for (int i=0;i<n;i++) {
    digitalWrite(v_pin, HIGH);
           delay(v_delay);
    digitalWrite(v_pin, LOW);
           delay(v_delay); 
  }         
}

// Serial LCD Communication
void selectLineOne(){  //puts the cursor at line 0 char 0.
   Serial1.write(0xFE);   //command flag
   Serial1.write(128);    //position
//   SelectlineOne();
}
void selectLineTwo(){  //puts the cursor at line 0 char 0.
   Serial1.write(0xFE);   //command flag
   Serial1.write(192);    //position
}
void clearLCD(){
   Serial1.write(0xFE);   //command flag
   Serial1.write(0x01);   //clear command.
    delay(50);
}
void backlightOn(){  //turns on the backlight
    delay(100);
    Serial1.write(0x7C);   //command flag for backlight stuff
    Serial1.write(157);    //light level.
}
void backlightOff(){  //turns off the backlight
    delay(100);
    Serial1.write(0x7C);   //command flag for backlight stuff
    Serial1.write(128);     //light level for off.
}

Credits

Konstantin Dorohov

Konstantin Dorohov

3 projects • 3 followers
Biophysics research scientist in USSR Acad. of Sciences - 20 yrs; 25 yrs in IT, including 20 yrs as Oracle Developer.

Comments