Sommario:
- Passaggio 1: Opsamling dati Af per Vægt Samt Registrazione Af UID
- Passaggio 2: programma Arduino
- Passaggio 3: Nodo-RED, Lagring Af Data I Database
- Passaggio 4: progettazione del database
- Passaggio 5: Patelog
- Passaggio 6: tabella degli ordini
- Passaggio 7: tabella clienti
- Step 8: Rangetable
- Passaggio 9: programma C#
Video: EAL-Industri4.0-RFID Dataopsamling Til Database: 10 passaggi (con immagini)
2024 Autore: John Day | [email protected]. Ultima modifica: 2024-01-30 10:04
Dette projekt omhandler opsamling af vægtdata, registrering af identiteter vha. RFID, lagring di dati nel database MySQL vha. node-RED, samt fremvisning og behandling di dati opsamlede e il programma C# formò un'applicazione Windows Form. Vi forestiller os følgende:
Vi har en produktionslinje som producerer leverpostej i 200g foliebakker. Tutti i tipi di tag RFID e di tag RFID e di etichettatura, oltre a un indeholder e un ID unikt (UID = Unique Identifier, in codice a 32 bit, 8 caratteri esadecimale) per l'identificazione dell'intero numero di elementi. Da færdigvægten af hver enkelt bakke leverpostej kan svinge (afhængig af råvarer, fordampning i ovn mm), og da kunderne hver har et specifikt krav færdigvægten, bruges UID tagget til at knylevation hver enkelt leverpostejer til én specific kunde. Kunderne er supermarkedskæder:
1. Irma. Vægten på Irmas luksus leverpostej skal holde sig inden per +/- 5%, altså minimo 190g og maksimum 210g.
2. Bruges. Vægten på Brugsens leverpostej skal holde sig inden per +/- 10%, altså minimo 180 g og massimo 220 g.
3. Aldi. Vægten på Aldis sconto leverpostej skal holde sig inden per +/- 15%, altså minimo 170g og maksimum 230g.
Der er således følgende sorteringer:
Range0: fuori range
Gamma 1: minimo 190 g/massimo 210 g
Gamma2: minimo 180 g/massimo 220 g
Gamma3: minimo 170 g/massimo 230 g
Passaggio 1: Opsamling dati Af per Vægt Samt Registrazione Af UID
Fino all'acquisizione dei dati per la visualizzazione, come la registrazione dei tag RFID e la vendita su Arduino MEGA2560 con lettore/scrittore RFID-RC522. Da vi ikke har nogen vægt, simulerer vi data for vægten med et potmeter tilsluttet en analog indgang på Arduinoen.
Følgende opstilling er anvendt:
1 stk potmeter 25k lineært. Yder-benene er tilsluttet hhv. GND e +5V, intermedi e bassi AN0
RFID-RC522 per schede Arduino per schede Arduino Porta SPI per dimensioni:
SDA -> pin 53
SCK -> pin52
MOSI ->pin51
MISO->pin50
IRQ ->NC
GND -> GND
RST -> pin5
3,3 V -> 3,3 V
Dati opsamlede, per hhv. UID e vægten, invia per den serielle port som en komma-separeret tekststreng videre til node-Red som står per den efterfølgende præsentation på et dashboard og lagring nel database.
Passaggio 2: programma Arduino
Il programma Arduino include il file biblioteker SPI.h og MFRC522.h per la maggior parte dei codici RFID. I starten af programt initialiseres de anvendte variabile. Der laves en instans af MFRC522. I Setup blocchi inizializzate per serielle forbindelse, porta SPI og MFRC522. Scansioni successive ai tag RFID. For ikke at sende det samme UID afsted flere gange efter hinanden, er der lavet en stump kode som tjekker for dette. Non hai più scannet e tag UID, carica una serie di nyUID con il netop læste UID. Hvis array nyUID er forskellig fra oldUID er tale om et nyt UID som kan sendes på den serielle port. Hvis nyUID e oldUID er ens, er der tale om samme UID tag og UID'et skal ignoreres. Hvis der er tale om et nyt UID, invia UID'et på den serielle port sammen med en læst værdi fra den serielle port. Den analoge værdi skaleres til området 150-250. I dati inviano alcuni tekststreng komma-separeret. Som det sidste sættes oldUID = nyUID, således e koden klart fino a læse et nyt RFID tag.. Densate funktion i programter er den funktion som sammenligner 2 arrays. Funktionen returnerer true hvis array'ne er ens, og false hvis array'ne er forskellige.
#includere
#include // Questo programma esegue la scansione delle schede RFID utilizzando la scheda di lettura/scrittura RDIF-RC522. // Viene letto l'UID, viene letto un pin analogico. Il valore analogico 0-1023 viene scalato a 150-250. // L'UID e il valore analogico vengono inviati come testo separato da virgole sulla porta seriale utilizzando 9600, N, 8, 1. // È stata prestata attenzione a inviare ogni UID solo una volta di seguito, // è necessario un nuovo UID presente prima che lo stesso UID possa essere inviato nuovamente. // Questa funzione viene implementata nel codice confrontando gli array: oldUIDnyUID nella funzione array_cmp(oldUID, nyUID)
constexpr uint8_t RST_PIN = 5;
constexpr uint8_t SS_PIN = 53; int sensorePin = A0; int Valore = 0; String StringValue = "0000"; byte oldUID[4] = {}; byte nyUID[4] = {};
MFRC522 mfrc522(SS_PIN, RST_PIN); // Crea un'istanza MFRC522.
configurazione nulla()
{ Serial.begin(9600); // Avvia una comunicazione seriale SPI.begin(); // Avvia il bus SPI mfrc522. PCD_Init(); // Avvia MFRC522 }
ciclo vuoto()
{ // Cerca nuove carte if (! mfrc522. PICC_IsNewCardPresent()) { return; } // Seleziona una delle carte if (! mfrc522. PICC_ReadCardSerial()) { return; } //carica nyUID con il tag UID for (byte i = 0; i < mfrc522.uid.size; i++) { nyUID = mfrc522.uid.uidByte; } // if oldUIDnyUID if (!array_cmp(oldUID, nyUID)) { // invia il tag UID sulla porta seriale for (byte i = 0; i 1000) { Value = 1000; } Valore = (Valore / 10) + 150; // invia il valore analogico scalato Serial.print(Value); // invia nuova riga Serial.println(); //set oldUID = nyUID for (byte z = 0; z < 4; z++) oldUID[z] = nyUID[z]; } // aspetta 1 sec delay(1000); }
// confronta 2 array…
boolean array_cmp(byte a, byte b) { bool test = true; //verifica che ogni elemento sia lo stesso. se solo uno non lo è, restituisce false for (byte n = 0; n < 4; n++) { if (a[n] != b[n]) test = false; // if on byte non uguale, test = false } if (test == true) return true; altrimenti restituisce false; }
Passaggio 3: Nodo-RED, Lagring Af Data I Database
Følgende flower er lavet i node-RED:
COM4 er den serielle forbindelse hvor data modtages fra Arduino boardet. Funzionalità "Dividi e ottieni valore" e "Dividi e ottieni UID" Teksstrengen ved kommaet og returnere hhv vægten and UID. Vgten bruges til fremvisning på dashboardet et linechart og en scale. UID fremvises i et tekstfelt. Funktionen test_sound advarer verbalt med sætningen "Out of range", hvis vægten er under 170g eller over 230g, dvs i range 0.
Dividi e ottieni valore:
var output = msg.payload.split(', ');
temp = {carico utile:(output[1])}; temperatura di ritorno;
Dividi e ottieni UID:
var output = msg.payload.split(", ");
temp = {carico utile:output[0]}; temperatura di ritorno;
suono_test:
var numero = parseInt(msg.payload);
if (numero >230 || numero<170) { newMsg = {payload:"Fuori intervallo"}; restituisce nuovoMsg; } else { newMsg = {payload:""}; ritorna nuovoMsg; }
Funzioni Split string ", " indsætter et timestamp, UID e vægten nel database patedb.patelog.
var output = msg.payload.split(", "); //dividi msg.payload per virgola in array
UIDTag = output[0]; //prima parte in prima posizione [0] ValueTag = output[1]; //seconda parte in seconda posizione [1]
var m = {
topic: "INSERT INTO patedb.patelog (timestamp, UID, peso) VALUES('"+new Date().toISOString()+"', '"+ UIDTag +"', '"+ValueTag+"');" }; ritorno m;
Patelog er en MySQL database forbindelse so er sat op med følgende parametro:
Host: localhost
Porta: 3306
Utente: root
Database: patedb
Passaggio 4: progettazione del database
Databasen patedb indeholder 4 tabeller
Patelog er dataopsamlingstabellen, tilskrives data af node-RED og C# programt
ordertable er en tabel som indeholder data om de genemførte ordrer, tilskrives data af C# programt
customertable er et kunderegister
rangetable er en tabel som indeholder grænseværdierne for de i C# programt benyttede ranges.
Passaggio 5: Patelog
Tabellen patelog indeholder folgende 6 kolonner:
pateID (int) er chiave primaria og inkrementeres automatisk.
Timestamp, UID e vægt er af typen varchar (med forskellig max længde)
rangeNr er af typen tinyint (beregnes og tilføjes af C# programt)
orderID er af typen int (orderID tilføjes af C# programt)
Node-RED tilføjer ikke værdier til kolonnerne rangeNr og orderID. rangeNr og orderID tillader NULL værdier, det bruges i C# programt til at detektere de rækker som skal tilskrives værdier for rangeNr og orderID
Passaggio 6: tabella degli ordini
indeholder tabella ordinabile 5 kolonner:
orderID (int) er det aktuelle ordrenummer
orderQuant (mediumint) er ordens pålydende antal
quantProduced (mediumint) er antal der rent faktisk er produceret på ordren. (Tlles a C# programt)
comment (tinytext) er en eventuel kommentar til ordren.
customerID (int) er det aktuelle kundenummer på ordren.
Passaggio 7: tabella clienti
customertable indeholder 6 kolonner:
customerID (int) er chiave primaria og auto inc.
nome, indirizzo, telefono, e-mail (varchar) med forskellig max længde
rangeNr (int)
Step 8: Rangetable
portatarga indeholder 3 kolonner:
rangeNr (int) er chiave primaria og auto inc.
rangeMin (int)
rangeMax (int)
Passaggio 9: programma C#
Når der produceres en ordre leverpostej, er proceduren følgende:
Kundenummer, ordrenummer, ordreantal og en eventuel kommentar indtastes i C# programt (i praksis overføres det digitalt fra virksomhedens ordresystem. Produktionen startes nu ved tryk på 'start'- knappen. på et transportbånd) Samhørende værdier af UID og den aktuelle vægt sendes serielt til node-RED, som viser de opsamlede data på dashboard 'et. Samtidig skrives timestamp, UID og vægt i en ny række i patednv. tidspunkt ikke tilskrives værdier til rangeNr og orderID vil de have værdien NULL.
Med e timerinterval undersøger C# programt patedb.patelogtabellen for nye tilkomne rækker med NULL værdier i rangeNr kolonnen. Når der er detekteret en række med NULL værdi, beregnes rangeNr og det tilføjes sammen med det aktuelle orderID. Når en ordre er produceret, afsluttes ordren ved tryk på”stop”- knappen. Når ordren afsluttes, tilføjes en række til patedb.ordertable med de aktuelle ordredata. Non si può ordinare, non è possibile eseguire operazioni di dati e visualizzare tabelle di fremvises e provare a eseguire operazioni di forskellige knapper nel gruppo Update DataGridview. ordertable kan også vises, og der kan søges ordredata på individueller UID'er eller kundedata på individuelle ordrer.
usando System;usando System. Collections. Generic; utilizzando System. ComponentModel; utilizzando System. Data; utilizzando System. Drawing; utilizzando System. Linq; utilizzando System. Text; utilizzando System. Threading. Tasks; utilizzando System. Windows. Forms; utilizzando MySql. Data. MySqlClient;
spazio dei nomi show_data_from_database
{ public partial class Form1: Form { MySqlConnection connection = new MySqlConnection("datasource=localhost; username=root; password=''"); int NumeroRiga = 0; // Variabile per la memorizzazione del valore pateID int RangeNumber = 0; //Variabile per memorizzare rangenumber int peso =0; // Variabile per memorizzare il peso int OrderNr = 0; // Variabile per memorizzare OrderNR int QuantProduced = 0; //Variabile per memorizzare la quantità prodotta int NumberOfRows = 0; //numero di righe con null.. bool ProdRunning = false; //Variabile che indica se i pulsanti di avvio e arresto sono stati attivati intlimits = new int[6];// inizializza l'array int CustomerID; // Variabile per memorizzare customerID public Form1() { InitializeComponent(); load_table(); // chiama load_table }
void load_table()
{ MySqlCommand command = new MySqlCommand("SELECT * FROM patedb.patelog ORDER BY timestamp DESC;", connection); prova { adattatore MySqlDataAdapter = new MySqlDataAdapter(); adapter. SelectCommand = comando; DataTable dbdataset = new DataTable(); adapter. Fill(dbdataset); BindingSource bsource = new BindingSource(); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; SetRowOrder(); adapter. Update(dbdataset); } catch (eccezione es.) { MessageBox. Show(ex. Message); } }
vuoto privato SetRowOrder()
{ dataGridView1. Columns["pateID"]. DisplayIndex = 0; // Il suo kan rækkefølgen af kolonner ndres dataGridView1. Columns["timestamp"]. DisplayIndex = 1; // Il suo kan rækkefølgen af kolonner ndres dataGridView1. Columns["UID"]. DisplayIndex = 2; // Her kan rækkefølgen af kolonner ndres dataGridView1. Columns["weight"]. DisplayIndex = 3; // Il suo kan rækkefølgen af kolonner ndres dataGridView1. Columns["rangeNr"]. DisplayIndex = 4; // Il suo kan rækkefølgen af kolonner ndres dataGridView1. Columns["orderID"]. DisplayIndex = 5; // Il suo kan rækkefølgen af kolonner ændres }
private void GetData_Click (mittente oggetto, EventArgs e) // Legge la tabella del database e gli ordini per Timestamp
{ load_table(); }
private void btnRefreshUID_Click (mittente oggetto, EventArgs e) //
{ string timeStr = "SELECT * FROM patedb.patelog ORDER BY UID;"; comando MySqlCommand = new MySqlCommand(timeStr, connessione); prova { adattatore MySqlDataAdapter = new MySqlDataAdapter(); adapter. SelectCommand = comando; DataTable dbdataset = new DataTable(); adapter. Fill(dbdataset); BindingSource bsource = new BindingSource(); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; SetRowOrder(); adapter. Update(dbdataset); } catch (eccezione es.) { MessageBox. Show(ex. Message); } }
private void btnRefreshValue_Click (mittente oggetto, EventArgs e)
{ string weightSort = "SELECT * FROM patedb.patelog ORDER BY CAST(weight AS SIGNED INTEGER);"; comando MySqlCommand = new MySqlCommand(weightSort, connection); prova { adattatore MySqlDataAdapter = new MySqlDataAdapter(); adapter. SelectCommand = comando; DataTable dbdataset = new DataTable(); adapter. Fill(dbdataset); BindingSource bsource = new BindingSource(); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; SetRowOrder(); adapter. Update(dbdataset); } catch (eccezione es.) { MessageBox. Show(ex. Message); } }
private void ChkNullBtn_Click (mittente oggetto, EventArgs e)
{ if (ProdRunning) { CheckTableForNull(); load_table(); } }
private void CheckTableForNull()
{ //Controlla/imposta l'intervallo del timer minimo 100 ms int i; int. TryParse(textTimer1. Text, out i); if (i <100) { timer1. Stop(); io = 100; timer1. Intervallo = i; MessageBox. Show("Valore minimo i 100mS"); timer1. Start(); } else { timer1. Intervallo = i; } textTimer1. Text = timer1. Interval. ToString(); //Controlla se sono disponibili righe con null nella tabella, restituisce il numero di righe nella variabile:NumberOfRows string weightStr = ""; string chkNull = "SELECT COUNT(*) FROM patedb.patelog WHERE rangeNR IS NULL ORDER BY pateID LIMIT 1;"; comando MySqlCommand = new MySqlCommand(chkNull, connessione); prova { connessione. Open(); NumberOfRows = Convert. ToInt32(command. ExecuteScalar()); connessione. Chiudi(); } catch (eccezione es.) { MessageBox. Show(ex. Message); } infine { if (NumberOfRows != 0) { try { //Seleziona il numero pateID più basso dove rangeNr è NULL string readID = "SELECT pateID FROM patedb.patelog WHERE rangeNR IS NULL ORDER BY pateID ASC LIMIT 1;"; MySqlCommand cmdID = new MySqlCommand(readID, connessione); { connessione. Apri(); RowNumber = (int)cmdID. ExecuteScalar(); //numero intero!! connessione. Chiudi(); } listPateID. Text = RowNumber. ToString(); // legge il numero PateID selezionato // Seleziona il peso dalla stringa rownumber selezionata row = RowNumber. ToString(); stringa readweight = "SELECT peso FROM patedb.patelog WHERE pateID=" + riga; MySqlCommand cmdweight = new MySqlCommand(readweight, connection); { connessione. Apri(); weightStr = (string)cmdweight. ExecuteScalar(); //Corda !! connessione. Chiudi(); } peso = int. Parse(weightStr); // converti in int txtWeight. Text = weight. ToString(); // print int RangeNumber = 0; if (peso>= limiti[0] && peso = limiti[2] && peso = limiti[4] && peso <= limiti[5]) { RangeNumber = 3; } } txtRange. Text = RangeNumber. ToString(); AggiornaLog(); } catch (eccezione es.) { MessageBox. Show(ex. Message); } QuantProduced = QuantProduced + 1; } } } private void btnStart_Click (mittente oggetto, EventArgs e) { if (ProdRunning == false) { int valtest; prova { CustomerID = int. Parse(txtCustomerNr. Text); //read customerID } catch { MessageBox. Show("Inserisci i dati di produzione e premi il pulsante 'start'."); }
stringa test = "SELECT COUNT(*) FROM patedb.customertable WHERE customerID ="+CustomerID;
MySqlCommand cmdtestcustomer = new MySqlCommand(test, connection); { connessione. Apri(); valtest = Convert. ToInt32(cmdtestcustomer. ExecuteScalar()); // restituisce 0 se il cliente non esiste connection. Close(); } if (valtest==1) // se il cliente esiste nel database - avvia la produzione { try { OrderNr = int. Parse(txtOrderNumber. Text); ProdRunning = vero; timer1. Start(); textTimer1. Text = timer1. Interval. ToString(); ReadLimits(); } catch (eccezione es.) { MessageBox. Show("Inserisci i dati di produzione e premi il pulsante 'start'."); } } else MessageBox. Show("Cliente non presente nel database, riprova"); } //Limiti di lettura(); }
private void ReadLimits()
{ // Legge i limiti da rangetable, range da 1 a 3 int counter = 0; for (int rangeNr = 1; rangeNr < 4; rangeNr++) { string readmin = "SELECT rangeMin FROM patedb.rangetable WHERE rangeNr=" + rangeNr; MySqlCommand cmdmin = new MySqlCommand(readmin, connection); { connessione. Apri(); limit[counter] = (int)cmdmin. ExecuteScalar(); contatore = contatore + 1; connessione. Chiudi(); } // MessageBox. Show(counter. ToString()); stringa readmax = "SELECT rangeMax FROM patedb.rangetable WHERE rangeNr=" + rangeNr; MySqlCommand cmdmax = new MySqlCommand(readmax, connection); { connessione. Apri(); limit[counter] = (int)cmdmax. ExecuteScalar(); contatore = contatore + 1; connessione. Chiudi(); } } // fine del ciclo }
privato void UpdateLog()
{ // AGGIORNA rangeNR e orderID string Range = RangeNumber. ToString(); string Order = OrderNr. ToString(); string update = "UPDATE patedb.patelog SET rangeNr= "+Range+', ' + "orderID= "+OrderNr+" WHERE pateID="+RowNumber; MySqlCommand updatecmd = new MySqlCommand(aggiornamento, connessione); prova { connessione. Open(); updatecmd. ExecuteNonQuery(); connessione. Chiudi(); } catch (eccezione es.) { MessageBox. Show(ex. Message); } }
private void btnStop_Click(mittente oggetto, EventArgs e)
{ if (ProdRunning == true) { timer1. Stop(); ProdRunning = false; UpdateOrderTable(); } else { MessageBox. Show("Nessuna produzione ancora iniziata. Inserisci i dati e premi il pulsante 'start'"); } }
private void UpdateOrderTable()
{ string insert = "INSERT INTO patedb.ordertable (orderID, orderQuant, quantProduced, comment, customerID) VALUES ('" + this.txtOrderNumber. Text + "', '" + this.txtOrderQuant. Text + "', '"+ QuantProduced. ToString()+"', '"+this.txtComment. Text+"', '"+this.txtCustomerNr. Text+"');"; MySqlCommand insertcmd = new MySqlCommand(insert, connection); prova { connessione. Open(); insertcmd. ExecuteNonQuery(); connessione. Chiudi(); QuantProdotto = 0; } catch (eccezione es.) { MessageBox. Show(ex. Message); } }
private void timer1_Tick (mittente oggetto, EventArgs e)
{ CheckTableForNull(); load_table(); }
private void btnShowOrderTable_Click(mittente oggetto, EventArgs e)
{ if (ProdRunning == false) { MySqlCommand command = new MySqlCommand("SELECT * FROM patedb.ordertable ORDER BY orderID DESC;", connection); prova { adattatore MySqlDataAdapter = new MySqlDataAdapter(); adapter. SelectCommand = comando; DataTable dbdataset = new DataTable(); adapter. Fill(dbdataset); BindingSource bsource = new BindingSource(); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; adapter. Update(dbdataset); } catch (eccezione es.) { MessageBox. Show(ex. Message); } } else { MessageBox. Show("Premi stop per visualizzare la tabella degli ordini"); } }
private void btnShowOrderDetails_Click(mittente oggetto, EventArgs e)
{ if (ProdRunning == false) { string test = ("SELECT patedb.ordertable.orderID, orderQuant, quantProduced, comment, customerID FROM patedb.ordertable INNER JOIN patedb.patelog ON patedb.patelog.orderID= patedb.ordertable.orderID WHERE patedb.patelog. UID = '" + txtShowOrderDetails. Text + "'"); comando MySqlCommand = new MySqlCommand(test, connection); prova { connessione. Open(); Adattatore MySqlDataAdapter = new MySqlDataAdapter(); adapter. SelectCommand = comando; DataTable dbdataset = new DataTable(); adapter. Fill(dbdataset); BindingSource bsource = new BindingSource(); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; adapter. Update(dbdataset); } catch (eccezione es.) { MessageBox. Show(ex. Message); } connessione. Close(); } else { MessageBox. Show("Premi stop per visualizzare i dettagli dell'ordine"); } }
private void btnShowCustomerDetails_Click(mittente oggetto, EventArgs e)
{ if (ProdRunning == false) { string test = ("SELECT patedb.customertable.customerID, nome, indirizzo, telefono, e-mail, rangeNr FROM patedb.customertable INNER JOIN patedb.ordertable ON patedb.ordertable.customerID= patedb.customertable. customerID WHERE patedb.ordertable.orderID = '" + txtShowCustomerDetails. Text + "'"); comando MySqlCommand = new MySqlCommand(test, connection); prova { adattatore MySqlDataAdapter = new MySqlDataAdapter(); adapter. SelectCommand = comando; DataTable dbdataset = new DataTable(); adapter. Fill(dbdataset); BindingSource bsource = new BindingSource(); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; adapter. Update(dbdataset); } catch (eccezione es.) { MessageBox. Show(ex. Message); } } else { MessageBox. Show("Premi stop per visualizzare i dettagli del cliente"); } } }
}
Consigliato:
UCL-IIOT - Sistema di allarme con database e nodo rosso: 7 passaggi
UCL-IIOT - Sistema di allarme con database e Node-red: lo scopo di questa build è insegnare come collegare Arduino con Node-red e un database, in modo da poter registrare i dati e anche raccoglierli per un uso successivo. Per questa build utilizzo un semplice sistema di allarme arduino che emette 5 numeri di dati, ciascuno separato da un
Creazione di un database con XAMPP: 4 passaggi
Creazione di un database con XAMPP: XAMPP è una distribuzione Apache completamente gratuita contenente MariaDB, PHP e Perl. XAMPP fornisce un'interfaccia grafica per SQL, che consente di memorizzare le informazioni nel database che creeremo oggi. Quando ho iniziato a utilizzare i database per i progetti
Come smontare un computer con semplici passaggi e immagini: 13 passaggi (con immagini)
Come smontare un computer con semplici passaggi e immagini: questa è un'istruzione su come smontare un PC. La maggior parte dei componenti di base sono modulari e facilmente smontabili. Tuttavia è importante che tu sia organizzato al riguardo. Questo ti aiuterà a non perdere parti e anche a rendere più facile il rimontaggio
Connetti il database IOT Raspberry Pi con MS Excel - Configurazione: 3 passaggi
Connetti il database IOT Raspberry Pi con MS Excel - Configurazione: nel mondo dell'acquisizione dei dati IOT, si creano molti dati che vengono invariabilmente salvati in un sistema di database come Mysql o Oracle. Per ottenere l'accesso e manipolare questi dati, uno dei metodi più efficienti è utilizzare i prodotti Microsoft Office
EAL-Industria 4.0-Razzo intelligente: 8 passaggi (con immagini)
EAL-Industry 4.0-Smart Rocket: Questo è un progetto scolastico, realizzato su Erhversakademiet Lillebælt in Danimarca.Il progetto è realizzato in una classe chiamata "Industri 4.0".Il compito è implementare un sistema automatico dell'industria 4.0 principi.Il sistema dovrebbe essere in grado di