Inhaltsverzeichnis:

EAL - Industriel Internet - Fabrikshal - Gunook
EAL - Industriel Internet - Fabrikshal - Gunook

Video: EAL - Industriel Internet - Fabrikshal - Gunook

Video: EAL - Industriel Internet - Fabrikshal - Gunook
Video: Erfindungen aus Fulda - der erste Kleinwagen | Pioniere in Fulda | erlebnis hessen | doku 2024, Juli
Anonim
EAL - Industrielles Internet - Fabrikshal
EAL - Industrielles Internet - Fabrikshal
EAL - Industrielles Internet - Fabrikshal
EAL - Industrielles Internet - Fabrikshal
EAL - Industrielles Internet - Fabrikshal
EAL - Industrielles Internet - Fabrikshal

Der blevet fået stillet til opgave at implementere and automatiseret system ud fra industri 4.0 princippet. I dennne opgave, er der lavet en lille simulation af en fabrikshal. I hallen står der en servomotor, samt et par dioder. Udevendig, sidder der en RFID kortlæser, der skulle bruges til at lukke de relevante ind i fabrikshallen. Alt-Daten, gemmes in einer Datenbank in Wampserver.

Schritt 1: RFID Kortlæser

RFID Kortlæser
RFID Kortlæser
RFID Kortlæser
RFID Kortlæser

Der er inkludiert und RFID kortlæser. Hensigten er at ud fra de id numre der er på det kort, og den brik der er med er skrevet ind i vores Arduino kode. Det gør at når kortlæseren opfanger en brik eller et kort, kigger den på enhedens id-nummer, og godkender forst når det nummer stemmer overens med det der er skrevet ind i koden.

Når kortlæseren giver adgang, så tændes lyset i fabrikken. Lyset slukkes igen, når enhed, der er godkendt af kortlæseren, bliver detekteret.

Kortlæseren bliver fjernet fra projektet, da den kører seriel kommunikation. Det vil sige at der kan opstå forstyrrelser på den seriel port, der er på projektets Arduino Uno. Serielle Portierung, Skalierung von Brügge für Arduinoens-Bestellungen, den Zugriff auf die Windows Forms-Anwendung. Ich den sammenhæng er lyset også fravalgt.

Schritt 2: Servomotor (Anlæg)

Servomotor (Anlæg)
Servomotor (Anlæg)
Servomotor (Anlæg)
Servomotor (Anlæg)
Servomotor (Anlæg)
Servomotor (Anlæg)

I hallen er der en servomotor, der styret af en Arduino Uno. Den skalsimulere et anlæg, der kanproduzenten forskellige produkter. Ordrerbeholdningen, samt antallet af de udførte produkter, bliver gemt i en MySQL-Datenbank. Motoren kan køre ud i tre forskellige positioner. Hver position symboliserer tre forskellige produkter. Når produktet er færdigproduceret, kører motoren tilbage i nul position, og afventer nye order. Det er meningen at man, via WPF applikationen kan afgive new order to motoren. Alt hvad bliver Produceret bliver gemt i en MySQL-Datenbank.

Schritt 3: MySQL-Datenbank - Indhold

MySQL-Datenbank - Indhold
MySQL-Datenbank - Indhold
MySQL-Datenbank - Indhold
MySQL-Datenbank - Indhold
MySQL-Datenbank - Indhold
MySQL-Datenbank - Indhold

I MySQL-Datenbanken vil der være tre tabeller. Den første holder øje med hvilke produkter der er bestilt, og hvor mange. En anden table vil logge alle de udførte produkter. Den tredje, og sidste tabel indenholder en oversigt over hvor mange produkter der er productionet, og hvor mange der mangler. Ydermere er der et tidspunkt på, hvornår de pågældende produkter er producet. Det er Windows Forms applikationen der vil styre, hvad der skal sendes Arduinoen, samt databasen. Når der bliver afgivet en ordrer, vil den blive sendt til Arduinoen, efterfølgende, vil den relevanten data blive logget i databasen. Der bliver sendt tre forskellige datatyper to databasen. En Integer, de String, som bliver kaldt und VarChar, i databasen. Der er også et TimeStamp, Det er en indstilling, der er tilføjet in databasen.

Schritt 4: Arduino-Kode

#enthalten

Servo myServo;

int servoPos; Zeichenprodukt = '0'; Void setup () { myServo.attach (3); // Serial kommunikation startet Serial.begin (9600); aufrechtzuerhalten. Void loop () {// Læsning von einem seriellen Portprodukt = Serial.read (); // Godkendelse af ingående order switch(produkt) { // Produkt A (1) udføres i dennne case case '1': myServo.write(50); Verzögerung (1000); myServo.write(0); Verzögerung (1000); Serial.println ("Fertig"); brechen; // Produkt B (2) udføres i dennne case case '2': myServo.write(100); Verzögerung (1000); myServo.write(0); Verzögerung (1000); Serial.println ("Fertig"); brechen; // Produkt C (3) udføres i dennne case case '3': myServo.write(150); Verzögerung (1000); myServo.write(0); Verzögerung (1000); Serial.println ("Fertig"); brechen; } }

Schritt 5: Windows Forms-Anwendung

using System; using System. Collections. Generic; Verwenden von System. ComponentModel; Verwenden von System. Data; Verwenden von System. Drawing; Verwenden von System. Linq; Verwenden von System. Text; Verwenden von System. Threading. Tasks; Verwenden von System. Windows. Forms; Verwenden von System. Collections; Verwenden von System. IO. Ports; Verwenden von MySQL; Verwenden von MySql. Data. MySqlClient;

Namespace WindowsFormsApp2

{ öffentliche partielle Klasse Form1: Form { /* Ich habe die Klasse bliver alle öffentlichen Variablen oprettet. Herunder er der oprettet en Class (MySqlConnection) der skal tages i brug, for at kunne oprette forbindelse til MySQL serveren. Ydermere er der oprettet en String (connectionString) den bruges til at definere hvilken bruger der skal på og password, og hvilken database der er tale om. Der er oprettet en integer, i et 2d array (orde). Grunden til det er at en ordrer kan bestå af flere produktioner af et produkt, eller flere produkter. Serielle Kommunikationen für Arduinoen bliver også defineret her. Der bliver også oprettet en Class (BackgroundWorker). Den gør at en bestemt del af programt bliver eksikveret gentagende gange i baggrunden. I dette tilfælde er det brugbart, da der kan blive oprettet nye ordrer, med korte mellemrum. */ MySqlConnection-Verbindung; Zeichenfolge connectionString;

private Int-Ordernummer;

private int[,] order = new int[100, 100]; private int sendOrder = new int[100]; private Zeichenfolge prodType;

SerialPort sp = neuer SerialPort();

privater BackgroundWorker myWorker = new BackgroundWorker();

öffentliches Formular1()

{ Initialisieren der Komponente(); //Ihr bliver vores String (connectionString) defineret. connectionString = "server=192.168.1.100;userid=root;pwd=langeland;database=arduino;"; /* Ihre bliver variablen "myWorker" sat til at logge på hvor longt diverse bestillinger er i deres proces. */ myWorker. DoWork += neuer DoWorkEventHandler(myWorker_DoWork); myWorker. WorkerReportsProgress = true; myWorker. WorkerSupportsCancellation = true; // Ihr bliver selve baggrundsgennemløbet eksikveret. myWorker. RunWorkerAsync(); // Ihr bliver der defineret hvilket format datoen kører i. Ihr Format ist nach MySQL-Datenbanken am besten. dateTimePicker1. CustomFormat = "yyyy-MM-dd"; dateTimePicker1. Format = DateTimePickerFormat. Custom; }

private void Afgiv_Ordre_Click(Objektsender, EventArgs e)

{ /* Her er der oprettet nogle variabler, der kun bliver brugt i dette void. De tre første er Integers der skal definere hvilket produkt der er tale om. De næste tre er oprettet for at kunne skrive det antal man ønsker, ind i applikationen. Den sidste er oprettet for at få en længde på den pågældende ordre. */ int produktA = 1; int produktB = 2; int produktC = 3; int prodA = int. Parse(prodAOrder. Text); int prodB = int. Parse(prodBOrder. Text); int prodC = int. Parse(prodCOrder. Text); int orderLength = prodA + prodB + prodC; /* I disse for loops bliver køen oprettet, således at ordrene bliverproduceret i den rækkefølge, de er bestilt i. */ for (int prod1A = 0; prod1A < prodA; prod1A++) { order[ordrenummer, prod1A] = produktA; }

for (int prod1B = (prodA); prod1B < (prodB + prodA); prod1B++) { order[ordrenummer, prod1B] = produktB; }

für (int prod1C = (prodA + prodB); prod1C 99)

{ Bestellnummer = 0; } // Her overføres de bestilte produkter til databasen. DBQuery("INSERT INTO `bestilteprod`(`Produkt A`, `Produkt B`, `Produkt C`) VALUES (" + prodA + ", " + prodB + ", " + prodC + ")"); // Ihre overføres en oversigt over hvilke produkter der mangler bei bliveproducerert, til databasen. DBQuery("UPDATE `total` SET `manglende produkter`= (`manglende produkter` +(" + (prodA+prodB+prodC) + ")) WHERE 1"); }

// I dette void er alt det kode der skal køre i baggrunden, lagt ind.

private void myWorker_DoWork(object sender, EventArgs e) { while (true) { /* Så længe at sumen af den afsendte ordre ikke er lig med 0, vil dette while loop køre. */ Status(); while (sendingOrder. Sum() != 0) { /* I dette for loop fungerer det således, at så længe den oprettede Integer (i) er mindre end længden på den afgivet ordre, vil det eksikvere. Variablen (i) kigger på den pågældende række i arrayet, der på nuværende tidspunkt arbejdes i. Den kigger i kolonnen, ser hvilket tal der står i kolonnen. Tallet bliver eksikveret, og inden at variablen rykker videre to næste kolonne, bliver den pågældende coloonne sat bis 0. De eksikverede producter bliver uploadet to databasen. Inden if sætningerne bliver kommunikationen für Arduinoen åbnet, og den afgivet ordre bliver sendt til Arduinoen. */ for (int i = 0; i < sendOrder. Length; i++) { Status(); sp. BaudRate = 9600; sp. PortName = "COM4"; sp. Open(); sp. Write(sendingOrder. ToString()); // Programmet der er i en af disse if-Anweisungen, vil blive eksikveret, afhængig af hvilket tal fra et til tre der er i variablen (i). if (sendingOrder == 1) { prodType = "Produkt A"; } else if(sendingOrder == 2) { prodType = "Produkt B"; } else if(sendingOrder == 3) { prodType = "Produkt C"; }

sendOrder = 0;

// Når hele den eksikverede række i arrayet samlet giver 0, bliver de udførte produkter uploadet in databasen, og komunikationen til Arduinoen, bliver lukket. if (sendingOrder. Sum() == 0) { DBQuery("INSERT INTO `udforte`(`Produkt type`) VALUES ('" + prodType + "')");

DBQuery("UPDATE `total` SET `produceret produkter`= (`produceret producter` + 1), `manglende produkter`= (`manglende produkter` - 1)");

sp. Schließen();

brechen; } /* Her afventes der at Arduinoen er færdig med ordren. Der kvitteres med et "done". Når det er modtaget, bliver de udførte endnu en gang uploadet til databasen Grunden til dette, er at man skal være sikker på at det sidste udførte produkt bliver overført to databasen. */ sp. ReadTo("Fertig");

DBQuery("INSERT INTO `udforte`(`Produkttyp`) WERTE ('" + prodType + "')");

DBQuery("UPDATE `total` SET `produceret produkter`= (`produceret producter` + 1), `manglende produkter`= (`manglende produkter` - 1)");

sp. Schließen(); Status(); } } // Ich dette for loop bliver der lag en ny række med ordre til eksikvering, når den foregående række er eksikveret (summen af foregående række er lig med 0). for (int i = 0; i < order. GetLength(0); i++) { int test = order[i, 0]; if (test != 0) { for (int j = 0; j < 100; j++) { sendOrder[j] = order[i, j];

Ordnung[i, j] = 0;

}

brechen; } }

}

} /* Her er der oprettet et void ved navn "Status". Det er lavet for at skulle undgå at skrive de samme linjer kode flere steder. I stedet kan man nøjes med at skrive "Status" Dette void er også inkluderet i det void, med det andet kode, der kører i baggrunden. */ private void Status() { /* Ihr åbner man MySQL forbindelsen, vælger alt fra den table der hedder total, og eksikverer den forespørgsel. */ MySqlConnection con = new MySqlConnection(connectionString); con. Open(); string str = "select * from total"; MySqlCommand com = new MySqlCommand(str, con); MySqlDataReader-Reader = com. ExecuteReader(); // Denne funktion er med für at dele Baggrundskoden på en tråd i CPU'en, og en anden tråd til resten af koden. Leser. Read(); MissingProd. Invoke((MethodInvoker)delegate { // Her bliver de manglende produkter, samt produkter der er lavet, skrevet ud på applikationen. MissingProd. Text = "manglende produkter: " + (reader["manglende produkter"]. ToString()); OrdereProd. Text = "produkter lavet: " + (reader["produceret produkter"]. ToString()); }); // Her bliver der implementeret hvad procentbaren, skal udfyldes efter. ProcenteDone. Invoke((MethodInvoker)delegate { // Hvis læseren i My SQL forbindelsen læser at "produceret produkter ikke er lig med 0, bliver denne if Anweisung eksikveret. Hvis det er lig med 0, bliver der udskresvet "0%" label. if (int. Parse(reader["produceret produkter"]. ToString()) != 0) { // Her tager man deproduceret produkter og plusser med de manglende produkter få det ud i procent. ProcenteDone. Text = Math. Round((float. Parse(reader["produceret produkter"]. ToString()) /(float. Parse(reader["produceret produkter"]. ToString()) + float. Parse(reader["manglende produkter"]. ToString()))) * 100). ToString(); // Ihr bliver resultatet af tidligere udregning lagt over på procentbaren. progressBar1. Value = Int32. Parse(ProcenteDone. Text). på den valgte dato, lagt ud på a pplikationen. privat Void Vis_Produkter_Click_1 (Objektsender, EventArgs e) { string date = dateTimePicker1. Value. ToString(). Remove(10);

date = dateTimePicker1. Text;

string query = "SELECT `Produkt type`, `Tid` FROM udforte WHERE Tid >= '" + Datum + " 00:00:00' AND Tid <= '" + Datum + " 23:59:59'"; using (connection = new MySqlConnection(connectionString)) using (MySqlCommand command = new MySqlCommand(query, connection)) using (MySqlDataAdapter adapter = new MySqlDataAdapter(command)) { DataTable prodTable = new DataTable(); adapter. Fill(prodTable);

dataGridView1. DataSource = prodTable;

}

} // Ich dette void bliver MySQL forbindelsen styret. Den fungerer således bei forbindelsen bliver åbnet, eksikverer, og lukkes. privates Void DBQuery (Zeichenfolge cmd) { Zeichenfolgenabfrage = cmd; using (connection = new MySqlConnection(connectionString)) using (MySqlCommand command = new MySqlCommand(query, connection)) { connection. Open();

Befehl. ExecuteScalar();

Verbindung. Schließen();

} } } }

Schritt 6: Materialliste

1 Stk. Arduino Uno

1 Stk. Mikroservo SG90 9g

Schritt 7: Fobindelsesdiagramm / I/O-Liste

Fobindelsesdiagramm / I/O-Liste
Fobindelsesdiagramm / I/O-Liste

Servomotor:

+ = Rød

- = Sortieren

Signal = Grøn

Empfohlen: