Introduction: UCL - IIoT - Schoole Made, Coffee Machine

About: Made by; clau3111, nico749g and hans1627

We are a group of students from UCL, we have made a Coffee Machine, from the scratch. In our process we used 3D-, laser printer and an Arduino Mega 2560. Our education is Automation Engineering, and we are on our third Semester. This is a self chosen project, where we have to learn about, industry 4.0, data logging, database and smart connect. Last year we made our Coffee Machine, this time we had to optimize it, so it can be related to the industry 4.0 world.

https://www.instructables.com/id/Coffee-Machine-EA...

Step 1: Database

Step 2: Node-Red

Step 3: Dashboard

Step 4: Communication

Step 5: Program

Step 1: Database

One of our plans for optimizing the Coffee Machine, was to logging a lot of data from our Arduino program. It shouldn't just be some random data, but data we could use for something practical. Therefore we decided to log some data, from the motors and pump. To do that, we had to make a database for controlling all of the data, a database is a systematic collection of data. Since the data in a database is organized, it makes the data management easier. There are several servers you can use to make your own database, we used MySQL, MySQL is an easy client-server program consisting a server and different client programs. SQL(Structured Query Language) is the language, today SQL is the most popular database language.

The data from our database, will be used later in Node-Red, before they are displayed in the Dashboard.

In the Appendix you can see that we have 5 columns in our database, one for coffee, hot chocolate, milk, pump and one for the timestamp. When it's put in the database, it's written to the database as text. So when we take the numbers from the database, we have to convert them into numbers. In Node-Red we have a function called "nodered" which take the data and turn it in to a string and send it to our Database.

Step 2: Node-Red

Node-Red is a visual programming tool, that is performed with drag-drop commands, written in JavaScript.

We have used Node-Red to connect the Arduino Mega 2650 with our MySQL database. This is done so we could collect information from the mechanical parts, its done to provide an overview of when to replace the mechanical pars. In order to reduce downtime at the machine and ordering new spear parts, in time. It works in such a way that the Arduino sends the "time" engine 1, 2, 3 and the pump has run (and more information) to Node-Red. In our process, did we find out that we could use the "time", for saying when the silos where empty and need refilling. This information can be forwarded to our database and/or displayed on our dashboard.

Step 3: Dashboard

Our dashboard is made to control our Coffee Machine, In a easy way over the network. At the Dashboard you can see some different values, about the Coffee Machine. the temperature it is hot enough, time for the motors for the mixing is proceeded. The level in our silos, so we know when to refill, the Powder. There are 3 sliders that control, how long the motors have run, they can vary from 0 to 8 seconds.

The Dashboard is controlled by Node-Red who gets the instructions from Arduino.

Step 4: Communication

We had a wish to establish a wifi module to avoid wired communication between our Coffee Machine and PC.

Along with our work, several issues arose . First, we tried to get an UDP (User Datagram Protocol) connection up running. It wasn't possible because there were no libraries, that worked with the Mega2560 and ESP8266 setup.

Then we tried to establish a server-client communication, where the ESP8266 module acts as a server. The ESP8266 module connects to a local network, the PC should then be the client and be in the same network. In that way, it was possible to read our information on a browser or read it, into Node-Red. It did work, but we got trouble updating our information within a desired range. The wish was to update after the end of the program cycle, but it wasn't possible to bring the time under 10 seconds. In that way it would take 10 seconds, for choosing a product and ordering the drink. Which we didn't think would be optimal, and therefore did we chose to use the wired connection, to make the best way possible for our coffee maker.

Step 5: Program

In combination with our Coffee Machine, we had developed a little in our Arduino program.
At the top of Instructables, there is a link to the original Coffee Machine, where you can find the old code from from where we started.There isn't much left of the original code, among other things did we have lot of delays, that we change to millis to optimize the program. When we used delays our communication stopped while making a cup of coffee, it meant that the watch we had on our dashboard, couldn't show how far the brewing was. With the delays, the entire program had to run through, before the Arduino could send information. It didn’t make sense, therefore did we change the drive to millis.

Then we made our program into 2 programs. 1 for brewing coffee over the Dashboard, second for brewing directly from the Coffee Machine. We had to do that because the 2 programs works in different ways. On the front of our Coffee Machine, we have some contacts that provide digital inputs. These inputs can't be overwritten from the program we use to the Dashboard and Node-Red. because we have 2 different programs, means also that we have different choices of strength to the coffee, chocolate and milk. Our program for the Coffee Machine, have 3 inputs 0,1 or 2, and the Dashboard is analog.

After setting up the Dashboard, we had to make some data collection and communication. We are sending all the data by using serial communication, to sending strings to Node-Red. Through Node-Red and Arduino are we exchanging data about, how long the engines have run, temperature of the water, level in the silos and how filled the cup are. Our Arduino program sends data approx 10 times in a second to Node-Red. Then we got some data from node-Red to Arduino diverse buttons, and some "sliders" to set the strength, of the drink, it is being sent as a float to the Arduino, where we split the data to different variables.

//indgange
int kaffe; int dbkaffe; int kakao; int dbkakao; int maelk; int dbmaelk; float temp; int niveau; int start; //udgange int kaffemotor; int kakaomotor; int maelkemotor; int pumpe; int done; int varme; int brygning; int klar; int brygger; int fejl;

//interne int og floats float a; //kaffe timetæller float b; //kakao timetæller float cc; //mælk timetæller float e; //pumpe timetæller int d; //aktuel step float f; long g; float h; float i; float j; float k; float l; float m; float n; float o; float p; float q; float r; float s; float t; float kaffekoeretidwifi; //tid fra server hvor meget kaffe der skal bruges float kakaokoeretidwifi; //tid fra server hvor meget kakao der skal bruges float maelkekoeretidwifi; //tid fra server hvor meget mælk der skal bruges //forskellige køretider til div motorer long sek2; long sek3; long sek4; long sek5; long sek6; long sek7; long sek8; //starttidspunkt for millis timere unsigned long starttime; unsigned long starttime2; unsigned long starttime3;

unsigned long currenttime; //"ur" i arduino

void setup() {

pinMode(48,OUTPUT); pinMode(49,OUTPUT); pinMode(50,OUTPUT); pinMode(51,OUTPUT); pinMode(44,OUTPUT); pinMode(45,OUTPUT); pinMode(46,OUTPUT); pinMode(47,OUTPUT);

//sætter forskellige tider til køretider af motorer sek2=2000; sek3=3000; sek4=4000; sek5=5000; sek6=6000; sek7=7000; sek8=8000;

// sætter floats til 0 for at have en start værdi float l=0; float m=0; float n=0; float o=0; float p=0; float q=0;

// giver ind- og udgange navne

//indgange temp =A0; kaffe =22; dbkaffe =23; kakao =24; dbkakao =25; maelk =26; dbmaelk =27; start =28; niveau =29;

//udgange kaffemotor =48; kakaomotor =49; maelkemotor =50; pumpe = 51; varme = 44; klar = 45; brygger = 46; fejl = 47;

//fortæller hvilke der er indgange og udgange pinMode(22,INPUT); pinMode(23,INPUT); pinMode(24,INPUT); pinMode(25,INPUT); pinMode(26,INPUT); pinMode(27,INPUT); pinMode(28,INPUT); pinMode(29,INPUT); //sørger for at motorerne er slukket digitalWrite(kaffemotor,HIGH); digitalWrite(kakaomotor,HIGH); digitalWrite(maelkemotor,HIGH); digitalWrite(pumpe,HIGH); d=0; Serial.begin(9600); }

void loop() { currenttime = millis();

if ((analogRead(temp)>=425)&&(digitalRead(niveau)==LOW)) digitalWrite(varme,LOW); //tænder for varmen når vandet bliver for koldt else if ((analogRead(temp)<=423)||(digitalRead(niveau)==HIGH)) digitalWrite(varme,HIGH); //slukker for varmen når vandet er varmt nok else(delay(0)); if ((digitalRead(niveau)==HIGH)||(analogRead(temp)>=430)){ //hvis vandet ikke er varmt nok eller der ikke er vand i beholderen så tænder den digitalWrite(fejl,HIGH);} //"fejl" dioden og slukker "klar" dioden else digitalWrite(fejl,LOW); //hvis der er vand nok i beholderen og varmt nok så tænder den //"klar" dioden og slukker "fejl" dioden if (d==0){ digitalWrite(brygger,LOW);} //slukker "brygger" dioden else digitalWrite(brygger,HIGH); //tænder "brygger" dioden

if (((d==0)&&(digitalRead(niveau)==LOW)&&(analogRead(temp)<=430))){ digitalWrite(klar,HIGH);} //tænder "klar" dioden else digitalWrite(klar,LOW); //slukker "klar" dioden

//hvis den er i standby step og der er vand i tanken og dee er varmt nok og man trykker start så starter processen if ((d==0)&&(digitalRead(start)==HIGH)&&(digitalRead(niveau)==LOW)&&(analogRead(temp)<=430)){ d=1;

} else delay(0);

//kaffe if ((d==1)&&(digitalRead(kaffe)==HIGH)){ //hvis kaffe 1 er valgt kører dette "step" digitalWrite(kaffemotor,LOW); starttime=currenttime; d=2;} else if ((d==1)&&(digitalRead(dbkaffe)==HIGH)){ //hvis kaffe 2 er valgt kører dette "step" digitalWrite(kaffemotor,LOW); starttime=currenttime; d=3;}

else if ((d==1)&&((digitalRead(kaffe)==LOW)&&(digitalRead(dbkaffe)==LOW)))(d=4); //hvis kaffe ikke er valgt kører dette "step" else delay(0);

if ((d==2)&&(currenttime-starttime>=sek5)){ //hvis kaffe 2 er valgt kører dette "step" digitalWrite(kaffemotor,HIGH); a=a+5; l=l+5;

d=4;} else delay(0); if ((d==3)&&(currenttime-starttime>=sek8)){ //hvis kaffe 1 er valgt kører dette "step" digitalWrite(kaffemotor,HIGH); a=a+8; l=l+8;

d=4;} else delay(0); //kakao

if ((d==4)&&(digitalRead(kakao)==HIGH)){ //hvis kakao 1 er valgt kører dette "step" digitalWrite(kakaomotor,LOW); starttime=currenttime; d=5;} else if ((d==4)&&(digitalRead(dbkakao)==HIGH)){ //hvis kakao 2 er valgt kører dette "step" digitalWrite(kakaomotor,LOW); starttime=currenttime; d=6;}

else if ((d==4)&&((digitalRead(kakao)==LOW)&&(digitalRead(dbkakao)==LOW)))(d=7);//hvis kakao ikke er valgt kører dette "step" else delay(0);

if ((d==5)&&(currenttime-starttime>=sek5)){ //hvis kakao 1 er valgt kører dette "step" digitalWrite(kakaomotor,HIGH); b=b+5; m=m+5;

d=7;} else delay(0); if ((d==6)&&(currenttime-starttime>=sek8)){ //hvis kakao 2 er valgt kører dette "step" digitalWrite(kakaomotor,HIGH); b=b+8; m=m+8;

d=7;} else delay(0);

//maelk if ((d==7)&&(digitalRead(maelk)==HIGH)){ //hvis mælk 1 er valgt kører dette "step" digitalWrite(maelkemotor,LOW); starttime=currenttime; d=8;} else if ((d==7)&&(digitalRead(dbmaelk)==HIGH)){ //hvis mælk 2 er valgt kører dette "step" digitalWrite(maelkemotor,LOW); starttime=currenttime; d=9;} else if ((d==7)&&((digitalRead(maelk)==LOW)&&(digitalRead(dbmaelk)==LOW)))(d=10); //hvis mælk ikke er valgt kører dette "step"

else delay(0); if ((d==8)&&(currenttime-starttime>=sek5)){ //hvis mælk 1 er valgt kører dette "step" digitalWrite(maelkemotor,HIGH); cc=cc+2; n=n+2;

d=10;} else delay(0); if ((d==9)&&(currenttime-starttime>=sek8)){ //hvis mælk 2 er valgt kører dette "step" digitalWrite(maelkemotor,HIGH); cc=cc+4; n=n+4;

d=10;} else delay(0); // pumpe if (d==10){ //tænder pumpen starttime=currenttime; digitalWrite(pumpe,LOW); d=11;} else delay(0); if ((d==11)&&(currenttime-starttime>=sek7)){ //slukker pumpen digitalWrite(pumpe,HIGH); e=e+7;

d=0;} else delay(0);

////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////

/via database if ((d==0)&&(k==1)&&(digitalRead(niveau)==LOW)&&(analogRead(temp)<=430)){ d=21; starttime2=currenttime; } else delay(0);

//kaffe if (d==21){ //hvis kaffe 1 er valgt kører dette "step" digitalWrite(kaffemotor,LOW); starttime=currenttime; d=22;} else delay(0);

if ((d==22)&&(currenttime-starttime>=kaffekoeretidwifi)){ digitalWrite(kaffemotor,HIGH); a=a+(kaffekoeretidwifi/1000); l=l+(kaffekoeretidwifi/1000);

d=24;} else delay(0); //kakao

if (d==24){ digitalWrite(kakaomotor,LOW); starttime=currenttime; d=25;} else delay(0);

if ((d==25)&&(currenttime-starttime>=kakaokoeretidwifi)){ digitalWrite(kakaomotor,HIGH); b=b+(kakaokoeretidwifi/1000); m=m+(kakaokoeretidwifi/1000);

d=27;} else delay(0);

//maelk if (d==27){ //hvis mælk 1 er valgt kører dette "step" digitalWrite(maelkemotor,LOW); starttime=currenttime; d=28;} else delay(0); if ((d==28)&&(currenttime-starttime>=maelkekoeretidwifi)){ digitalWrite(maelkemotor,HIGH); cc=cc+(maelkekoeretidwifi/1000); n=n+(maelkekoeretidwifi/1000); d=30;} else delay(0); // pumpe if (d==30){ starttime=currenttime; digitalWrite(pumpe,LOW); d=31;} else delay(0); if ((d==31)&&(currenttime-starttime>=sek7)){ digitalWrite(pumpe,HIGH); e=e+7; d=0;} else delay(0); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //procent hvor langt brygningen er f=100/(kaffekoeretidwifi+kakaokoeretidwifi+maelkekoeretidwifi+sek7); g=currenttime-starttime2; h= (float)g; i=h*f; if (d<=20)i=0; else delay(0);

while(Serial.available()>0){ j += Serial.parseFloat();}

//her tager den dataene fra arduino og laver dem og lægger dem i de rigtige variabler if ((j >= 2)&&(j<=10002)) kaffekoeretidwifi=j-2; else delay(0);

if ((j >= 10003)&&(j<=20003)) kakaokoeretidwifi=j-10003; else delay(0);

if ((j >= 20004)&&(j<=30004)) maelkekoeretidwifi=j-20004; else delay(0);

if (j==1)k=1; else k=0;

r=((l-o)*-1)+100; s=((m-p)*-1)+100; t=((n-q)*-1)+100;

Serial.print(a); Serial.print(","); Serial.print(b); Serial.print(","); Serial.print(cc); Serial.print(","); Serial.print(e); Serial.print(",:,"); Serial.print(analogRead(temp)*-0.5+297.5); Serial.print(","); Serial.print(j); Serial.print(","); Serial.print(i); Serial.print(","); Serial.print(r); Serial.print(","); Serial.print(s); Serial.print(","); Serial.print(t); Serial.println("");

if (j==24007){ a=0; b=0; cc=0; e=0; } if (j==24008){ o=l;

} if (j==24009){ p=m;

} if (j==24010){ q=n; } j=0;

delay(100);

}

Step 6: Demo