/****************************************** "VF1904B_i2cslave.ino" VFD単管時計 VF1904(DG12H1x4) の制御プログラム 動作概要: - SW1 1秒カウント - SW2 0.1秒カウント - SW3 0.01秒カウント control board:VF1904B CPU : ATmega328P-AU/16MHz (Arduino Uno compatible) pins PD1(1) SIB PB5(13) CLK PC0(A0) STB PC1(A1) BLK PB1(9/PWM) 電源用モータードライバ入力 PB0(8) VFD電源供給sw(IC1にNORを使用した場合に適用、通常はなし?) PD5(5) SW1 PD6(6) SW2 PD7(7) SW3 PC4(A4/SDA) SDA PC5(A5/SCL) SCL 2019/04/30 vfd-fun@post.nifty.jp *******************************************/ #include #include #define dg_pwm 9 //電源モータードライバ入力 #define dg_psw 8 //VFD電源供給sw(IC1にNORを使用した場合に適用) #define dg_sib 1 //SIB(VF1904) #define dg_clk 13 //CLK #define dg_stb A0 //STB #define dg_blk A1 //BLK #define sw1 5 //SW1 #define sw2 6 //SW2 #define sw3 7 //SW3 #define sda A4 // PC4 #define scl A5 // PC5 void dg_putnum_dec4(int n); //DG_1byte書き込み(latchなし) void dg_putnum_base4(unsigned int n); //DG_1byte書き込み(latchなし) void dg_put(byte onebyte); //DG_1byte書き込み(latchなし) void dg_latch(); //DG_data latch void dg_putnum(int putnum); //DG_数字1桁書き込み(Dp表示無の数字) // 1024 / 5 = 204 frames (wait, p0, p1, p2, p3)* #define WAIT_END 255 #define WAIT_RESTART 0 int playframe = -1; int currentframe = -1; #define ADR_I2C_SLAVE 8 void dg_on(int flg) { analogWrite(dg_pwm, flg ? 127 : 0); //50%(31kHz) // control ON/OFF if (!flg) { for (int i = 0; i < 4; i++) dg_put(0); dg_latch(); } } void onReceiveEvent(int len) { if (len == 0) { dg_on(0); currentframe = -1; } else if (len == 1) { while (!Wire.available()); int n = Wire.read(); dg_on(n); playframe = currentframe = n; } else if (len == 2) { dg_on(1); currentframe = -1; int n = 0; for (int i = 0; i < len; i++) { while (!Wire.available()); int m = Wire.read() & 0xff; n |= m << (i * 8); } dg_putnum_dec4(n); } else if (len == 3) { dg_on(1); currentframe = -1; while (!Wire.available()); int base = Wire.read(); if (base >= 16) { base = 16; } else if (base < 2) { base = 2; } while (!Wire.available()); unsigned int n = Wire.read(); while (!Wire.available()); n |= (unsigned int)Wire.read() << 8; dg_putnum_base4(n, base); } else if (len == 4) { dg_on(1); currentframe = -1; byte d[4]; for (int i = 0; i < len; i++) { while (!Wire.available()); d[i] = Wire.read(); } for (int i = 0; i < len; i++) { dg_put(d[len - i - 1]); } dg_latch(); } else if (len == 6) { byte d[6]; for (int i = 0; i < len; i++) { while (!Wire.available()); d[i] = Wire.read(); } int address = d[0] * 5; EEPROM.write(address++, d[1]); // wait or command for (int i = 3; i >= 0; i--) { EEPROM.write(address++, d[i + 2]); } } else { Wire.endTransmission(); // 効かない? } } void setup() { pinMode(sw1, INPUT_PULLUP); pinMode(sw2, INPUT_PULLUP); pinMode(sw3, INPUT_PULLUP); pinMode(dg_sib, OUTPUT); pinMode(dg_clk, OUTPUT); pinMode(dg_stb, OUTPUT); pinMode(dg_blk, OUTPUT); digitalWrite(dg_blk, LOW); //pinMode(dg_psw, OUTPUT); //IC1にNORを使用した場合に対応(通常はなくてok?) //digitalWrite(dg_psw, LOW); // 電源モータドライバ入力 TCCR1B &= B11111000; TCCR1B |= B00000001; //pin9,10/PWM分周比1(=31.37kHz) dg_on(0); // Serial // Serial.begin(115200); // Serial.print("initialized\n"); // I2C Wire.begin(ADR_I2C_SLAVE); //pinMode(SDA, INPUT); // 内部プルアップ無効 //pinMode(SCL, INPUT); // 内部プルアップ無効 Wire.onReceive(onReceiveEvent); // masterからの受信要求 // Wire.onRequest(onRequestEVent); // masterからの送信要求 int p = 0; EEPROM.write(p++, 10); for (int i = 0; i < 4; i++) EEPROM.write(p++, 0x20); EEPROM.write(p++, 10); for (int i = 0; i < 4; i++) EEPROM.write(p++, 0x40); playframe = currentframe = 0; /* dg_on(1); dg_putnum_dec4(playframe); delay(500); */ /* for (int i = 0; i < 10; i++) { int n = EEPROM.read(i); dg_putnum_dec4(i); delay(500); dg_putnum_dec4(n); delay(500); } */ /* // opening dg_on(1); dg_put(0x20); dg_put(0); dg_put(0); dg_put(0); dg_latch(); delay(100); dg_on(0); */ /* delay(300); // dg_putnum_dec4(0); dg_on(1); for (int i = 0; i < 7; i++) { for (int j = 0; j < 4; j++) { dg_put(i == j || i == 6 ? 0x20 : 0); } dg_latch(); delay(i < 5 ? 100 : 300); } dg_on(0); */ } void dg_putnum_dec4(int n) { int beam = 0; for (int i = 0; i < 4; i++) { dg_putnum(n % 10); beam++; n /= 10; if (!n) break; } for (int i = beam; i < 4; i++) { dg_putnum(-1); } dg_latch(); } void dg_putnum_base4(unsigned int n, int base) { for (int i = 0; i < 4; i++) { dg_putnum(n % base); n /= base; } dg_latch(); } int dg_playEEPROM() { if (currentframe < 0 || currentframe >= 200) return 0; int address = currentframe * 5; int w = EEPROM.read(address++); if (w == 255) { playframe = currentframe = -1; dg_on(0); return 0; } dg_on(1); //dg_putnum_dec4(w); if (w == 0) { currentframe = playframe; address = currentframe * 5; w = EEPROM.read(address++); } for (int i = 0; i < 4; i++) { byte b = EEPROM.read(address++); dg_put(b); } dg_latch(); currentframe++; return w; } void loop() { int wait = 10; int w = dg_playEEPROM(); if (w) wait = w * 50; delay(wait); } void dg_put(byte onebyte) { shiftOut(dg_sib, dg_clk, MSBFIRST, onebyte); } void dg_latch() { digitalWrite(dg_stb, HIGH); digitalWrite(dg_stb, LOW); } static const byte PATTERN_NUM[] = { 0xd7, 0x50, 0xcb, 0xd9, 0x5c, 0x9d, 0x9f, 0xd4, 0xdf, 0xdd, // 0-9 0xde, 31, 135, 91, 143, 142 // a-f }; void dg_putnum(int putnum) { if (putnum < 0 || putnum > 16) dg_put(0); else dg_put(PATTERN_NUM[putnum]); }