NCS314 Custom Firmware
Nixie Tubes Clocks | Shields for Arduino Clocks | Raspberry Pi HAT Nixie Clocks | DIY KITs for Nixie Clocks | Cases for Nixie Clocks | Nixie Tubes | RF Units | Assembled Boards | Bare PCBs | Components | Spare Parts | Circuits | Firmwares… › Forums › Questions and answers about PRODUCTS › NCS314 Custom Firmware
This topic contains 3 replies, has 2 voices, and was last updated by Filt_r 1 year, 10 months ago.
-
AuthorPosts
-
27.01.2023 at 22:07 #41430
Hello,
I’ve got an old NCS314 Nixie shield for the UNO that I’ve had for a number of years, still working great but I want to repurpose it for a new project.
Was looking through the schematics and source code, looks like it’s controlled via SPI controller, but I’m still trying to get my bearings when it comes to how it works exactly (what to bit-bang where and in what order, what the encoding is etc.).
If you guys had a piece of example code that just flashed the board such that it displayed a static 6 digit number with the two dots on or off, I’d very much appreciated it as that’d just about tell me everything I needed to know.
Thanks,
– Luca31.01.2023 at 02:28 #41435I’ve been working on some custom firmware for my NCS314-6 with an Arduino Mega, perhaps I can help. I’m not an embedded software expert by any means and I’m not sure your level of experience so I’m going to bias towards over-explaining it.
So, my clock has 6 digits/IN-14 tubes, each with 10 possible values plus the two colons for a total of 64 individual elements that can be switched on or off. On my board (HW rev 2.3) there are two 32-bit high-voltage shift registers daisy chained together (HV5122 on my board), so that any data that overflows from the first one is passed on to the second one. Both are clocked by the SPI clock SCK and fed data by SPI MOSI. Essentially, every time you want to update the display, you have to send 64-bits out over SPI – the first 32 bits correspond to the on/off state of the 32 outputs of the second shift register in the daisy chain (M:SS), and the next 32 bits you send control the outputs of the first shift register (HH:M)
The encoding works like this: each nixie element has ten possible values (if we only turn one number on in a single tube at a time). So, we can break the 64-bit control word up into chunks of 10 bits per tube plus 2 bits for each colon (top dot, bottom dot). If you have 4 digits, then you’d have a 42-bit data structure that holds the state of the display. I’m going to use my 64-element display for the sake of example. On my board, the shift registers are mapped as follows:
If my display looks like this:
|H1| |H2| |C1| |M1| |M2| |C2| |S1| |S2|
Then the control word maps as follows:
[ C2[top,bot], S2[9-0], S1[9-0], M2[9-0], C1[top,bot], H2[9-0], H1[9-0], M1[9-0] ]
=
[00 0000000000 0000000000 0000000000 00 0000000000 0000000000 0000000000]
So, if you wanted to turn on just the colons, you’d send the following 64 bits out over SPI. I added spaced to divide the bits into groups per-nixie tube + colons:
[11 0000000000 0000000000 0000000000 11 0000000000 0000000000 0000000000]
or if you wanted to illuminate all of the zeroes and no colons, you’d have this:
[00 0000000001 0000000001 0000000001 00 0000000001 0000000001 0000000001]
Here’s a table of the binary, hex, and decimal equivalents for each 10-bit chunk, per tube:
+----------+------------+------+-----------+ | Display | Binary-10 | Hex | Decimal | +----------+------------+------+-----------+ | 0 | 0000000001 | 001 | 1 | | 1 | 0000000010 | 002 | 2 | | 2 | 0000000100 | 004 | 4 | | 3 | 0000001000 | 008 | 8 | | 4 | 0000010000 | 010 | 16 | | 5 | 0000100000 | 020 | 32 | | 6 | 0001000000 | 040 | 64 | | 7 | 0010000000 | 080 | 128 | | 8 | 0100000000 | 100 | 256 | | 9 | 1000000000 | 200 | 512 | +----------+------------+------+-----------+
The basic order of operations to update the display is the following:
1. Initialize SPI and set up the shift register output-enable pin as a digital output. On my board, that is digital pin 10 and it’s named “LEpin” in the stock firmware.
2. Initialize the data structure you’ll use to store the state of the display. This can be a 32-bit value that we change after sending once.
3. Send the display data out over SPI. AVR are 8-bit microcontrollers so we must do this one byte (8 bits) at a time. Since I’m using a 32-bit int to store 1/2 of the display state at a time, I send it once for the first three digits and colon, change the value, then send it again for the last three digits and colon.
4. Turn the output enable pin HIGH to illuminate the tubes in whatever state the data you just sent corresponds to. Then turn it off after some interval before you update the display again.So in code, if I wanted to show “12:34:56” on my display, I would do the following:
const byte LEpin=10 // control pin pinMode(LEpin, OUTPUT); SPI.begin(); SPI.beginTransaction(SPISettings(2000000, LSBFIRST, SPI_MODE2)); uint32_t display_state= 0; // the 32-bit data struct used to store half of the display state, fill with zeroes to start (= all elements turned off) digitalWrite(LEpin, LOW); // ensure the display is turned off // display data that corresponds to "4:56" (M:SS) display_state = 0b11000100000000001000000000010000; // Start transferring the first 32 bits to the shift registers SPI.transfer(display_state>>24); SPI.transfer(display_state>>16); SPI.transfer(display_state>>8); SPI.transfer(display_state); // Now the first shift reg is filled with data for the second shift reg - it will overflow and be pushed into the second shift reg after the next 32 bits are sent // update the display data for to "12:3" (HH:M) before sending display_state = 0b11000000100000000001000000000010; SPI.transfer(display_state>>24); // transfer the most significant byte first SPI.transfer(display_state>>16); SPI.transfer(display_state>>8); SPI.transfer(display_state); // ending with the least significant byte digitalWrite(LEpin, HIGH); // Power the nixie tubes and display the state that we just sent _delay_ms(2000); // Stay on for 2 seconds digitalWrite(LEpin, LOW); // turn tubes off
Also note that the HV5222 uses LSB-first encoding so you have to send the 8 bit chunks in the opposite order if you have that part on your board.
There’s a lot of code that already exists in the provided firmware to convert from intended display digits (i.e. 0-9) to the control words that get sent out over SPI. Since data types convert like in the table above, you don’t have to use expanded binary to represent this data, rather you can just shift (using << or >>) and concatenate the hex or decimal values to do the same thing. Hopefully this helps!31.01.2023 at 04:24 #41438Awesome, thank you very much this was just what I was looking for 🙂
31.01.2023 at 19:56 #41440Great! I am glad that helped.
-
AuthorPosts
You must be logged in to reply to this topic.