Inhoudsopgave:

EAL - Industrieel internet - Fabrikshal - Ajarnpa
EAL - Industrieel internet - Fabrikshal - Ajarnpa

Video: EAL - Industrieel internet - Fabrikshal - Ajarnpa

Video: EAL - Industrieel internet - Fabrikshal - Ajarnpa
Video: Андрю Блум: Что такое Интернет на самом деле? 2024, Juli-
Anonim
EAL - Industrieel internet - Fabrikshal
EAL - Industrieel internet - Fabrikshal
EAL - Industrieel internet - Fabrikshal
EAL - Industrieel internet - Fabrikshal
EAL - Industrieel internet - Fabrikshal
EAL - Industrieel internet - Fabrikshal

Der er blevet fået stillet til opgave at implementere et automatiseret system ud fra industri 4.0 princippet. I denne opgave, er der lavet en lille simulatie 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 data, gemmes i en database i Wampserver.

Stap 1: RFID Kortlæser

RFID Kortlser
RFID Kortlser
RFID Kortlser
RFID Kortlser

Der er inkluderet en RFID kortlæser. Hensigten er op ud fra de id numre der er på det kort, en 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, en godkender først når det nummer stemmer overens med det der er skrevet ind i koden.

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

Kortlseren 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. Serieel porten, skal også brugge til Arduinoens order, den vil få fra vores Windows Forms applikation. I den sammenhæng er lyset også fravalgt.

Stap 2: Servomotor (Anlæg)

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

Ik hallen er der en servomotor, der er styret van en Arduino Uno. Den skalsimulere et anlæg, der kan producerer forskellige produkter. Ordrerbeholdningen, saamt antallet uit de udførte produkter, bliver gemt in en MySQL-database. Motoren kunnen worden gebruikt in een forskellige klepstandsteller. Hver position symboliserer tre forskellige produkter. Nr geproduceerde færdigproduceret, kører motoren tilbage i nul position, en afventer nye order. Det er komt bij de mens, via WPF-applikationen kan geven nye order til motoren. Alt hvad bliver produceret bliver gemt i en MySQL database.

Stap 3: MySQL-database - Indhold

MySQL-database - Indhold
MySQL-database - Indhold
MySQL-database - Indhold
MySQL-database - Indhold
MySQL-database - Indhold
MySQL-database - Indhold

I MySQL-database in de vorm van een tabeller. Den voorste houder øje med hvilke produkter der er bestilt, og hvor schurft. En anden tabel vil logge alle de udførte produkter. Den tredje, og sidste tabel indenholder en toezicht over hvor mange produkter der er produceret, og hvor mange der mangler. Ydermere er der et tidspunkt på, hvornår de pågældende produkter er produceret. Det er Windows Forms-applikationen der vil styre, hvad der skal sendes Arduinoen, samt databasen. Nr der bliver geven en bestellen, vil den blive verzonden naar Arduinoen, efterfølgende, vil den relevante data blive logget in databasen. Der bliver stuurt tre forskellige datatyper naar databasen. En Integer, en String, som bliver kaldt en VarChar, i databasen. Der er også et TimeStamp, Det er en indstilling, der er tilføjet i databasen.

Stap 4: Arduino-code

#erbij betrekken

Servo mijnServo;

int servoPos; char produkt = '0'; void setup() { myServo.attach(3); // Seriële communicatie start Serial.begin (9600); } void loop() { // Læsning fra seriële poort produkt = Serial.read(); //Godkendelse af ingående order switch(produkt) { // Produkt A (1) udføres i denne case case '1': myServo.write(50); vertraging (1000); mijnServo.write(0); vertraging (1000); Serial.println("Gereed"); pauze; // Produkt B (2) udføres i denne case case '2': myServo.write(100); vertraging (1000); mijnServo.write(0); vertraging (1000); Serial.println("Gereed"); pauze; // Produkt C (3) udføres i denne case case '3': myServo.write(150); vertraging (1000); mijnServo.write(0); vertraging (1000); Serial.println("Gereed"); pauze; } }

Stap 5: Windows Forms-toepassing

met behulp van System;met behulp van System. Collections. Generic; met behulp van System. ComponentModel; met behulp van systeemgegevens; met behulp van System. Drawing; met behulp van System. Linq; met behulp van System. Text; met behulp van System. Threading. Tasks; met behulp van System. Windows. Forms; met behulp van System. Collections; met behulp van System. IO. Ports; met behulp van MySql; met behulp van MySql. Data. MySqlClient;

naamruimte WindowsFormsApp2

{ public gedeeltelijke klasse Form1: Form { /* I denne class bliver alle public variabler oprettet. Herunder er der oprettet en Class (MySqlConnection) der skal tages i brug, voor bij kunne oprette forbindelse til MySQL serveren. Ydermere er der oprettet en String (connectionString) den brugge til at definitionre hvilken bruger der skal på og wachtwoord, en hvilken database der er tale om. Der er oprettet en integer, i et 2d array (orde). Grunden til det er at en orderrer can bestå uit flere produktioner af et produkt, eller flere produkter. Seriel kommunikationen til Arduinoen bliver også definiret 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 orderrer, me korte mellemrum. */ MySqlConnection-verbinding; string verbindingString;

privé int ordernummer;

private int[,] order = nieuwe int[100, 100]; privé int sendOrder = nieuw int[100]; privé string prodType;

SerialPort sp = nieuwe SerialPort();

private BackgroundWorker myWorker = nieuwe BackgroundWorker();

openbaar formulier1()

{ InitializeComponent(); //Haar bliver vores String (connectionString) definiret. connectionString = "server=192.168.1.100;userid=root;pwd=langeland;database=arduino;"; /* Haar bliver variabele "myWorker" zat tot bij logge på hvor langt diverse bestillinger er i deres proces. */ myWorker. DoWork += nieuwe DoWorkEventHandler (myWorker_DoWork); myWorker. WorkerReportsProgress = waar; myWorker. WorkerSupportsCancellation = waar; // Haar bliver zelf baggrundsgennemløbet eksikveret. myWorker. RunWorkerAsync(); // Haar bliver der defineret hvilket format datoen kører i. Haar formaat is het beste na MySQL-databasen. dateTimePicker1. CustomFormat = "jjjj-MM-dd"; dateTimePicker1. Format = DateTimePickerFormat. Custom; }

private void Afgiv_Ordre_Click (objectafzender, EventArgs e)

{ /* Her er der oprettet nogle variabler, der kun bliver brugt i dette void. De tre første er Integers der skal gedefinieerde 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 bij ordrene bliver produceret i den rækkefølge, de er bestilt i. */ for (int prod1A = 0; prod1A < prodA; prod1A++) { order[ordernummer, prod1A] = produktA; }

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

voor (int prod1C = (prodA + prodB); prod1C 99)

{ bestelnummer = 0; } // Haar gegevens over de beste producten naar de database. DBQuery("INSERT INTO `bestilteprod`(`Produkt A`, `Produkt B`, `Produkt C`) WAARDEN (" + prodA + ", " + prodB + ", " + prodC + ")"); // Haar overzicht en toezicht op hvilke produkter der mangler bij blive producerert, 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 (objectafzender, EventArgs e) { while (true) { /* Så længe at summen af den afsendte ordre ikke er lig med 0, vil dette while loop køre. */ Toestand(); 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. Variabelen (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 til næste kolonne, bliver den pågældende kolonne sat til 0. De eksikverede producter bliver uploadet til databasen. Inden if sætningerne bliver kommunikationen til Arduinoen åbnet, og den agivet ordre bliver sendt til Arduinoen. */ for (int i = 0; i < sendOrder. Length; i++) { Status(); sp. BaudRate = 9600; sp. PortName = "COM4"; sp. Open(); sp. Write(verzendvolgorde. ToString()); // Programmet der er i en af disse if statements, 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"; }

verzendenOrder = 0;

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

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

sp. Sluiten();

pauze; } /* Haar afventes der bij Arduinoen er færdig med ordren. Der kvitteres med et "done". Verdere modificatie, 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 til databasen. */ sp. ReadTo("Klaar");

DBQuery("INSERT INTO `udforte`(`Produkttype`) VALUES ('" + prodType + "')");

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

sp. Sluiten(); Toestand(); } } // I dette for loop bliver der lagt 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];

volgorde [i, j] = 0;

}

pauze; } }

}

} /* Haar er der oprettet et void ved navn "Status". Det er lavet for at skulle undgå at skrive de samme linjer kode flere steder. Ik heb een man niet gevonden met een skrive "Status" Dette void er også inkluderet i det void, med det andet kode, der kører en baggrunden. */ private void Status() { /* Her åbner man MySQL forbindelsen, vælger alt fra den tabel der hedder total, og eksikverer den forespørgsel. */ MySqlConnection con = nieuwe MySqlConnection(connectionString); con. Open(); string str = "selecteer * uit totaal"; MySqlCommand com = nieuw MySqlCommand(str, con); MySqlDataReader-lezer = com. ExecuteReader(); // Denne funktion er med for at dele Bagrrundskoden op en tråd i CPU'en, og en anden til resten af koden. lezer. Lees(); MissingProd. Invoke((MethodInvoker)delegate { // Her bliver de manglende producter, samt produkter der er lavet, skrevet ud på applikationen. MissingProd. Text = "manglende produkter: " + (reader["manglende produkt"]. ToString() OrdereProd. Text = "product lavet: " + (reader["produceret producter"]. ToString()); }); // Haar 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 statement eksikveret. Hvis det er lig med 0, bliver der udskrevet "0%" skrevet label. if (int. Parse(reader["produceret produkter"]. ToString()) != 0) { // Her tager man de produceret produkt en plusser med de manglende produkter. Resultatet uit dette ganger man med honderd, voor op få det ud i procent. ProcenteDone. Text = Math. Round((float. Parse(reader["produceret producter"]. ToString()) /(float. Parse(reader["produceret producter"]. ToString()) + float. Parse(reader["manglende produkter"]. ToString()))) * 100). ToString(); // Haar bliver resultatet na tidligere udregning lagt over på procentbaren. progressBar1. Value = Int32. Parse(ProcenteDone. Text); } else { ProcenteDone. Text = "0%"; } });// Her lukkes MySQL forbindelsen.reader. Close(); con. Close(); } // I dette void bliver alle produkter, der er produceret på den valgte dato, lagt ud på a toepassingen. private void Vis_Produkter_Click_1(object afzender, EventArgs e) { string date = dateTimePicker1. Value. ToString(). Remove(10);

datum = dateTimePicker1. Text;

string query = "SELECT `Produkttype`, `Tid` FROM udforte WHERE Tid >= '" + date + " 00:00:00' AND Tid <= '" + date + " 23:59:59'"; met behulp van (verbinding = nieuwe MySqlConnection (connectionString)) met behulp van (MySqlCommand-opdracht = nieuwe MySqlCommand (query, verbinding)) met behulp van (MySqlDataAdapter-adapter = nieuwe MySqlDataAdapter (opdracht)) { DataTable prodTable = nieuwe DataTable (); adapter. Fill (prodTable);

dataGridView1. DataSource = prodTable;

}

} // I dette void bliver MySQL forbindelsen styret. Den fungerer således bij forbindelsen bliver åbnet, eksikverer, og lukkes. private void DBQuery (string cmd) { string query = cmd; met behulp van (verbinding = nieuwe MySqlConnection(connectionString)) met behulp van (MySqlCommand-opdracht = nieuwe MySqlCommand (query, verbinding)) { connection. Open();

commando. ExecuteScalar();

verbinding. Sluiten();

} } } }

Stap 6: Materiaalkeuze

1 stk. Arduino Uno

1 stk. Micro-servo SG90 9g

Stap 7: Fobindelsesdiagram / I/O Lliste

Fobindelsesdiagram / I/O Lliste
Fobindelsesdiagram / I/O Lliste

servomotor:

+ = Rood

- = Sorteren

Signaal = Grøn

Aanbevolen: