Hi, I am completely new & after days of Googling, need some help. I have no real coding experience at all. I have hacked butchered other people's simple code several times on simple projects..
Out of all of my searching, I see Charlieplexing as the closest to what I need, but know it is not right.
I have a VFD (Vacuum Fluorescent Display) from a ham radio. 7 segment 7 digit. I already have the 2 lower right connectors figured out. What I need is a way to drive the SEA through SEG (I assume these are segments) the GRA-GRD (I know this is BCD) which switch through the digits. I only need 7 of the 10 segments. to show frequency.
I am not looking for someone to write my code, unless they are feeling generous. I just need a lead towards some examples that I can butcher up & make this work.
I will get the frequency form the CAT output of a PC's serial signal. I will probably use an Arduino Mega for Frequency, Mode, and driving an analog meter.
Can anyone point me in the right direction?
Thank you very much,
Ed
So, could it be as easy as a 0-9 counter loop outputted in BCD with the LED code in the display loop?
Ed
So, a 0-9 counter code I found with BCD out. Just have to lower or remove the delays. Found here: Counter 0-9 Arduino (tinkercad.com)
#define BIT_A 10
#define BIT_B 11
#define BIT_C 12
#define BIT_D 13
int d = 30; //DELAY DEFAULT
int dm = 30; // DELAY MINIMAL
void setup()
{
pinMode(BIT_A, OUTPUT);
pinMode(BIT_B, OUTPUT);
pinMode(BIT_C, OUTPUT);
pinMode(BIT_D, OUTPUT);
}
void loop()
{
//ZERO .... [0]
digitalWrite(BIT_A, LOW);
digitalWrite(BIT_B, LOW);
digitalWrite(BIT_C, LOW);
digitalWrite(BIT_D, LOW);
delay(d);
//ONE ---. [1]
digitalWrite(BIT_A, HIGH);
delay(d); // 0001 ON
digitalWrite(BIT_A, LOW);
delay(dm); // 0001 OFF
//TWO --.- [2]
digitalWrite(BIT_B, HIGH);
delay(d); // 0010 ON
digitalWrite(BIT_B, LOW);
delay(dm); // 0010 OFF
//THREE --.. [3]
digitalWrite(BIT_A, HIGH);
digitalWrite(BIT_B, HIGH);
delay(d); // 0011 ON
digitalWrite(BIT_A, LOW);
digitalWrite(BIT_B, LOW);
delay(dm); // 0011 OFF
//FOUR -.-- [4]
digitalWrite(BIT_C, HIGH);
delay(d); // 0100 ON
digitalWrite(BIT_C, LOW);
delay(dm); // 0101 OFF
//FIVE -.-. [5]
digitalWrite(BIT_A, HIGH);
digitalWrite(BIT_C, HIGH);
delay(d); // 0101 ON
digitalWrite(BIT_A, LOW);
digitalWrite(BIT_C, LOW);
delay(dm); // 0101 OFF
//SIX -..- [6]
digitalWrite(BIT_B, HIGH);
digitalWrite(BIT_C, HIGH);
delay(d); // 0110 ON
digitalWrite(BIT_B, LOW);
digitalWrite(BIT_C, LOW);
delay(dm); // 0110 OFF
//SEVEN -... [7]
digitalWrite(BIT_A, HIGH);
digitalWrite(BIT_B, HIGH);
digitalWrite(BIT_C, HIGH);
delay(d); // 0111 ON
digitalWrite(BIT_A, LOW);
digitalWrite(BIT_B, LOW);
digitalWrite(BIT_C, LOW);
delay(dm); // 0111 OFF
//EIGTH .--- [8]
digitalWrite(BIT_D, HIGH);
delay(d); // 1000 ON
digitalWrite(BIT_D, LOW);
delay(dm); // 1000 OFF
//NINE .--. [9]
digitalWrite(BIT_A, HIGH);
digitalWrite(BIT_D, HIGH);
delay(d); // 1001 ON
digitalWrite(BIT_A, LOW);
digitalWrite(BIT_D, LOW);
delay(dm); // 1001 OFF
}
Ed
Hi Ed,
I don't see any connection to Charlieplexing here. Multiplexing, yes.
10 segments? There only seem to be 7 SEG pins in that top row of connectors. Which connectors do you think control the other 3 segments?
How do you know that? What do you mean by BCD? I know it as Binary Coded Decimal, but I don't see a connection here
Can you explain what you mean by the CAT output?
Could it be that your 7 segment connections and 4 digits (?) connections would be compatible with the Arduino SevSeg library? You could try one of the example sketches from that library to see if you can get the VFD to work.
A typo. There are 9 or 10 digits. I only need 7 of them.
GRA-GRD go to the 7442, which is a BCD to decimal chip, that picks the digit. (Datasheet) 4-Line BCD To 10-Line Decimal Decoders datasheet (ti.com)
CAT (Computer Aided Transceiver) is a way for computers ham radios to communicate, Read or Write.
Computer Aided Transceiver - Wikipedia
I went through the SevSeg library did not find anything like what I have. Now, when I feel better (Flu), I will dive deeper into the project.
I am gutting an Icom 765 ham radio (Early 90s vintage) & installing a NUC & SDR (Software Defined Radio) Which is the Hermes Lite-2. I will use CAT and an Arduino Mega for the display & metering (What I have on hand) and also 5VDC tolerant I will use a Teensy 4.1 for the front panel knobs switched over USB MIDI to control the SDR( Which I have generally outlined in my notebook.).
I'm sorry to have not included more information. I am used to ham radio forums &they usually understand. Typos were from having the flu.
Do, basically, I will take the CAT signal & strip out the frequency. Then, probably using some other code examples to generate the digits, Put that in a loop with the above code (Delays both changed to 30) to get the 60ms signal shown on the schematic. That should work the 7442 0-9 & operate the VFD like stock.
Please understand, my ADHD precludes me from coding. I have tried for years to learn. All I can really do is use snippets of other people's code to make things happen. This will be my 3rd real arduino project, other than trying the book examples. I just tackle 1 section at a time, Verify/Compile, test.
I used the above code with the Delays at 30 & got the proper 30ms rise decay in the schematic.
Most times I have to write things out to understand them & this has helped (2:03AM "Hey, I just need a -9 counter to BCD" & found the above code.
Thank you,
Ed
Yes, thinking about it further, SevSeg expects to directly control each of the digit pins with Arduino pins. You need to select the digit through the 4-to-10 line decoder. I suspect SevSeg doesn't have an option for that.
The code you posted above is, frankly, very poor. I'm sure the forum can help you write something much better.
I did just check the library & there is no provision for BCD to "Shift" the output.
I know I could use simpler methods, but this driver board & display work fine will make this radio seem stock to the casual eye.
That was just a code example that works for what I need, as an example. I have many more sections to the code. Broascast "AI" (I think) over serial/USB, to get frequency, mode, VFO A/B, etc & put them in a format to operate the display & meter. This is just the beginning.
Thank you,
Ed
Code above changed for both Delays at 30, which seems to work on my scope, per the waveform on the schematic. This code is just to shift to the next digit & show no flicker on the VFD.
Ed
Ok let's tidy that code up a bit.
Please don't update previous posts, except to correct spelling errors etc. Wholesale updates make the subsequent posts make little sense.
const byte digitSelectPin[4] = {10, 11, 12, 13};
int d = 30; //DELAY DEFAULT
int dm = 30; // DELAY MINIMAL
byte digit=0;
void setup()
{
for (byte bit=0; bit<4; bit++)
pinMode(digitSelectPin[bit], OUTPUT);
}
void loop()
{
for (byte bit=0; bit<4; bit++) {
if (bitRead(digit, bit) == 1)
digitalWrite(digitSelectPin[bit], HIGH)
}
delay(d);
for (byte bit=0; bit<4; bit++) {
if (bitRead(digit, bit) == 1)
digitalWrite(digitSelectPin[bit], LOW);
}
delay(dm); //not sure why you would want this, it would make display dimmer and flickery
digit++;
if (digit >= 10) digit = 0;
}
You are correct on this. Just re ran the 1st code & it shows up incorrectly. I will run this later, after the drugs take effect. Bad flu.
I think I can change 10 to 7, so as to not display 3 "MEM" digits? Memory channels on display, as I will not be using them for now. Of course, if I can implement them, I could change it back.
I tried these changes & it had an error. "digitalWrite(digitSelectPin[bit], HIGH)" needed a semicolon. Added it & it verifies & compiles. I will run it when I am more clear headed.
Just so you understand, the "Thetis" software I use for the SDR displays everything on PC screens, of which I will have 2. It displays everything on the screens & mouse clicks & drags change settings. I would just like to implement everything on the front panel that I can, to make it look & operate as close to factory.
The SDR is just AD/DA converters, an FPGA & ethernet. All DSP control is on the PC software, "Thetis..
const byte digitSelectPin[4] = {10, 11, 12, 13};
int d = 30; //DELAY DEFAULT
//int dm = 30; // DELAY MINIMAL
byte digit=0;
void setup()
{
for (byte bit=0; bit<4; bit++)
pinMode(digitSelectPin[bit], OUTPUT);
}
void loop()
{
for (byte bit=0; bit<4; bit++) {
if (bitRead(digit, bit) == 1)
digitalWrite(digitSelectPin[bit], HIGH);
}
delay(d);
for (byte bit=0; bit<4; bit++) {
if (bitRead(digit, bit) == 1)
digitalWrite(digitSelectPin[bit], LOW);
}
//delay(dm); //not sure why you would want this, it would make display dimmer and flickery
digit++;
if (digit >= 7) digit = 0;
}
Thank you,
Ed
If you look at the schematic, on the upper right, the signal is a 60ms between rising triggers & 30ms delay from the decay to the next rise. Being a VFD, it's already pretty bright. Would there be a possibility of too much duty cycle if the delay is removed?
Thank you,
Ed
So, I added an example of SevSeg & commented all of mine with //Ed, so as to keep my possible screw ups removable. This would display 7 digits as the number "4" with the 30ms delay as per the OEM. Being fluorescent, the display may have a natural persistance that leaves a slow decay of the light produced. The 30ms delay may be due to duty cycle, or just the slow speed of the early 90s processors used. I have verified & compiled, but have not tried it.
This is just my way of trying to combine code & hopefully get it to work. If it does, I will change "sevseg.setNumber(4); //Ed" to some form of variable, that will have to be decided in the future, as I am just working on getting the display to "Work".
#include "SevSeg.h" //Include SevSeg library Ed
SevSeg sevseg; // I don't understand why the upper case to lower case change Ed
const byte digitSelectPin[4] = {10, 11, 12, 13};
int d = 30; //DELAY DEFAULT
//int dm = 30; // DELAY MINIMAL
byte digit=0;
void setup()
{
for (byte bit=0; bit<4; bit++)
pinMode(digitSelectPin[bit], OUTPUT);
byte numDigits = 1; //Ed
byte digitPins[] = {}; //Ed
byte segmentPins[] = {6, 5, 2, 3, 4, 7, 8}; //A, B, C, D, E, F, G, (No DP) Ed
bool resistorsOnSegments = true; //Ed
byte hardwareConfig = COMMON_CATHODE; //Ed
sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments); //Ed
sevseg.setBrightness(90); //Ed
}
void loop()
{
for (byte bit=0; bit<4; bit++) {
if (bitRead(digit, bit) == 1)
digitalWrite(digitSelectPin[bit], HIGH);
}
delay(d);
for (byte bit=0; bit<4; bit++) {
if (bitRead(digit, bit) == 1)
digitalWrite(digitSelectPin[bit], LOW);
}
//delay(dm); //not sure why you would want this, it would make display dimmer and flickery? You are right, as 2 different 0ms delays are not needed.
digit++;
if (digit >= 7) digit = 0;
sevseg.setNumber(4); //Ed
sevseg.refreshDisplay(); //Ed
}
Thank you for your time, guidance & patience,
Ed
The above added code annotated by "//Ed" comes from How to Set up Seven Segment Displays on the Arduino - Circuit Basics
Ed
Don't forget, we have not seen this display. But, yes, if you change it from 10 to 7 you will get only 7 digits lit. Which 7 of the 10, hard to say.
I thought we had agreed SevSeg isn't going to work for your display, because it doesn't have the option to control the digits through the 4-to-10 line decoder?
I'm afraid you probably wasted your time on that.
We can move forward with the code in post #10.
I am thinking to use the SevSeg to produce the actual number to be displayed? The BCD is to drive the 7442 chip to move the digit for a 7 digit display. In the schematic, there are SEA-SEG (7 segments). In my muddled mind, this should use SevSeg example to produce the single "number 4", shifted by the 0-7 BCD on the 7447 to all 7 digits of the display? Later, I will work towards the variable to replace the "4", when I figure out the output from the radio? I have to pull the radio apart to get the harness, which is actually the same pitch of the breadboard.
Then I can plug the radio in to get power to the display & use this code to show "4444444" for now.
sevseg.setNumber(4);
sevseg.refreshDisplay();
Thank you,
Ed
const byte digitSelectPin[4] = {10, 11, 12, 13};
const byte segmentPins[7] = {6, 5, 2, 3, 4, 7, 8};
const byte digitPatterns[10] = {
//abcdefg
0b1111110, // zero
0b0110000, // one
...
0b1111011 // nine
};
byte displayDigit[7] = {0, 1, 2, 3, 4, 5, 6, 7};
int d = 30; //DELAY DEFAULT
//int dm = 30; // DELAY MINIMAL
byte digit=0;
void setup()
{
for (byte bit=0; bit<4; bit++)
pinMode(digitSelectPin[bit], OUTPUT);
for (byte seg=0; seg<7; seg++)
pinMode(segmentPins[seg], OUTPUT);
}
void loop()
{
//Switch off the previous digit
for (byte bit=0; bit<4; bit++) {
if (bitRead(digit, bit) == 1)
digitalWrite(digitSelectPin[bit], LOW);
}
//Move to next digit
digit++;
if (digit >= 7) digit = 0;
//Set up the segments
byte thisDigit = displayDigit[digit];
byte pattern = digitPatterns[thisDigit];
for (byte seg=0; seg<7; seg++) {
if (bitRead(pattern, seg) == 1
digitalWrite(segmentPins[seg], HIGH);
else
digitalWrite(segmentPins[seg], LOW);
}
//Switch on the digit
for (byte bit=0; bit<4; bit++) {
if (bitRead(digit, bit) == 1)
digitalWrite(digitSelectPin[bit], HIGH);
}
delay(d);
}
Sorry, SevSeg doesn't work like that. You would need to change the library code. Easier to just not use it.
OK. I see understand now. I'll let this sink in a bit. I try never to ask for freebies am just trying to show that I am putting effort into this. Your coding skills are much better than my butchering of example code
Thank you,
Ed
Should I assume that I need to remove the "7" from {0, 1, 2, 3, 4, 5, 6, 7};` as this is 8 & I have no decimal point in these digits?
Thank you,
Ed
Well spotted. In fact it probably would not compile because there are more values between the {} than the array has indexes.