M5StickC Nixie tube Clock
M5StickC で ニキシー管時計を製作しました。 2019.06.06, rev 2019.06.15
ニキシー管は 高電圧が必要である事や 高価である為 製作する機会がありません。
見たい気持ちは大きく ソフトで製作しました。
費用:M5StickC以外の材料費は0円です。
外観:M5StickC の IPS Display は 80×160 で表示サイズは小さいですが
_ 明るく綺麗で見やすいです。
機能:M5のスイッチで YYYY,MM,DD, HH,MM,SS 表示と
_ MM,SS 表示に切り換える事ができます。
追記:2019.06.15
Carlos Orts に スケッチがパクられました。
McOrts/M5StickC_Nixie_tube_Clock: Jun 14, 2019
原作者(macsbug) や URLリンク が削除されています。
M5Stack Community / PROJECTS にMcOrts/M5StickC_Nixie_tube_Clockを記載しました。
その中で 3箇所に 原作者(macsbug) や URLリンクが削除されている事を記載しました。
.
追記:2020.09.02:uiFlow IDEによるニキシー管時計。
world101氏が M5StickC-PlusデバイスのuiFlow IDEにニキシー管時計を実装しました。uiFlow IDEを使用することで、新しいプログラマーや子供たちにとって簡単になりました。多くの人が楽しめる様になり world101氏に感謝致します。
github:https://github.com/bstein2379/M5StickC-Plus-Nixie-clock
M5Stack Community:M5StickC Nixie tube Clock
.
準備:以下の画像をドラック&ドロップし 画像を入手します。
ニキシー管 画像の製作:元画像 18×34 pixel
.
ニキシー管 画像の製作:元画像 35×67 pixel
.
参考:画像から Hex.c の作成方法は M5Stack CoinMarketCap:2019.05.30 を参照下さい。
⭕ HEX File 変換の準備:
_ png画像を「lcd-image-converter 」アプリで hex ( .c ) に変換します。
_ 「lcd-image-converter」は Windowsアプリです。
_ 「lcd-image-converter 20180211-beta」を使用します。
_ メモ:投稿時 最新の20190317 は エラーで動作しません。
_ Mac では「Wine.app」を使用しWindows アプリケーションを動かすことができます。
_ Wine.app Downloads:例 Wine 2.0 を 選択し Download を押します。
_ 約5sec後に「Continue」が表示されますので「Continue」を選択します。
_ 約4sec後に 右上(のアイコン) を選択します。Wine_2.0.dmg 175.6MB が DLされます。
_ 解凍すると Wine.app ができます。
_
⭕ HEX File 変換方法:
1. Wine.app を起動し LCD image Converter を動作させます。
_ 事前に Wine.app や LCD image Converter の動かし方や 配置を把握しておきます。
_ 初めての場合は Winの配置等に慣れない為に時間を要するかと思います。
2. LCD image Converter:
_ File Menu から png 又は Jpg を読み込みます。読み込まれると画像が表示されます。
_ Option Menu を選択します。一番上の Preset: は「Color R5G6B5」を選択します。
_ Image を選択し Block size: は「8 bit」を選択します。「OK」を押します。
_ File Menu にある 「Convert… 」 で 例「vfd_35x67_8.c」が出力されます。
_ 事前に読み込み先 ong や 出力先を把握しておきます。
_ 全ての画像を読み込み 「Convert… all」で 全部の出力もできます。
_
3. .c の編集:そのままではエラーが出ますので ご使用のエディターで修正します。
_ 上位にある 「static const uint8_t image_data_vfd_35x67[4690] = {」は
_ 解りやすくする為に名前を編集します。
_ ⭕ 「image_data_ 」を削除し「static const uint8_t vfd_35x67_8[4690] = {」にします。
_ ⭕最下位にある「const tImage vfd_35x67 = { image_data_vfd_35x67, 35, 67, 8 };」は
_ 削除します。
_ 例「vfd_35x67_8」を保存します。
_ 同様に 0 から 9 まで実施し 保存します。
_ ⭕ 0 から 9 までのファイルは1つにした方が便利です。「0」の行末の後に
_ 1 から 9 までの名前とデーター部を全て「0」の下に追加し 1つのファイルにします。
4. スケッチの作成。
_ 最下位にあるスケッチをコピーして 以下の画像の様に準備し
_ 画像フォント「vfd_18x34.c」 と 「vfd_35x67.c」 もフォルダーに入れます。
_
_ 以上で完了です。
.
M5StickC 開発環境:
Arduino IDE 1.8.9
_ 1. Upload Speed : “115200”
_ 1. シリアルモニター:115200 baud:OPEN 又は CLOSE で可能。
_ 2. Upload Speed : “500000”
_ 2. シリアルモニター:500000 baud:OPEN である事。
_ 書込み時に「A fatal error occurred: Timed out waiting for packet header」
_ が発生する場合があります。
_ 速度を速くしたく board.txt を書き換える方法もありますが、
_ 手順の簡単な 115200 baud が無難かと思います。
.
参考:
RTC: I2C BM8563:RTC機能を実現する。アドレス:0x15。
_ M5.Rtc.GetBm8563Time(); : ASCII形式で Rtc.Hour / Rtc.Minute / Rtc.Second
m5stack/m5-docs / system_m5stickc:M5stickC システム。
m5stack/m5-docs / axp192_m5stickc:AXP192 電源管理IC。
m5stack/m5-docs / lcd_m5stickc: IPS Display。
m5stack/m5-docs / sh200q_m5stickc:SH200Q 6 axis inertial sensor。
Virtual nixie tube (digitron) display – DHTML component library:nixie tube の画像データーがあります。
Long-ship:M5Stick-CのRTCをNTPサーバーからセットする:NTPが可能です。
.
感想:
画像の製作:画像処理により飽和したり綺麗でない場合がありますので
_ 手間ですが綺麗な表示になるように編集します。
_ 発光文字部分とニキシー管の背景とのバランスが重要です。
_ ニキシー管の背景が無いと雰囲気出ませんし強調すると全体が白く飽和します。
_ hex.c の編集が面倒でしたら「M5Stack CoinMarketCap」での
_ microSD 方式で 画像を使用する方法も良いかとも思います。
時刻:書込み時に PC の時刻を読み込み ESP内部の RTCに設定しています。
_ NTPは使用していません。
ニキシー管:ニキシー管をなんとか見る事ができて ほっとしています。
_ 私もそうですが ニキシー管を好きな人が多い様です。
_ 光る数値は前後に配置され数値の部分が重なる所があります。
_ 細かく見るとフィラメントが重なる部分は綺麗に表示されないのですね。
github:使用していませんので大きなデータやリストを載せられず申し訳有りません。
M5StickC 価格:M5Stack Official Store = 1799円。$16.64。輸送期間 8日。
_ スイッチサイエンス = 2444円。
_ 10個購入する場合 M5Stack Official Store は 国内販売よりも 6450円お得になります。
M5Stack版:同様に M5Stack FIRE でも表示可能です。
_ M5Stack FIRE Nixie tube Clock:
.
スケッチ:M5StickC Nixie tube Clock: 2019.06.06 macsbug
追記:2020.06.05:Add Down Load。
_ Down Load:m5stickc_nixie_tube_clock.zip:( File は .pdf です )
_ DL後に File name を m5stickc_nixie_tube_clock.zip ( .zip ) に変更します。
_ 解凍すると M5StickC_Nixie_tube_Clock の Folder ができます。
// M5StickC Nixie tube Clock: 2019.06.06 macsbug // https://macsbug.wordpress.com/2019/06/06/m5stickc-nixie-tube-clock/ #include <M5StickC.h> #include "vfd_18x34.c" #include "vfd_35x67.c" RTC_TimeTypeDef RTC_TimeStruct; RTC_DateTypeDef RTC_DateStruct; int mode_ = 2; // 2: 2line, 1:1line const uint8_t*n[] = { // vfd font 18x34 vfd_18x34_0,vfd_18x34_1,vfd_18x34_2,vfd_18x34_3,vfd_18x34_4, vfd_18x34_5,vfd_18x34_6,vfd_18x34_7,vfd_18x34_8,vfd_18x34_9 }; const uint8_t*m[] = { // vfd font 35x67 vfd_35x67_0,vfd_35x67_1,vfd_35x67_2,vfd_35x67_3,vfd_35x67_4, vfd_35x67_5,vfd_35x67_6,vfd_35x67_7,vfd_35x67_8,vfd_35x67_9 }; const char *monthName[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; void setup(void){ M5.begin(); pinMode(M5_BUTTON_HOME, INPUT); M5.Lcd.fillScreen(BLACK); M5.Lcd.setRotation(1); M5.Axp.ScreenBreath(10); // 7-15 // rtc setup start --------------------------------------------- String pt = (__DATE__ " " __TIME__); // PC DATE TIME READ //000000000011111111112 Read data //012345678901234567890 //Jun 6 2019 07:20:41 char m1[3]; int m2; // Month conversion ( Jun to 6 ) (pt.substring(0,3)).toCharArray(m1,4); for (int mx = 0; mx < 12; mx ++) { if (strcmp(m1, monthName[mx]) == 0){m2 = mx + 1; break;} } RTC_DateTypeDef DateStruct; // Month, Date, Year DateStruct.Month = m2; DateStruct.Date = (pt.substring(4, 6)).toInt(); DateStruct.Year = (pt.substring(7,11)).toInt(); M5.Rtc.SetData(&DateStruct); RTC_TimeTypeDef TimeStruct; // Hours, Minutes, Seconds TimeStruct.Hours = (pt.substring(12,14)).toInt(); TimeStruct.Minutes = (pt.substring(15,17)).toInt(); TimeStruct.Seconds = (pt.substring(18,20)).toInt(); M5.Rtc.SetTime(&TimeStruct); // rtc setup end ----------------------------------------------- } void loop(void){ if(digitalRead(M5_BUTTON_HOME) == LOW){ if (mode_ == 2){mode_ = 1;M5.Lcd.fillScreen(BLACK);return;} if (mode_ == 1){mode_ = 2;M5.Lcd.fillScreen(BLACK);return;} } if ( mode_ == 2 ){ vfd_2_line();} // yyyy,mm,dd,hh,mm,ss if ( mode_ == 1 ){ vfd_1_line();} // mm,ss delay(500); } void vfd_2_line(){ M5.Rtc.GetTime(&RTC_TimeStruct); M5.Rtc.GetData(&RTC_DateStruct); //Serial.printf("Data: %04d-%02d-%02d\n",RTC_DateStruct.Year,RTC_DateStruct.Month,RTC_DateStruct.Date); //Serial.printf("Week: %d\n",RTC_DateStruct.WeekDay); //Serial.printf("Time: %02d : %02d : %02d\n",RTC_TimeStruct.Hours,RTC_TimeStruct.Minutes,RTC_TimeStruct.Seconds); // Data: 2019-06-06 // Week: 0 // Time: 09 : 55 : 26 int y1 = int(RTC_DateStruct.Year / 1000 ); int y2 = int((RTC_DateStruct.Year - y1*1000 ) / 100 ); int y3 = int((RTC_DateStruct.Year - y1*1000 - y2*100 ) / 10 ); int y4 = int(RTC_DateStruct.Year - y1*1000 - y2*100 - y3*10 ); int j1 = int(RTC_DateStruct.Month / 10); int j2 = int(RTC_DateStruct.Month - j1*10 ); int d1 = int(RTC_DateStruct.Date / 10 ); int d2 = int(RTC_DateStruct.Date - d1*10 ); int h1 = int(RTC_TimeStruct.Hours / 10) ; int h2 = int(RTC_TimeStruct.Hours - h1*10 ); int i1 = int(RTC_TimeStruct.Minutes / 10 ); int i2 = int(RTC_TimeStruct.Minutes - i1*10 ); int s1 = int(RTC_TimeStruct.Seconds / 10 ); int s2 = int(RTC_TimeStruct.Seconds - s1*10 ); M5.Lcd.pushImage( 0, 0,18,34, (uint16_t *)n[y1]); M5.Lcd.pushImage( 19, 0,18,34, (uint16_t *)n[y2]); M5.Lcd.pushImage( 38, 0,18,34, (uint16_t *)n[y3]); M5.Lcd.pushImage( 57, 0,18,34, (uint16_t *)n[y4]); M5.Lcd.drawPixel( 77,13, ORANGE); M5.Lcd.drawPixel( 77,23,ORANGE); M5.Lcd.pushImage( 80, 0,18,34, (uint16_t *)n[j1]); M5.Lcd.pushImage( 99, 0,18,34, (uint16_t *)n[j2]); M5.Lcd.drawPixel(118,13, ORANGE); M5.Lcd.drawPixel(119,23,ORANGE); M5.Lcd.pushImage(120, 0,18,34, (uint16_t *)n[d1]); M5.Lcd.pushImage(140, 0,18,34, (uint16_t *)n[d2]); M5.Lcd.pushImage( 00,40,18,34, (uint16_t *)n[h1]); M5.Lcd.pushImage( 20,40,18,34, (uint16_t *)n[h2]); M5.Lcd.drawPixel( 48,54, ORANGE); M5.Lcd.drawPixel( 48,64,ORANGE); M5.Lcd.pushImage( 60,40,18,34, (uint16_t *)n[i1]); M5.Lcd.pushImage( 80,40,18,34, (uint16_t *)n[i2]); M5.Lcd.drawPixel(108,54, ORANGE); M5.Lcd.drawPixel(108,64,ORANGE); M5.Lcd.pushImage(120,40,18,34, (uint16_t *)n[s1]); M5.Lcd.pushImage(140,40,18,34, (uint16_t *)n[s2]); if ( i1 == 0 && i2 == 0 ){ fade();} } void vfd_1_line(){ M5.Rtc.GetTime(&RTC_TimeStruct); M5.Rtc.GetData(&RTC_DateStruct); int i1 = int(RTC_TimeStruct.Minutes / 10 ); int i2 = int(RTC_TimeStruct.Minutes - i1*10 ); int s1 = int(RTC_TimeStruct.Seconds / 10 ); int s2 = int(RTC_TimeStruct.Seconds - s1*10 ); //M5.Lcd.drawPixel( 48,54, ORANGE); M5.Lcd.drawPixel( 48,64,ORANGE); M5.Lcd.pushImage( 2,6,35,67, (uint16_t *)m[i1]); M5.Lcd.pushImage( 41,6,35,67, (uint16_t *)m[i2]); //M5.Lcd.drawPixel(108,54, ORANGE); M5.Lcd.drawPixel(108,64,ORANGE); M5.Lcd.pushImage( 83,6,35,67, (uint16_t *)m[s1]); M5.Lcd.pushImage(121,6,35,67, (uint16_t *)m[s2]); if ( s1 == 0 && s2 == 0 ){ fade();} } void fade(){ for (int i=7;i<16;i++){M5.Axp.ScreenBreath(i);delay(25);} for (int i=15;i>7;i--){M5.Axp.ScreenBreath(i);delay(25);} M5.Axp.ScreenBreath(12); }
.
M5StickC , VFD , Nixie tube , ニキシー管 , IPS , clock , M5Stack Official Store , Hex File
Please, could you upload or send to me the vfd_18x34.c and vfd_35x67.c files?
Thanks
Carlos Orts
6月 14, 2019 at 3:48 pm
訪問をありがとうございます。
1. nixie tubeのhex変換は 画像データーから「LCD image Converter 」で行ないます。各自で変換してください。
2. 他の nixie tube の画像データーは Virtual nixie tube display: – DHTML component library (Virtual nixie tube (http://cestmir.freeside.sk/projects/dhtml-nixie-display/ ) に有りますので変換してご使用下さい。
3. WordPress は残念ながら vfd_18x34.c と vfd_35x67.c の zip file をアップする事ができません。必要ならば WordPressで zipも扱える様に WordPressに要請してください。
4. 私は Github を使用していません。
以下の2つに「macsbug」と 「https://macsbug.wordpress.com/2019/06/06/m5stickc-nixie-tube-clock/」を記入してください。
Enter “macsbug” and “https://macsbug.wordpress.com/2019/06/06/m5stickc-nixie-tube-clock/” in the following two.
1, McOrts/M5StickC_Nixie_tube_Clock:
https://github.com/McOrts/M5StickC_Nixie_tube_Clock
2, Nixie Tube Watch Simulated on ESP32 Using the M5Stick:
https://www.hackster.io/McOrts/nixie-tube-watch-simulated-on-esp32-using-the-m5stick-7ab9d9
macsbug
6月 15, 2019 at 11:56 am