#include "SevSeg.h"
#include "Button.h"
#include <TM1637.h>
#include "HX711_ADC.h"
#include <Servo.h>
Servo ServoGate;
HX711_ADC LoadCell(A5, A4);
TM1637 SEGMENT_TM1, SEGMENT_TM2;
Button PIN_UP(A0);
Button PIN_DOWN(A1);
Button PIN_SETUP(A2);
Button PIN_CANCEL(A3);
Button BTN_GATE_OPEN(2);
Button BTN_MACHINE_START(3);
byte directionPin = 12;
byte stepPin = 13;
int pulseWidthSec = 1; // microsecondo
// How many of the shift registers
#define NUM_SHIFT_REGS 1
#define DATA_PIN 5 // Pin connected to DS of 74HC595
#define LATCH_PIN 6 // Pin connected to STCP of 74HC595
#define CLOCK_PIN 7 // Pin connected to SHCP of 74HC595
const uint8_t numOfRegisterPins = NUM_SHIFT_REGS * 8;
bool registers[numOfRegisterPins];
void clearRegisters() {
// Reset all register pins
for (int i = numOfRegisterPins - 1; i >= 0; i--) {
registers[i] = LOW;
}
}
void writeRegisters() {
// Set and display registers
digitalWrite(LATCH_PIN, LOW);
for (int i = numOfRegisterPins - 1; i >= 0; i--) {
digitalWrite(CLOCK_PIN, LOW);
digitalWrite(DATA_PIN, registers[i]);
digitalWrite(CLOCK_PIN, HIGH);
}
digitalWrite(LATCH_PIN, HIGH);
}
void setup() {
// Serial.begin(4800);
Serial.begin(9600);
ServoGate.attach(4); // attaches the servo on pin 4 to the servo object
SEGMENT_TM1.begin(8, 9, 4); // (clockpin, datapin, #digits)
SEGMENT_TM1.displayClear();
SEGMENT_TM1.setBrightness(7); // full brightness, default is 3
SEGMENT_TM2.begin(10, 11, 4); // clockpin, datapin, #digits
SEGMENT_TM2.displayClear();
SEGMENT_TM2.setBrightness(7); // full brightness, default is 3
int holding_button_time_trigger = 700;
int holding_button_speed = 5;
PIN_UP.begin();
PIN_UP.set_repeat(holding_button_time_trigger, holding_button_speed);
PIN_DOWN.begin();
PIN_DOWN.set_repeat(holding_button_time_trigger, holding_button_speed);
PIN_SETUP.begin();
PIN_SETUP.set_repeat(holding_button_time_trigger, -1);
PIN_CANCEL.begin();
BTN_GATE_OPEN.begin();
BTN_MACHINE_START.begin();
// PIN_SETUP.set_repeat(holding_button_time_trigger, -1);
LoadCell.begin();
LoadCell.start(1000);
LoadCell.setCalFactor(0.42);
pinMode(directionPin, OUTPUT);
pinMode(stepPin, OUTPUT);
pinMode(DATA_PIN, OUTPUT);
pinMode(CLOCK_PIN, OUTPUT);
pinMode(LATCH_PIN, OUTPUT);
clearRegisters();
writeRegisters();
}
int target_weigth = 3000; // init target_weigth
int previos_value = 0;
int max_limit = 5000;
int min_limit = 100;
char buffer[5];
void display_amount(TM1637 seqment_display, String amt_value) {
String amount = amt_value;
int str_amt_len = amount.length();
if (str_amt_len == 3) {
amount = " " + amt_value;
} else if (str_amt_len == 2) {
amount = " " + amt_value;
} else if (str_amt_len == 1) {
amount = " " + amt_value;
}
buffer[0] = amount.charAt(0);
buffer[1] = amount.charAt(1);
buffer[2] = amount.charAt(2);
buffer[3] = amount.charAt(3);
buffer[4] = '\0';
seqment_display.displayPChar(buffer);
}
void blink(TM1637 display, String blink_text) {
for (int l = 0; l < 3; l++) {
display_amount(display, " ");
delay(250);
display_amount(display, blink_text);
delay(250);
}
display_amount(display, " ");
}
String state = "IDLE";
void main_ctrl() {
motor_status();
if (state == "IDLE" ) {
display_amount(SEGMENT_TM1, String(target_weigth));
}
if (state == "RUN") {
display_amount(SEGMENT_TM1, String(target_weigth));
motor_running();
} else if (state == "SETTING") {
if (PIN_UP.pressed() ) {
previos_value += 1;
if (previos_value > max_limit) {
blink(SEGMENT_TM1, "Error---");
delay(500);
previos_value = max_limit;
}
}
if (PIN_DOWN.pressed() && state == "SETTING") {
previos_value -= 1;
if (previos_value < min_limit) {
blink(SEGMENT_TM1, "Error---");
delay(500);
previos_value = 100;
}
}
display_amount(SEGMENT_TM1, String(previos_value));
}
if (BTN_MACHINE_START.pressed() ) {
if (state == "RUN") {
state = "STOP";
} else if (state == "IDLE" || state == "STOP") {
state = "RUN";
}
Serial.println("BTN_MACHINE_START :" + state);
}
if (PIN_SETUP.pressed()) {
if (state == "IDLE" || state == "STOP") {
// enter edit state
blink(SEGMENT_TM1, "-------");
previos_value = 0 + target_weigth;
display_amount(SEGMENT_TM1, String(previos_value));
state = "SETTING";
} else if (state == "SETTING") {
// save/exit edit state
blink(SEGMENT_TM1, "Save");
delay(1000);
target_weigth = 0 + previos_value;
display_amount(SEGMENT_TM1, String(target_weigth));
state = "IDLE";
}
Serial.println("PIN_SETUP :" + state);
}
if (PIN_CANCEL.pressed() && state == "SETTING") {
blink(SEGMENT_TM1, "XXXXXX");
display_amount(SEGMENT_TM1, String(target_weigth));
state = "IDLE";
Serial.println("PIN_CANCEL :" + state);
}
}
float get_weight() {
LoadCell.update();
return LoadCell.getData();
}
void setRegisterPin(int index, int value) {
// Set an individual pin HIGH or LOW
registers[index] = value;
}
String weight_status = "";
float current_weigth = 0;
float last_weight_stop = 0;
int GREEN_LED_GATE = 0; // 74HC PIN 0
int YELLO_LED_RUNNING = 2; // 74HC PIN 1
int RED_LED_GATE = 1; // 74HC PIN 2
int MOTOR_MS1 = 4; // 74HC PIN 4
int MOTOR_MS2 = 5; // 74HC PIN 5
int MOTOR_MS3 = 6; // 74HC PIN 6
float led_blink = millis();
bool led_state = false;
void motor_status() {
// YELLO_LED_RUNNING
if (state == "RUN") {
float step = millis();
if (step - led_blink > 1000) {
led_state = !led_state;
led_blink = step;
}
ic74HC_Control(YELLO_LED_RUNNING, led_state);
} else {
ic74HC_Control(YELLO_LED_RUNNING, false);
}
}
void motor_ms_control(bool ms1, bool ms2, bool ms3) {
ic74HC_Control(MOTOR_MS1, ms1);
ic74HC_Control(MOTOR_MS2, ms2);
ic74HC_Control(MOTOR_MS3, ms3);
}
void motor_running() {
float diff_weigth = target_weigth - current_weigth;
Serial.println("diff_weigth :" + String(diff_weigth, 0));
if (diff_weigth > 1000) { // 200 Microsteps/revolution
motor_ms_control(false, false, false);
} else if (diff_weigth > 500) { // 400 Microsteps/revolution
motor_ms_control(true, false, false);
} else if (diff_weigth > 200) { // 800 Microsteps/revolution
motor_ms_control( false, true, false);
} else if (diff_weigth > 100) { // 1600 Microsteps/revolution
motor_ms_control( true, true, false);
} else if (diff_weigth > 10) { // 3200 Microsteps/revolution
motor_ms_control( true, true, true);
}
digitalWrite(directionPin, HIGH);
digitalWrite(stepPin, HIGH);
delay(pulseWidthSec);
digitalWrite(stepPin, LOW);
}
bool toggle = false;
void loop() {
main_ctrl();
current_weigth = get_weight();
if (weight_status != "WEIGHT_OK") {
display_amount(SEGMENT_TM2, String(current_weigth, 0));
} else {
display_amount(SEGMENT_TM2, String(last_weight_stop, 0));
}
if (state == "RUN") {
current_weigth = get_weight();
if (int(current_weigth) >= target_weigth ) {
weight_status = "WEIGHT_OK";
state = "STOP"; // Motor STOP
last_weight_stop = current_weigth;
ic74HC_Control(GREEN_LED_GATE, true);
blink(SEGMENT_TM2, String(current_weigth, 0));
}
}
if (weight_status == "WEIGHT_OK") {
if (BTN_GATE_OPEN.pressed()) {
Serial.println("BTN_GATE_OPEN :" + state);
ic74HC_Control(GREEN_LED_GATE, false);
ic74HC_Control(RED_LED_GATE, true);
delay(1000);
servoState("OPEN");
delay(1000);
ic74HC_Control(RED_LED_GATE, false);
servoState("CLOSE");
delay(1000);
weight_status = "";
state = "RUN";
}
} else {
ic74HC_Control(GREEN_LED_GATE, false);
}
}
void ic74HC_Control(int idx, bool state) {
setRegisterPin(idx, state);
writeRegisters();
}
int pos = 270; // variable to store the servo position
void servoState(String status) {
int degrees_idx = 270;
if (status == "OPEN") {
for (pos = 0; pos <= degrees_idx; pos += 1) { // goes from 0 degrees to NNN degrees
// in steps of 1 degree
ServoGate.write(pos); // tell servo to go to position in variable 'pos'
delay(1); // waits 15ms for the servo to reach the position
}
} else if (status == "CLOSE") {
for (pos = degrees_idx; pos >= 0; pos -= 1) { // goes from NNN degrees to 0 degrees
ServoGate.write(pos); // tell servo to go to position in variable 'pos'
delay(1); // waits 15ms for the servo to reach the position
}
}
}