Innehållsförteckning:
- Steg 1: Opsamling av data för Vægt Samt Registrering Af UID
- Steg 2: Arduino-program
- Steg 3: Node-RED, Lagring Af Data I Database
- Steg 4: Databasdesign
- Steg 5: Patelog
- Steg 6: Ordertable
- Steg 7: Anpassningsbar
- Steg 8: Räckvidd
- Steg 9: C# -program
Video: EAL-Industri4.0-RFID Dataopsamling Til Database: 10 Steg (med bilder)
2024 Författare: John Day | [email protected]. Senast ändrad: 2024-01-30 12:46
Detta projekt omhandler opsamling av viktdata, registrering av identiteter vha. RFID, lagring af data i en MySQL -databas vha. node-RED, samt framvisning och behandling av de opsamlade data i och C# -program i form av en Windows Form Application. Vi forestiller oss följande:
Vi har en produktionslinje som producent leverpostej i 200g foliebakker. Alla färdiga leverantörsutrustningar utrustas med en RFID -tagg i plastlåget/etiketter, som innehåller ett unikt ID (UID = Unique Identifier, är en 32 bitars kod, 8 hexadecimale karakterer) för entydig identifikation av varje enkelt bakre leverpostej. Da färdigvægten av varje enkelt bakke leverpostej kan svinge (ansvarig av råvaror, fordampning i ovn mm), och då kunderne varje har och specifika krav færdigvægten, används UID -tagget för att knyta varje enkelt leverpost till en specifik lagerlokation på lager, där det kan lagras leverpostejer till en specifik kunde. Kunderne är supermarkedskæder:
1. Irma. Vægten på Irmas luksus leverpostej ska hålla sig inom +/- 5%, alltså minst 190g och högst 210g.
2. Brugsen. Vægten på Brugsens leverpostej ska hålla sig inom +/- 10%, alltså minst 180g och max 220g.
3. Aldi. Vægten på Aldis rabattpapper ska hållas inom +/- 15%, alltså minst 170g och högst 230g.
Der är således följande sorteringer:
Range0: utanför intervallet
Område 1: minst 190 g/max 210 g
Område 2: minst 180 g/max 220 g
Område 3: minst 170 g/max 230 g
Steg 1: Opsamling av data för Vægt Samt Registrering Af UID
Till insamling av data för vikt, samt registrering av RFID-taggar används för en Arduino MEGA2560 med en RFID-RC522 läsare/skribent. Vi har inte någon vikt, simulerer vi data for vægten med och potmeter tillsluttet en analog indgang på Arduinoen.
Följande inställning används:
1 stk potmeter 25k lineært. Yder-benene er tilsluttet hhv. GND og +5V, midterbenet är tilsluttet AN0
RFID-RC522 är tillsluttet Arduino-kort SPI-port på följande sätt:
SDA -> stift 53
SCK -> pin52
MOSI -> pin51
MISO-> pin50
IRQ -> NC
GND -> GND
RST -> pin5
3.3V -> 3.3V
De opsamlede data, för hhv. UID och vægten, skickar på den seriella porten som en kommaseparerad textsträng vidare till nod-Röd som står för den efterföljande presentationen på et instrumentpanel och lagring i en databas.
Steg 2: Arduino-program
I Arduino programmet ingåres to to biblioteker SPI.h og MFRC522.h for at kunne använda RFID læseren. Jag startar av programmet initialiseres de applicte variable. Der laves en instans af MFRC522. I Setup blokken initialiseres den serielle connection, SPI porten och MFRC522. Derefter scannes efter RFID -taggar. For ikke at sende det samme UID afsted flera gange efter varandra, det är gjort som en stumpkod som tjekker för detta. När der er scannet et UID tag, loades arary nyUID med det just läste UID. Om array nyUID är forskligt från oldUID är det berättelse om och nytt UID som kan skickas på den seriella porten. Om nyUID och oldUID är ens, är der tale om samma UID -tagg och UID'et ska ignoreres. Om der er tale om et nyt UID, skickar UID'et på den seriella porten tillsammans med en läst värde från den seriella porten. Den analoga värdet ska visas till området 150-250. Data skickar som en komma-separeret textstreng. Som det sista sattes oldUID = nyUID, således att koden klart kan läsa och nyt RFID -tagg.. Den sista funktionen i programmet är den funktion som jämförar 2 matriser. Funktionen returnerer true om array'ne är ens, och false hvis array'ne är olika.
#omfatta
#include // Detta program skannar RFID-kort med RDIF-RC522 läsare/skrivarkort. // UID läses, en analog pin läses. Analogt värde 0-1023 skalas till 150-250. // UID och analogt värde skickas som kommaseparerad text på seriell port med 9600, N, 8, 1. // Man har varit noga med att bara skicka varje UID en gång i rad, // ett nytt UID måste vara närvarande innan samma UID kan skickas igen. // Denna funktion implementeras i koden genom att jämföra matriser: oldUID nyUID i funktion array_cmp (oldUID , nyUID )
constexpr uint8_t RST_PIN = 5;
constexpr uint8_t SS_PIN = 53; int sensorPin = A0; int värde = 0; String StringValue = "0000"; byte oldUID [4] = {}; byte nyUID [4] = {};
MFRC522 mfrc522 (SS_PIN, RST_PIN); // Skapa MFRC522 -instans.
void setup ()
{Serial.begin (9600); // Starta en seriell kommunikation SPI.begin (); // Starta SPI -buss mfrc522. PCD_Init (); // Starta MFRC522}
void loop ()
{// Leta efter nya kort om (! Mfrc522. PICC_IsNewCardPresent ()) {return; } // Välj ett av korten om (! Mfrc522. PICC_ReadCardSerial ()) {return; } // ladda nyUID med UID -tagg för (byte i = 0; i <mfrc522.uid.size; i ++) {nyUID = mfrc522.uid.uidByte ; } // if oldUID nyUID if (! array_cmp (oldUID, nyUID)) {// skicka UID -tagg på seriell port för (byte i = 0; i 1000) {Value = 1000; } Värde = (Värde / 10) + 150; // skicka skalat analogt värde Serial.print (värde); // skicka newline Serial.println (); // ställ in oldUID = nyUID för (byte z = 0; z <4; z ++) oldUID [z] = nyUID [z]; } // vänta 1 sek fördröjning (1000); }
// jämför 2 matriser …
booleskt array_cmp (byte a , byte b ) {bool test = true; // testa att varje element är detsamma. om bara en inte är det, returnera false för (byte n = 0; n <4; n ++) {if (a [n]! = b [n]) test = false; // if on byte not equal, test = false} if (test == true) return true; annars returnera falskt; }
Steg 3: Node-RED, Lagring Af Data I Database
Följande flöde är gjort i nod-RÖD:
COM4 är den seriella anslutningen där data mottages från Arduino boardet. Funktionerne "Split and Get value" och "Split and Get UID" splitter textstrengen vid kommaet och returnere hhv vægten och UID. Vægten används för att visa på instrumentpanelen i en linjechart och en skala. UID framvises i och textfelt. Funktionen test_sound advarer verbalt med sætningen "Out of range", om vægten är under 170g eller över 230g, dvs i intervall 0.
Dela och få värde:
var output = msg.payload.split (',');
temp = {nyttolast: (utmatning [1])}; returtemp;
Dela och få UID:
var output = msg.payload.split (",");
temp = {nyttolast: output [0]}; returtemp;
test_ljud:
var number = parseInt (msg.payload);
if (nummer> 230 || nummer <170) {newMsg = {nyttolast: "Out of range"}; returnera newMsg; } annat {newMsg = {nyttolast: ""}; returnera newMsg; }
Funktioner Split string "," indsætter and timestamp, UID and vægten i en database patedb.patelog.
var output = msg.payload.split (","); // dela msg.payload med kommatecken i array
UIDTag = output [0]; // första delen till första position [0] ValueTag = output [1]; // andra delen till andra position [1]
var m = {
ämne: "INSERT INTO patedb.patelog (tidsstämpel, UID, vikt) VÄRDEN ('"+nytt datum (). toISOString ()+"', '"+UIDTag+"', '"+ValueTag+"');" }; återvända m;
patelog är en MySQL -databasförbindelse som kan användas med följande parametrar:
Värd: lokal värd
Port: 3306
Användare: root
Databas: patedb
Steg 4: Databasdesign
Databasen innehåller 4 tabeller
patelog er dataopsamlingstabellen, tilskrives data af node-RED och C# program
ordertable är en tabell som innehåller data om de genemførte ordrer, tilskrives data av C# program
kundanpassad är och kundregister
rangetable är en tabell som innehåller greenseværdierne för de i C# programmet benyttede intervall.
Steg 5: Patelog
Tabellen patelog innehåller följande 6 kolonner:
pateID (int) är primär nyckel och inkrementeres automatiskt.
Tidsstämpel, UID & vikt är av typen varchar (med forskellig max längd)
rangeNr är av typen tinyint (beräkningar och tilfåligheter av C# program)
orderID är af typen int (orderID tilføjes af C# program)
Node-RÖD kan inte värderas till kolonnern rangeNr och orderID. rangeNr och orderID tillader NULL värden, det används i C# program för att detektera de rækker som ska tilskrives värden för rangeNr och orderID
Steg 6: Ordertable
ordertable innehåller 5 kolonner:
orderID (int) är det aktuella ordrenummer
orderQuant (mediumint) är ordens pålydende antal
quantProduced (mediumint) är antal der rent faktiskt är produceret på ordren. (Tælles af C# program)
comment (tinytext) är en eventuel kommentar till ordren.
customerID (int) är aktuell kundenummer på ordren.
Steg 7: Anpassningsbar
anpassningsbar innehåller 6 kolonner:
customerID (int) är primärnyckel og auto inc.
namn, adress, telefon, e -post (varchar) med forskellig max längd
rangeNr (int)
Steg 8: Räckvidd
rangetable innehåller 3 kolonner:
rangeNr (int) är primärnyckel og auto inc.
rangeMin (int)
rangeMax (int)
Steg 9: C# -program
När der produceres en ordre leverpostej, är proceduren följande:
Kundenummer, ordrenummer, ordreantal och en eventuel kommentar indtastes i C# program (i praktiken används det digitalt från företagets ordresystem. Produktionen startar nu med tryck på 'start'- knappen. på och transportbånd) Samhørende värderingar av UID och den aktuella vikten skickar seriell till node-RED, som visar uppsamlingsdata på instrumentpanelen 'och samtidigt skrives tidsstämpel, UID och vikt i en ny rad i patedb.patelog tabellen. tid kan inte tillskrives värden för rangeNr och orderID kommer att ha värden NULL.
Med et timerinterval undersøger C# program patedb.patelogtabellen for nye tilkomne rækker med NULL värderar i rangeNr kolonnen. När der är detektering en rad med NULL -värde, beräknad rangeNr och det tilföjes tillsammans med aktuella orderID. När en ordre är producent, avsluttar ordningen med tryck på”stop”- knappen. När ordren avsluttes, tilføjes en rad till patedb.ordertable med de aktuella ordredata. När en ordre är avslöjad, kan jag använda data i patelog tabellen för att trycka på de olika knapparna i gruppen Uppdatera DataGridview. ordertable kan också visas, och det kan söges ordredata på individueller UID'er eller kundedata på individuell ordrer.
använder System; använder System. Collections. Generic; använder System. ComponentModel; använder System. Data; använder System. Drawing; använder System. Linq; använder System. Text; använder System. Threading. Tasks; använder System. Windows. Forms; med MySql. Data. MySqlClient;
namnområde show_data_from_database
{public partial class Form1: Form {MySqlConnection connection = new MySqlConnection ("datasource = localhost; username = root; password = ''"); int radnummer = 0; // Variabel för lagring av pateID -värde int RangeNumber = 0; // Variabel för lagring av rangenumber int vikt = 0; // Variabel för lagring av vikten int OrderNr = 0; // Variabel för lagring av OrderNR int QuantProduced = 0; // Variabel för lagring av producerad kvantitet int NumberOfRows = 0; // antal rader med nullar.. bool ProdRunning = false; // Variabel som anger om start- och stoppknappar har aktiverats int limits = new int [6]; // initialize array int CustomerID; // Variabel för lagring av customerID public Form1 () {InitializeComponent (); load_table (); // call load_table}
void load_table ()
{MySqlCommand -kommando = nytt MySqlCommand ("VÄLJ * FRÅN patedb.patelog ORDER BY tidsstämpel DESC;", anslutning); prova {MySqlDataAdapter adapter = new MySqlDataAdapter (); adapter. SelectCommand = kommando; DataTable dbdataset = new DataTable (); adapter. Fyll (dbdataset); BindingSource bsource = ny BindingSource (); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; SetRowOrder (); adapter. Update (dbdataset); } catch (Undantag ex) {MessageBox. Show (ex. Message); }}
private void SetRowOrder ()
{dataGridView1. Columns ["pateID"]. DisplayIndex = 0; // Her kan följd av kolonner ändras dataGridView1. Columns ["tidsstämpel"]. DisplayIndex = 1; // Her kan följd av kolonner ändras dataGridView1. Columns ["UID"]. DisplayIndex = 2; // Her kan följd av kolonner ändras dataGridView1. Columns ["weight"]. DisplayIndex = 3; // Her kan följd av kolonner ändras dataGridView1. Columns ["rangeNr"]. DisplayIndex = 4; // Her kan följd av kolonner ändras dataGridView1. Columns ["orderID"]. DisplayIndex = 5; // Her kan följeslag av kolonner ändres}
private void GetData_Click (objektavsändare, EventArgs e) // Läser databastabell och order efter tidsstämpel
{load_table (); }
privat void btnRefreshUID_Click (objektavsändare, EventArgs e) //
{string timeStr = "VÄLJ * FRÅN patedb.patelog ORDER BY UID;"; MySqlCommand -kommando = nytt MySqlCommand (timeStr, anslutning); prova {MySqlDataAdapter adapter = new MySqlDataAdapter (); adapter. SelectCommand = kommando; DataTable dbdataset = new DataTable (); adapter. Fyll (dbdataset); BindingSource bsource = new BindingSource (); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; SetRowOrder (); adapter. Update (dbdataset); } catch (Undantag ex) {MessageBox. Show (ex. Message); }}
private void btnRefreshValue_Click (objektavsändare, EventArgs e)
{string weightSort = "SELECT * FRÅN patedb.patelog BESTÄLLNING PÅ CAST (vikt SIGNERAD INTEGER);"; MySqlCommand -kommando = nytt MySqlCommand (weightSort, anslutning); prova {MySqlDataAdapter adapter = new MySqlDataAdapter (); adapter. SelectCommand = kommando; DataTable dbdataset = new DataTable (); adapter. Fyll (dbdataset); BindingSource bsource = ny BindingSource (); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; SetRowOrder (); adapter. Update (dbdataset); } catch (Undantag ex) {MessageBox. Show (ex. Message); }}
privat tomrum ChkNullBtn_Click (objektavsändare, EventArgs e)
{if (ProdRunning) {CheckTableForNull (); load_table (); }}
privat tomrum CheckTableForNull ()
{// Kontrollera/ställ in tidsintervall minst 100 ms int i; int. TryParse (textTimer1. Text, ut i); if (i <100) {timer1. Stop (); i = 100; timer1. Interval = i; MessageBox. Show ("Minsta värde i 100mS"); timer1. Start (); } annat {timer1. Interval = i; } textTimer1. Text = timer1. Interval. ToString (); // Kontrollera om några rader med null finns i tabellen, returnerar antalet rader i variabeln: NumberOfRows string weightStr = ""; string chkNull = "VÄLJ RÄKNE (*) FRÅN patedb.patelog VAR rangeNR ÄR NULL BESTÄLLNING PateID LIMIT 1;"; MySqlCommand -kommando = nytt MySqlCommand (chkNull, anslutning); prova {connection. Open (); NumberOfRows = Convert. ToInt32 (command. ExecuteScalar ()); anslutning. Stäng (); } catch (Undantag ex) {MessageBox. Show (ex. Message); } slutligen {if (NumberOfRows! = 0) {try {// Väljer lägsta pateID -nummer där rangeNr är NULL string readID = "SELECT pateID FRÅN patedb.patelog WHERE rangeNR IS NULL ORDER BY pateID ASC LIMIT 1;"; MySqlCommand cmdID = nytt MySqlCommand (readID, anslutning); {connection. Open (); RowNumber = (int) cmdID. ExecuteScalar (); //heltal!! anslutning. Stäng (); } listPateID. Text = RowNumber. ToString (); // läs upp valt PateID -nummer // Väljer vikt från vald radnummer för radnummer = RowNumber. ToString (); string readweight = "VÄLJ vikt FRÅN patedb.patelog WHERE pateID =" + rad; MySqlCommand cmdweight = nytt MySqlCommand (läsvikt, anslutning); {connection. Open (); weightStr = (string) cmdweight. ExecuteScalar (); // Sträng !! anslutning. Stäng (); } vikt = int. Parse (weightStr); // konvertera till int txtWeight. Text = weight. ToString (); // print int RangeNumber = 0; if (vikt> = gränser [0] && vikt = gränser [2] && vikt = gränser [4] && vikt <= gränser [5]) {RangeNumber = 3; }} txtRange. Text = RangeNumber. ToString (); UpdateLog (); } catch (Undantag ex) {MessageBox. Show (ex. Message); } QuantProduced = QuantProduced + 1; }}} private void btnStart_Click (objektavsändare, EventArgs e) {if (ProdRunning == false) {int valtest; prova {CustomerID = int. Parse (txtCustomerNr. Text); // läs customerID} catch {MessageBox. Show ("Ange produktionsdata och tryck på" start "-knappen."); }
string test = "SELECT COUNT (*) FRÅN patedb.customertable WHERE customerID ="+CustomerID;
MySqlCommand cmdtestcustomer = nytt MySqlCommand (test, anslutning); {connection. Open (); valtest = Convert. ToInt32 (cmdtestcustomer. ExecuteScalar ()); // returnerar 0 om kunden inte har anslutning. Close (); } if (valtest == 1) // om kunden finns i databasen - starta produktionen {prova {OrderNr = int. Parse (txtOrderNumber. Text); ProdRunning = true; timer1. Start (); textTimer1. Text = timer1. Interval. ToString (); ReadLimits (); } catch (Undantag ex) {MessageBox. Show ("Ange produktionsdata och tryck på" start "-knappen."); }} else MessageBox. Show ("Kunden finns inte i databasen, försök igen"); } // ReadLimits (); }
privat tomrum ReadLimits ()
{// Läser gränser från rangetable, intervall 1 till 3 int räknare = 0; för (int rangeNr = 1; rangeNr <4; rangeNr ++) {string readmin = "SELECT rangeMin FROM patedb.rangetable WHERE rangeNr ="+rangeNr; MySqlCommand cmdmin = nytt MySqlCommand (readmin, anslutning); {connection. Open (); gränser [räknare] = (int) cmdmin. ExecuteScalar (); räknare = räknare + 1; anslutning. Stäng (); } // MessageBox. Show (counter. ToString ()); string readmax = "SELECT rangeMax FROM patedb.rangetable WHERE rangeNr =" + rangeNr; MySqlCommand cmdmax = nytt MySqlCommand (readmax, anslutning); {connection. Open (); gränser [räknare] = (int) cmdmax. ExecuteScalar (); räknare = räknare + 1; anslutning. Stäng (); }} // slut för loop}
private void UpdateLog ()
{// UPDATE rangeNR & orderID string Range = RangeNumber. ToString (); string Order = OrderNr. ToString (); string update = "UPDATE patedb.patelog SET rangeNr ="+Range+','+"orderID ="+OrderNr+"WHERE pateID ="+RowNumber; MySqlCommand updatecmd = nytt MySqlCommand (uppdatering, anslutning); prova {connection. Open (); updatecmd. ExecuteNonQuery (); anslutning. Stäng (); } catch (Undantag ex) {MessageBox. Show (ex. Message); }}
private void btnStop_Click (objektavsändare, EventArgs e)
{if (ProdRunning == true) {timer1. Stop (); ProdRunning = false; UpdateOrderTable (); } else {MessageBox. Show ("Ingen produktion har påbörjats ännu. Ange data och tryck på" start "-knappen"); }}
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 = nytt MySqlCommand (infoga, anslutning); prova {connection. Open (); insertcmd. ExecuteNonQuery (); anslutning. Stäng (); QuantProduced = 0; } catch (Undantag ex) {MessageBox. Show (ex. Message); }}
private void timer1_Tick (objektavsändare, EventArgs e)
{CheckTableForNull (); load_table (); }
private void btnShowOrderTable_Click (objektavsändare, EventArgs e)
{if (ProdRunning == false) {MySqlCommand command = new MySqlCommand ("SELECT * FROM patedb.ordertable ORDER BY orderID DESC;", connection); prova {MySqlDataAdapter adapter = new MySqlDataAdapter (); adapter. SelectCommand = kommando; DataTable dbdataset = new DataTable (); adapter. Fyll (dbdataset); BindingSource bsource = ny BindingSource (); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; adapter. Update (dbdataset); } catch (Undantag ex) {MessageBox. Show (ex. Message); }} else {MessageBox. Show ("Tryck på stopp för att se orderTable"); }}
private void btnShowOrderDetails_Click (objektavsändare, 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 +"' ""); MySqlCommand -kommando = nytt MySqlCommand (test, anslutning); prova {connection. Open (); MySqlDataAdapter -adapter = ny MySqlDataAdapter (); adapter. SelectCommand = kommando; DataTable dbdataset = new DataTable (); adapter. Fyll (dbdataset); BindingSource bsource = ny BindingSource (); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; adapter. Update (dbdataset); } catch (Undantag ex) {MessageBox. Show (ex. Message); } anslutning. Stäng (); } annars {MessageBox. Show ("Tryck på stopp för att visa orderinformation"); }}
private void btnShowCustomerDetails_Click (objektavsändare, EventArgs e)
{if (ProdRunning == false) {string test = ("SELECT patedb.customertable.customerID, name, address, phone, email, rangeNr FROM patedb.customertable INNER JOIN patedb.ordertable ON patedb.ordertable.customerID = patedb.customertable. customerID WHERE patedb.ordertable.orderID = '" + txtShowCustomerDetails. Text +"' "); MySqlCommand -kommando = nytt MySqlCommand (test, anslutning); prova {MySqlDataAdapter adapter = new MySqlDataAdapter (); adapter. SelectCommand = kommando; DataTable dbdataset = new DataTable (); adapter. Fyll (dbdataset); BindingSource bsource = ny BindingSource (); bsource. DataSource = dbdataset; dataGridView1. DataSource = bsource; adapter. Update (dbdataset); } catch (Undantag ex) {MessageBox. Show (ex. Message); }} else {MessageBox. Show ("Tryck på stopp för att se kundinformation"); }}}
}
Rekommenderad:
Skapa Ms Access Database Software för att förbereda lön i ditt företag: 6 steg
Skapa Ms Access Database Software för att förbereda lön i ditt företag: Jag ger dig den korta instruktionen för att skapa ett lönesystem med MS -åtkomst för att generera månadslöner och enkelt skriva ut lönesedlar med detta. På så sätt kan du hålla varje månad lönedetaljer under databasen och kan redigera eller granska sent
Dataopsamling Af Tyverialarm IIOT 4.0: 8 steg
Dataopsamling Af Tyverialarm IIOT 4.0: Detta projekt i faget IIOT är en vidareudvikling av entyverialarm, som jag har gjort på en Arduino i och tidigare projekt. Det här projektet har fokuserats på lagring av data, jag får från min tyverialarm, samt att lave och användargränssnitt. D
Trådlös fjärrkontroll med 2,4 GHz NRF24L01 -modul med Arduino - Nrf24l01 4 -kanals / 6 -kanals sändarmottagare för Quadcopter - Rc helikopter - RC -plan med Arduino: 5 steg (med bilder)
Trådlös fjärrkontroll med 2,4 GHz NRF24L01 -modul med Arduino | Nrf24l01 4 -kanals / 6 -kanals sändarmottagare för Quadcopter | Rc helikopter | Rc -plan med Arduino: Att driva en Rc -bil | Quadcopter | Drone | RC -plan | RC -båt, vi behöver alltid en mottagare och sändare, antag att för RC QUADCOPTER behöver vi en 6 -kanals sändare och mottagare och den typen av TX och RX är för dyr, så vi kommer att göra en på vår
Hur man tar isär en dator med enkla steg och bilder: 13 steg (med bilder)
Hur man tar isär en dator med enkla steg och bilder: Detta är en instruktion om hur man demonterar en dator. De flesta av de grundläggande komponenterna är modulära och lätt att ta bort. Det är dock viktigt att du är organiserad kring det. Detta hjälper dig att inte förlora delar, och även för att göra ommonteringen
EAL-Industry 4.0-Smart Rocket: 8 steg (med bilder)
EAL-Industry 4.0-Smart Rocket: Detta är ett skolprojekt, gjort på Erhversakademiet Lilleb æ lt i Danmark. Projektet är gjord i en klass som kallas "Industri 4.0". Uppgiften är att implementera ett automatiskt system från industrin 4.0 principer. Systemet bör kunna