// C++ code
//
/* */
/* driver A4988 e DRV8825 */
/* ,-----------, */
/* ENABLE |o o| V_MOTORE */
/* MS1 |o ____ o| GND */
/* MS2 |o| | o| 2B */
/* MS3 |o|____| o| 2A */
/* RESET |o o| 1A */
/* SLEEP |o o| 1B */
/* STEP |o o| VDD */
/* DIR |o o| GND */
/* `-----------' */
/* */
/* ========================================== */
/* MS1 | MS2 | MS3 | Microstep resolution */
/* -----|------|------|---------------------- */
/* Low | Low | Low | Full step */
/* High | Low | Low | 1/2 step */
/* Low | High | Low | 1/4 step */
/* High | High | Low | 1/8 step */
/* High | High | High | 1/16 step */
/* ========================================= */
/*########################################################*/
/* VERSION INFO HERE */
float VERSION = 1.0;
int maxCount = 149;
// Do not edit below this line
//#define stepsSpeed 10 // lowest resolution
#define stepsSpeed .1 // .1 highst resolution
#define delaySteps 500 // started at 1000
float annealTime = 2;
#define dirPin 12 //2
#define stepPin 3
#define ms1Pin 9
#define ms2Pin 8
#define ms3Pin 4
//#define stepsPerRevolution 110 // in lowest resolution
#define stepsPerRevolution 700 // in highest resolution
#define stepsAtDrop 200 // last few steps prior to dropping
#define stepsToGrabCase 300 //160
volatile bool toggleState = false;
#include <Arduino.h>
//#include <LiquidCrystal_I2C.h>
#include <Wire.h>
int seconds = 0;
//LiquidCrystal lcd(0);
//LiquidCrystal_I2C lcd(0x27, 16, 2);
int startButton = 10;
//int profileButton = 11; //increment button also
//int downButton = 6; //decrement/and case sensor input button also
int stopButton = 2;
int modeButton = 13;
int menu = 0;
int lastMenuValue = 0;
int zvs = 7;
int caseKick = 5;
int caseCount = 0;
int increment = A0;
int decrement = A1;
int x = 0;
float annealTimeStr = 3.0;
bool profiles = true;
// Define 16x2 LCD for scrolling text
int screenWidth = 16;
int screenHeight = 2;
int stringStart, stringEnd = 0;
int scrollCursor = screenWidth;
void haltAnnealCase(){
digitalWrite(zvs,LOW);
delay(10);
//lcd.clear();
//lcd.setCursor(0, 0);
//lcd.print("System Paused");
//lcd.setCursor(0, 1);
//lcd.print("Clearing Case");
Serial.println("haltAnnealCase: Clearing Case");
}
void haltKickCase(){
digitalWrite(caseKick,HIGH);
delay(3000);
digitalWrite(caseKick,LOW);
}
void haltSys(){
String scrollMessage(caseCount);
scrollMessage += " case(s) completed. Green to continue or Yellow to change mode.";
haltAnnealCase();
haltKickCase();
toggleState = false;
delay(5000);
//lcd.clear();
//lcdScrollLineTwo("Paused: ",scrollMessage);
Serial.println(scrollMessage);
return;
}
void lcdScrollLineTwo(String line1, String line2){
//
//lcd.setCursor(3, 0); // Seting the cursor on first row
//lcd.print(line1); // To print line1 message
while (true){
if(digitalRead(modeButton) == LOW){
Serial.println("lcdScrollLineTwo: mode button pressed");
return;
}
if(digitalRead(startButton) == LOW){
Serial.println("lcdScrollLineTwo: start button pressed");
return;
}
//lcd.setCursor(0,1);
//lcd.print(" ");
//lcd.setCursor(scrollCursor, 1); // Seting the cursor on first row and (scrolling from left end to right)
//lcd.print(line2.substring(stringStart,stringEnd)); // To print line1 first character "T"
if(stringStart == 0 && scrollCursor > 0){
scrollCursor--; // Moving cursor from 16 to 0
stringEnd++; // Character T, H, I, S ...
// it will print out character from 0 to 15 the whole length of the screen
}
else if (stringStart == stringEnd){ // start all over again
stringStart = stringEnd = 0;
scrollCursor = screenWidth;
}
else if (stringEnd == line2.length() && scrollCursor == 0) { // if reach to the end character
stringStart++;
}
else { // it will print out character from (1 to 16) to end character (this case it's !))
stringStart++;
stringEnd++;
}
delay(200);
}
}
void grabCase(){
// //pinMode(downButton, INPUT_PULLUP);
// pinMode(downButton, INPUT);
// if (!digitalRead(downButton)){
// delay(500);
// Serial.println("case sensor HIGH");
// }
//lcd.clear();
//
//lcd.print("Grabbing next");
Serial.println("Grabbing next case");
//lcd.setCursor(0, 1);
//lcd.print("case");
// rotate counter clock wise to get case
digitalWrite(dirPin, LOW);
for(int i = 0; i < stepsToGrabCase; i++)
{
// These four lines result in 1 step:
digitalWrite(stepPin, HIGH);
delayMicroseconds(1000);
digitalWrite(stepPin, LOW);
delayMicroseconds(1000);
delay(stepsSpeed);
//delay(1000);
}
//lcd.clear();
//lcd.print("Red to Stop");
//got case go back to start
digitalWrite(dirPin, HIGH);
for(int i = 0; i < stepsToGrabCase; i++)
{
// These four lines result in 1 step:
digitalWrite(stepPin, HIGH);
delayMicroseconds(delaySteps);
digitalWrite(stepPin, LOW);
delayMicroseconds(delaySteps);
delay(stepsSpeed);
}
// after we grab case, rotate to drop it
// Set the spinning direction clockwise:
// Spin the stepper motor to drop the case:
for(int i = 0; i < stepsPerRevolution; i++)
{
// These four lines result in 1 step:
digitalWrite(stepPin, HIGH);
delayMicroseconds(delaySteps);
digitalWrite(stepPin, LOW);
delayMicroseconds(delaySteps);
delay(stepsSpeed);
}
for(int i = 0; i < stepsAtDrop; i++)
{
// These four lines result in 1 step:
digitalWrite(stepPin, HIGH);
delayMicroseconds(1500);
digitalWrite(stepPin, LOW);
delayMicroseconds(1500);
delay(stepsSpeed);
}
// Spin the stepper motor back to home position
digitalWrite(dirPin, LOW);
for(int i = 0; i < (stepsPerRevolution + stepsAtDrop); i++)
{
// These four lines result in 1 step:
digitalWrite(stepPin, HIGH);
delayMicroseconds(delaySteps);
digitalWrite(stepPin, LOW);
delayMicroseconds(delaySteps);
delay(stepsSpeed);
}
}
void lcdout(char first_value[],float second_value){
annealTime = second_value;
//lcd.clear();
//lcd.print(first_value);
//lcd.print(" ");
//lcd.print(annealTime);
//lcd.setCursor(0,1);
//lcd.print("Green to Start");
Serial.println("Green to Start");
Serial.println(first_value);
Serial.println(annealTime);
Serial.println("Ready: press start");
}
void haltButton(){
if (digitalRead(stopButton) == LOW){
toggleState = true;
Serial.println("stop button pressed");
}
}
void runMenuUpdate() {
//lcd.clear();
//lcd.print("System Running");
Serial.println("System Running");
//lcd.setCursor(0, 1);
//lcd.print("Red to Stop");
}
void annealCase(){
//lcd.clear();
//lcd.print("Annealing case");
Serial.println("annealing case");
//lcd.setCursor(0,1);
//lcd.print(annealTime);
Serial.print("anneal time: ");
Serial.println(annealTime);
//lcd.print(" seconds");
digitalWrite(zvs,HIGH);
//delay(annealTime);
unsigned long delayTimeMillis = annealTime * 1000;
// Use the delay function with the calculated delay time
delay(delayTimeMillis);
digitalWrite(zvs,LOW);
}
void kickCase(){
//delay(1000);
//lcd.clear();
//lcd.print("Kicking annealed");
Serial.println("kickCase: kicking annealed case to bin");
//lcd.setCursor(0,1);
//lcd.print("case to bin");
digitalWrite(caseKick,HIGH);
delay(1000);
digitalWrite(caseKick,LOW);
}
void runSystem(){
if(caseCount > maxCount){
String scrollMessage(caseCount);
scrollMessage += " Case(s) annealed. Power cycle annealer to clear max count. This process helps keep unit from overheating zvs board";
String TopMsg= ":Max count";
//lcd.clear();
lcdScrollLineTwo(TopMsg, scrollMessage );
Serial.println(scrollMessage);
Serial.println(TopMsg);
delay(50);
}else{
caseCount++;
grabCase();
annealCase();
kickCase();
//lcd.clear();
//lcd.print(caseCount);
Serial.println(caseCount);
//lcd.setCursor(0, 1);
//lcd.print("case(s) completed");
Serial.println("cases completed");
//delay(1500);
}
}
void runAnnealCycle(){
Serial.println("running anneal cycle");
if(annealTime < 1){
//lcd.clear();
//lcd.print("Paused Cycle");
//lcd.setCursor(0, 1);
//lcd.print("Time To Low");
//delay(5000);
toggleState = true;
}
while (true) {
if ( toggleState == true ) {
haltSys();
break;
}
runSystem();
delay(100);
}
}
void menuItems(){
int upButtonVal, downButtonVal;
delay(200);
upButtonVal = (analogRead(increment));
if(upButtonVal < 200){
delay(100);
menu++;
}
downButtonVal = (analogRead(decrement));
if(downButtonVal < 200){
delay(100);
menu--;
}
if(digitalRead(startButton) == LOW){
delay(500);
runAnnealCycle();
}
if(digitalRead(modeButton) == LOW){
delay(500);
profiles = false;
//lcd.clear();
//lcd.println("Timer Menu");
Serial.println("-customTimer: Timer Menu");
//lcd.setCursor(0,1);
//lcd.println("----------------");
delay(2000);
//lcd.clear();
//lcd.println("Turn Knob");
Serial.println("-customTimer: Black to increment - Blue to decrement");
//lcd.setCursor(0,1);
//lcd.println("to change time");
delay(3000);
//lcd.clear();
//lcd.println("Current Timer:");
//lcd.setCursor(0,1);
//lcd.println(annealTimeStr);
Serial.print(annealTimeStr);
annealTime = annealTimeStr;
return;
}
if(menu != lastMenuValue) {
switch(menu)
{
/* #############################################
Add CASES HERE between these comments only */
case 1:
lcdout("win 308", 4.4);
break;
case 2:
lcdout("r-p 308", 5.0);
break;
case 3:
lcdout("r-p 223", 4.4);
break;
case 4:
lcdout("win 223", 4.4);
break;
case 5:
lcdout("FC Dots 223", 4.4);
break;
case 6:
lcdout("FC 11", 4.4);
break;
case 7:
lcdout("FC 14", 4.4);
break;
/* Add CASES HERE between these comments only
############################################# */
default:
menu=0;
lcdout("Other", 3.5);
break;
}
lastMenuValue = menu;
}
}
//end ammo
void customTimer(){
int upButtonVal, downButtonVal;
delay(200);
upButtonVal = (analogRead(increment));
if(upButtonVal < 200){
delay(100);
annealTimeStr = annealTimeStr + .1;
annealTime = annealTimeStr;
Serial.println("Current Timer:");
Serial.println(annealTimeStr);
}
downButtonVal = (analogRead(decrement));
if(downButtonVal < 200){
delay(100);
annealTimeStr = annealTimeStr - .1;
annealTime = annealTimeStr;
Serial.println("Current Timer:");
Serial.println(annealTimeStr);
}
if(digitalRead(startButton) == LOW){
if(annealTime < 1){
Serial.println("Anneal time set to below 1 second. Too low. Set to higher time");
//lcd.clear();
//lcd.print("Time to low");
//lcd.setCursor(0,1);
//lcd.println("Make > than 1.0");
delay(500);
return;
}
delay(500);
runAnnealCycle();
}
if(digitalRead(modeButton) == LOW){
delay(500);
profiles = true;
//lcd.clear();
//lcd.print("Profile Menu");
Serial.println("-menuItems: Profile menu:");
Serial.println("-menuItems: Black or Blue to scroll through profiles, Green to start");
//lcd.setCursor(0,1);
//lcd.println("----------------");
delay(1000);
//lcd.clear();
//lcd.print("Turn Knob");
//lcd.setCursor(0,1);
//lcd.println("Green to Start");
return;
}
}
void firstMenu(){
Serial.println("firstmenu");
//lcd.clear();
//lcd.print("Change Mode:");
//lcd.setCursor(0,1);
//lcd.print("Yellow Button");
//delay(3000);
//lcd.clear();
//lcd.print("To Stop System:");
//lcd.setCursor(0,1);
//lcd.print("Red Button");
//delay(3000);
//lcd.clear();
//lcd.print("Change Profile:");
//lcd.setCursor(0,1);
//lcd.print("Turn Knob ");
Serial.println("- firstMenu: ");
Serial.println("Press Green to start or Yellow to change mode after selecting profile with Blue or Black");
//delay(4000);
}
void setup()
{
//Serial.begin(9600);
//Serial.begin(115200);
Serial.begin(9600);
Serial.println("I'm on line now");
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
digitalWrite(ms1Pin,HIGH);
digitalWrite(ms2Pin,HIGH);
digitalWrite(ms3Pin,LOW);
pinMode(zvs,OUTPUT);
pinMode(caseKick, OUTPUT);
digitalWrite(zvs,LOW);
//lcd.begin(16, 2);
//lcd.init();
//lcd.backlight();
//
//lcd.print(" Howe Gun Works ");
Serial.println("Howe Gun Works");
//lcd.setCursor(0,1);
//lcd.print(" First Shot! ");
delay(2000);
//lcd.setCursor(0,0);
//lcd.print(" HGW Annealer ");
//lcd.setCursor(0,1);
//lcd.print(" ");
//lcd.print(String("V"));
//lcd.println(VERSION, 1);
//lcd.print(" ");
//delay(2000);
pinMode(startButton, INPUT_PULLUP);
//pinMode(profileButton, INPUT_PULLUP);
pinMode(stopButton, INPUT_PULLUP);
//pinMode(downButton, INPUT_PULLUP);
pinMode(modeButton, INPUT_PULLUP);
firstMenu();
attachInterrupt(digitalPinToInterrupt(stopButton),haltButton, LOW);
}
/* MAIN LOOP !!!!!!!!!!!!!!!!!!!!!! */
void loop()
{
if(profiles == true) {
menuItems();
}else{
customTimer();
}
if(digitalRead(modeButton) == LOW){
delay(400);
if(profiles == true){
profiles = false;
return;
}
if(profiles == false){
profiles = true;
return;
}
}
/* ------------------ Main Loop above */
}
/* End Main LOOP !!!!!!!!!!!!!!!!!!!!!!!! */