/*
Arduino | coding-help
Patrick — 7/8/24 at 2:47 PM
i have 2 motors for the feeder mechanism, both controlled
by mosfet drivers, and 1 motor for the roller mechanism,
controlled by an h-bridge. the servo pushes the rolled paper,
and i have 2 switches, one of them is for starting and stopping
all the motors and servo from moving, and another switch to
change the amount of time the feeder motors spin
https://www.tinkercad.com/things/elhXWSUz0qQ-paper-roller?sharecode=hASNLu9QX-RSk37BhITgG65vq9ObuSO6LljnYSjQt3g
*/
#include <Servo.h>
#include <LiquidCrystal_I2C.h>
// user constants
const int NUM_TYPES = 3;
const int PAPER_TYPE[NUM_TYPES][2] = {
// feed time, servo count, 1 pair per type
{1000, 5},
{5000, 5},
{10000, 1}
};
const int ROLL_TIME = 2000;
const int UNROLL_TIME = 1000;
const int KICK_TIME = 1000;
const int SYS_TIME = 2000;
// pin constants
const int STOP_BTN_PIN = 12;
const int TYPE_BTN_PIN = 11;
const int FEED1_MTR_PIN = 10;
const int FEED2_MTR_PIN = 9;
const int ROLL_MTR_EN_PIN = 6;
const int ROLL_MTR_IN1_PIN = 5;
const int ROLL_MTR_IN2_PIN = 4;
const int KICK_SERVO_PIN = 2;
unsigned long prevFeed = 0;
unsigned long prevRoll = 0;
unsigned long prevUnRoll = 0;
unsigned long prevKickTime = 0;
unsigned long prevSysDelay = 0;
//int kickCounter = 0;
int state = 0;
int type = 0;
bool isRunning = false;
Servo servo;
LiquidCrystal_I2C lcd(0x27, 16, 2);
void checkSpeed() {
static int oldBtnState = HIGH;
if (!isRunning) {
int btnState = digitalRead(TYPE_BTN_PIN);
if (btnState != oldBtnState) {
oldBtnState = btnState;
if (btnState == LOW) { // button was pressed
type++;
if (type >= NUM_TYPES) type = 0;
Serial.print("Feed time: ");
Serial.print(PAPER_TYPE[type][0] / 1000);
Serial.println(" sec.");
} else { // button was released
// nothing to do
}
delay(20); // for debounce
}
}
}
void checkStart() {
static int oldBtnState = HIGH;
int btnState = digitalRead(STOP_BTN_PIN);
if (btnState != oldBtnState) {
oldBtnState = btnState;
if (btnState == LOW) { // button was pressed
isRunning = !isRunning;
Serial.print("System: ");
Serial.println(isRunning ? "RUN" : "STBY");
} else { // button was released
// nothing to do
}
delay(20); // for debounce
}
}
void displayStatusLCD(bool mode) {
char buffer[16];
lcd.setCursor(0, 0);
snprintf(buffer, 16, "System: %s", mode ? "RUN " : "STBY");
lcd.print(buffer);
if (!mode) {
lcd.setCursor(0, 1);
//snprintf(buffer, 16, "Feed : %2d sec.", (PAPER_TYPE[type][0] / 1000));
snprintf(buffer, 16, "Paper type: %d", type + 1);
lcd.print(buffer);
}
}
void runProcess() {
static int kickCounter = 0;
char buffer[16];
switch (state) {
case 0:
lcd.setCursor(0, 1);
lcd.print("Feeding ");
digitalWrite(FEED1_MTR_PIN, HIGH);
digitalWrite(FEED2_MTR_PIN, HIGH);
prevFeed = millis();
state = 1;
break;
case 1:
if (millis() - prevFeed >= PAPER_TYPE[type][0]) {
digitalWrite(FEED1_MTR_PIN, LOW);
digitalWrite(FEED2_MTR_PIN, LOW);
state = 2;
}
break;
case 2:
lcd.setCursor(0, 1);
lcd.print("Rolling ");
digitalWrite(ROLL_MTR_EN_PIN, HIGH);
digitalWrite(ROLL_MTR_IN1_PIN, HIGH);
digitalWrite(ROLL_MTR_IN2_PIN, LOW);
prevRoll = millis();
state = 3;
break;
case 3:
if (millis() - prevRoll >= ROLL_TIME) {
digitalWrite(ROLL_MTR_EN_PIN, HIGH);
digitalWrite(ROLL_MTR_IN1_PIN, LOW);
digitalWrite(ROLL_MTR_IN2_PIN, HIGH);
prevUnRoll = millis();
state = 4;
}
break;
case 4:
lcd.setCursor(0, 1);
lcd.print("Unrolling ");
if (millis() - prevUnRoll >= UNROLL_TIME) {
digitalWrite(ROLL_MTR_EN_PIN, HIGH);
digitalWrite(ROLL_MTR_IN1_PIN, HIGH);
digitalWrite(ROLL_MTR_IN2_PIN, LOW);
kickCounter++;
state = 5;
}
break;
case 5:
if (kickCounter == PAPER_TYPE[type][1]) {
lcd.setCursor(0, 1);
lcd.print("Store ");
digitalWrite(ROLL_MTR_EN_PIN, LOW);
digitalWrite(ROLL_MTR_IN1_PIN, LOW);
digitalWrite(ROLL_MTR_IN2_PIN, LOW);
servo.write(180);
prevKickTime = millis();
kickCounter = 0;
state = 6;
} else {
prevSysDelay = millis();
state = 7;
}
break;
case 6:
//lcd.setCursor(0, 1);
//lcd.print("Store ");
if (millis() - prevKickTime >= KICK_TIME) {
servo.write(90);
prevSysDelay = millis();
state = 7;
}
break;
case 7:
lcd.setCursor(0, 1);
lcd.print("Paused ");
if (millis() - prevSysDelay >= SYS_TIME) {
state = 0;
}
break;
default:
break;
}
}
void setup() {
Serial.begin(115200);
lcd.init();
lcd.backlight();
pinMode(STOP_BTN_PIN, INPUT_PULLUP);
pinMode(TYPE_BTN_PIN, INPUT_PULLUP);
pinMode(FEED1_MTR_PIN, OUTPUT);
pinMode(FEED2_MTR_PIN, OUTPUT);
pinMode(ROLL_MTR_EN_PIN, OUTPUT);
pinMode(ROLL_MTR_IN1_PIN, OUTPUT);
pinMode(ROLL_MTR_IN2_PIN, OUTPUT);
pinMode(KICK_SERVO_PIN, OUTPUT);
servo.attach(KICK_SERVO_PIN);
servo.write(90);
// splash screen
lcd.setCursor(1, 0);
lcd.print("Roller Device");
lcd.setCursor(5, 1);
lcd.print("V1.00");
delay(2000);
lcd.clear();
}
void loop() {
checkStart();
checkSpeed();
if (isRunning) {
displayStatusLCD(isRunning);
runProcess();
} else {
displayStatusLCD(isRunning);
// stop all motors
servo.write(90);
digitalWrite(FEED1_MTR_PIN, LOW);
digitalWrite(FEED2_MTR_PIN, LOW);
digitalWrite(ROLL_MTR_EN_PIN, LOW);
digitalWrite(ROLL_MTR_IN1_PIN, LOW);
digitalWrite(ROLL_MTR_IN2_PIN, LOW);
state = 0;
}
}
ENA IN1 IN2
Roller
Feeder1
Feeder2
Start / Stop
Paper type