// *********************************************************************//
// includes //
// *********************************************************************//
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <LCDMenuLib2.h>
#include <Keypad.h>
#include <Servo.h>
#include <HX711.h>
// CONFIGURATION FOR LOADCELL HX711
#define DEBUG_HX711
#define CALIBRATION_FACTOR 0.42 //-217.7777777777778 sa codes natin
byte pinData = A0;
byte pinClk = A1;
int currentstep = 1; //keep the track ng steps natin
double weight1 = 5; // 5 grams of Grass
double weight2 = 10; // 10 grams of paper
double weight3 = 25; // 25 grams of Banana peel
double weight1a = 5; // 5 grams of grass
double weight2a = 10; // 10 grams of Banana peel
double weight3a = 25; // 25grams of Paper
double weight1b = 10; //10grams of grass
double weight2b = 20; //20 grams of paper
double weight3b = 50; //50 grams of Banana peel
HX711 scale;
// CONFIGURATION FOR SERVO MOTOR
Servo myServo0;
Servo myServo1;
int servoPin0 = 9;
int servoPin1 = 10;
int pos0 = 0;
int pos1 = 30;
int pos3 = 0 ; // Initial position of servo motor when sysyem turns on
// CONFIGURATION FOR RELAY MODULES
int SOLENOID_PIN = 11;
int RELAY_PIN = 12;
int Pump_PIN = 13;
//CONFIGURATION FOR I2C LCD
#define _LCDML_DISP_cols 20
#define _LCDML_DISP_rows 4
#define _LCDML_DISP_cfg_cursor 0x3E // cursor Symbol
#define _LCDML_DISP_cfg_scrollbar 1 // enable a scrollbar
LiquidCrystal_I2C lcd(0x27,_LCDML_DISP_cols,_LCDML_DISP_rows);
const uint8_t scroll_bar[5][8] = {
{B10001, B10001, B10001, B10001, B10001, B10001, B10001, B10001}, // scrollbar top
{B11111, B11111, B10001, B10001, B10001, B10001, B10001, B10001}, // scroll state 1
{B10001, B10001, B11111, B11111, B10001, B10001, B10001, B10001}, // scroll state 2
{B10001, B10001, B10001, B10001, B11111, B11111, B10001, B10001}, // scroll state 3
{B10001, B10001, B10001, B10001, B10001, B10001, B11111, B11111} // scrollbar bottom
};
void lcdml_menu_display();
void lcdml_menu_clear();
void lcdml_menu_control();
LCDMenuLib2_menu LCDML_0 (255, 0, 0, NULL, NULL); // root menu element (do not change)
LCDMenuLib2 LCDML(LCDML_0, _LCDML_DISP_rows, _LCDML_DISP_cols, lcdml_menu_display, lcdml_menu_clear, lcdml_menu_control);
LCDML_add (0 , LCDML_0 , 1 , "MODE 1" , MODE1); // this menu function can be found on "LCDML_display_menuFunction" tab
LCDML_add (1 , LCDML_0 , 2 , "MODE 2" , MODE2); // this menu function can be found on "LCDML_display_menuFunction" tab
LCDML_add (2 , LCDML_0 , 3 , "MODE 3" , MODE3);
LCDML_add (3 , LCDML_0 , 4 , "MANUAL MODE" , NULL);
LCDML_add (4 , LCDML_0_4 , 1 , "GRINDING/MIXING" , Manual1);
LCDML_add (5 , LCDML_0_4 , 2 , "SOLENOID VALVE" , Manual2);
LCDML_add (6 , LCDML_0_4 , 3 , "PUMP" , Manual3);
LCDML_add (7 , LCDML_0_4 , 4 , "WEIGHT SCALE" , Manual4);
LCDML_add (8 , LCDML_0_4 , 5 , "BACK" , mFunc_back);
// NULL = no menu function
#define _LCDML_DISP_cnt 8 //How many Display content
LCDML_createMenu(_LCDML_DISP_cnt);
// *********************************************************************//
// SETUP HERE //
// *********************************************************************//
void setup()
{
//SETUP FOR RELAYS
pinMode(SOLENOID_PIN, OUTPUT);
pinMode(RELAY_PIN, OUTPUT);
pinMode(Pump_PIN, OUTPUT);
digitalWrite(SOLENOID_PIN, HIGH);
digitalWrite(RELAY_PIN, HIGH);
digitalWrite(Pump_PIN, HIGH);
//SETUP FOR LOADCELL HX711
#ifdef DEBUG_HX711
// Initialize serial communication
Serial.begin(9600);
Serial.println("[HX7] Sensor start HX711");
#endif
scale.begin(pinData, pinClk);
scale.set_scale(CALIBRATION_FACTOR);
scale.tare();
//SETUP FOR SERVO MOTOR
myServo0.attach(servoPin0);
myServo1.attach(servoPin1);
myServo0.write(pos3);
myServo1.write(pos3);
// SETUP FOR LCD
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("QCU ELECTRONICS");
lcd.setCursor(0, 1);
lcd.print("ENGINEERING DEPT");
delay(2500);
lcd.clear();
delay(150);
lcd.setCursor(3, 0);
lcd.print("CONFIG");
delay(200);
lcd.setCursor(9, 0);
lcd.print(".");
delay(200);
lcd.setCursor(10, 0);
lcd.print(".");
delay(200);
lcd.setCursor(11, 0);
lcd.print(".");
delay(200);
lcd.setCursor(12, 0);
lcd.print(".");
delay(200);
delay(1000);; // initialize the LCD
lcd.createChar(0, (uint8_t*)scroll_bar[0]);
lcd.createChar(1, (uint8_t*)scroll_bar[1]);
lcd.createChar(2, (uint8_t*)scroll_bar[2]);
lcd.createChar(3, (uint8_t*)scroll_bar[3]);
lcd.createChar(4, (uint8_t*)scroll_bar[4]);
LCDML_setup(_LCDML_DISP_cnt);
LCDML.MENU_enRollover();
LCDML.SCREEN_disable();
}
// *********************************************************************//
// LOOP //
// *********************************************************************//
void loop()
{
LCDML.loop();
}
// *********************************************************************//
// Control //
// *********************************************************************//
#define _LCDML_CONTROL_cfg 4
#if(_LCDML_CONTROL_cfg == 4)
#define _LCDML_CONTROL_keypad_rows 4 // Four rows
#define _LCDML_CONTROL_keypad_cols 3 // Three columns
// global vars
char keys[_LCDML_CONTROL_keypad_rows][_LCDML_CONTROL_keypad_cols] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'#','0','*'}
};
byte rowPins[_LCDML_CONTROL_keypad_rows] = { 8, 7, 6, 5 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins.
byte colPins[_LCDML_CONTROL_keypad_cols] = { 4, 3, 2 }; // Create the Keypad
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, _LCDML_CONTROL_keypad_rows, _LCDML_CONTROL_keypad_cols );
void lcdml_menu_control(void)
{
// If something must init, put in in the setup condition
if(LCDML.BT_setup()) {
}
char key = kpd.getKey();
if(key) // Check for a valid key.
{
switch (key)
{
// this is the default configuration
case '#': LCDML.BT_enter(); break;
case '2': LCDML.BT_up(); break;
case '8': LCDML.BT_down(); break;
case '4': LCDML.BT_left(); break;
case '6': LCDML.BT_right(); break;
case '*': LCDML.BT_quit(); break;
// when you want to use all characters you have to use the CE_ functionality
// CE stands for "custom event" and you can define 64 evetns
// the following code is only an example
/*
case '1': LCDML.CE_set(2); break;
case '2': LCDML.CE_set(3); LCDML.BT_up(); break;
case '3': LCDML.CE_set(4); break;
case '4': LCDML.CE_set(5); LCDML.BT_left(); break;
case '5': LCDML.CE_set(6); break;
case '6': LCDML.CE_set(7); LCDML.BT_right(); break;
case '7': LCDML.CE_set(8); break;
case '8': LCDML.CE_set(9); LCDML.BT_down(); break;
case '9': LCDML.CE_set(10); break;
case '0': LCDML.CE_set(1); break;
case '#': LCDML.CE_set(12); LCDML.BT_enter(); break;
case '*': LCDML.CE_set(11); LCDML.BT_quit(); break;
*/
default: break;
}
}
}
#else
#error _LCDML_CONTROL_cfg is not defined or not in range
#endif
void lcdml_menu_clear()
{
lcd.clear();
lcd.setCursor(0, 0);
}
void lcdml_menu_display()
{
if (LCDML.DISP_checkMenuUpdate()) {
LCDML.DISP_clear();
char content_text[_LCDML_DISP_cols]; // save the content text of every menu element
LCDMenuLib2_menu *tmp;
uint8_t i = LCDML.MENU_getScroll();
uint8_t maxi = _LCDML_DISP_rows + i;
uint8_t n = 0;
if ((tmp = LCDML.MENU_getDisplayedObj()) != NULL)
{
do
{
if (tmp->checkCondition())
{
if(tmp->checkType_menu() == true)
{
LCDML_getContent(content_text, tmp->getID());
lcd.setCursor(1, n);
lcd.print(content_text);
}
else
{
if(tmp->checkType_dynParam()) {
tmp->callback(n);
}
}
i++;
n++;
}
} while (((tmp = tmp->getSibling(1)) != NULL) && (i < maxi));
}
}
if(LCDML.DISP_checkMenuCursorUpdate())
{
uint8_t n_max = (LCDML.MENU_getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.MENU_getChilds());
uint8_t scrollbar_min = 0;
uint8_t scrollbar_max = LCDML.MENU_getChilds();
uint8_t scrollbar_cur_pos = LCDML.MENU_getCursorPosAbs();
uint8_t scroll_pos = ((1.*n_max * _LCDML_DISP_rows) / (scrollbar_max - 1) * scrollbar_cur_pos);
for (uint8_t n = 0; n < n_max; n++)
{
lcd.setCursor(0, n);
if (n == LCDML.MENU_getCursorPos()) {
lcd.write(_LCDML_DISP_cfg_cursor);
} else {
lcd.write(' ');
}
if (_LCDML_DISP_cfg_scrollbar == 1) {
if (scrollbar_max > n_max) {
lcd.setCursor((_LCDML_DISP_cols - 1), n);
lcd.write((uint8_t)0);
}
else {
lcd.setCursor((_LCDML_DISP_cols - 1), n);
lcd.print(' ');
}
}
}
if (_LCDML_DISP_cfg_scrollbar == 1) {
if (scrollbar_max > n_max) {
//set scroll position
if (scrollbar_cur_pos == scrollbar_min) {
// min pos
lcd.setCursor((_LCDML_DISP_cols - 1), 0);
lcd.write((uint8_t)1);
} else if (scrollbar_cur_pos == (scrollbar_max - 1)) {
// max pos
lcd.setCursor((_LCDML_DISP_cols - 1), (n_max - 1));
lcd.write((uint8_t)4);
} else {
// between
lcd.setCursor((_LCDML_DISP_cols - 1), scroll_pos / n_max);
lcd.write((uint8_t)(scroll_pos % n_max) + 1);
}
}
}
}
}
// *********************************************************************//
// Menu Call Back //
// *********************************************************************//
void MODE1 (uint8_t param)
{
if(LCDML.FUNC_setup()) // ****** SETUP *********
{
LCDML.FUNC_setLoopInterval(100);
LCDML_UNUSED(param);
}
if(LCDML.FUNC_loop()) // ****** LOOP *********
{
#ifdef DEBUG_HX711
Serial.print("[HX7] Reading: ");
Serial.print(scale.get_units(), 2);
Serial.print(" Kgs");
Serial.println();
#endif
int Scale = scale.get_units();
lcd.setCursor (0, 1);
lcd.print( "Reading:" );
lcd.print(Scale);
lcd.print(" g");
if (currentstep == 1 && Scale >= weight1 && Scale < weight2) {
lcd.setCursor(0, 3);
lcd.print(" GRASS ATTAINED!");
delay(2000);
digitalWrite(SOLENOID_PIN, HIGH);
digitalWrite(RELAY_PIN, HIGH);
myServo0.write(pos1);
myServo1.write(pos1);
delay(1000);
lcd.clear();
currentstep++;
} else if (currentstep == 2 && Scale >= weight2 && Scale < weight3) {
lcd.setCursor(0, 3);
lcd.print(" PAPER ATTAINED");
delay(2000);
digitalWrite(SOLENOID_PIN, HIGH);
digitalWrite(RELAY_PIN, HIGH);
myServo0.write(pos1);
myServo1.write(pos1);
delay(1000);
lcd.clear();
currentstep++;
} else if (currentstep== 3 && Scale >= weight3) {
lcd.setCursor(0, 3);
lcd.print("Banana Peel Attained");
delay(2000);
lcd.clear();
myServo0.write(pos1);
myServo1.write(pos1);
delay(500);
myServo0.write(pos0);
myServo1.write(pos0);
lcd.setCursor(0, 1);
lcd.print(" PLEASE WAIT!!!!");
digitalWrite(SOLENOID_PIN, LOW);
delay(10000);
digitalWrite(SOLENOID_PIN,HIGH);
delay(100);
digitalWrite(RELAY_PIN, LOW);
delay(10000);
digitalWrite(RELAY_PIN,HIGH);
delay(100); //Double check natin yung delay kapag andyan na adjust natin~
digitalWrite(Pump_PIN, LOW);
delay(10000);
digitalWrite(Pump_PIN, HIGH);
delay(1000);
lcd.clear();
currentstep++;
} else {
lcd.setCursor (1, 0);
lcd.print( "PLACE RAW MATERIALS" );
digitalWrite(SOLENOID_PIN, HIGH);
digitalWrite(RELAY_PIN, HIGH);
digitalWrite(Pump_PIN, HIGH);
myServo0.write(pos0);
myServo1.write(pos0);
}
if (currentstep == 4) {
currentstep = 1;
}
delay(50);
}
if(LCDML.FUNC_close()){ // ****** STABLE END *********
{
}
}
}
void MODE2 (uint8_t param)
{
if(LCDML.FUNC_setup()) // ****** SETUP *********
{
LCDML.FUNC_setLoopInterval(100);
LCDML_UNUSED(param);
}
if(LCDML.FUNC_loop()) // ****** LOOP *********
{
#ifdef DEBUG_HX711
Serial.print("[HX7] Reading: ");
Serial.print(scale.get_units(), 2);
Serial.print(" Kgs");
Serial.println();
#endif
int Scale = scale.get_units();
lcd.setCursor (0, 1);
lcd.print( "Reading:" );
lcd.print(Scale);
lcd.print(" g");
if (currentstep == 1 && Scale >= weight1a && Scale < weight2a) {
lcd.setCursor(0, 3);
lcd.print(" GRASS ATTAINED!");
delay(2000);
digitalWrite(SOLENOID_PIN, HIGH);
digitalWrite(RELAY_PIN, HIGH);
myServo0.write(pos1);
myServo1.write(pos1);
delay(1000);
lcd.clear();
currentstep++;
} else if (currentstep == 2 && Scale >= weight2a && Scale < weight3a) {
lcd.setCursor(0, 3);
lcd.print("Banana Peel Attained");
delay(2000);
digitalWrite(SOLENOID_PIN, HIGH);
digitalWrite(RELAY_PIN, HIGH);
myServo0.write(pos1);
myServo1.write(pos1);
delay(1000);
lcd.clear();
currentstep++;
} else if (currentstep== 3 && Scale >= weight3a) {
lcd.setCursor(0, 3);
lcd.print(" PAPER ATTAINED");
delay(2000);
lcd.clear();
myServo0.write(pos1);
myServo1.write(pos1);
delay(500);
myServo0.write(pos0);
myServo1.write(pos0);
lcd.setCursor(0, 1);
lcd.print(" PLEASE WAIT!!!!");
digitalWrite(SOLENOID_PIN, LOW);
delay(10000);
digitalWrite(SOLENOID_PIN,HIGH);
delay(100);
digitalWrite(RELAY_PIN, LOW);
delay(10000);
digitalWrite(RELAY_PIN,HIGH);
delay(100); //Double check natin yung delay kapag andyan na adjust natin~
digitalWrite(Pump_PIN, LOW);
delay(10000);
digitalWrite(Pump_PIN, HIGH);
delay(1000);
lcd.clear();
currentstep++;
} else {
lcd.setCursor (1, 0);
lcd.print( "PLACE RAW MATERIALS" );
digitalWrite(SOLENOID_PIN, HIGH);
digitalWrite(RELAY_PIN, HIGH);
digitalWrite(Pump_PIN, HIGH);
myServo0.write(pos0);
myServo1.write(pos0);
}
if (currentstep == 4) {
currentstep = 1;
}
delay(50);
}
if(LCDML.FUNC_close()){ // ****** STABLE END *********
{
}
}
}
void MODE3 (uint8_t param)
{
if(LCDML.FUNC_setup()) // ****** SETUP *********
{
LCDML.FUNC_setLoopInterval(100);
LCDML_UNUSED(param);
}
if(LCDML.FUNC_loop()) // ****** LOOP *********
{
#ifdef DEBUG_HX711
Serial.print("[HX7] Reading: ");
Serial.print(scale.get_units(), 2);
Serial.print(" Kgs");
Serial.println();
#endif
int Scale = scale.get_units();
lcd.setCursor (0, 1);
lcd.print( "Reading:" );
lcd.print(Scale);
lcd.print(" g");
if (currentstep == 1 && Scale >= weight1b && Scale < weight2b) {
lcd.setCursor(0, 3);
lcd.print(" GRASS ATTAINED!");
delay(2000);
digitalWrite(SOLENOID_PIN, HIGH);
digitalWrite(RELAY_PIN, HIGH);
myServo0.write(pos1);
myServo1.write(pos1);
delay(1000);
lcd.clear();
currentstep++;
} else if (currentstep == 2 && Scale >= weight2b && Scale < weight3b) {
lcd.setCursor(0, 3);
lcd.print("Banana Peel Attained");
delay(2000);
digitalWrite(SOLENOID_PIN, HIGH);
digitalWrite(RELAY_PIN, HIGH);
myServo0.write(pos1);
myServo1.write(pos1);
delay(1000);
lcd.clear();
currentstep++;
} else if (currentstep== 3 && Scale >= weight3b) {
lcd.setCursor(0, 3);
lcd.print(" PAPER ATTAINED");
delay(2000);
lcd.clear();
myServo0.write(pos1);
myServo1.write(pos1);
delay(500);
myServo0.write(pos0);
myServo1.write(pos0);
lcd.setCursor(0, 1);
lcd.print(" PLEASE WAIT!!!!");
digitalWrite(SOLENOID_PIN, LOW);
delay(10000);
digitalWrite(SOLENOID_PIN,HIGH);
delay(100);
digitalWrite(RELAY_PIN, LOW);
delay(10000);
digitalWrite(RELAY_PIN,HIGH);
delay(100); //Double check natin yung delay kapag andyan na adjust natin~
digitalWrite(Pump_PIN, LOW);
delay(10000);
digitalWrite(Pump_PIN, HIGH);
delay(1000);
lcd.clear();
currentstep++;
} else {
lcd.setCursor (1, 0);
lcd.print( "PLACE RAW MATERIALS" );
digitalWrite(SOLENOID_PIN, HIGH);
digitalWrite(RELAY_PIN, HIGH);
digitalWrite(Pump_PIN, HIGH);
myServo0.write(pos0);
myServo1.write(pos0);
}
if (currentstep == 4) {
currentstep = 1;
}
delay(50);
}
if(LCDML.FUNC_close()){ // ****** STABLE END *********
{
}
}
}
// *********************************************************************
void mFunc_back(uint8_t param) /////////////////////////////////////
// *********************************************************************
{
if(LCDML.FUNC_setup()) // ****** SETUP *********
{
// remmove compiler warnings when the param variable is not used:
LCDML_UNUSED(param);
// end function and go an layer back
LCDML.FUNC_goBackToMenu(1); // leave this function and go a layer back
}
}
// *********************************************************************
void Manual1(uint8_t param) /////////////////////////////////////
// *********************************************************************
{
if(LCDML.FUNC_setup()) // ****** SETUP *********
{
LCDML.FUNC_setLoopInterval(1);
LCDML_UNUSED(param);
lcd.setCursor (1, 0);
lcd.clear();
lcd.print( "SOLENOID VALVE" );
lcd.setCursor (1, 1);
lcd.print( " STATUS: ON" );
lcd.setCursor (0, 2);
lcd.print( "To turn off pressed" );
lcd.setCursor (5, 3);
lcd.print( "BACK" );
digitalWrite(SOLENOID_PIN, LOW);
}
if(LCDML.FUNC_loop()){
char key = kpd.getKey();
if(key) // Check for a valid key.
{
switch (key)
{
// this is the default configuration
case '#': digitalWrite(RELAY_PIN,LOW); LCDML.BT_enter(); break;
case '*': digitalWrite(RELAY_PIN, HIGH); LCDML.BT_quit(); break;
}
}
}
}
// *********************************************************************
void Manual2(uint8_t param) /////////////////////////////////////
// *********************************************************************
{
if(LCDML.FUNC_setup()) // ****** SETUP *********
{
lcd.setCursor (1, 0);
lcd.print( "SOLENOID VALVE" );
lcd.setCursor (1, 1);
lcd.print( " STATUS: ON" );
lcd.setCursor (0, 2);
lcd.print( "To turn off pressed" );
lcd.setCursor (5, 3);
lcd.print( "BACK" );
digitalWrite(SOLENOID_PIN, LOW);
}
}
// *********************************************************************
void Manual3(uint8_t param) /////////////////////////////////////
// *********************************************************************
{
if(LCDML.FUNC_setup()) // ****** SETUP *********
{
lcd.setCursor (1, 0);
lcd.print( "SOLENOID_PIN" );
lcd.setCursor (1, 1);
lcd.print( " STATUS: ON" );
lcd.setCursor (0, 2);
lcd.print( "To turn off pressed" );
lcd.setCursor (5, 3);
lcd.print( "BACK" );
digitalWrite( Pump_PIN, LOW);
}
}
// *********************************************************************
void Manual4(uint8_t param) /////////////////////////////////////
// *********************************************************************
{
LCDML.FUNC_setLoopInterval(100);
LCDML_UNUSED(param); // ****** SETUP *********
{
#ifdef DEBUG_HX711
Serial.print("[HX7] Reading: ");
Serial.print(scale.get_units(), 2);
Serial.print(" Kgs");
Serial.println();
#endif
int Scale = scale.get_units();
lcd.setCursor (0, 1);
lcd.print( "Reading:" );
lcd.print(Scale);
lcd.print(" g");
}
}