arduino:spektrumanalysator:programmversion_0.5
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende Überarbeitung | ||
arduino:spektrumanalysator:programmversion_0.5 [01.10.2017 00:43] – Frickelpiet | arduino:spektrumanalysator:programmversion_0.5 [18.05.2023 12:34] (aktuell) – Externe Bearbeitung 127.0.0.1 | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
====== Spektrumanalysator - Programmversion 0.5 ====== | ====== Spektrumanalysator - Programmversion 0.5 ====== | ||
+ | Diese Programmversion bindet ein OLED-Display ein. Die Bibliothek von Adafruit ist sehr langsam, was die Verwendung des Displays stark einschränkt. Perspektivisch soll das Display aber primär dafür verwendet werden, verschiedene Parameter anzuzeigen, so dass der Inhalt nur geändert werden muss, wenn Einstellungen vorgenommen wurden. Dafür ist die Geschwindigkeit der Bibliothek ausreichend. | ||
- | (kommt bald!) | + | Wenn das Eingangssignal unter einen gewissen Pegel fällt und auf diesem Pegel verbleibt, wird das OLED-Display mit einem coolen Effekt ausgeschaltet. |
+ | |||
+ | Menüstruktur: | ||
+ | Hauptmenü | ||
+ | * Input Select | ||
+ | * Anzeigemodi | ||
+ | * Auto Input Level Control | ||
+ | * Pixel Fading | ||
+ | |||
+ | |||
+ | Der Code zur Ansteuerung der Signalrelais ist noch nicht getestet. | ||
+ | |||
+ | < | ||
+ | // Spektrumanalysator | ||
+ | // Für einen NeoPixel-Streifen mit 72 NeoPixeln | ||
+ | // Bindet ein OLED-Display ein | ||
+ | // Steuert drei Signalrelais | ||
+ | |||
+ | // | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | // Pins | ||
+ | #define encoderChannelA | ||
+ | #define encoderChannelB | ||
+ | |||
+ | #define NEOPIXELPIN | ||
+ | |||
+ | #define relayA_on | ||
+ | #define relayA_off | ||
+ | #define relayB_on | ||
+ | #define relayB_off | ||
+ | #define relayC_on | ||
+ | #define relayC_off | ||
+ | |||
+ | #define sclk 14 // 38 | ||
+ | #define mosi 7 // 39 | ||
+ | #define dc 20 | ||
+ | #define cs 21 | ||
+ | #define rst 8 | ||
+ | |||
+ | // Color definitions | ||
+ | #define BLACK | ||
+ | #define BLUE 0x001F | ||
+ | #define RED | ||
+ | #define GREEN | ||
+ | #define CYAN 0x07FF | ||
+ | #define MAGENTA | ||
+ | #define YELLOW | ||
+ | #define WHITE | ||
+ | |||
+ | // Option 1: use any pins but a little slower | ||
+ | Adafruit_SSD1351 oled = Adafruit_SSD1351(cs, | ||
+ | |||
+ | // Option 2: must use the hardware SPI pins | ||
+ | // (for UNO thats sclk = 13 and sid = 11) and pin 10 must be | ||
+ | // an output. This is much faster - also required if you want | ||
+ | // to use the microSD card (see the image drawing example) | ||
+ | // | ||
+ | |||
+ | // Dreh-Encoder | ||
+ | Encoder myEnc(encoderChannelA, | ||
+ | |||
+ | long newPosition = 0; | ||
+ | long oldPosition; | ||
+ | |||
+ | // Signaleingang | ||
+ | int input = 0; // 0 = kein Input, 1 = digital, 2 = analog Cinch, 3 = analog Klinke | ||
+ | |||
+ | // Signalrelais | ||
+ | boolean relayA = HIGH; // Input digital | ||
+ | boolean relayB = LOW; // Input Cinch | ||
+ | boolean relayC = LOW; // Input Klinke | ||
+ | |||
+ | // OLED-Display | ||
+ | boolean refresh = true; // Wird wahr, wenn das Display aktualisiert werden muss | ||
+ | float autoGainGraphArray[128]; | ||
+ | int x; | ||
+ | int z; | ||
+ | float masterPeakGraphArray[128]; | ||
+ | |||
+ | // Menü Spektrumanalysator | ||
+ | unsigned char analyzerMode = 0; // Verschiedene Anzeigemodi | ||
+ | |||
+ | // Automatische Eingangspegelregelung | ||
+ | boolean autoInputLevelControl = true; // Aktiviert und deaktiviert die automatische Eingangspegelregelung | ||
+ | float peakMaxDecrease = 0.001; | ||
+ | |||
+ | float level_L[36]; | ||
+ | float level_R[36]; | ||
+ | float leftPeak; | ||
+ | float rightPeak; | ||
+ | float masterPeak; | ||
+ | float masterPeakMax; | ||
+ | float peakDecrease = 0.001; | ||
+ | float autoGain; | ||
+ | float masterPeakArray[10]; | ||
+ | float peak_Max; | ||
+ | int a; | ||
+ | |||
+ | // Konfiguriert den NeoPixel-Ring | ||
+ | int numPixels = 72; // Anzahl der NeoPixel | ||
+ | Adafruit_NeoPixel strip = Adafruit_NeoPixel(numPixels, | ||
+ | |||
+ | // Anzeige Spektrumanalysator | ||
+ | float n; | ||
+ | int i; // Variable zum zählen | ||
+ | byte r = 0; | ||
+ | byte g = 0; | ||
+ | byte b = 0; | ||
+ | byte w = 0; | ||
+ | |||
+ | // GUItool: begin automatically generated code | ||
+ | AudioInputI2S | ||
+ | AudioMixer4 | ||
+ | AudioMixer4 | ||
+ | AudioAnalyzePeak | ||
+ | AudioAnalyzeFFT1024 | ||
+ | AudioAnalyzePeak | ||
+ | AudioAnalyzeFFT1024 | ||
+ | AudioConnection | ||
+ | AudioConnection | ||
+ | AudioConnection | ||
+ | AudioConnection | ||
+ | AudioConnection | ||
+ | AudioConnection | ||
+ | AudioControlSGTL5000 | ||
+ | // GUItool: end automatically generated code | ||
+ | |||
+ | // Definiert die Tracking-Variablen für die IF-Abfragen | ||
+ | unsigned long previousMillisAutoInputLevelControl = 0; // Berechnung des maximalen Peaks für die automatische Inputlevel-Regelung | ||
+ | unsigned long previousMillisOLED = 0; // OLED-Display | ||
+ | |||
+ | // Definiert die Intervalle für die IF-Abfragen in Millisekunden | ||
+ | unsigned long intervalAutoInputLevelControl = 100; // Berechnung des maximalen Peaks für die automatische Inputlevel-Regelung | ||
+ | unsigned long intervalOLED = 100; // OLED-Display | ||
+ | |||
+ | |||
+ | // Taktung Schleifen | ||
+ | unsigned long lastMillis = 0; | ||
+ | unsigned long duration = 0; | ||
+ | |||
+ | |||
+ | void setup() { | ||
+ | Serial.begin(115200); | ||
+ | |||
+ | // OLED-Display | ||
+ | oled.begin(); | ||
+ | |||
+ | oled.fillScreen(BLACK); | ||
+ | oled.setCursor(15, | ||
+ | oled.setTextColor(WHITE, | ||
+ | oled.setTextSize(0); | ||
+ | oled.print(" | ||
+ | oled.setCursor(20, | ||
+ | oled.print(" | ||
+ | oled.setCursor(45, | ||
+ | oled.setTextSize(2); | ||
+ | oled.print(" | ||
+ | |||
+ | delay(500); | ||
+ | oled.fillScreen(BLACK); | ||
+ | |||
+ | // Audio-Funktionen | ||
+ | AudioMemory(22); | ||
+ | |||
+ | sgtl5000_1.enable(); | ||
+ | sgtl5000_1.muteHeadphone(); | ||
+ | sgtl5000_1.muteLineout(); | ||
+ | sgtl5000_1.inputSelect(AUDIO_INPUT_LINEIN); | ||
+ | sgtl5000_1.lineInLevel(5); | ||
+ | |||
+ | // Configure the window algorithm to use | ||
+ | fft1024_L.windowFunction(AudioWindowHanning1024); | ||
+ | fft1024_R.windowFunction(AudioWindowHanning1024); | ||
+ | |||
+ | // Eingangsrelais | ||
+ | pinMode(relayA_on, | ||
+ | pinMode(relayA_off, | ||
+ | pinMode(relayB_on, | ||
+ | pinMode(relayB_off, | ||
+ | pinMode(relayC_on, | ||
+ | pinMode(relayC_off, | ||
+ | |||
+ | digitalWrite(relayA_on, | ||
+ | delay(20); | ||
+ | digitalWrite(relayA_on, | ||
+ | delay(20); | ||
+ | digitalWrite(relayA_off, | ||
+ | delay(20); | ||
+ | digitalWrite(relayA_off, | ||
+ | delay(20); | ||
+ | |||
+ | digitalWrite(relayB_on, | ||
+ | delay(20); | ||
+ | digitalWrite(relayB_on, | ||
+ | delay(20); | ||
+ | digitalWrite(relayB_off, | ||
+ | delay(20); | ||
+ | digitalWrite(relayB_off, | ||
+ | delay(20); | ||
+ | |||
+ | digitalWrite(relayC_on, | ||
+ | delay(20); | ||
+ | digitalWrite(relayC_on, | ||
+ | delay(20); | ||
+ | digitalWrite(relayC_off, | ||
+ | delay(20); | ||
+ | digitalWrite(relayC_off, | ||
+ | delay(20); | ||
+ | |||
+ | if (input == 1) { | ||
+ | digitalWrite(relayA_on, | ||
+ | delay(20); | ||
+ | digitalWrite(relayA_on, | ||
+ | } | ||
+ | else if (input == 2) { | ||
+ | digitalWrite(relayB_on, | ||
+ | delay(20); | ||
+ | digitalWrite(relayB_on, | ||
+ | } | ||
+ | else if (input == 3) { | ||
+ | digitalWrite(relayC_on, | ||
+ | delay(20); | ||
+ | digitalWrite(relayC_on, | ||
+ | } | ||
+ | |||
+ | // Initialisiert den NeoPixel-Teststrip | ||
+ | strip.begin(); | ||
+ | strip.show(); | ||
+ | strip.setBrightness(64); | ||
+ | |||
+ | // Legt den Anzeigemodus fest (provisorisch) | ||
+ | analyzerMode = 0; | ||
+ | |||
+ | // Schaltet die automatische Inputlevelregelung ein bzw. aus. (Kann später im Menü aktiviert und deaktiviert werden.) | ||
+ | autoInputLevelControl = true; | ||
+ | } | ||
+ | |||
+ | void loop() { | ||
+ | // Aktuelle Zeit abfragen | ||
+ | unsigned long currentMillis = millis(); | ||
+ | |||
+ | // Encoder | ||
+ | newPosition = myEnc.read(); | ||
+ | if (newPosition | ||
+ | oldPosition = newPosition; | ||
+ | } | ||
+ | if (newPosition < 0) { | ||
+ | newPosition = 0; | ||
+ | } | ||
+ | if (newPosition >= 120) { | ||
+ | newPosition = 120; | ||
+ | } | ||
+ | |||
+ | // Gain Control | ||
+ | if (autoInputLevelControl == false) { // Die manuelle Inputlevel-Kontrolle ist nur aktiv, wenn die automatische Inputlevel-Regelung deaktiviert ist | ||
+ | mixer_L.gain(0, | ||
+ | mixer_R.gain(0, | ||
+ | } | ||
+ | |||
+ | // Fast Fourier Transformation (FFT) | ||
+ | if (fft1024_L.available() && fft1024_R.available()) { // Wenn die FFT neue Daten berechnet hat, werden für beide Kanäle je 512 FFT Frequenzen ausgelesen und in je 36 Bändern zusammengefasst. | ||
+ | |||
+ | // Zuerst ist der linke Kanal an der Reihe | ||
+ | level_L[35] = fft1024_L.read(0); | ||
+ | level_L[34] = fft1024_L.read(1); | ||
+ | level_L[33] = fft1024_L.read(2); | ||
+ | level_L[32] = fft1024_L.read(3); | ||
+ | level_L[31] = fft1024_L.read(4, | ||
+ | level_L[30] = fft1024_L.read(6, | ||
+ | level_L[29] = fft1024_L.read(8, | ||
+ | level_L[28] = fft1024_L.read(10, | ||
+ | level_L[27] = fft1024_L.read(12, | ||
+ | level_L[26] = fft1024_L.read(15, | ||
+ | level_L[25] = fft1024_L.read(18, | ||
+ | level_L[24] = fft1024_L.read(21, | ||
+ | level_L[23] = fft1024_L.read(25, | ||
+ | level_L[22] = fft1024_L.read(29, | ||
+ | level_L[21] = fft1024_L.read(33, | ||
+ | level_L[20] = fft1024_L.read(38, | ||
+ | level_L[19] = fft1024_L.read(44, | ||
+ | level_L[18] = fft1024_L.read(50, | ||
+ | level_L[17] = fft1024_L.read(57, | ||
+ | level_L[16] = fft1024_L.read(65, | ||
+ | level_L[15] = fft1024_L.read(74, | ||
+ | level_L[14] = fft1024_L.read(84, | ||
+ | level_L[13] = fft1024_L.read(95, | ||
+ | level_L[12] = fft1024_L.read(108, | ||
+ | level_L[11] = fft1024_L.read(122, | ||
+ | level_L[10] = fft1024_L.read(138, | ||
+ | level_L[9] = fft1024_L.read(156, | ||
+ | level_L[8] = fft1024_L.read(176, | ||
+ | level_L[7] = fft1024_L.read(199, | ||
+ | level_L[6] = fft1024_L.read(224, | ||
+ | level_L[5] = fft1024_L.read(252, | ||
+ | level_L[4] = fft1024_L.read(284, | ||
+ | level_L[3] = fft1024_L.read(320, | ||
+ | level_L[2] = fft1024_L.read(360, | ||
+ | level_L[1] = fft1024_L.read(405, | ||
+ | level_L[0] = fft1024_L.read(455, | ||
+ | |||
+ | // Und dann der rechte Kanal | ||
+ | level_R[0] = fft1024_R.read(0); | ||
+ | level_R[1] = fft1024_R.read(1); | ||
+ | level_R[2] = fft1024_R.read(2); | ||
+ | level_R[3] = fft1024_R.read(3); | ||
+ | level_R[4] = fft1024_R.read(4, | ||
+ | level_R[5] = fft1024_R.read(6, | ||
+ | level_R[6] = fft1024_R.read(8, | ||
+ | level_R[7] = fft1024_R.read(10, | ||
+ | level_R[8] = fft1024_R.read(12, | ||
+ | level_R[9] = fft1024_R.read(15, | ||
+ | level_R[10] = fft1024_R.read(18, | ||
+ | level_R[11] = fft1024_R.read(21, | ||
+ | level_R[12] = fft1024_R.read(25, | ||
+ | level_R[13] = fft1024_R.read(29, | ||
+ | level_R[14] = fft1024_R.read(33, | ||
+ | level_R[15] = fft1024_R.read(38, | ||
+ | level_R[16] = fft1024_R.read(44, | ||
+ | level_R[17] = fft1024_R.read(50, | ||
+ | level_R[18] = fft1024_R.read(57, | ||
+ | level_R[19] = fft1024_R.read(65, | ||
+ | level_R[20] = fft1024_R.read(74, | ||
+ | level_R[21] = fft1024_R.read(84, | ||
+ | level_R[22] = fft1024_R.read(95, | ||
+ | level_R[23] = fft1024_R.read(108, | ||
+ | level_R[24] = fft1024_R.read(122, | ||
+ | level_R[25] = fft1024_R.read(138, | ||
+ | level_R[26] = fft1024_R.read(156, | ||
+ | level_R[27] = fft1024_R.read(176, | ||
+ | level_R[28] = fft1024_R.read(199, | ||
+ | level_R[29] = fft1024_R.read(224, | ||
+ | level_R[30] = fft1024_R.read(252, | ||
+ | level_R[31] = fft1024_R.read(284, | ||
+ | level_R[32] = fft1024_R.read(320, | ||
+ | level_R[33] = fft1024_R.read(360, | ||
+ | level_R[34] = fft1024_R.read(405, | ||
+ | level_R[35] = fft1024_R.read(455, | ||
+ | |||
+ | // Anzeigemodi | ||
+ | //Effekt " | ||
+ | if (analyzerMode == 0) { | ||
+ | |||
+ | // Anschließend werden Farbwerte für die linke Seite des NeoPixel-Streifens berechnet | ||
+ | for (i=0; i< | ||
+ | n = level_L[i]; | ||
+ | if (n >= 0.01) { | ||
+ | // Scale ' | ||
+ | byte t192 = round((n * 2000 /255.0) * 191); | ||
+ | |||
+ | byte heatramp = t192 & 0x3F; // 0..63 | ||
+ | heatramp <<= 2; // scale up to 0..252 | ||
+ | |||
+ | if(t192 > 0x80) { // hottest | ||
+ | strip.setPixelColor(i, | ||
+ | } | ||
+ | else if(t192 > 0x40) { // middle | ||
+ | strip.setPixelColor(i, | ||
+ | } | ||
+ | else { // coolest | ||
+ | strip.setPixelColor(i, | ||
+ | } | ||
+ | } | ||
+ | else { | ||
+ | strip.setPixelColor(i, | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // Dann werden die Farbwerte für die rechte Seite des NeoPixel-Streifens berechnet | ||
+ | for (i=0; i< | ||
+ | n = level_R[i]; | ||
+ | if (n >= 0.01) { | ||
+ | // Scale ' | ||
+ | byte t192 = round((n * 2000 /255.0) * 191); | ||
+ | |||
+ | byte heatramp = t192 & 0x3F; // 0..63 | ||
+ | heatramp <<= 2; // scale up to 0..252 | ||
+ | |||
+ | if(t192 > 0x80) { // hottest | ||
+ | strip.setPixelColor(i+36, | ||
+ | } | ||
+ | else if(t192 > 0x40) { // middle | ||
+ | strip.setPixelColor(i+36, | ||
+ | } | ||
+ | else { // coolest | ||
+ | strip.setPixelColor(i+36, | ||
+ | } | ||
+ | } | ||
+ | else { | ||
+ | strip.setPixelColor(i+36, | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // Die Daten werden an den NeoPixel-Streifen geschickt | ||
+ | strip.show(); | ||
+ | } | ||
+ | |||
+ | |||
+ | // Automatische Eingangspegelregelung | ||
+ | if (autoInputLevelControl == true) { | ||
+ | // Es werden die Pegel des linken und rechten Audiokanals ausgelesen. | ||
+ | if (peak_L.available() && peak_R.available()) { | ||
+ | leftPeak = peak_L.read(); | ||
+ | rightPeak = peak_R.read(); | ||
+ | } | ||
+ | // Für die automatische Eingangspegelregelung wird der lautere der beiden Audiokanäle verwendet. | ||
+ | masterPeak = max(leftPeak, | ||
+ | |||
+ | // Der Maximalpegel wird gespeichert | ||
+ | if (masterPeak > masterPeakMax) { | ||
+ | masterPeakMax = masterPeak; | ||
+ | } | ||
+ | // Alle 100 Millikekunden wird die Eingangspegelanpassung berechnet | ||
+ | if ((unsigned long)(currentMillis - previousMillisAutoInputLevelControl) >= intervalAutoInputLevelControl) { | ||
+ | // Die automatische Eingangspegelanpassung hebt leise Eingangspegel an, aber ohne den Pegel vollständig zu kompensieren. | ||
+ | // Auf diese Weise haben leise Eingangssignale einen geringeren Pegelausschalg als laute, es wird aber dennoch " | ||
+ | masterPeakMax = masterPeakMax - peakDecrease; | ||
+ | |||
+ | autoGain = (1.00 - masterPeakMax) * 4; // autoGain wird berechnet | ||
+ | if (autoGain > 4.00) { // Die Maximale Pegelanhebung soll den Faktor 4 nicht überschreiten | ||
+ | autoGain = 4.00; | ||
+ | } | ||
+ | if (autoGain < 1.00) { // Die Maximale Pegelanhebung soll den Faktor 1 nicht unterschreiten | ||
+ | autoGain = 1.00; | ||
+ | } | ||
+ | mixer_L.gain(0, | ||
+ | mixer_R.gain(0, | ||
+ | |||
+ | previousMillisAutoInputLevelControl = currentMillis; | ||
+ | } | ||
+ | // Für die grafische Darstellung des Maximalpegels auf dem OLED-Display wird der größte aus 10 Messwerten bestimmt | ||
+ | a++; // Es werden 10 Werte in einem Array gespeichert | ||
+ | masterPeakArray[a] = masterPeak; | ||
+ | if (a > 9) { | ||
+ | a = 0; | ||
+ | } | ||
+ | unsigned char kmax=0; | ||
+ | float max=0; | ||
+ | for (unsigned char k=0; k<10; k++) { | ||
+ | if (masterPeakArray[k] > max) { | ||
+ | max = masterPeakArray[k]; | ||
+ | kmax = k; | ||
+ | } | ||
+ | } | ||
+ | peak_Max = masterPeakArray[kmax]; | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | // Es wird die Zeit in Millisekunden berechnet, die für einen Durchgang benötigt wurde | ||
+ | duration = currentMillis - lastMillis; | ||
+ | lastMillis = currentMillis; | ||
+ | |||
+ | // Serieller Output | ||
+ | Serial.print(" | ||
+ | Serial.print(AudioProcessorUsageMax()); | ||
+ | Serial.print(" | ||
+ | Serial.print(AudioMemoryUsageMax()); | ||
+ | Serial.print(" | ||
+ | Serial.print(duration); | ||
+ | Serial.print(" | ||
+ | Serial.print(float(newPosition) / 40); | ||
+ | Serial.print(" | ||
+ | Serial.print(leftPeak); | ||
+ | Serial.print(" | ||
+ | Serial.print(rightPeak); | ||
+ | Serial.print(" | ||
+ | Serial.print(masterPeak); | ||
+ | Serial.print(" | ||
+ | Serial.print(masterPeakMax); | ||
+ | if (autoInputLevelControl == true) { | ||
+ | Serial.print(" | ||
+ | Serial.print(autoGain); | ||
+ | } | ||
+ | Serial.println(); | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | } | ||
+ | // OLED-Display | ||
+ | if (refresh == true) { | ||
+ | oled.setTextColor(WHITE, | ||
+ | oled.setTextSize(0); | ||
+ | oled.setCursor(0, | ||
+ | oled.print(" | ||
+ | if (autoInputLevelControl == true) { | ||
+ | oled.print(" | ||
+ | } | ||
+ | else if (autoInputLevelControl == false) { | ||
+ | oled.print(" | ||
+ | } | ||
+ | refresh = false; | ||
+ | } | ||
+ | if ((unsigned long)(currentMillis - previousMillisOLED) >= intervalOLED) { | ||
+ | x++; | ||
+ | if (x < 127) { // Bis x = 126 wird ein Graph gezeichnet | ||
+ | autoGainGraphArray[x] = autoGain; | ||
+ | oled.drawPixel(x, | ||
+ | masterPeakGraphArray[x] = peak_Max; | ||
+ | // | ||
+ | oled.drawFastVLine(x, | ||
+ | } | ||
+ | else if (x >= 127) { // Ab x >= 127 wird der alte Graph gelöscht, um ein Pixel nach links verschoben, um den aktuellen Messwert ergänzt und neu gezeichnet | ||
+ | for (z=0; z<127; z++) { | ||
+ | oled.drawPixel(z, | ||
+ | // | ||
+ | oled.drawFastVLine(z, | ||
+ | } | ||
+ | for (z=1; z<127; z++) { | ||
+ | autoGainGraphArray[z - 1] = autoGainGraphArray[z]; | ||
+ | masterPeakGraphArray[z - 1] = masterPeakGraphArray[z]; | ||
+ | } | ||
+ | autoGainGraphArray[126] = autoGain; | ||
+ | masterPeakGraphArray[126] = peak_Max; | ||
+ | for (z=0; z<128; z++) { | ||
+ | oled.drawPixel(z, | ||
+ | // | ||
+ | oled.drawFastVLine(z, | ||
+ | } | ||
+ | x = 127; | ||
+ | } | ||
+ | previousMillisOLED = currentMillis; | ||
+ | } | ||
+ | |||
+ | } // Void Loop Ende | ||
+ | </ | ||
+ | {{tag> |
arduino/spektrumanalysator/programmversion_0.5.1506811431.txt.gz · Zuletzt geändert: 18.05.2023 12:16 (Externe Bearbeitung)