Sunday, December 1, 2013

My first impression on Cogwheel Nixie clock

Many months ago I bought, attracted by the clearance price, the PCB for the "Nixie Driver Board Rev A" from "Cogwheel circuit works" store. I was hoping that, with all documentation in place, I would be able to build it on my own, considering it's controlled by an ATmega328 and the software was available, though not the source code.

First thing to note is that the board uses mostly SMDs. If anything went wrong (and there was a high chance, since the PCB was already described as a "mistake the board house made"), the board would become a coaster.

The schematic includes some exotic components, like the HV513 Nixie driver, not offered by digikey. Others are the DS1302 RTC and the optional DS32KHZ oscillator for RTC, which I heard of for the first time. But thanks to the detailed BOM, gathering the components was relatively (some of them are already discontinued, for example) easy.

High voltage for the Nixie tubes is generated by a hardware PWM under software control. So, like the Ice Tube Clock, in order to measure the high voltage and make sure the HV circuitry works, some software must be uploaded onto the processor. I expected the released software to do that. Unfortunately, the highest voltage I saw was under 9V.




After some digging (and learning in the process), I ended up with this simple sketch, adapted from Satashnik Nixie clock, which generates a stable 190V. I know, I was surprised too :)

#include "Arduino.h"

#define DDRHVPUMP  DDRB
#define BV2(a,b) (_BV(a)|_BV(b))
#define BV6(a,b,c,d,e,f) (_BV(a)|_BV(b)|_BV(c)|_BV(d)|_BV(e)|_BV(f))
#define VOLTAGE_WASTE   370                     //!< ~180V
#define VOLTAGE_SAVE    355                     //!< ~170V

volatile uint16_t voltage; 
static volatile uint16_t voltage_setpoint = VOLTAGE_WASTE;
static const uint16_t ocr1a_reload = 60;

void pump_init()
{
    // set fast pwm mode
    // COM1A1:0 = 10, clear oc1a on compare match, set at top
    // COM1B1:0 = 00, normal port operation
    // no FOC
    // WGM11:10 (WGM = Fast PWM, TOP=ICR1: 1110) = 11
    TCCR1A = BV2(COM1A1, WGM11);
    TCCR1B = BV2(WGM13,  WGM12);
    OCR1A = ocr1a_reload; 
    ICR1 = 170;
    TCCR1B |= _BV(CS10); // clk/1 (16MHz)
    DDRHVPUMP |= BV2(1,2);
}

void adc_init()
{
    voltage = 0;
    // PORTA.6 is the feedback input, AREF = AREF pin
    ADMUX = 6;  
    // ADC enable, autotrigger, interrupt enable, prescaler = 111 (divide by 32)
    ADCSRA = BV6(ADEN, ADATE, ADIE, ADPS2, ADPS1, ADPS0); 
    ADCSRA |= _BV(ADSC); 
}

/// Start voltage booster
void voltage_start()
{
    adc_init();
    pump_init();
}

ISR(ADC_vect)
{
    voltage = (voltage + ADC) / 2;
    if (voltage < voltage_setpoint) {
        OCR1A = ocr1a_reload;
    } else {
        OCR1A = 0;
    }
}

void setup()
{
    sei();
    voltage_start();        // start HV generation    
}

void loop()
{
  // clock functionality in here;
}

The next big step is to write the software to drive the tubes and actually show the time, which is essentially re-writing the Cogwheel Nixie clock code (or at least the basic functionality) from scratch. Then open source it. Any help would be appreciated :)

2 comments:

  1. I was always interested in one of these due to the 7th digit…was a differentiating factor of his clock…Bob seems to have gone quiet on the nixie clock front..if you can get one of these babies up and running Florin, I'll be paying close attention! (and I'll buy a board too!).

    All the best

    Nick

    PS BTW, you're on a building frenzy at the moment!

    ReplyDelete
    Replies
    1. Thanks Nick. I wish it was a "building frenzy". I am just trying to clear the backlog of unfinished projects and make some room on my desk.

      Delete