顯示具有 vfd 標籤的文章。 顯示所有文章
顯示具有 vfd 標籤的文章。 顯示所有文章

2015年12月31日 星期四

IV-18 Arduino Clock


這應該算是第二版了,這個版本改成控制板+顯示板,先來列一下特色
  1. 自動亮度控制
  2. Wifi 設定(校時,時區,鬧鐘,顯示風格,手動亮度控制)
  3. 蜂鳴器鬧鐘
  4. Build with Arduino Leonardo(Atmega32U4)
控制板主要有
  1. Atmega32U4 as MCU
  2. Linkit connect module to connect to Internet
  3. RTC (DS1307 or PCF8563) with CR1215 battery backup
  4. Buzzer 
  5. Four tact switch
  6. Photocell

顯示板主要有
  1. HV5812 VFD controller
  2. Attiny24 I2C VFD scanner
  3. build in Step-up
這次版本最重要的就是把我想很就的Wifi功能加了進去,主要就是為了NTP校正時鐘
所以先從這邊講起,
一般來說,時間校正(先不管計時機制),有下列這幾種
  1. 網路
  2. 無線電校時(大人的科學有電波鐘套件,就那種Type)
  3. GPS
  4. GSM(基地台會幫你校時)
以前Wifi模組還很貴的時候基本上都是用2或3,但是無線電台灣沒有開發射站了,所以只能收日本的,訊號很差,甚至還要用音源線+OOXXZZZ做簡易的發射源,太麻煩
GPS的問題也不是說訊號太弱,但是不是每個人都會把時鐘放在窗邊,至於GSM就無視吧
所以這三個在我以前做時鐘的時候都沒用
之前為了時鐘的準確度(懶得校時)所以就用了比較高級的RTC(DS3231),真的覺得不錯,一年下來差不到幾秒.

然後最近幾年,Wifi模組的價錢可以說是直接殺了下來,以前在櫥窗的那些Microchip貴桑桑的無線網路模組,現在只要台幣幾百塊錢,所以是時候把時鐘也連上網了.(我還可以宣稱是科技潮流的 I-O-T 喔喔喔喔喔)

這次用的Wifi模組是聯發科的MT7681模組
就一個標準的3.3V,UART無線網路模組.有Arduino 的範例也有接線圖https://github.com/will127534/7681-ATcmd
範例就是NTP time sync

好了,那已經有網路校時了,這Wifi模組還可以發揮甚麼功能?
顯示股票大跌,不準的公車預估到達時間,永遠掛0~9的新郵件數目
這些當然都很好,只是說Code不夠用......

所以就先把設定值搬到網路上

===========期末考完再來補...===============







2015年3月6日 星期五

IV-18 真空管時鐘 RC1


 這次因為成本的關係,我打算再做一組子版,所以這個版本不算是正式版,算是RC版
這次把升壓電路也做進去了,也改用MAX6921 SSOP的IC控制,不過也是因為這個IC所以成本超高.....MAX6921已經夠貴了,SSOP的版本又更上一層樓 Q__Q

這邊可以看到Attiny24 & 升壓電路(電容後來我改用SMD的了)
MAX6921 SSOP

2014年11月2日 星期日

IV-18 真空管時鐘 beta2.0

總之這是第二版的試做,這是大概50%的beta版,主要是IV-18的holder加上他所需要的升壓板
這次我加了一個Attiny44來控制MAX6921,專門拿來掃描,這樣一來Arduino就不需要一直去掃描,使得程式速度不一樣而影響到亮度,
所以這次Holder就多了兩個IC,Attiny+MAX6921
不過下次應該還會再做一次,把升壓模組也放上去,因為空間還滿大的,不用白不用
另外就是應該有人發現了,這真空管亮度有點問題,這主要是燈絲的電壓造成的,我一來電阻搞太大,二來這又是用直流電,所以就悲劇了.下一版會用一個MAX628做燈絲電源的極性切換

2014年1月23日 星期四

IV-18 Arduino Shield 製作


於是,IV-18 時鐘的Arduino 版登場啦~~~
經過快半個月的時間這張板子終於到了我手上,沒辦法,我真的找不到有哪一家比OSHPark便宜的PCB製作廠了

好啦,言歸正傳,這次的版本沿用http://forum.43oh.com/topic/2487-siv-18-vfd-clock-booster-pack/大致上的Layout,但是增加了DS1307 RTC,然後5V可以直接從Arduino拉過來.
首先,先上MC34063,MAX6921,DS1307,By the way,我的DS1307還沒到所以右下角沒焊接

SOIC應該不會很難焊,圖片稍微放大一點就可以發現我的焊工根本___
再來上電阻,二極體,可變電阻
剩下電容,電感,電池座和針母上完後,主體大致上就完成了
然後不想等DS1307只好把手邊的RTC模組拆了(=゚ω゚)ノ
右下角就全補齊了

再來先插上Arduino測試MC34063升壓得如何
測量點是二極體的輸出端,電壓大概20~30V就可以了,太高太低就轉可變電阻
之後換重頭戲,IV-18的轉接版~
英文不錯的話就看http://learn.adafruit.com/ice-tube-clock-kit/board-assembly這裡其中的IV-18部分吧

先上90度的雙排針,這點需要非常注意,排針要從右手邊插,如圖,如果插了的話會"非常麻煩"喔
接下來就是上IV-18
上板子之前,最好先把他的腳給剪一剪,繞一圈長度越來越短,這樣的話會比較好上去
注意到了嗎?中間有三個PIN腳是沒有功能的,這三隻PIN要插到標示在PCB上三個"NC"的地方
,插進去後,先不要焊接,把Program upload到Arduino上面,再把這個板子插到Shield上測試
測試完成後再焊接.
Program is here:GITHUB

焊接完就大功告成啦~

後來順便改一下電路板把一些缺點修一修
把有點占空間的電池座換了一個,然後有多的空間讓DS3231放背面,還有蜂鳴器也可以直接放在板子上,電感挪到MC34063旁邊
不過電池彈片還真難買.....光華繞了大半圈都沒有,只好從RS叫貨了

另外就是我發現MAX6921只能叫貨.....非常不方便,尤其是我手邊的6921快沒了
所以只好另尋他法
希望這版能測試成功

==Update==
程式碼加入了調整時間的直接方式
先輸入大寫的S,就可以進到調整時間的程式

#include <Arduino.h>

#include <Wire.h>  
#include <Time.h>  
#define DS1307_ADDRESS 0x68
#define  dataPin  11
#define  clockPin 13
#define  loadPin  5

byte zero = 0x00;
const byte segFont[] ={B00111111, B00000110, B01011011, B01001111,B01100110, B01101101, B01111100, B00000111,B01111111, B01100111, B01000000};

int lastsecond = 0;

byte bChars[10] ;
int dChars[10] ;

byte seconds;
byte hours;
byte minutes;

void serialEvent();
void setTime();
byte readByteq();
void RefreshIV18();
byte bcdToDec(byte val);
void timetoIV18(byte h,byte m,byte s);
byte decToBcd(byte val);
void printDate();

void setup()
{
  pinMode(loadPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  
  Serial.begin(9600);
  Wire.begin();
  timetoIV18(12,75,34);
  printDate();
  RefreshIV18();

}

void loop(){

  printDate();
  timetoIV18(hours,minutes,seconds);

  if (lastsecond != seconds){
   lastsecond = seconds;
   dChars[1] = !dChars[1];
   dChars[4] = !dChars[4];
   dChars[7] = !dChars[7];
   timetoIV18(hours,minutes,seconds);
 }
 RefreshIV18();

}
void serialEvent(){
int answer = Serial.read();
if (answer=='S'){
  Serial.read();
  setTime();
}
}

void setTime() {
  Serial.read();
  Serial.println("Please enter the current year, 00-99. - ");

  byte yearsett = readByteq();
  Serial.println("Please enter the current month, 1-12. - ");
  byte monthset = readByteq();
  //Serial.println(months[monthset-1]);
  Serial.println("Please enter the current day of the month, 1-31. - ");
  byte monthdayset = readByteq();
  //Serial.println(monthday);
  Serial.println("Please enter the current day of the week, 1-7.");
  Serial.println("1 Sun | 2 Mon | 3 Tues | 4 Weds | 5 Thu | 6 Fri | 7 Sat - ");
  byte weekdayset = readByteq();
  //Serial.println(days[weekday-1]);
  Serial.println("Please enter the current hour in 24hr format, 0-23. - ");
  byte hourset = readByteq();
  //Serial.println(hour);
  Serial.println("Please enter the current minute, 0-59. - ");
  byte minuteset = readByteq();
  //Serial.println(minute);
  byte secondset = 0;
  Serial.println("The data has been entered.");

  // The following codes transmits the data to the RTC
  Wire.beginTransmission(0x68);
  Wire.write(byte(0));
  Wire.write(decToBcd(secondset));
  Wire.write(decToBcd(minuteset));
  Wire.write(decToBcd(hourset));
  Wire.write(decToBcd(weekdayset));
  Wire.write(decToBcd(monthdayset));
  Wire.write(decToBcd(monthset));
  Wire.write(decToBcd(yearsett));
  Wire.write(byte(0));
  Wire.endTransmission();
  // Ends transmission of data
}


byte readByteq() {
  while (!Serial.available()) delay(10);
  byte reading = 0;
  byte incomingByte = Serial.read();
  while (incomingByte != '\n') {
    if (incomingByte >= '0' && incomingByte <= '9')
      reading = reading * 10 + (incomingByte - '0');
    else;
    incomingByte = Serial.read();
  }
  Serial.flush();
  return reading;
}
void RefreshIV18() 
  for (int count = 1;count<=9;count++){

    long data=0;
    data = segFont[bChars[count]];
    bitSet(data,17-count);
    if (dChars[count] == 1){
      bitSet(data,7);
    }
    digitalWrite(loadPin, LOW); 
  //Shiftin 20 bits
  for(byte i=0; i<20; i++) 
  { 
    //clockPin LOW
    digitalWrite(clockPin, LOW);
    //datapin bit to 1 OR 0 
    digitalWrite(dataPin,bitRead(data, i));
    //Set clockPin HIGH
    digitalWrite(clockPin, HIGH); 
  }

  digitalWrite(loadPin, HIGH);

}
}

byte bcdToDec(byte val)  {
// Convert binary coded decimal to normal decimal numbers
return ( (val/16*10) + (val%16) );
}


void timetoIV18(byte h,byte m,byte s)
{
  memset(bChars,0,sizeof(bChars));

  bChars[7]=h % 10;
  bChars[8]=h / 10;
  
  bChars[6]=10;

  bChars[4]=m % 10;
  bChars[5]=m / 10;

  bChars[3]=10;

  bChars[1]=s % 10;
  bChars[2]=s / 10;

  

}


byte decToBcd(byte val){
// Convert normal decimal numbers to binary coded decimal
return ( (val/10*16) + (val%10) );
}
void printDate(){
  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.write(zero);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_ADDRESS, 3);

  seconds = bcdToDec(Wire.read());
  minutes = bcdToDec(Wire.read());
  hours = bcdToDec(Wire.read() & 0b111111); //24 hour time
   /*
  int weekDay = bcdToDec(Wire.read()); //0-6 -> sunday - Saturday
  int monthDay = bcdToDec(Wire.read());
  int months = bcdToDec(Wire.read());
  int years = bcdToDec(Wire.read());

  //print the date EG   3/1/11 23:59:59
  Serial.print(months);
  Serial.print("/");
  Serial.print(monthDay);
  Serial.print("/");
  Serial.print(years);
  Serial.print(" ");
  Serial.print(hours);
  Serial.print(":");
  Serial.print(minutes);
  Serial.print(":");
  Serial.println(seconds);
  */
}


有日期的版本:
#include <Arduino.h>

#include <Wire.h>  
#include <Time.h>  
#define DS1307_ADDRESS 0x68
#define  dataPin  11
#define  clockPin 13
#define  loadPin  5

byte zero = 0x00;
const byte segFont[] ={B00111111, B00000110, B01011011, B01001111,B01100110, B01101101, B01111100, B00000111,B01111111, B01100111, B01000000, B00000000};

int lastsecond = 0;

byte bChars[10] ;
int dChars[10] ;

byte seconds;
byte hours;
byte minutes;
int weekDay ; //0-6 -> sunday - Saturday
  int monthDay ;
  int months ;
  int years ;
void serialEvent();
void setTime();
byte readByteq();
void RefreshIV18();
byte bcdToDec(byte val);
void timetoIV18(byte h,byte m,byte s);
byte decToBcd(byte val);
void printDate();

void setup()
{
  pinMode(loadPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  
  Serial.begin(9600);
  Wire.begin();
  timetoIV18(12,75,34);
  printDate();
  RefreshIV18();

}

void loop(){

  printDate();
  datetoIV18(years,months,monthDay);

  for(int j=0;j<=1000;j++){
 RefreshIV18();
}
 timetoIV18(hours,minutes,seconds);
 for(int j=0;j<=1000;j++){
 RefreshIV18();
}

}
void serialEvent(){
int answer = Serial.read();
if (answer=='S'){
  Serial.read();
  setTime();
}
}

void setTime() {
  Serial.read();
  Serial.println("Please enter the current year, 00-99. - ");

  byte yearsett = readByteq();
  Serial.println("Please enter the current month, 1-12. - ");
  byte monthset = readByteq();
  //Serial.println(months[monthset-1]);
  Serial.println("Please enter the current day of the month, 1-31. - ");
  byte monthdayset = readByteq();
  //Serial.println(monthday);
  Serial.println("Please enter the current day of the week, 1-7.");
  Serial.println("1 Sun | 2 Mon | 3 Tues | 4 Weds | 5 Thu | 6 Fri | 7 Sat - ");
  byte weekdayset = readByteq();
  //Serial.println(days[weekday-1]);
  Serial.println("Please enter the current hour in 24hr format, 0-23. - ");
  byte hourset = readByteq();
  //Serial.println(hour);
  Serial.println("Please enter the current minute, 0-59. - ");
  byte minuteset = readByteq();
  //Serial.println(minute);
  byte secondset = 0;
  Serial.println("The data has been entered.");

  // The following codes transmits the data to the RTC
  Wire.beginTransmission(0x68);
  Wire.write(byte(0));
  Wire.write(decToBcd(secondset));
  Wire.write(decToBcd(minuteset));
  Wire.write(decToBcd(hourset));
  Wire.write(decToBcd(weekdayset));
  Wire.write(decToBcd(monthdayset));
  Wire.write(decToBcd(monthset));
  Wire.write(decToBcd(yearsett));
  Wire.write(byte(0));
  Wire.endTransmission();
  // Ends transmission of data
}


byte readByteq() {
  while (!Serial.available()) delay(10);
  byte reading = 0;
  byte incomingByte = Serial.read();
  while (incomingByte != '\n') {
    if (incomingByte >= '0' && incomingByte <= '9')
      reading = reading * 10 + (incomingByte - '0');
    else;
    incomingByte = Serial.read();
  }
  Serial.flush();
  return reading;
}
void RefreshIV18() 
  for (int count = 1;count<=9;count++){

    long data=0;
    data = segFont[bChars[count]];
    bitSet(data,17-count);
    if (dChars[count] == 1){
      bitSet(data,7);
    }
    digitalWrite(loadPin, LOW); 
  //Shiftin 20 bits
  for(byte i=0; i<20; i++) 
  { 
    //clockPin LOW
    digitalWrite(clockPin, LOW);
    //datapin bit to 1 OR 0 
    digitalWrite(dataPin,bitRead(data, i));
    //Set clockPin HIGH
    digitalWrite(clockPin, HIGH); 
  }

  digitalWrite(loadPin, HIGH);

}
}

byte bcdToDec(byte val)  {
// Convert binary coded decimal to normal decimal numbers
return ( (val/16*10) + (val%16) );
}


void timetoIV18(byte h,byte m,byte s)
{
  memset(bChars,0,sizeof(dChars));
  memset(dChars,0,sizeof(bChars));
  bChars[7]=h % 10; 
  bChars[8]=h / 10;
  bChars[6]=11;
  dChars[6]=1;

  bChars[4]=m % 10; 
  bChars[5]=m / 10;
 bChars[3]=11;
  dChars[3]=1;

  bChars[1]=s % 10; 
  bChars[2]=s / 10;

  

}
void datetoIV18(int yy,int mm,int dd)
{
  memset(dChars,0,sizeof(dChars));
  memset(bChars,0,sizeof(bChars));

  bChars[8]=yy/10;
  bChars[7]=yy%10; 
  
  bChars[6]=10;

  bChars[5]=mm/10; 
  bChars[4]=mm%10;

  bChars[3]=10;

  bChars[2]=dd / 10;
  bChars[1]=dd % 10; 

}


byte decToBcd(byte val){
// Convert normal decimal numbers to binary coded decimal
return ( (val/10*16) + (val%10) );
}

void printDate(){
  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.write(zero);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_ADDRESS, 7);

  seconds = bcdToDec(Wire.read());
  minutes = bcdToDec(Wire.read());
  hours = bcdToDec(Wire.read() & 0b111111); //24 hour time
  
   weekDay = bcdToDec(Wire.read()); //0-6 -> sunday - Saturday
  monthDay = bcdToDec(Wire.read());
  months = bcdToDec(Wire.read());
   years = bcdToDec(Wire.read());
/*
  //print the date EG   3/1/11 23:59:59
  Serial.print(months);
  Serial.print("/");
  Serial.print(monthDay);
  Serial.print("/");
  Serial.print(years);
  Serial.print(" ");
  Serial.print(hours);
  Serial.print(":");
  Serial.print(minutes);
  Serial.print(":");
  Serial.println(seconds);
  */
}

2014年1月3日 星期五

IV-18 VFD 真空管時鐘


是的,我又做了一個真空管時鐘
這次是做VFD的版本,利用IV-18 booster pack + 放置PLAY很久的MSP430

先介紹IV-18吧

蘇聯製最大隻的VFD真空管,包含8個數字(含小數點)及一個指示點
比起Nixie 的 IN-18 ,可說是便宜很多啊(這隻含運200~300)
這隻VFD管的接腳一共20隻,包含9個選擇位數的+8個7段顯示器含小數點的腳+三個dummy
看到這應該可以想像驅動方式是掃描式了吧XD

至於驅動方式,引用http://led.eefocus.com/article/10-07/1459731278923416.html這篇文章的圖
燈絲通電後電子衝出來,經過欄極加速後,衝到陰極,如果通電的話就撞上去,撞到螢光粉發光
通常燈絲電壓為5V,欄極與陰極為30V左右(每種都不太一樣)

所以驅動這管子,需要有能夠輸出30V給VFD管的IC,這個版本用的是MC34063升壓IC,以及MAX6921 VFD 專用驅動IC,
MC34063將5V升到大約30V後,供電給MAX6921,MAX6921一共20個輸出腳位(by the way 我們只要用到 17個)至於燈絲電流,加個限流電阻就直接接VFD

MAX6921的驅動方式很簡單,就像SPI一樣,給個CLOCK+DATA還有幾個控制腳就可以了
VSS的負電壓沒有用到
LOAD高電壓的時候傳送資料由DIN+CLK傳送,而BLANK為高電壓時會強制輸出為0

至於RTC就用MSP430內建的電路,只要外接震盪器就可以用了

順帶一提,Arduino shield 已經送洗了XDDD 好期待