#include <LiquidCrystal.h>
unsigned int timeLeft = 0;
unsigned int timeLeft2 = 0;
int zapnute = 0; // turned on
int zacate = 0; // started
int spinSel = 0;
int prog = 0;
int spinPlus = 0;
int drumSpeedWash = 90; // speed of drum when washing (in eRPM)
int currSpinSpeed = 90; // current spinning RPM (here it is once set to be wash drum speed)
int select = 1;
int error = 0;
int step = 0;
unsigned long errcode = 0;
unsigned long coiltime = 0; // time between switching to another coil
unsigned long coilfreq = 0; // frequency of coil switching
unsigned long present = 0;
unsigned long past = 0;
unsigned long past2 = 0;
unsigned long past4 = 0;
unsigned long past5 = 0;
unsigned long present3 = 0;
unsigned long past3 = 0;
int spinRPM = 9000; // default spin speed in eRPM (3 pole motor recommended)
// eRPM is easier for me to deal with
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
// <> [] {}
void setup() {
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT); // LCD pins
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT); // drain
pinMode(9, OUTPUT); // U
pinMode(10, OUTPUT); // V
pinMode(11, OUTPUT); // W
pinMode(12, OUTPUT); // fill
pinMode(13, OUTPUT); // backlight
lcd.begin(16, 2);
pinMode(A1, INPUT_PULLUP); // Spin selection
pinMode(A2, INPUT_PULLUP); // On/Off (simulated)
pinMode(A3, INPUT_PULLUP); // Start button ("only starts the selected program")
pinMode(A4, INPUT_PULLUP); // Spin+ toggle ("4000rpm spin, but only up to 50 grams due to risk of overload and motor desynchronization")
pinMode(A5, INPUT_PULLUP); // Door switch ("interrupts program and shows a time based error code, example: E-53")
lcd.print("Time left");
lcd.setCursor(0, 1);
lcd.print("is in minutes");
delay(2000);
lcd.clear();
lcd.print("Prog + HowSoiled");
lcd.setCursor(0, 1);
lcd.print("Time + RPM");
delay(2000);
lcd.clear();
Serial.begin(9600);
}
void loop() {
present = millis(); // general purpose time fetcher
present3 = micros(); // motor driving time fetcher
// displaying things {
while (error == 1 && zapnute == 1) {
zacate = 0;
error = 1;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("DOOR ERROR");
lcd.setCursor(0, 1);
lcd.print("Fault nr.:");
lcd.setCursor(11, 1);
lcd.print(errcode);
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
digitalWrite(11, LOW);
digitalWrite(12, LOW);
if (zapnute == 1 && digitalRead(A2) == LOW) {
delay(250);
zapnute = 0;
}
delay(10);
}
errcode = millis() / 5157952;
if (zapnute == 1) {
digitalWrite(13, HIGH);
}
if (zapnute == 0) {
digitalWrite(13, LOW);
lcd.clear();
error = 0;
zacate = 0;
spinSel = 0;
spinPlus = 0;
past5 = 0;
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
digitalWrite(11, LOW);
digitalWrite(12, LOW);
}
if (zapnute == 1 && digitalRead(A2) == LOW) {
delay(250);
zapnute = 0;
}
if (zapnute == 0 && digitalRead(A2) == LOW) {
delay(250);
zapnute = 1;
select = 1;
}
if (spinPlus == 1 && digitalRead(A4) == LOW) {
delay(250);
spinPlus = 0;
}
if (spinPlus == 0 && digitalRead(A4) == LOW) {
delay(250);
spinPlus = 1;
spinSel = 0;
}
if (zacate == 1 && digitalRead(A3) == LOW) {
delay(250);
zacate = 0;
select = 1;
}
if (digitalRead(A5) == HIGH && zacate == 1) {
delay(250);
zacate = 0;
error = 1;
}
if (digitalRead(A5) == HIGH && analogRead(A3) == LOW) {
delay(250);
zacate = 0;
error = 1;
}
if (zacate == 0 && digitalRead(A3) == LOW && digitalRead(A5) == LOW) {
delay(250);
zacate = 1;
select = 0;
past2 = present;
}
if (spinPlus == 1) {
spinRPM = 12000;
}
if (spinSel == 14) {
spinSel = 0;
}
if (digitalRead(A1) == LOW) {
delay(250);
spinSel = spinSel + 1;
}
if (zacate == 0) {
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
digitalWrite(11, LOW);
digitalWrite(12, LOW);
past5 = present;
currSpinSpeed = 90;
coilfreq = 15;
coiltime = 222222;
}
if (zapnute == 1 && zacate == 0 && present - past >= 500 && select == 1) {
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 0);
prog = analogRead(A0) / 148;
timeLeft2 = timeLeft;
switch (prog) {
case 0:
timeLeft = 30;
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print("Fast ");
lcd.setCursor(8, 0);
lcd.print("Slightly");
lcd.setCursor(0, 1);
lcd.print("0:30");
lcd.setCursor(12, 1);
lcd.print(" ");
lcd.setCursor(12, 1);
lcd.print(spinRPM / 3);
break;
case 1:
timeLeft = 120;
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print("Slow ");
lcd.setCursor(8, 0);
lcd.print(" Heavily");
lcd.setCursor(0, 1);
lcd.print("2:00");
lcd.setCursor(12, 1);
lcd.print(" ");
lcd.setCursor(12, 1);
lcd.print(spinRPM / 3);
break;
case 2:
timeLeft = 60;
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print("Normal");
lcd.setCursor(8, 0);
lcd.print("Mediumly");
lcd.setCursor(0, 1);
lcd.print("1:00");
lcd.setCursor(12, 1);
lcd.print(" ");
lcd.setCursor(12, 1);
lcd.print(spinRPM / 3);
break;
case 3:
timeLeft = 20;
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print("Fast+ ");
lcd.setCursor(9, 0);
lcd.print("Faintly");
lcd.setCursor(0, 1);
lcd.print("0:20");
lcd.setCursor(12, 1);
lcd.print(" ");
lcd.setCursor(12, 1);
lcd.print(spinRPM / 3);
break;
case 4:
timeLeft = 10;
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print("Spin ");
lcd.setCursor(10, 0);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print("0:10");
lcd.setCursor(12, 1);
lcd.print(" ");
lcd.setCursor(12, 1);
lcd.print(spinRPM / 3);
break;
case 5:
timeLeft = 1;
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print("Drain ");
lcd.setCursor(10, 0);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print("0:01");
lcd.setCursor(12, 1);
lcd.print(" ");
break;
case 6:
timeLeft = 30;
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.setCursor(0, 0);
lcd.print("Rinse ");
lcd.setCursor(10, 0);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print("0:30");
lcd.setCursor(12, 1);
lcd.print(" ");
lcd.setCursor(12, 1);
lcd.print(spinRPM / 3);
break;
}
past = present;
}
if (spinPlus == 0) {
switch (spinSel) {
case 0:
spinRPM = 9000;
break;
case 1:
spinRPM = 7500;
break;
case 2:
spinRPM = 6000;
break;
case 3:
spinRPM = 5400;
break;
case 4:
spinRPM = 4800;
break;
case 5:
spinRPM = 4500;
break;
case 6:
spinRPM = 4200;
break;
case 7:
spinRPM = 3600;
break;
case 8:
spinRPM = 3000;
break;
case 9:
spinRPM = 2400;
break;
case 10:
spinRPM = 1800;
break;
case 11:
spinRPM = 1200;
break;
case 12:
spinRPM = 600;
break;
case 13:
spinRPM = 120;
break;
}
}
if (zapnute == 1 && zacate == 1 && present - past2 >= 60000 && timeLeft > 0) {
timeLeft2 = timeLeft - 1;
timeLeft = timeLeft2;
past2 = present;
}
if (timeLeft == 0 && zapnute == 1 && present - past >= 1000) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Done washing! ");
lcd.setCursor(0, 1);
lcd.print(" Ready for more ");
past = present;
digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
digitalWrite(11, LOW);
digitalWrite(12, LOW);
}
if (zapnute == 1 && zacate == 1 && present - past >= 1000) {
lcd.setCursor(0, 0);
lcd.print("Running... ");
lcd.setCursor(0, 1);
lcd.print("Time left: ");
lcd.setCursor(13, 1);
lcd.print(timeLeft);
past = present;
}
// } displaying things
// program calling {
if (zapnute == 1 && zacate == 1 && select == 0) {
bldcMove();
coilfreq = currSpinSpeed / 2;
coiltime = 10000000 / coilfreq;
switch (prog) {
case 0:
fast();
break;
case 1:
slow();
break;
case 2:
normal();
break;
case 3:
fastplus();
break;
case 4:
spin();
break;
case 5:
drain();
break;
case 6:
rinse();
break;
}
// } program calling
}
}
void drain() {
if (present - past5 <= 59000) {
digitalWrite(8, HIGH);
}
else {
digitalWrite(8, LOW);
}
}
void spin() {
if (present - past5 < 510000) {
drainstart();
speedup();
}
if (present - past5 >= 510000 && present - past5 <= 599000) {
drainstop();
speeddown();
}
}
void fastplus() {
if(present - past5 > 1000 && present - past5 <= 20000) {
fill();
}
if (present - past5 >= 270000 && present - past5 < 540000) {
drainstart();
speedup();
}
if (present - past5 >= 540000 && present - past5 < 660000) {
drainstop();
speeddown();
if (currSpinSpeed == 95) {
fill();
}
}
if (present - past5 >= 660000 && present - past5 < 780000) {
drainstart();
speedup();
}
if (present - past5 >= 780000 && present - past5 < 900000) {
drainstop();
speeddown();
if (currSpinSpeed == 95) {
fill();
}
}
if (present - past5 >= 900000 && present - past5 < 1050000) {
drainstart();
speedup();
}
if (present - past5 >= 1050000 && present - past5 < 1200000) {
drainstop();
speeddown();
}
}
void rinse() {}
void fast() {}
void normal() {}
void slow() {}
void speedup() {
if (currSpinSpeed < spinRPM && present - past4 >= 3) {
currSpinSpeed = currSpinSpeed + 1;
past4 = present;
}
if (currSpinSpeed >= spinRPM) {
currSpinSpeed = spinRPM;
}
}
void speeddown() {
if (currSpinSpeed > drumSpeedWash && present - past4 >= 2) {
currSpinSpeed = currSpinSpeed - 1;
past4 = present;
}
if (currSpinSpeed <= drumSpeedWash) {
currSpinSpeed = drumSpeedWash;
}
}
void bldcMove() {
switch (step) {
case 0:
digitalWrite(10, LOW);
digitalWrite(11, LOW);
digitalWrite(9, HIGH);
break;
case 1:
digitalWrite(9, LOW);
digitalWrite(11, LOW);
digitalWrite(10, HIGH);
break;
case 2:
digitalWrite(10, LOW);
digitalWrite(9, LOW);
digitalWrite(11, HIGH);
break;
}
if (step >= 3) {
step = 0;
}
if (present3 - past3 >= coiltime) {
step = step + 1;
past3 = present3;
}
}
void fill() {
digitalWrite(9, LOW);
digitalWrite(10, LOW);
digitalWrite(11, LOW);
digitalWrite(12, HIGH);
delay(5000);
digitalWrite(12, LOW);
delay(5000);
digitalWrite(12, HIGH);
delay(5000);
digitalWrite(12, LOW);
delay(5000);
digitalWrite(12, HIGH);
delay(5000);
digitalWrite(12, LOW);
delay(5000);
}
void drainstart() {
digitalWrite(8, HIGH);
}
void drainstop() {
digitalWrite(8, LOW);
}
//if(present - past5 >= && present - past5 < ) {}