01.08.2025, 08:41 AM
(10.11.2023, 04:18 PM)kahlo schrieb: So, this circuit should be generally reproducible.
- Suitable for controlling any plasma bar display (Russian, American, English, whatever) with 3 or 5 phases.
- 3-phase configuration. For 5 phases, pins 5 and 6 (3 and 4
) on the processor are reserved. The circuit can be easily duplicated there as for phases 1 to 3.
- Any Arduino or compatible board is suitable. Theoretically, any microcontroller with enough pins that can be programmed with the Arduino IDE will do. If you want to use an Arduino with a 3.3V operating voltage, you'll need to adjust the power supply and clamp the two analog inputs to 3.3V (see the note for the LEDs).
- The step-up converter was taken from Bozo (cheap, good, easy to replicate).
- The LEDs must be selected so that the voltage cannot significantly exceed 5V. They serve as input limiters on the Arduino's analog pins.
- D4, D8 and U3 may NOT be exchanged for "anything else".
For the sake of completeness, here is the code again (Arduino):
Code:
// Bargraph @ Teensy 2.0
// Version 0.1beta
#include <FlexiTimer2.h>
#include <math.h>
const byte Frequency = 67; // Target frequency of the display in Hz
const byte Segments = 201; // Number of segments of the display
const byte Phases = 3; // Number of phases of the display (maximum 5)
const byte ResetPin = 5; // Reset connection
const byte InputPin_1 = 21; // Input pins
const byte InputPin_2 = 20; // Input pins
const byte InputPin_3 = 19; // Input pins
const byte InputPin_4 = 18; // Input pins
const byte LinLogPin = 23; // Lin-Log toggle pin
const byte AnodePin_1 = 6; // anode pins
const byte AnodePin_2 = 7; // anode pins
const byte AnodePin_3 = 8; // anode pins
const byte AnodePin_4 = 9; // anode pins
const byte Umax = 5; // Maximum voltage at the analog input
const float Ustep = 0.004888;// Voltage between 2 ADC values
volatile int Actual_Phase; // Counter for the phase control
volatile int Old_Phase; // Counter for phase control
volatile int Actual_Segment = 1; // Counter for phase control
int Input_1 = 0; // Analog memory variable
int Input_2 = 0; // Analog memory variable
int Input_3 = 0; // Analog memory variable
int Input_4 = 0; // Analog memory variable
int InputScaler; // Factor for scaling the ADC values to the number of segments (linear display)
int Balken_1 = 0; // Variable for the current bar length
int Balken_2 = 0; // Variable for the current bar length
int Balken_3 = 0; // Variable for the current bar length
int Balken_4 = 0; // Variable for the current bar length
double dBV; // dBV log
int LogTab[1024]; // LogTable ADC values - segments
void flush() { // Interrupt service routine for phase control
switch (Actual_Segment) {
case Segments: // Last segment reached?
digitalWrite(Actual_Phase, LOW); // Turn off the last segment
digitalWrite(ResetPin, HIGH); // Reset the display
Actual_Segment = 1; // Reset the counters
Actual_Phase = Phases; // Reset the counters
digitalWrite(AnodePin_1, LOW); // Turn the anodes back on
digitalWrite(AnodePin_2, LOW); // Turn the anodes back on
digitalWrite(AnodePin_3, LOW); // Turn the anodes back on
digitalWrite(AnodePin_4, LOW); // Turn the anodes back on
break;
default: // Core of the display control
Actual_Segment++; // Increment pointer to the current segment
if (Bar_1 < Actual_Segment) digitalWrite(AnodePin_1, HIGH); // When the bar reaches the desired length, the anode is switched off
if (Bar_2 < Actual_Segment) digitalWrite(AnodePin_2, HIGH); // When the bar reaches the desired length, the anode is switched off
if (Bar_3 < Actual_Segment) digitalWrite(AnodePin_3, HIGH); // When the bar reaches the desired length, the anode is switched off
if (Bar_4 < Actual_Segment) digitalWrite(AnodePin_4, HIGH); // When the bar reaches the desired length, the anode is switched off
Old_Phase = Actual_Phase++; // Increase pointer to the current phase and save the old value
if (Actual_Phase > Phases - 1) Actual_Phase = 0; // Phase overflow to zero
digitalWrite(Actual_Phase, HIGH); // Switch on the next segment
digitalWrite(Old_Phase, LOW); // Turn off the old segment
digitalWrite(ResetPin, LOW); // Disable reset if active
break;
}
}
void setup() {
pinMode(0, OUTPUT); // The pins for a maximum of 5 phases are defined as output pins
pinMode(1, OUTPUT);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(ResetPin, OUTPUT); // Reset pin is defined as output pin
pinMode(LinLogPin, INPUT_PULLUP); // Pin open: linear, pin connected to GROUND: logarithmic
pinMode(AnodePin_1, OUTPUT);
pinMode(AnodePin_2, OUTPUT);
pinMode(AnodePin_3, OUTPUT);
pinMode(AnodePin_4, OUTPUT);
Actual_Phase = Phases;
InputScaler = 1024/Segments; // Factor for scaling the ADC values to the number of segments (linear display)
// Write log table
LogTab[0] = 1; // Fade out below -45dBV, relative to the maximum level
LogTab[1] = 2;
LogTab[2] = 3;
LogTab[3] = 3;
LogTab[4] = 4;
LogTab[5] = 4;
for(int x = 6; x < 1024; x++) { // Calculate the log table
dBV = 20.0 * log10(x * Ustep / Umax);
LogTab[x] = 4.4 * dBV + Segments;
}
digitalWrite(ResetPin, HIGH); // Reset the display
FlexiTimer2::set(1, 1.0/(Frequency*Segments), flush); // Definition of the timer interrupt
FlexiTimer2::start(); // Activation of the interrupt
}
void loop() { // main program
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, internal pull-up resistor is enabled
Bar_1 = Input_1/InputScaler; // linear scaling of the ADC values to the number of segments
Bar_2 = Input_2/InputScaler; // linear scaling of the ADC values to the number of segments
Bar_3 = Input_3/InputScaler; // linear scaling of the ADC values to the number of segments
Bar_4 = Input_4/InputScaler; // linear scaling of the ADC values to the number of segments
break;
case LOW: // Logarithmic
Balken_1 = LogTab[Input_1]; // Read the log table
Bar_2 = LogTab[Input_2];
Bar_3 = LogTab[Input_3];
Bar_4 = LogTab[Input_4];
break;
}
}
Greetings,
I just built this - I could not get any action with an Arduino Nano but the Teensy worked right away - I think I may have some confusion over my Nano GPIO numbering - regardless. I note that the 33K resistor on the Zener is getting mighty warm - I used a 1206 sized smd part but I am guessing that the current must be greater as multiple 'phases' could be active at any one time - am I even close?
My plan is to use this as a seconds indicator on an clock so I have not used the Audio input part of the design, I also utilised an available HV module for the 245volts.
I tried working out the current requirements using the data sheet for the display (I am using the ones with 5 x phase connections) but failed miserably.
Could you point me in the right direction?
Thank you
Richard