IV-27M 蛍光表示管を Arduino で動かしてみる。

土曜日に基本の点灯まで行いました IV-27M 蛍光表示管ですが、シフトレジスタにデータ流す順番とかの整理もかねて配線を一部やりなおしました。とりあえずブレッドボードに乗っている部品から下記の回路図を書き出しもしました。

IV-27M CLOCK01

これに、Arduino UNO を接続しまして、シリアルポートから受信した数字を表示するようにプログラムを作成。これは、仕込んでおきたかった機能で、ゴースト確認用に数文字おきに表示とかしたいときなど便利です。
24V ではブランキングタイム入れてない状態でもゴーストほとんど出てないですが、24V の電源をもう少しあげてみたらハッキリ出るかも知れないので、一応ということです。

[vine url=”https://vine.co/v/MxXXwtDiqDg”]

#include <SPI.h>
#include <stdio.h>
#include <string.h>

/* ------------------------------------------------------------
 -- Grobal Variables
 ------------------------------------------------------------ */
unsigned int msCount = 0;
boolean msCountOVF;
unsigned char vfdDigit = 0;
unsigned char vfdSeg[14];
unsigned char vfdDot[14];
char str01[20];

String inputString = "";     // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete


/* ------------------------------------------------------------
 -- Interrupt hundler (every 0.5ms)
 ------------------------------------------------------------ */
ISR(TIMER2_COMPA_vect) {

  sendVfd();
  msCount++;
  if(msCount >= 2000) {  // 1seconds 
    msCount = 0;
    msCountOVF = true;
  }
  // Reset interrupt flag and counter.
  TIFR2 &= ~(1<<OCF2A);
}

/* ------------------------------------------------------------
 -- Initial Setup
 ------------------------------------------------------------ */
void setup() {

  pinMode(4, OUTPUT);  // SCLR
  pinMode(5, OUTPUT);  // RCK

  // initialize SPI
  SPI.begin();
  SPI.setClockDivider(SPI_CLOCK_DIV2);
  SPI.setDataMode(SPI_MODE0);
  SPI.setBitOrder(MSBFIRST);

  //
  Serial.begin(9600);

  // Setup TIMER2
  // a. Disable the Timer/Counter2 interrupts by clearing OCIE2x and TOIE2.
  // b. Select clock source by setting AS2 as appropriate.
  // c. Write new values to TCNT2, OCR2x, and TCCR2x.
  // d. To switch to asynchronous operation: Wait for TCN2xUB, OCR2xUB, and TCR2xUB.
  // e. Clear the Timer/Counter2 Interrupt Flags.
  // f. Enable interrupts, if needed.

  // TIMSK2 2=OCIE2B 1=OCIE2A 0=TOIE2
  // Disable interrupt enable
  TIMSK2 &= ~(1<<OCIE2B);
  TIMSK2 &= ~(1<<OCIE2A);
  TIMSK2 &= ~(1<<TOIE2);
  // ASSR – Asynchronous Status Register
  // 6=EXCLK 5=AS2 4=TCN2UB 3=OCR2AUB 2=OCR2BUB 1=TCR2AUB 0=TCR2BUB  
  // AS2=0 CLKIO,  AS2=1 TOSC1
  ASSR &= ~(1<<AS2);
  // Waveform Generation Mode set to NORMAL mode WGM22,21,20=0
  TCCR2A &= ~(1<<WGM20);
  TCCR2A |= (1<<WGM21);
  TCCR2B &= ~(1<<WGM22);
  // TCCR2B – Timer/Counter Control Register B
  // 7=FOC2A 6=FOC2B 3=WGM22 2=CS22 1=CS21 0=CS20
  // CS22 CS21 CS20 Description
  // 0    0    0    No clock source (Timer/Counter stopped).
  // 0    0    1    clkT2S/(No prescaling)
  // 0    1    0    clkT2S/8 (From prescaler)
  // 0    1    1    clkT2S/32 (From prescaler)
  // 1    0    0    clkT2S/64 (From prescaler)
  // 1    0    1    clkT2S/128 (From prescaler)
  // 1    1    0    clkT2S/256 (From prescaler)
  // 1    1    1    clkT2S/1024 (From prescaler)
  TCCR2B |= (1<<CS22);
  TCCR2B &= ~(1<<CS21);
  TCCR2B &= ~(1<<CS20);
  TCNT2 = 0;
  OCR2A = 124; // 16MHz / 64 = 4us. 4us * 125 = 0.5ms
  // Clear interrupt flag
  // TIFR2 – Timer/Counter2 Interrupt Flag Register
  // 2=OCF2B 1=OCF2A 0=TOV2
  TIFR2 &= ~(1<<OCF2A);
  // TIMSK2 2=OCIE2B 1=OCIE2A 0=TOIE2
  // Enable interrupt
  TIMSK2 |= (1<<OCIE2A);
}

/* ------------------------------------------------------------
 -- Main loop
 ------------------------------------------------------------ */
void loop() {

  int i;
  int charLen;
  // serial input done
  // 9600 bps
  // help&#91;RET&#93; -> print help message
  // HH MM SS[RET] -> set time
  //
  if (stringComplete == true) {
    //Serial.println(inputString); 
    if(inputString.equals("help\r")) {
      Serial.println("help: I'm alive");
    } 
    else {
      for(i = 0; i < 14; i++) {
        vfdSeg&#91;i&#93; = 0;
        str01&#91;i&#93; = 0;
      }
      charLen = inputString.length();
      if(charLen > 15) {
        charLen = 15;
      }
      inputString.toCharArray(str01, charLen);
      for(i = 0; i < 14; i++) {
        convVfdSeg(i);
      }
    }
    inputString = "";
    stringComplete = false;
  }

}

/* ------------------------------------------------------------
 -- sendVfd
 ------------------------------------------------------------ */
void sendVfd() {

  unsigned int vfdBit;
  unsigned char vfdBitH;
  unsigned char vfdBitL;

  // HC595 SCLR(negedge: shift register clear)
  digitalWrite(4,LOW);
  digitalWrite(4,HIGH);  

  // HC595 RCK (posedge: data latch)
  digitalWrite(5,LOW);
  digitalWrite(5,HIGH);

  // send to shift register
  vfdBit = (1 << vfdDigit);
  vfdBitL = vfdBit & 0x00FF;
  vfdBitH = (vfdBit >> 8);
  //if(vfdDot[vfdDigit] != 0) {
  //  digit |= 0x80;
  // }

  SPI.transfer(vfdBitH);
  SPI.transfer(vfdBitL);
  SPI.transfer(vfdSeg[vfdDigit]);  


  // HC595 RCK (posedge: data latch)
  digitalWrite(5,LOW);
  digitalWrite(5,HIGH);  

  vfdDigit++;
  if(vfdDigit > 13) {
    vfdDigit = 0;
  }
}

/* ------------------------------------------------------------
 -- sendVfd
 ------------------------------------------------------------ */
void convVfdSeg(int digit) {

  switch(str01[digit]) {
  case '0': 
    vfdSeg[digit] = 0xFC; 
    break;
  case '1': 
    vfdSeg[digit] = 0x60; 
    break;
  case '2': 
    vfdSeg[digit] = 0xda; 
    break;
  case '3': 
    vfdSeg[digit] = 0xf2; 
    break;
  case '4': 
    vfdSeg[digit] = 0x66; 
    break;
  case '5': 
    vfdSeg[digit] = 0xb6; 
    break;
  case '6': 
    vfdSeg[digit] = 0xbe; 
    break;
  case '7': 
    vfdSeg[digit] = 0xe0; 
    break;
  case '8': 
    vfdSeg[digit] = 0xfe; 
    break;
  case '9': 
    vfdSeg[digit] = 0xe6; 
    break;
  case '-': 
    vfdSeg[digit] = 0x02; 
    break;
  }
}


/*
  SerialEvent occurs whenever a new data comes in the
 hardware serial RX.  This routine is run between each
 time loop() runs, so using delay inside loop can delay
 response.  Multiple bytes of data may be available.
 */
void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read(); 
    // add it to the inputString:
    inputString += inChar;
    Serial.write(inChar);
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\r') {
      stringComplete = true;
      Serial.write('\r');
      Serial.write('\n');
    } 
  }
}

NE555P が出てきたので Lチカ (LEDチカチカ)

IMG_0205

午前中は蛍光表示管のテストをしていましたが、午後は片付けをしていました。が、片付けしているときに NE555P を発見。とりあえず L チカしましょ。10k や 4.7k など手持ちの部品で作りましたのできちんと 1 秒にはなっていませんがだいたい1秒ちょいで点滅したようです。よかった。

2014-07-12 17.29.16

回路は後からメモったものです。

[vine url=”https://vine.co/v/MxOvPpOj0XX”]

IV-27M 蛍光表示管点灯試験

2014-07-12 11.54.16

土曜日、朝からお昼までのワークで点灯試験というか基本回路の確認まできたところの状態。朝一は、あるていどちゃんと配線したほうがいいよなーと思いつつ作業初めましたが、途中でブチギレ。結局スパゲティになっちゃいました(笑)

2014-07-12 08.36.55

作業開始直後の切れる前に IV-27M 蛍光表示管のリード線をはんだ付け。ブレッドボードからジャンプワイヤ刺せるようにしておきました。

そのあと、ブレッドボードに 74HC595 のシフトレジスタと、TD62783 のソースドライバを配線して蛍光表示管と接続します。CPU は Arduino UNO です。以前作成した LD8113 蛍光表示管キットのテスト用に組んだ簡単な Arduino スケッチがあるのでを流用して 6 桁から 14 桁まで増やす修正入れて書き込み。最後にブレッドボードに組んだシフトレジスタと接続して完成でございます。

点灯させてみた感じは、14桁ダイナミック点灯したわりには明るさあったのがラッキー。ヒーター直流点灯も左右で極端に明るさ違ういうこともないのでラッキー。Aruduino UNO の USB 給電でも問題なく動いているので消費電力も低めかな。というのもラッキーなところです。
気になる点が減ったので、よかったです。数少ないけど頒布品にしましょうかねぇ。

Digilent NEXYS3 で HDMI 出力

2014-07-06 11.17.46

この土日は散歩しに行こうと思いつつも、土曜日の朝、「積み基板で遊ぼう」と思いついたのが優先事項になってしまいまして NEXYS3 SPARTAN-6 LX16 ボードをひっぱり出す。Xilinx のサイトにある、XAPP495(Implementing a TMDS Video Interface in the Spartan-6 FPGA) をダウンロードして作業開始。

この XAPP495 の対象ボードは Digilent の ATLYS という SPARTAN-6 LX45 搭載のボードが対象です。私の積み基板のより規模の大きいのが載ってまして HDMI コネクタもオンボードで付いてます。私のには HDMI コネクタが付いていないので、この NEXYS 3 基板買ったときに追加の小さいボードも買いました。これにマイクロなHDMI コネクタが4つとpmodコネクタ3つ付いてます。

今回はカラーバー出れば満足なので、Planahead 14.7 で新規プロジェクトを作成しサンプルのソースから vtc_demo.v をトップモジュールにして ucf ファイル書き換えてシンセサイズとインプリして、書き込みしたら OK なはずでした。
が、ioclock が配線出来ませんと言われ土曜日の午前中はあきらめて一旦終了。

こういうときは UCF ファイルが悪いのが相場なので、オリジナル ATLYS 基板用の UCF でビルドしてワーニングとかは出るもののインプリメント出来るのを確認。結局のところ 100MHz のクロック入力が、 ATLYS は BANK1 のポート、NEXYS3 は BANK2 のポートですが、この UCF のピン番号を替えたらエラーの山でした。

モジュールの内部は 50MHz で動いているので、100MHz のクロックを50MHz にしているところがあります。ここらへんを書き換えたら動くのではないかと修正開始。

  IBUF sysclk_buf (.I(SYS_CLK), .O(sysclk));
  BUFIO2 #(.DIVIDE_BYPASS("FALSE"), .DIVIDE(2))
  sysclk_div (.DIVCLK(clk50m), .IOCLK(), .SERDESSTROBE(), .I(sysclk));
 BUFG clk50m_bufgbufg (.I(clk50m), .O(clk50m_bufg));

もとのソースは クロック入力ピンを IBUF で受けて、それを BUFIO2 で分周。50MHz 出力を BUFG でグローバルなクロック配線に載せるいうことをやっています。これの入力のピン位置がかわるだけで、インプリ出来んのはバグちゃう?と思いたくなりますが、仕方ありません。

  • DCM で 50MHZ を作ってそれを使うように修正してみたところ、「タイミング守れません」でアウト。FPGA EDITOR でDCM変更でなとかなるかもしれませんが、なんとかするスキルはありません(笑)
  • 仕方ないので always で分周する方法を。遅延なしにちゃんと分周出来る保証はありませんが簡単なのでやってみたら動きだした

という次第。居間にあるハーフパネルの液晶テレビ(家に HDMI 入力あるのはこれだけで PC は DVI なので変換が必要)に接続してみて、表示されるか確認。「信号がありません」とは言われませんでした。表示サイズがあわないかしておかしい表示になっていますが一つ進んだかな。

IV-27 (ИВ-27) VFD (蛍光表示管) のピンアサインを調べた

2014-06-28 14.59.55-1

ピンアサインがわからないと使えませんので仕方なく調査開始。ブレッドボードに MC34063A を使用した 5V から 24V に昇圧するコンバーターと、パーツボックスに1個だけあった 3.3V 三端子レギュレータを配線して電源まわり完成でございます。

蛍光表示管はカソード(ヒーター)さえわかれば、ピンアサインを調べるのはなんとかなります。そしてヒーターは電線が繋っているのでテスターであたればわかります。それ以外がアノードとグリッドです(笑)
で調べた結果は以下のとおり。見直ししていないので保証はありません。すいません。

IV-27_pinAssign2

一覧に、IV-27M と IV-27 を載せてます。M サフィックスなしが古いやつです。IV-27M は比較的リード線の状態もマシなので不良はなさそうですが、届いた荷物に数個混ってた IV-27 は胡散臭い感じします。そしてピンアサインも違うので困ったものです。つか前回の記事にあげたデータシートと全然違ったので、あわてて前の記事から表消すなども困ったことです。さらに、ピンアサイン調査で既に2個不良発見というエゲツナイ状態。↓の写真のように半分しか表示されないとか、点灯しないとかです。
ヒーター電圧の確認は、電池で3V かけてみて赤くならず、電池一本追加で赤くなりました。データシートには 3.15V と 5.15V があったのですが。3Vのほうが正解だったようです。

2014-06-28 12.53.20-1

問題の無い管はヒーター以外に全部電圧かけてあげれば全部光ます。

2014-06-28 15.00.07-2

とりあえず、ピンアサインはだいたいわかったんでよしとしましょう。

IV-27 (ИВ-27) VFD (蛍光表示管) が届いた

2014-06-25 19.53.34

IV-27 ロシア製蛍光表示管が届きました。記号1桁数字13桁の合計14桁ある表示管です。買ったのはちょっとだけです。こんどの休みにヒーター電圧の確認はしておきたいなーと思うところです。この VFD より短かい IV-21 という 8桁やつはキットで売られてるのも見たことがあるのですが、この VFD って透き通っているというイメージがありました。届いた物の中(いちばん向こう側)は、古いのかして透き通ってないやつも混じっていました。これは別に取っておこうかしらと思うところ。

いつぞやの休みのときにロシア語のデータシートから写してみたものですが、キリル文字ローマ時変換で、現在使われていない文字とがたくさん出てきてたいへん苦労しました。セグメントなどは7セグ準拠におきかえています。空欄は翻訳出来ずに現物見ないとわかりせん状態であけてあります。
とにかくヒーター電圧の確認からですね。3.15V と書いているものと 5.15V と書いてあるデータシートがあるためです。ダイナミック点灯などうまくいけば、頒布品に加えられるかも知れませんがまだ先になりそうです。

事前に調べたピンアサインが全然違ったため画像は削除しました(2014.06.28)

LUFA ライブラリの USB Serial 変換が Strawberry Linux の Da Vinch(ATmega32U4) で動くかやってみた

2014-06-22 09.16.19

AT90USB シリーズや ATmega の USB インタフェース付きマイコンで、USB を使いやすくするライブラリが LUFA プロジェクト にて公開されています。とりあえず USB シリアルのコードが動くかやってみたくなったので Strawberry Linux さんとこのダ・ヴィンチボードを 1 個出してきてピンヘッダもはんだ付けして、FLIP から L チカのプログラムを書き込んで動くのを確認したところ。が上の写真。

Atmel Studio 6.2 を起動して、Extentension Manager や、Atmel ギャラリーなどから LUFA を入れます。クリックすれば入るのであんまり説明するところがありません。

スクリーンショット 2014-06-22 11.12.46

Atmel Studio 6.2 を起動しなおしてから、[File] -> [New] -> [Example Project] を選択。上のハードコピーのようなサンプル選択画面になるので、USB – シリアル変換を選択して、プロジェクトというか今はソリューションでしたかね。を作成します

スクリーンショット 2014-06-22 11.22.18

プロジェクトのディレクトリが作成されてプログラム出来るようになりますが、サンプルプロジェクトのプロパティを見ますと AT90USB1287 を使用するようになっています。今回使うのは ATmega32U4 なので [Change Deivce] ボタンを押して ATmega32u4 に修正します。いろいろ確認のダイアログが出ますが OK で続行

スクリーンショット 2014-06-22 11.23.06

無事ターゲットプロセッサの修正は出来ましたがまだやることがあります。サンプルプロジェクトは、AT90USBKEY というボードを使用するようになっているため、この情報も修正しなければいけません。

スクリーンショット 2014-06-22 11.23.38

[ASF] -> [ASF Wizard] を起動すると上記のような画面が表示されます。ここで右側ペインの中にあるリストボックスが USBKEY になっているのを LEONARD にします。実際に使用するボードはダ・ヴィンチボードですが、そんなもんは定義されていないので、構成が近い Arduino Leonard を使わせてもらう意味での選択です。今回は LED とかは別に点かなくてもいいので適当です。

スクリーンショット 2014-06-22 11.24.41

次はプロジェクトをビルドする時の指定を変更します。

  • F_CPU=8000000UL と F_USB=8000000UL は 8MHz クロックの指定ですが 16MHz なので 16000000UL に修正
  • BOARD= のボード指定は BOARD=BOARD_LEONARDO だけにする

スクリーンショット 2014-06-22 11.28.25

あとはビルドして、マイコンに書き込んだら USB シリアル変換の完成です。問題なく認識すると LUFA USB to Serial(COMnn) というシリアルポートがデバイスマネージャに出ると思います。ドライバの読み込みに失敗した場合は .inf ファイルがAtmel Studio のプロジェクトディレクトリにあるので、それを使ってドライバの更新して下さい。

2014-06-22 11.57.23

どうやってテストするか考えるのが面倒だったので、ATmega32U4 の TXD/RXD をそのまま接続してループバックさせることにしました。

スクリーンショット 2014-06-22 11.59.37

TeraTerm で LUFA の COMポートをオープンして

スクリーンショット 2014-06-22 12.01.19

文字をキーボードから打ち込みまして、それがマイコンから帰ってきまして無事表示されました。

動いてよかったー

MAX1771 スイッチング電源案もう少し考えてみる

MAX1771SMPS_01

これ以上 MAX1771 にかかわるのは止めておこうと思いつつも何故か意地になって回路図案を引いてみる次第。こないだ作ったユニバーサル基板は頭の中で考えたままを作っただけですが、一応メモとして残しておこうと… ちなみに、この回路図は案なのでマネしても動く保証はありません。注意下さい。

データシートの非ブートストラップモード回路例には、フィードバック電圧の分圧抵抗(上側)に 100p のコンデンサ抱かせているけど付けなくてもいいかな。というのとインダクタの容量ですなぁ。回路図では仮で 100uH と書いてますが巻線抵抗考えると 47uH あたりがいいかなぁとも。FET の選別も必要。FET は TO-220 でいくとしてインダクタはテスト用に 700mil 幅でスルーホールと面実装用のパターンをいっしょくたにした配線パターンにしてみましょうか。

  • 真空管とかに使う(250V 以上欲しい)のなら、インダクタの入力は 24V にして三端子レギュレータで MAX1771 用の 12V 電源作成して動かす(今回は実装しません)
  • シャットダウン端子は使えるように端子は出す
  • スイッチング FET は TO-220 で放熱器を付けられるレイアウトを考慮
  • 電流センス用抵抗は面実装パーツにしてMAX1771のCS端子との距離を出来るだけ短かくする
  • 電源入力からインダクタまでの配線方法

考えはじめるとキリがないのでこのへんにしておこう… 部品選びもしよう…

ブレッドボードでニキシー管用 DC/DC 電源をちょっといじってみる

2014-06-01 16.50.40

先々週くらいに、MC34063A の定番回路(頒布品の回路にも使ってます)をブレッドボードに組んで、インダクタの容量変えてみたり、タイミングコンデンサの容量変えてみたりしながら、ブレッドボードで組んでも 2.5W くらいはいけますかなぁ。というところまでは確認してたりしてます。実際には頒布品の巻線見えるインダクタをケース入りに変更したいなぁ。というやつでちょっと確認していた次第。

2014-06-09 21.06.24

実験ついでなので、通販で MAX1771 と 22uH,47uH のインダクタを買いましてこいつもブレッドボードに組んでみました。さすがに高能率な石は違います。(インダクタの巻線抵抗も低いやつ使ってたりしてますが) 200V で、5KΩ の負荷。8W は出てます。
IC の 1.5V フィードッバック入力のところは非常に敏感で、データシートにもプリント基板のレイアウトはちゃんとしなさいとあります。ここにコンデンサ入れて電圧安定させるのはいけないのです。が、ブレッドボードでの実験ゆえコンデンサ無い状態だと、どうしても電圧安定しなかったので入れてズルしています。

この石使った電源ユニットは、うちとこの小出力真空管アンプの電源に入っていたりしてますし、別の方の電源ユニット頒布品でもありまして、どちらも 24W 出せる電源です。ちゃんと作ればスゴイですね。私の作る頒布物には使用することのない IC やと思いますが、もうしばらく勉強がてらいじってみようかなと思います。

6C33C-B シングルアンプのリップルフィルター温度測定

2014-06-07 11.33.11

このアンプを使っていて、出力管 6C33C-B の近くにあるリップルフィルターは大丈夫なんやろか?という疑問を解かないまま結構時間が経過してしまいました。とにかく測ってみようということで、スイッチサイエンスさんにあった「K型熱電対温度センサモジュールキット(SPI接続)MAX31855使用 5V版」というのを通販で購入。このモジュールは、5V と 3.3V 動作のがありますが、MAX31855 の動作電圧に 3.3V にするレギュレータの有無が違いだけのようです。

2014-06-07 13.25.05

Arduino UNO にサンプルスケッチを書き込みしまして、温度が読み出せるか動作確認しました。これは問題なし。プログラムの中をいろいろコメントアウトして温度だけ printf するようにして、ニキシー管 8 桁表示ユニットに接続して温度が表示出来るか確認。これも OK。
2014-06-07 19.53.29

スイッチサイエンス通販で届いたモジュールには熱電対は付属しているのですが、ちょっと太めでしたので別の熱電対を使用します。今回は熱電対の先っぽを、アンプ内 6C33C 用リップルフィルターのヒートシンクと FET を固定するクリップ(バネ)の間に入れてみました。FETの発熱に近いところではありますがクリップなどは金属なので放熱もしてしまいます。なのでシャーシ内の温度よりちょい高めの温度が記録される程度かなぁ。という感じです。

2014-06-07 21.42.38

で、無風状態のままアンプの電源を投入しまして、適当に選んだ CD を聞きつつ、用事しつつで、温度をメモ。

rippleFilterTemp_20140607

グラフの途切れは洗い物かなんかで欠測しました。結果からいきますと室温25℃の場合シャーシ内65℃くらいで温度上昇は鈍くなりました。22時以降温度が下がったのはエアコン投入と、5V USB パワーで動く小型扇風機をアンプの下に置いて空気を動かしたときです。ちょっとでも空気動いているほうがシャーシの放熱効果があがるので、こういう結果になったのかなぁと思いました。