- Vad är en DDS-funktionsgenerator?
- Förstå hur AD9833 funktionsgenerator IC fungerar
- Komponenter som krävs för att bygga den AD9833-baserade funktionsgeneratorn
- AD9833-baserad funktionsgenerator - schematiskt diagram
- AD9833-baserad funktionsgenerator - Arduino-kod
- Testar den AD9833-baserade funktionsgeneratorn
- Ytterligare förbättringar
Om du är en elektronisk entusiast som jag som vill finjustera med olika elektroniska kretsar blir det ibland obligatoriskt att ha en anständig funktionsgenerator. Men att äga en är ett problem eftersom sådan basutrustning kan kosta en förmögenhet. Att bygga din egen testutrustning är inte bara billigare utan också ett utmärkt sätt att förbättra din kunskap.
Så i den här artikeln ska vi bygga en enkel signalgenerator med Arduino och AD9833 DDS-funktionsgeneratormodul som kan producera sinus-, fyrkant- och triangelvågor med en maximal frekvens på 12 MHz vid utgången. Och slutligen kommer vi att testa utfrekvensen med hjälp av vårt oscilloskop.
Vi har tidigare byggt en Simple Sine Wave Generator, en Square Wave Generator och en Triangle Wave Generator med hjälp av grundläggande analoga kretsar. Du kan kolla in dem om du letar efter några grundläggande Waveform Generator Circuits. Om du vill bygga en billigare Arduino-funktionsgenerator utan att använda AD9833-modulen kan du också kolla in DIY Arduino Waveform Generator Project.
Vad är en DDS-funktionsgenerator?
Som namnet antyder är en funktionsgenerator en enhet som kan mata ut en specifik vågform med en specifik frekvens vid inställning. Tänk till exempel att du har ett LC-filter som du vill testa ditt utfrekvenssvar för, det kan du enkelt göra med hjälp av en funktionsgenerator. Allt du behöver göra är att ställa in önskad utgångsfrekvens och vågform, sedan kan du vrida ner den eller uppåt för att testa svaret. Detta var bara ett exempel, du kan göra fler saker med det när listan fortsätter.
DDS står för Direct Digital Synthesis. Det är en typ av vågformgenerator som använder digitala till analoga omvandlare (DAC) för att bygga en signal från grunden. Denna metod används specifikt för att generera en sinusvåg. Men IC som vi använder kan producera fyrkantiga eller triangulära vågsignaler. Funktionerna som hände inuti ett DDS-chip är digitala så att det kan växla frekvensen väldigt snabbt eller det kan växla från en signal till en annan mycket snabbt. Enheten har en fin frekvensupplösning med ett brett frekvensspektrum.
Förstå hur AD9833 funktionsgenerator IC fungerar
Kärnan i vårt projekt är AD9833 Programmerbar vågformgenerator IC som är designad och utvecklad av analoga enheter. Det är en programmerbar vågformgenerator med låg effekt som kan producera sinus-, triangulär och fyrkantig våg med en maximal frekvens på 12 MHz. Det är en mycket unik IC som kan ändra utfrekvensen och fasen med bara ett program. Den har ett 3-tråds SPI-gränssnitt vilket är anledningen till att kommunicera med denna IC blir väldigt enkelt och enkelt. Det funktionella blockdiagrammet för denna IC visas nedan.
Arbetet med denna IC är väldigt enkelt. Om vi tittar på det funktionella blockschemat ovan, kommer vi att observera att vi har en fasackumulator vars uppgift är att lagra alla möjliga digitala värden för en sinusvåg, från 0 till 2π. Därefter har vi SIN ROM vars uppgift är att konvertera fasinformationen som senare kan mappas direkt till amplitud. SIN ROM använder den digitala fasinformationen som en adress till en uppslagstabell och omvandlar fasinformationen till amplitud. Och slutligen har vi en 10-bitars digital till analog omvandlare vars uppgift är att ta emot digitala data från SIN ROM och konvertera den till motsvarande analoga spänningar, det är vad vi får från utgången. Vid utgången har vi också en omkopplare som vi kan slå på eller av med bara en liten mjukvarukod. Vi kommer att prata om det senare i artikeln.Detaljerna du ser ovan är en mycket avskalad version av vad som händer inuti IC, och de flesta detaljerna du ser ovan är hämtade från databladet AD9833, du kan också kolla in det för mer information.
Komponenter som krävs för att bygga den AD9833-baserade funktionsgeneratorn
Komponenterna som krävs för att bygga den AD9833-baserade funktionsgeneratorn listas nedan, vi designade den här kretsen med mycket generiska komponenter, vilket gör replikeringsprocessen väldigt enkel.
- Arduino Nano - 1
- AD9833 DDS-funktionsgenerator - 1
- 128 X 64 OLED-skärm - 1
- Generisk roterande kodare - 1
- DC Barrel Jack - 1
- LM7809 Spänningsregulator - 1
- 470uF kondensator - 1
- 220uF kondensator - 1
- 104pF kondensator - 1
- 10K motstånd - 6
- Taktila omkopplare - 4
- Skruvplint 5.04mm - 1
- Huvudrubrik - 1
- 12V strömkälla - 1
AD9833-baserad funktionsgenerator - schematiskt diagram
Det fullständiga kretsschemat för AD9833 och Arduino-baserad funktionsgenerator visas nedan.
Vi ska använda AD9833 med Arduino för att generera önskad frekvens. Och i detta avsnitt kommer vi att förklara alla detaljer med hjälp av schemat; låt mig ge dig en kort översikt över vad som händer med kretsen. Låt oss börja med AD9833-modulen. AD9833-modulen är funktionsgeneratormodulen och den är ansluten till Arduino enligt schemat. För att driva kretsen använder vi en LM7809 spänningsregulator IC, med en anständig frikopplingskondensator, detta är nödvändigt eftersom matningsbruset kan störa utsignalen vilket resulterar i oönskad utgång. Som alltid arbetar Arduino som hjärnan för detta projekt. För att visa inställd frekvens och annan värdefull information har vi anslutit en 128 X 64 OLED-skärmmodul. För att ändra frekvensområdet använder vi tre brytare. Den första sätter frekvensen till Hz, den andra sätter utfrekvensen till KHz, och den tredje sätter frekvensen till MHz, vi har också en annan knapp som kan användas för att aktivera eller inaktivera utgången. Slutligen har vi den roterande kodaren,och vi måste fästa något uppdragningsmotstånd med det annars fungerar inte dessa omkopplare eftersom vi kontrollerar knapptryckningshändelsen på poolmetoden. Den roterande kodaren används för att ändra frekvensen och den taktila omkopplaren inuti den roterande kodaren används för att välja den inställda vågformen.
AD9833-baserad funktionsgenerator - Arduino-kod
Den fullständiga koden som används i detta projekt finns längst ner på denna sida. När du har lagt till de nödvändiga rubrikfilerna och källfilerna bör du kunna kompilera Arduino-filen direkt. Du kan ladda ner ad9833 Arduino-biblioteket och andra bibliotek från länken nedan eller annars kan du använda metoden för styrelseshanterare för att installera biblioteket.
- Ladda ner AD9833-biblioteket av Bill Williams
- Ladda ner SSD1306 OLED-biblioteket av Adafruit
- Ladda ner Adafruit GFX-bibliotek
Förklaringen till koden i ino. filen är som följer. Först börjar vi med att inkludera alla bibliotek som krävs. Biblioteket för AD9833 DDS-modulen följs först av biblioteket för OLED och matematikbiblioteket krävs för några av våra beräkningar.
#include // LIbrary for AD9833 Module #include
Därefter definierar vi alla nödvändiga in- och utgångsstift för knapparna, switch, roterande kodare och OLED.
#define SCREEN_WIDATA_PINH 128 // OLED-skärm Bredd i pixlar #definiera SCREEN_HEIGHT 64 // OLED-skärmhöjd, i pixlar #definiera SET_FREQUENCY_HZ A2 // Tryckknapp för att ställa in frekvens i Hz #definiera SET_FREQUENCY_KHZ A3 // Tryckknapp för att ställa in frekvens i Khz A6 // Tryckknapp för att ställa in frekvens i Mhz #define / Datapinne på kodaren #definiera BTN_PIN 9 // Intern tryckknapp på kodaren
Därefter definierar vi alla nödvändiga variabler som krävs i denna kod. Först definierar vi en heltalsvariabel räknare som lagrar den roterande givarvärdet. De följande två variablerna clockPin och clockPinState lagrar den stiftstaty som krävs för att förstå kodarriktningen. Vi har en tid variabel som håller nuvarande timer-räknarvärden, denna variabel används för knapp studsborttagning. Därefter har vi en osignerad lång variabel modulFrekvens som innehåller den beräknade frekvensen som ska tillämpas. Därefter har vi debounce-förseningen. Denna fördröjning kan justeras efter behov. Därefter har vi tre booleska variabler set_frequency_hz,set_frequency_Khz och set_frequency_Mhz dessa tre variabler används för att bestämma den aktuella inställningen för modulen. Vi kommer att prata om det mer detaljerat senare i artikeln. Därefter har vi variabeln som lagrar utgångsvågformens status, standardutgångsvågformen är en sinusvåg. Och slutligen har vi encoder_btn_count- variabeln som innehåller räknarens knappantal som används för att ställa in utgångsvågformen.
int-räknare = 1; // Detta räknevärde kommer att öka eller minska om den roterande kodaren vrids int clockPin; // Platshållare för stiftstatus som används av den roterande kodaren int clockPinState; // Platshållare för stiftstatus som används av den roterande kodaren osignerad lång tid = 0; // Används för att avvisa osignerad lång modulFrequency; // används för att ställa in utgångsfrekvens lång debounce = 220; // Avstängningsfördröjning bool btn_state; // används för att aktivera inaktivera utdata från AD98333-modulen bool set_frequency_hz = 1; // Defultfrekvens för AD9833-modulens bool set_frequency_khz; bool set_frequency_mhz; Sträng waveSelect = "SIN"; // Startvågvåg för modulen int encoder_btn_count = 0; // används för att kontrollera kodarens knapptryckning Nästa, vi har våra två objekt ett är för OLED-skärmen och ett annat är för AD9833-modulen.Adafruit_SSD1306 display (SCREEN_WIDATA_PINH, SCREEN_HEIGHT, & Wire, -1); AD9833 gen (FNC_PIN);
Därefter har vi vår setup () -funktion, i den installationsfunktionen börjar vi med att aktivera Serial för felsökning. Vi initialiserar AD9833-modulen med hjälp av start () -metoden. Därefter ställer vi in alla tilldelade roterande kodstift som ingång. Och vi lagrar värdet på klockstiftet i variabeln ClockPinState, detta är ett nödvändigt steg för den roterande kodaren.
Därefter ställer vi in alla knappstiften som inmatning och aktiverar OLED-skärmen med hjälp av metoden display.begin () , och vi letar också efter eventuella fel med ett if-uttalande . När det är klart rensar vi skärmen och skriver ut en startskärm, vi lägger till en fördröjning på 2 sekunder vilket också är förseningen för stänkskärmen och slutligen kallar vi funktionen update_display () som rensar skärmen och uppdaterar visas igen. Detaljerna i metoden update_display () kommer att diskuteras senare i artikeln.
ogiltig installation () {Serial.begin (9600); // Aktivera Serial @ 9600 baud gen.Begin (); // Detta MÅSTE vara det första kommandot efter att deklarera AD9833-objektet pinMode (CLK_PIN, INPUT); // Ställa in pins som ingångs pinMode (DATA_PIN, INPUT); pinMode (BTN_PIN, INPUT_PULLUP); clockPinState = digitalRead (CLK_PIN); pinMode (SET_FREQUENCY_HZ, INPUT); // Ställa in pins som ingång pinMode (SET_FREQUENCY_KHZ, INPUT); pinMode (SET_FREQUENCY_MHZ, INPUT); pinMode (ENABLE_DISABLE_OUTPUT_PIN, INPUT); if (! display.begin (SSD1306_SWITCHCAPVCC, 0x3C)) {// Address 0x3D for 128x64 Serial.println (F ("SSD1306 allocation failed")); för (;;); } display.clearDisplay (); // Rensa skärmdisplayen. SetTextSize (2); // Ställ in textstorlek display.setTextColor (WHITE); // ställ in LCD-färgskärm. setCursor (30, 0); // Ställ in markörposition display.println ("AD9833"); // Skriv ut denna textdisplay.setCursor (17, 20); // Ställ in markörposition display.println ("Funktion"); // Skriv ut denna textvisning.setCursor (13, 40); // Ställ in markörposition display.println ("Generator"); // Skriv ut denna textdisplay. Display (); // Uppdatera visningsfördröjningen (2000); // Fördröjning av 2 SEC update_display (); // Call update_display-funktion}
Därefter har vi vår loop () -funktion, alla viktiga funktioner är skrivna i loop-avsnittet.
Först läser vi klockstiftet på Rotary-kodaren och lagrar det i ClockPin-variabeln som vi har förklarat tidigare. Därefter kontrollerar vi i if- uttalandet om det tidigare värdet på stiftet och det aktuella värdet på stiftet liknar eller inte och vi kontrollerar också det aktuella värdet på stiftet. Om allt är sant, letar vi efter datapinnen, om det är sant betyder det att kodaren roterar moturs och vi minskar räknarvärdet med hjälp av motkommando. Annars ökar vi räknarvärdet med counter ++ -kommandot. Slutligen sätter vi en annan if- sats för att ställa in minimivärdet till 1. Därefter uppdaterar vi clockPinState med den aktuella clockPinvärde för framtida användning.
ogiltig slinga () {clockPin = digitalRead (CLK_PIN); if (clockPin! = clockPinState && clockPin == 1) {if (digitalRead (DATA_PIN)! = clockPin) {counter -; } annat {counter ++; // Encoder roterar CW så steg) om (counter <1) counter = 1; Serial.println (räknare); update_display (); }
Därefter har vi vår kod för att upptäcka en knapptryckning. I det här avsnittet har vi upptäckt knappen inuti kodaren med hjälp av några kapslade om uttalanden, om (digitalRead (BTN_PIN) == LOW && millis () - tid> avbryta), i detta uttalande kontrollerar vi först om knappen stiftet är lågt eller inte, om det är lågt trycks det in. Sedan kontrollerar vi åter timervärdet med avvisningsfördröjningen, om båda påståendena är sanna, förklarar vi det som en framgångsrik knapptryckningsåtgärd om så ökar värdet encoder_btn_count. Därefter deklarerar vi ett annat om uttalande för att ställa in det maximala räknarvärdet till 2, vi behöver det eftersom vi använder det för att ställa in utgångsvågformen.De på varandra följande tre om uttalanden gör det, om värdet är noll, är sinusvågform vald, om det är ett, är det en fyrkantig våg, och om värdet är 2 är det en triangulär våg. I alla tre av dessa if-uttalanden uppdaterar vi skärmen med funktionen update_display () . Och slutligen uppdaterar vi tidsvariabeln med det aktuella timerräknarvärdet.
// Om vi upptäcker en LÅG signal, trycks på knappen om (digitalRead (BTN_PIN) == LOW && millis () - time> debounce) {encoder_btn_count ++; // Öka värdena om (encoder_btn_count> 2) // om värdet är större än 2 återställ det till 0 {encoder_btn_count = 0; } if (encoder_btn_count == 0) {// om värdet är 0 sinusvåg har valts waveSelect = "SIN"; // uppdatera strängvariabeln med sin-värde update_display (); // uppdatera displayen} if (encoder_btn_count == 1) {// om värdet är 1 kvadratvåg valt waveSelect = "SQR"; // uppdatera strängvariabeln med SQR-värde update_display (); // uppdatera displayen} if (encoder_btn_count == 2) {// om värdet är 1 Triangulär våg är vald waveSelect = "TRI"; // uppdatera strängvariabeln med TRI-värde update_display ();// uppdatera displayen} time = millis (); // uppdatera tidsvariabeln}
Därefter definierar vi all nödvändig kod som krävs för att ställa in alla knappar med en avstängningsfördröjning. Eftersom knapparna är anslutna till de analoga stiften på Arduino använder vi det analoga läskommandot för att identifiera en knapptryckning om det analoga läsvärdet når under 30, då upptäcker vi att det är en lyckad knapptryckning och vi väntar på 200 ms att kontrollera om det bara är ett knapptryck eller ett ljud. Om detta uttalande är sant tilldelar vi de booleska variablerna värden som används för att ställa in funktionsgeneratorns Hz-, Khz- och Mhz-värden. Därefter uppdaterar vi skärmen och uppdaterar tidsvariabeln. Vi gör det för alla de fyra knapparna som är anslutna till Arduino.
if (analogRead (SET_FREQUENCY_HZ) <30 && millis () - time> debounce) {set_frequency_hz = 1; // uppdatera booleska värden set_frequency_khz = 0; set_frequency_mhz = 0; update_display (); // uppdatera visningstiden = millis (); // uppdatera tidsvariabeln} om (analogRead (SET_FREQUENCY_KHZ) <30 && millis () - time> debounce) {set_frequency_hz = 0; // uppdatera booleska värden set_frequency_khz = 1; set_frequency_mhz = 0; moduleFrequency = räknare * 1000; update_display (); // uppdatera visningstiden = millis (); // uppdatera tidsvariabeln} if (analogRead (SET_FREQUENCY_MHZ) <30 && millis () - time> debounce) {// kontrollera analog pin med debounce delay set_frequency_hz = 0; // uppdatera booleska värden set_frequency_khz = 0; set_frequency_mhz = 1; moduleFrequency = räknare * 1000000; update_display ();// uppdatera visningstiden = millis (); // uppdatera tidsvariabeln} om (analogRead (ENABLE_DISABLE_OUTPUT_PIN) <30 && millis () - time> debounce) {// kontrollera analog stift med avvisningsfördröjning btn_state =! btn_state; // Invertera knapptillståndet gener.EnableOutput (btn_state); // Aktivera / inaktivera utdata från funktionsgeneratorn beroende på knapptillstånd update_display (); // uppdatera visningstiden = millis (); // uppdatera tidsvariabeln}}// uppdatera tidsvariabeln}}// uppdatera tidsvariabeln}}
Slutligen har vi vår update_display () funktion. I den här funktionen gjorde vi mycket mer än bara att uppdatera den här skärmen eftersom en viss del av skärmen inte kan uppdateras i en OLED. För att uppdatera den måste du måla om den med nya värden. Detta gör kodningsprocessen mycket svårare.
Inuti denna funktion börjar vi med att rensa skärmen. Därefter ställer vi in vår önskade textstorlek. Därefter ställer vi in vår markör och tryckta funktionsgenerator med displayen.println ("Funktionsfunktion"); kommando. Vi sätter igen textstorleken till 2 och markören till (0,20) med hjälp av display.setCursor (0, 20) -funktionen.
Det är här vi skriver ut informationen för vilken våg det är.
display.clearDisplay (); // Först rensa displayen. SetTextSize (1); // set text Size display.setCursor (10, 0); // Ställ in visning av markörposition.println ("Funktionsgenerator"); // skriv ut textdisplayen.setTextSize (2); // ställa in text Storlek display.setCursor (0, 20); // Ställ in markörposition
Därefter kontrollerar vi de booleska variablerna för frekvensinformation och uppdaterar värdet i moduleFrequency- variabeln. Vi gör detta för Hz-, kHz- och MHz-värden. Därefter kontrollerar vi variabeln waveSelect och identifierar vilken våg som är vald. Nu har vi värdena för att ställa in vågtyp och frekvens.
if (set_frequency_hz == 1 && set_frequency_khz == 0 && set_frequency_mhz == 0) {// kontrollera om knappen för inställning av frekvensen i Hz trycks in modulFrequency = counter; // uppdatera moduleFrequency-variabeln med aktuellt räknarvärde} if (set_frequency_hz == 0 && set_frequency_khz == 1 && set_frequency_mhz == 0) {// kontrollera om knappen för att ställa in frekvensen i KHz trycks på moduleFrequency = räknare * 1000; // uppdatera moduleFrequency-variabeln med aktuellt räknarvärde men vi multiplicerar 1000 för att ställa in den på KHZ} om (set_frequency_hz == 0 && set_frequency_khz == 0 && set_frequency_mhz == 1) {// kontrollera om knappen för att ställa in frekvensen i MHz trycks på moduleFrequency = räknare * 1000000; if (moduleFrequency> 12000000) {moduleFrequency = 12000000;// låt inte frekvensen vara rivjärn som 12Mhz räknare = 12; }} om (waveSelect == "SIN") {// Sine wave är valt display.println ("SIN"); gen.ApplySignal (SINE_WAVE, REG0, moduleFrequency); Serial.println (moduleFrequency); } om (waveSelect == "SQR") {// Sqr-våg är vald display.println ("SQR"); gen.ApplySignal (SQUARE_WAVE, REG0, moduleFrequency); Serial.println (moduleFrequency); } om (waveSelect == "TRI") {// Tri wave är valt display.println ("TRI"); gen.ApplySignal (TRIANGLE_WAVE, REG0, moduleFrequency); // uppdatera AD9833-modulen. Serial.println (moduleFrequency); }} om (waveSelect == "SQR") {// Sqr-våg är vald display.println ("SQR"); gen.ApplySignal (SQUARE_WAVE, REG0, moduleFrequency); Serial.println (moduleFrequency); } om (waveSelect == "TRI") {// Tri wave är valt display.println ("TRI"); gen.ApplySignal (TRIANGLE_WAVE, REG0, moduleFrequency); // uppdatera AD9833-modulen. Serial.println (moduleFrequency); }} om (waveSelect == "SQR") {// Sqr-våg är vald display.println ("SQR"); gen.ApplySignal (SQUARE_WAVE, REG0, moduleFrequency); Serial.println (moduleFrequency); } om (waveSelect == "TRI") {// Tri wave är valt display.println ("TRI"); gen.ApplySignal (TRIANGLE_WAVE, REG0, moduleFrequency); // uppdatera AD9833-modulen. Serial.println (moduleFrequency); }
Vi ställer in markören igen och uppdaterar räknarvärdena. Återigen kontrollerar vi booleska för att uppdatera frekvensområdet på skärmen, vi måste göra detta eftersom OLED: s arbetsprincip är väldigt konstig.
display.setCursor (45, 20); display.println (räknare); // skriva ut räknarinformationen på displayen. if (set_frequency_hz == 1 && set_frequency_khz == 0 && set_frequency_mhz == 0) {display.setCursor (90, 20); display.println ("Hz"); // skriv ut Hz på displayens display. display (); // när alla inställningar uppdaterar skärmen} if (set_frequency_hz == 0 && set_frequency_khz == 1 && set_frequency_mhz == 0) {display.setCursor (90, 20); display.println ("Khz"); display.display (); // när alla inställningar uppdaterar skärmen} if (set_frequency_hz == 0 && set_frequency_khz == 0 && set_frequency_mhz == 1) {display.setCursor (90, 20); display.println ("Mhz"); display.display (); // när alla inställningar uppdaterar skärmen}
Därefter kontrollerar vi knapptryckningsvariabeln för att skriva ut / på ut till OLED. Återigen måste detta göras på grund av OLED-modulen.
om (btn_state) {display.setTextSize (1); display.setCursor (65, 45); display.print ("Output ON"); // skriva ut på displayen. display (); display.setTextSize (2); } annat {display.setTextSize (1); display.setCursor (65, 45); display.print ("Output OFF"); // utskriftsutgång till displayens display. display (); display.setTextSize (2); }
Detta markerar slutet på vår kodningsprocess. Om du är förvirrad vid denna tidpunkt kan du kontrollera kommentarerna i koden för mer förståelse.
Testar den AD9833-baserade funktionsgeneratorn
För att testa kretsen används ovanstående inställning. Som du ser har vi anslutit en 12V likströmsadapter till likströmsuttaget och vi har anslutit Hantek Oscilloskop till utgången på kretsen. Vi har också anslutit oscilloskopet till den bärbara datorn för att visualisera och mäta utfrekvensen.
När detta var klart ställde vi utfrekvensen till 5 KHz med hjälp av den roterande kodaren och vi testar sinusvågens utgång och nog är det en 5 KHz sinusvåg vid utgången.
Därefter har vi ändrat utgångsvågformen till en triangulär våg men frekvensen var densamma, utgångsvågformen visas nedan.
Sedan ändrade vi utgången till en fyrkantvåg och observerade utgången, och det var en perfekt fyrkantvåg.
Vi ändrade också frekvensområdena och testade utgången, och det fungerade bra.
Ytterligare förbättringar
Denna krets är endast ett bevis på konceptet och behöver ytterligare förbättringar. Först behöver vi en PCB av god kvalitet och en BNC-kontakt av god kvalitet för utgången, annars kan vi inte få en högre frekvens. Modulens amplitud är mycket låg, så för att förbättra det behöver vi några op-amp-kretsar för att förstärka utspänningen. En potentiometer kan anslutas för att variera utgångsamplituden. En omkopplare för att kompensera signalen kan anslutas; detta är också en måste-ha-funktion. Och vidare behöver koden mycket förbättras eftersom den är lite buggy. Slutligen måste OLED-skärmar ändras, annars är det omöjligt att skriva lättförståelig kod.
Detta markerar slutet på denna handledning, jag hoppas att du gillade artikeln och lärde dig något nytt. Om du har några frågor angående artikeln kan du lämna dem i kommentarsektionen nedan eller så kan du använda vårt elektronikforum.