Hello all I am a total noob and here looking for some advice on where to go next. My project is a wire length cutter, got the idea from a few examples online.
hardware:
Arduino mega 1260
big easy driver for stepper motor
I2C LCD (16,2)
servo for cutters
4x4 membrane keypad for input
theory:
user inputs wire length and wire quantity via keypad.
stepper feeds wire.
servo cuts wire.
repeat to desired quantity
simple in theory, but I cant quite get all the parts to collaborate with each other.
this is what I have so far:
(please excuse the mess i'm still learning):
//------------------------------- librarys ----------------------------------
#include <Wire.h>
#include <Servo.h>
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
#include <kissStepper.h>
//------------------------------- motors ------------------------------------
static const uint8_t PIN_MS1 = 47;
static const uint8_t PIN_MS2 = 48;
static const uint8_t PIN_MS3 = 49;
static const uint8_t PIN_DIR = 52;
static const uint8_t PIN_STEP = 53;
static const uint8_t PIN_ENABLE = 46;
#define servo 11
#define openAngle 0
#define closedAngle 90
#define Go 12
#define Back 13
//------------------------------- system settings ----------------------------------
const byte numRows = 4;
const byte numCols = 4;
char keymap[numRows][numCols] =
{
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[numRows] = {44, 42, 40, 38};
byte colPins[numCols] = {39, 41, 43, 45};
Keypad kpd = Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);
char key = kpd.getKey();
//char waitForKey();
//int loopcount = 0;
LiquidCrystal_I2C lcd(0x27, 16, 2);
//int incomingByte = 0;
int state = 0;
int previousWireLength = 0;
int previousWireQuantity = 0;
float cmPerStep = 0.017115;
unsigned int wireLength = 0;
unsigned int wireQuantity = 0;
const int stepsPerRevolution = 200;//
const int stepsToTake = (int)wireLength / cmPerStep;
static const uint8_t DRIVE_MODE = 4; // drive mode (number of microsteps taken, eg 1/8th stepping = 8)
static const uint16_t REVOLUTION_FULL_STEPS = 200; // number of full steps in one revolution of the test motor (see your motor's specs/datasheet)
static const uint32_t REVOLUTION_PULSES = REVOLUTION_FULL_STEPS * DRIVE_MODE; // number of microsteps in one revolution of the test motor
kissStepper mot(PIN_DIR, PIN_STEP, PIN_ENABLE);
Servo snippers;
void setup() {
Serial.begin(9600);
lcd.init();
lcd.backlight();
kpd.begin(9600);
Wire.begin();
mot.begin();
pinMode(Go, INPUT_PULLUP);
pinMode(Back, INPUT_PULLUP);
pinMode(PIN_MS1, OUTPUT);
pinMode(PIN_MS2, OUTPUT);
pinMode(PIN_MS3, OUTPUT);
pinMode(PIN_DIR, OUTPUT);
pinMode(PIN_STEP, OUTPUT);
pinMode(PIN_ENABLE, OUTPUT);
lcd.setCursor(0, 0);
lcd.print("CUTMEISTER!");
snippers.attach(servo);
snippers.write(openAngle);
delay(1000);
}
void loop()
{
if (!digitalRead(Go)) {
if (state == 5) {
state = 0;
}
else {
state += 1;
}
delay(200);
lcd.clear();
}
if (!digitalRead(Back) && state > 0 && state < 4) {
state -= 1;
delay(200);
lcd.clear();
}
switch (state) {
case 0:
homeScreen();
break;
case 1:
chooseWireLength();
break;
case 2:
chooseWireQuantity();
break;
case 3:
confirm();
break;
case 4:
currentlyCutting();
break;
case 5:
finishedCutting();
break;
}
}
void homeScreen() {
lcd.setCursor(0, 0);
lcd.print("CUTMEISTER!");
lcd.setCursor (7, 1);
lcd.print("PRESS GO>");
delay(100);
}
void chooseWireLength() {
//clear LCD if required
if (previousWireLength != wireLength) {
lcd.clear();
previousWireLength = wireLength;
}
wireLength = 12;
//---"wireLength = int changeValue();" will go here in place of number once keypad works.---
{
//Display information on LCD
lcd.setCursor(0, 0);
lcd.print("LENGTH:" + (String)wireLength + "cm");
displayNavigation();
}
}
void chooseWireQuantity() {
wireQuantity = 5;
//---"wireQuantity = int changeValue();" will go here in place of number once keypad works.---
//clear LCD if required
if (previousWireQuantity != wireQuantity) {
lcd.clear();
previousWireQuantity = wireQuantity;
}
//Display information on LCD
lcd.setCursor(0, 0);
lcd.print("QUANTITY:" + (String)wireQuantity);
Serial.println("QUANTITY:" + (String)wireQuantity);
displayNavigation();
}
void confirm() {
lcd.setCursor(0, 0);
lcd.print((String)wireLength + "cm x " + (String)wireQuantity + "pcs");
Serial.println((String)wireLength + "cm x " + (String)wireQuantity + "pcs");
lcd.setCursor(0, 1);
lcd.print("<BACK");
lcd.setCursor(10, 1);
lcd.print("START>");
delay(100);
}
void currentlyCutting() {
lcd.setCursor(0, 0);
lcd.print((String)0 + "/" + (String)wireQuantity);
lcd.setCursor(0, 1);
lcd.print("???s");
Serial.println("WireLength =" + (String)wireLength);
Serial.println("TotalSteps =" + (String)stepsToTake);
// int stepsToTake = (int)wireLength / cmPerStep;
unsigned long timeForOneCycle = millis();
int i = 0;
while (i < wireQuantity) {
feed();
Cut();
i ++;
}
lcd.setCursor(0, 0);
lcd.print((String)(i + 1) + "/" + (String)wireQuantity);
lcd.setCursor(0, 1);
unsigned long timeRemaining = ((millis() - timeForOneCycle) * (wireQuantity - (i + 1))) / 1000;
lcd.print((String)timeRemaining + "s ");
if (i >= wireQuantity) {
mot.disable();
state = 5;
}
else {
feed();
Cut();
}
}
void finishedCutting() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("CUTTING COMPLETE");
lcd.setCursor(10, 1);
lcd.print("RESET>");
mot.stop();
delay(100);
}
int changeValue() { //not fully functional and yes I know there should be more here..
key = kpd.getKey();
}
void displayNavigation() {
lcd.setCursor(0, 1);
lcd.print("<BACK");
lcd.setCursor(10, 1);
lcd.print("NEXT>");
delay(100);
}
void feed() {
int stepsToTake = (int)wireLength / cmPerStep;
mot.enable();
mot.setMaxSpeed(REVOLUTION_PULSES);
mot.setAccel(0);
mot.isMovingForwards();
mot.prepareMove(stepsToTake);
while (mot.move() != STATE_STOPPED);
mot.move();
}
void Cut() {
snippers.write(closedAngle);
delay(600);
snippers.write(openAngle);
delay(600);
}
I'm sure its an easy fix that I just don't have the experience to spot.
My main problem:
having trouble getting a value from the keypad to be stored/saved and used later.
And, the "feed(); cut(); loop doesn't function as expected.. it should feed wirelength then cut the wire and repeat until "i >= wireQuantity". the best I have gotten is one cycle of "feed/cut". or it will feed once and get stuck cutting until "i >= wireQuantity".
Everythig else works great.
if anyone has some advice it would be greatly appreciated.