Tuesday, February 19, 2013

Laser cut Nixie Tube clock powered by Arduino





http://www.thingiverse.com/thing:52252



I bought all the goodies to make a nice Nixie clock from Taylor Electronics, but I didn't have a nice case for it. It took me about 6 hours to design, cut, and re-cut parts until I had something I was happy with. I disabled the I2C master on the first TES 1361 SmartNixie board and replaced it with an Arduino Nano board connected in the unused RTC connector on the bottom of the backplane board. I poll the GPS RTC board via I2C to get the time and then send command over the I2C bus to the SmartNixie boards to display the digits.





Laser cut parts from 1/8 acrylic (The stuff I bought from Home Depot ended up being 2.2mm thick and not 3.175mm(1/8") so this drawing was designed for 2.2mm, but that isn't hard to change.)


Order these parts from http://www.tayloredge.com/storefront/index.html


1 x 1392 - 6 Digit IN18 Clock Backplane

6 x 1361 - SmartNixie IN18

1 x 1375 - SmartNixie GPS RTC

1 x 1364 - SmartNixie HVPS-H

1 x Active GPS Antenna

1 x Power Plug



I ordered my IN-18 tubes from super-gene on ebay: http://myworld.ebay.com/super-gene/

6 x IN-18 tubes



12V power supply and Arduino Nano can be ordered from Amazon here:

http://www.amazon.com/Wall-Adapter-Power-Supply-12VDC/dp/B006GEPUYA
http://www.amazon.com/Arduino-ARD-NANO30-Nano-v3-0/dp/B003YVL34O



Arduino Sketch:



 // Smart Nixie  
 // by Jason Garland <http://www.jasongarland.com>  
 #include <Wire.h>  
 #include <SeeedOLED.h>  
 #include <avr/pgmspace.h>  
 #include "DHT.h"  
 #define DHTPIN 2   // what pin Temperature sensor is connected to  
 #define DHTTYPE DHT22  // DHT 22 (AM2302)  
 DHT dht(DHTPIN, DHTTYPE);  
 byte tube[6]={0x0E, 0x0C, 0x0B, 0x0A, 0x09, 0x08};  
 char tubestate[7];  
 byte gps[14];  
 int tzoffset=-8;  
 char digit[7];  
 unsigned long counter=999999;  
 #define LEDPIN 13  
 int ledstate=0;  
 unsigned long lasttick = millis();  
 unsigned long lastdht = millis();  
 void setup()  
 {  
  Serial.begin(38400);  
  Serial.println("Starting up");  
  pinMode(A4, INPUT_PULLUP);  
  pinMode(A5, INPUT_PULLUP);  
  pinMode(LEDPIN, OUTPUT);  
  dht.begin();  
  Wire.begin(); // join i2c bus (address optional for master)  
  SeeedOled.init(); //initialze SEEED OLED display  
  DDRB|=0x21;      
  PORTB |= 0x21;  
  SeeedOled.setBrightness(255);  
  SeeedOled.clearDisplay();        // clear the screen and set start position to top left corner  
  SeeedOled.setNormalDisplay();   //Set display to normal mode (i.e non-inverse mode)  
  SeeedOled.setPageMode();      //Set addressing mode to Page Mode  
  SeeedOled.setTextXY(1,0);     //Set the cursor to Xth Page, Yth Column   
  SeeedOled.putString("Humidity:"); //Print the String "Hello World!"  
  SeeedOled.setTextXY(3,0);     //Set the cursor to Xth Page, Yth Column   
  SeeedOled.putString("Temperature:"); //Print the String "Hello World!"  
  SeeedOled.setTextXY(5,0);     //Set the cursor to Xth Page, Yth Column   
  SeeedOled.putString("Time: "); //Print the String "Hello World!"  
  init_gps(); // Initialize the GPS  
  //Set brightness on all tubes to 100%  
  for (int i=5; i>=0; i-- ){ setbrightness(i, 100); }  
 }  
 void loop() {  
  // Update once per 10th second  
  if (millis() - lasttick >= 100) {  
   lasttick = millis();  
   if ( random(1000) == 42) { pinball(); }  
   read_gps_time(digit);  
   update_display(digit);  
   SeeedOled.setTextXY(6,2);  
   SeeedOled.putString(digit);  
  }  
  update_oled_dht();  
   //Serial.println(counter);  
   //delay(1000);  
   //update_display(counter--);  
 }  
 void read_gps_time(char* digit_buffer) {  
  //int bytes=128;  
  int bytes=6;  
  Wire.requestFrom(81, bytes);  // request 14 bytes from slave device #81  
  int i=0;  
  while(Wire.available())  // slave may send less than requested  
  {  
   gps[i]=Wire.read();  
   i++;  
  }  
  char buffer[((bytes * 3) + 1)];  
  for(int j=0;j<bytes;j++){  
   sprintf(buffer+(j*3), "%02X ", gps[j]);  
   }  
  //Serial.println(buffer);  
  char hourbuffer[3];  
  int hour;  
  sprintf(hourbuffer, "%02X", gps[2]);  
  hour=atoi(hourbuffer);  
  //hour+=tzoffset;  
  if(hour < 0) {  
   hour+=24;  
  }  
  sprintf(digit_buffer,"%02d%02X%02X", hour, gps[1], gps[0]);  
  //Serial.println(digit_buffer);  
 }  
 void setbrightness(int place, int brightness) {  
   Wire.beginTransmission(tube[place]); // seconds 1s  
   Wire.write(byte(0x0B));    //register address=dimmer  
   Wire.write(brightness);    //dimmer=50%  
   Wire.endTransmission(); // stop transmitting  
 }  
 void update_display(unsigned long number){  
  char digit_buffer[7];  
  sprintf(digit_buffer, "%06lu",number%1000000);  
  update_display((char *)&digit_buffer);  
  }  
 void update_display(char* digit_buffer)  
 {  
  for (int i=5; i>=0; i-- ){  
   if ( tubestate[i]!=digit_buffer[i] ){  
    display_digit(i, digit_buffer[i]);  
    /*  
    Serial.print(tubestate[i]);  
    Serial.print(" ");  
    Serial.println(digit_buffer[i]);  
    //*/  
    //fade_digit(i, tubestate[i], digit_buffer[i]);  
    tubestate[i]=digit_buffer[i];  
   }  
  }  
  Serial.print("digit_buffer: ");  
  Serial.println(digit_buffer);  
  Serial.print("tubestate: ");  
  Serial.println(tubestate);  
  //*/  
 }  
 void fade_digit(int place, byte old_value, byte new_value){  
  for (int b=100; b>=30; b-=2 ){  
   Wire.beginTransmission(tube[place]); // seconds 1s  
   Wire.write(byte(0x0B));    //register address=dimmer  
   Wire.write(b);    //dimmer=50%  
   Wire.endTransmission(); // stop transmitting  
   delay(20);  
   }  
   Wire.beginTransmission(tube[place]); // tube  
   Wire.write(byte(0x00));    //set display  
   Wire.write(new_value-0x30);    //display digit  
   Wire.endTransmission(); // stop transmitting  
   for (int c=30; c<100; c+=2 ){  
   Wire.beginTransmission(tube[place]); // seconds 1s  
   Wire.write(byte(0x0B));    //register address=dimmer  
   Wire.write(c);    //dimmer=50%  
   Wire.endTransmission(); // stop transmitting  
   delay(20);  
   }  
  /*  
  for(int i=0; i<200; i++) {  
   display_digit(place, old_value);  
   for(int j=0; j<(200-i); j++) {  
    delayMicroseconds(1);  
   }  
   display_digit(place, new_value);  
   for(int j=0; j<i; j++) {  
    delayMicroseconds(4);  
   }  
  }  
  display_digit(place, new_value);  
  */  
 }  
 void display_digit(int place, byte value) {  
    if ( place == 5 ) { blink_led(); } // blink Arduino LED when the seconds digit increments  
    Wire.beginTransmission(tube[place]); // tube  
    Wire.write(byte(0x00));    //set display  
    Wire.write(value-0x30);    //display digit  
    Wire.endTransmission(); // stop transmitting  
 }  
 void init_gps() {  
    delay(500);  
    Wire.beginTransmission(byte(0x51)); // Write to GPS  
    Wire.write(byte(0x3C));    //set DL value  
    //Wire.write(byte(0x12));    //Set DL for Daylight Savings off  
    Wire.write(byte(0x22));    //Set DL for Daylight Savings on +1 hour  
    Wire.write(byte(0x08));    //set timezone hour offset to -8  
    Wire.endTransmission(); // stop transmitting  
    /*  
    Wire.beginTransmission(byte(0x51)); // Write to GPS  
    Wire.write(byte(0x3D));    //set timezone offset  
    Wire.write(byte(0x08));    //set timezone hour offset to -8  
    Wire.endTransmission(); // stop transmitting  
    */  
    Wire.beginTransmission(byte(0x51)); // Write to GPS  
    Wire.write(byte(0x02));    //start address 0x02  
    Wire.endTransmission(); // stop transmitting  
 }  
 void blink_led() {  
  ledstate = ~ledstate;  
  digitalWrite(LEDPIN, ledstate);  
 }  
 void pinball() {  
  char digit_buffer[6];  
  for (int i=0; i<100; i++ ){  
   sprintf(digit_buffer, "%06lu", random(1000000));  
   delay(50);  
   update_display(digit_buffer);  
   if (millis() - lasttick >= 100) {  
    lasttick = millis();  
    read_gps_time(digit);  
    SeeedOled.setTextXY(6,2);  
    SeeedOled.putString(digit);  
   }  
  }  
 }  
 //Celsius to Fahrenheit conversion  
 double Fahrenheit(double celsius)  
 {  
     return 1.8 * celsius + 32;  
 }  
 void update_oled_time() {  
 }  
 void update_oled_dht() {  
  if (millis() - lastdht >= 10000) {  
   lastdht = millis();  
   float h = dht.readHumidity();  
   float t = dht.readTemperature();  
   //SeeedOled.setTextXY(1,0);     //Set the cursor to Xth Page, Yth Column   
   //SeeedOled.putString("Humidity:"); //Print the String "Hello World!"  
   SeeedOled.setTextXY(2,2);     //Set the cursor to Xth Page, Yth Column   
   SeeedOled.putNumber(h); //Print the String  
   SeeedOled.putString("%");  
   //SeeedOled.setTextXY(3,0);     //Set the cursor to Xth Page, Yth Column   
   //SeeedOled.putString("Temperature:"); //Print the String "Hello World!"  
   SeeedOled.setTextXY(4,2);     //Set the cursor to Xth Page, Yth Column   
   SeeedOled.putNumber(Fahrenheit(t)); //Print the number  
   SeeedOled.putString(" F");  
  }  
 }  

3 comments:

iagoyanick said...

How to get to Slot Casino in San Francisco by Bus - JTAH Hub
Find 동두천 출장안마 out how 경기도 출장안마 to get to Slot Casino in 군포 출장마사지 San Francisco 사천 출장안마 by Bus, taxi, 양산 출장샵 biking, walking, driving, and ridesharing.

sandhurstlamonda said...

The likelihood distribution of that sum is approximately normal, with an average and an SD that we can to} approximate. Very few of the information histograms that we now have seen in this course have been bell formed. When we now have come throughout a bell formed distribution, it has nearly invariably been an empirical histogram of a statistic based on a random sample. The Breeders’ 스마일토토 Cup Classic is ready to close of the 2022 horse racing season on Saturday at Keeneland racetrack on Saturday afternoon. North Carolina residents trying to get in on the action can sign a lot as} greatest offshore sportsbooks for... You will then need to enter the related fee particulars, your promo code, and your deposit amount.

ikeishialabarge said...

There can also be|can be} an internet forum you can to|you presumably can} publish on for widespread questions. Despite having loads of avenues for assist, this playing site may do a lot higher at responding shortly. Ignition got here out as the winner, however the rest of|the remainder of} the casinos on our listing are fairly close competitors. Find 우리 계열 out if any of those casinos are extra proper up your alley. The transaction features a binding partnership between Gaming and Leisure Properties Inc. and The Cordish Cos. On future Cordish on line casino developments, nicely as|in addition to} potential financing partnerships between the entities on other actual estate and operating companies in Cordish’s portfolio.