/* BALLISTIC CHRONOGRAPH
*** NOT FOR DISTRIBUTION ***
20 character 4 line I2C Liquid Crystal Display
Backpack Interface labelled "YwRobot Arduino LCM1602 IIC V1"
Connect Vcc and Ground, SDA to A4, SCL to A5 on Arduino Nano
Connect the menu UP button to pin A1
Connect the menu DOWN button to pin A0
Connect the menu OK button to pin D3
First IR sensor (OPL550) input pin D10
SecondIR sensor (OPL550) input pin D11
***ENSURE CORRECT SENSOR SEPARATION DISTANCE IS SELECTED BELOW (line 177 *********)
ENSURE THAT ALL LIBRARIES ARE DOWNLOADED TO YOUR SYSTEM FIRST
John W 16/06/2021 [email protected]
*/
#include <Wire.h>
#include <OneButton.h>
#include <LiquidCrystal.h>
#define firstsensor_1 12 //D10 IR sensor (OPL550) input pin
#define secondsensor_2 11 //D11 IR sensor (OPL550)input pin
void(* resetFunc) (void) = 0;
OneButton buttonUP(4, true); //Digital pin 3 for Tare button
OneButton buttonDW(2, true); //Digital pin 4 for Weight button
OneButton buttonOK(3, true); //Digital pin 5 for Spine button
float fps = 0; //storage for feet per sec value
float ftlbs = 0;
float pWeight; //Pellet weight in grains
float elap, ms, joule;
float fpstotal = 0;
float average = 0;
float ftlbstotal = 0;
float energy = 0;
const int LCD_COLS = 20; // LCD geometry
const int LCD_ROWS = 4; // LCD geometry
int one = 1; //pellet weight loop control
int counter_shots = 0; //increment after each shot
unsigned long time1;
unsigned long time2;
LiquidCrystal lcd(10, 9, 8, 7, 6, 5);
void setup() {
//Serial.begin(9600);
lcd.begin(LCD_COLS, LCD_ROWS);
pWeight = 420;
buttonOK.attachClick(click1); //-----------------------------------------------
buttonOK.attachLongPressStop(pressStop1); //Attach different..
buttonUP.attachClick(click2); //..buttons actions
buttonDW.attachClick(click3); //-----------------------------------------------
pinMode (firstsensor_1, INPUT);
pinMode (secondsensor_2, INPUT);
digitalWrite(firstsensor_1, HIGH);
digitalWrite(secondsensor_2, HIGH);
lcd.clear();
lcd.setCursor(0, 0); //Start at character 3 on line 0 (*****character 0 is the first(LH)character****line 0 is TOP LINE****)
lcd.print("Cronografo V 1.0");
delay(5000);
lcd.clear();
lcd.setCursor(3, 0); //Start at character 3 on line 0 (*****character 0 is the first(LH)character****line 0 is TOP LINE****)
lcd.print("ARCIERI DI");
lcd.setCursor(5, 1);
lcd.print("ASCOLI");
delay(5000);
lcd.clear();
lcd.setCursor(2, 0); //Start at character 1 on line 0
lcd.print("PESO FRECCIA");
lcd.setCursor(3, 1);
lcd.print(pWeight, 0);
lcd.setCursor(8, 1); //Start at character 9 on line 2
lcd.print("grani");
lcd.setCursor(0, 1);
}
void loop()
{
buttonOK.tick(); //-----------------------------------------------
buttonUP.tick(); //Read button state
buttonDW.tick();
}
void click1() { //Event simple click for TARE before spine (button 3)
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Aspetto il colpo");
lcd.blink(); //display flashing cursor
while (digitalRead(firstsensor_1) == 0); //pellet timing
while (digitalRead(firstsensor_1));
time1 = micros();
while (digitalRead(secondsensor_2));
time2 = micros();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("# ");
delay(300);
lcd.print(++counter_shots);
elap = time2 - time1;
//fps = 196850 / elap; // for 60mm sensor spacing distance **********************
//fps = 262467 / elap; // for 80mm sensor spacing distance **********************
fps = 328084000 / elap; // for 100mm sensor spacing distance **********************
// Serial.print("FPS\t");
delay(300);
lcd.setCursor(3, 0); //Start at character 0 on line 1
lcd.print(fps , 0);
lcd.setCursor(6, 0);
lcd.print(" fps");
delay(300);
ms = fps * 0.3048; //metres per second calculation
lcd.setCursor(13, 0); //Start at character 11 on line 1
lcd.print(ms,0 );
lcd.setCursor(17, 0);
lcd.print("mps");
delay(300);
ftlbs = (pWeight * fps * fps) / 450240; //foot pounds and joules energy calculations
joule = ftlbs * 1.35582;
lcd.setCursor(3, 1); //Start at character 1 on line 2
lcd.print(joule, 0 );
lcd.setCursor(7, 1);
lcd.print("J");
delay(5000);
lcd.clear();
fpstotal = fpstotal + fps; // averaging code after 5 shots
average = fpstotal / (counter_shots);
ftlbstotal = ftlbstotal + ftlbs;
energy = ftlbstotal / (counter_shots);
//if (counter_shots == 5) {
lcd.setCursor(2, 0); //Start at character 4 on line 0
lcd.print ("MEDIA ");
//lcd.setCursor(0, 1);
lcd.print (counter_shots);
lcd.print (" TIRI");
lcd.setCursor(0, 1);
lcd.print ("FPS: ");
lcd.print(average, 0);
lcd.setCursor(7, 1);
lcd.print ("Joules: ");
lcd.print(energy, 0);
//lcd.setCursor(14, 2);
lcd.setCursor(20, 1);
//}
}
void reset_variables() {
time1 = 0;
time2 = 0;
}
// HOPE YOU HAVE FUN USING THIS ! CONTACT EMAIL ABOVE FOR QUERIES
void pressStop1() { //Event end of long press to tare before weight shaft
resetFunc();
}
void click2() { //Event simple click for TARE before spine (button 3)
pWeight = pWeight + 5;
lcd.setCursor(3, 1);
lcd.print(pWeight, 0);
lcd.setCursor(3, 3);
}
void click3() { //Event simple click for TARE before spine (button 3)
pWeight = pWeight - 5;
lcd.setCursor(3, 1);
lcd.print(pWeight, 0);
lcd.setCursor(3, 3);
}