10.11.2023, 04:18 PM
(Dieser Beitrag wurde zuletzt bearbeitet: 10.11.2023, 04:55 PM von kahlo.)
So, diese Schaltung sollte allgemein nachbaubar sein.
Der Vollständigkeit halber noch einmal der Code (Arduino):
- Geeignet zur Ansteuerung jeder Plasma-Balkenanzeige (Russisch, amerikanisch, englisch, was auch immer) mit 3 oder 5 Phasen.
- 3-phasiger Aufbau. Für 5 Phasen sind die Pins 5 und 6 (3 und 4 ) am Prozessor freigehalten. Dort kann einfach die Schaltung wie für die Phasen 1 bis 3 dupliziert werden.
- Geeignet ist jeder Arduino oder jedes kompatible Bord. Theoretisch auch jeder µC mit genug Beinen, der mit der Arduino-IDE programmiert werden kann. Falls ein Arduino mit 3,3V Betriebsspannung verwendet werden soll, muss die Spannungsversorgung angepasst werden und die beiden Analogeingänge auf 3,3V geklammert werden (siehe den Hinweis für die LED's).
- Der Step-Up-Wandler wurde von Bozo übernommen (billig, gut, einfach nachzubauen).
- Die LED's sind so zu selektieren, dass die Spannung nicht nennenswert über 5V steigen kann. Sie dienen als Inputbegrenzer an den Analogpins des Arduino.
- D4, D8 und U3 dürfen NICHT gegen "irgendwas anderes" getauscht werden.
Der Vollständigkeit halber noch einmal der Code (Arduino):
Code:
// Bargraph @ Teensy 2.0
// Version 0.1beta
#include <FlexiTimer2.h>
#include <math.h>
const byte Frequency = 67; // Zielfrequenz des Displays in Hz
const byte Segments = 201; // Anzahl der Segmente des Displays
const byte Phases = 3; // Anzahl der Phasen des Displays (maximal 5)
const byte ResetPin = 5; // Resetanschluss
const byte InputPin_1 = 21; // Eingangspins
const byte InputPin_2 = 20; // Eingangspins
const byte InputPin_3 = 19; // Eingangspins
const byte InputPin_4 = 18; // Eingangspins
const byte LinLogPin = 23; // Lin-Log-Umschalt-Pin
const byte AnodePin_1 = 6; // Anodenpins
const byte AnodePin_2 = 7; // Anodenpins
const byte AnodePin_3 = 8; // Anodenpins
const byte AnodePin_4 = 9; // Anodenpins
const byte Umax = 5; // Maximalspannung am Analog-Input
const float Ustep = 0.004888;// Spannung zwischen 2 ADC-Werten
volatile int Actual_Phase; // Zähler für die Phasensteuerung
volatile int Old_Phase; // Zähler für die Phasensteuerung
volatile int Actual_Segment = 1; // Zähler für die Phasensteuerung
int Input_1 = 0; // Analogspeichervariable
int Input_2 = 0; // Analogspeichervariable
int Input_3 = 0; // Analogspeichervariable
int Input_4 = 0; // Analogspeichervariable
int InputScaler; // Faktor zur Skalierung der ADC-Werte auf die Segmentzahl (lineare Anzeige)
int Balken_1 = 0; // Variable für die aktuelle Balkenlänge
int Balken_2 = 0; // Variable für die aktuelle Balkenlänge
int Balken_3 = 0; // Variable für die aktuelle Balkenlänge
int Balken_4 = 0; // Variable für die aktuelle Balkenlänge
double dBV; // dBV log
int LogTab[1024]; // LogTabelle ADC-Werte - Segmente
void flush() { // Interrupt service routine zur Phasensteuerung
switch (Actual_Segment) {
case Segments: // Das letzte Segment erreicht?
digitalWrite(Actual_Phase, LOW); // Das letzte Segment abschalten
digitalWrite(ResetPin, HIGH); // Reset des Displays
Actual_Segment = 1; // Rücksetzen der Zähler
Actual_Phase = Phases; // Rücksetzen der Zähler
digitalWrite(AnodePin_1, LOW); // Anoden wieder einschalten
digitalWrite(AnodePin_2, LOW); // Anoden wieder einschalten
digitalWrite(AnodePin_3, LOW); // Anoden wieder einschalten
digitalWrite(AnodePin_4, LOW); // Anoden wieder einschalten
break;
default: // Kern der Displaysteuerung
Actual_Segment++; // Zeiger auf das aktuelle Segment erhöhen
if (Balken_1 < Actual_Segment) digitalWrite(AnodePin_1, HIGH); // Bei Solllänge des Balkens wird die Anode abgeschaltet
if (Balken_2 < Actual_Segment) digitalWrite(AnodePin_2, HIGH); // Bei Solllänge des Balkens wird die Anode abgeschaltet
if (Balken_3 < Actual_Segment) digitalWrite(AnodePin_3, HIGH); // Bei Solllänge des Balkens wird die Anode abgeschaltet
if (Balken_4 < Actual_Segment) digitalWrite(AnodePin_4, HIGH); // Bei Solllänge des Balkens wird die Anode abgeschaltet
Old_Phase = Actual_Phase++; // Zeiger auf die aktuelle Phase erhöhen und den alten Wert sichern
if (Actual_Phase > Phases - 1) Actual_Phase = 0; // Phase overflow auf Null
digitalWrite(Actual_Phase, HIGH); // Das nächste Segment anschalten
digitalWrite(Old_Phase, LOW); // Das alte Segment ausschalten
digitalWrite(ResetPin, LOW); // Reset deaktivieren, falls aktiv
break;
}
}
void setup() {
pinMode(0, OUTPUT); // Die Pins für maximal 5 Phasen werden als Output-Pins definiert
pinMode(1, OUTPUT);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(ResetPin, OUTPUT); // Resetpin wird als Output-Pin definiert
pinMode(LinLogPin, INPUT_PULLUP); // Pin offen: linear, Pin mit GROUND verbunden: logarithmisch
pinMode(AnodePin_1, OUTPUT);
pinMode(AnodePin_2, OUTPUT);
pinMode(AnodePin_3, OUTPUT);
pinMode(AnodePin_4, OUTPUT);
Actual_Phase = Phases;
InputScaler = 1024/Segments; // Faktor zur Skalierung der ADC-Werte auf die Segmentzahl (lineare Anzeige)
// Logtabelle schreiben
LogTab[0] = 1; // Fade out unter -45dBV, relativ zum Maximalpegel
LogTab[1] = 2;
LogTab[2] = 3;
LogTab[3] = 3;
LogTab[4] = 4;
LogTab[5] = 4;
for(int x = 6; x < 1024; x++) { // Berechnung der Log-Tabelle
dBV = 20.0 * log10(x * Ustep / Umax);
LogTab[x] = 4.4 * dBV + Segments;
}
digitalWrite(ResetPin, HIGH); // Reset des Displays
FlexiTimer2::set(1, 1.0/(Frequency*Segments), flush); // Definition des Timerinterrupts
FlexiTimer2::start(); // Aktivierung des Interrupts
}
void loop() { // Hauptprogramm
Input_1 = analogRead(InputPin_1); // ADC
Input_2 = analogRead(InputPin_2);
Input_3 = analogRead(InputPin_3);
Input_4 = analogRead(InputPin_4);
switch (digitalRead(LinLogPin)) {
case HIGH: // Default linear, interner Pullup-Widerstand ist aktiviert
Balken_1 = Input_1/InputScaler; // lineare Skalierung der ADC-Werte auf die Segmentzahl
Balken_2 = Input_2/InputScaler; // lineare Skalierung der ADC-Werte auf die Segmentzahl
Balken_3 = Input_3/InputScaler; // lineare Skalierung der ADC-Werte auf die Segmentzahl
Balken_4 = Input_4/InputScaler; // lineare Skalierung der ADC-Werte auf die Segmentzahl
break;
case LOW: // Logarithmisch
Balken_1 = LogTab[Input_1]; // Lesen der Log-Tabelle
Balken_2 = LogTab[Input_2];
Balken_3 = LogTab[Input_3];
Balken_4 = LogTab[Input_4];
break;
}
}