Hallo Liebe Ardujaner,
hier eine kleine Projektvorstellung. Ich habe endlich nach langem meine Nixie-Clock fertig.
Im Anhang ein kleines Bild.
Folgende Komponenten:
-4* Nixie Röhren Z573M
-4*Nixie Driver K155ID1 (russische SN74141)
-2 Schieberegister 74HC595
-Attiny 84 (Clock int.)
-RTC DS1307 via I2C
-Nixie Power Supply von Taylor Electronics Bad insert location redirector
Die alles läuft hervorragen mit dem Attiny84. Ich musste die TinyWire Lib anpassen auf den Attiny84 und dann lief auch diese Problemlos mit dem I2C Bus. PullUp-Widerstände sind zwingend erforderlich, da diese nicht wie bei den Atmegas bei Benutzung der I2C intern aktiviert werden. Die RTC ist Batterie gepuffert. Ich habe extra eine 32.768kHz Crystal genommen mit einer Kapazität von 6pF da diese empfohlen ist von den Herstellern auf einer anderen Uhr habe ich diese erfolgreich im Einsatz d.h.8Wochen 1min zu langsam.
Hier noch der Code der Schaltplan kommt später
/*
Attiny84 Big 7 Segment Uhr mit 74HC595
*/
#include <TinyWireM.h>
#include <USI_TWI_Master.h>
#define Shiftdata 8 // Pin 8 Datenleiung Schieberegister connected to Data in (DS) of 74HC595
#define Shiftclock 10 // Pin 9 Clockleitung connected to clock pin (SH_CP) of 74HC595
#define Shiftlatch 9 // Pin 10 Latchleitung connected to latch pin (ST_CP) of 74HC595
#define PWMOUT 7
#define BUTTON 1
#define RTCPuls 2
#define LDR 3
#define RTC_ADDRESS 0x68
#define TIME 750
byte ie,iz,hz,he,mz,me=0; // Modulespeicher der stunden Minuten
boolean ldruck,druck=false; // Stellknopf für Zeit
boolean longpress,shortpress=false; // Unterscheidung langer kurzer druck
boolean blinktakt=false; // Blinktakt 500ms
boolean lpuls,puls=false; // Sekundenpuls
boolean hell=false;
unsigned long lmillis,start,ptime=0;
byte ss=0;
byte mm=0;
byte hh=0;
byte minuten,stunden=0;
byte setmode=0;
byte PWMArray[7]={
4,20,50,100,150,255};
byte Pointer=4;
byte SDec2Shift(byte x){
byte xeiner=x%10;
byte xzehner=(x-xeiner)/10;
return (xzehner<<4)+xeiner;
;
}
void setup(){
pinMode(Shiftdata,OUTPUT);
pinMode(Shiftclock,OUTPUT);
pinMode(Shiftlatch,OUTPUT);
pinMode(BUTTON,INPUT_PULLUP);
pinMode(RTCPuls,INPUT);
pinMode(PWMOUT,OUTPUT);
TinyWireM.begin(); // Start I2C Kommunikation
TinyWireM.beginTransmission(0x68); // Beginn Kommunikation auf Adresse 0x68
TinyWireM.send(0x07); // Pointer auf Control Register 0x07
TinyWireM.send(0x10); // Steuerwort Ex "0x30" Bin110000 Ausgang RTC Ausgang auf 1Hz Logic normal Levels setzn
TinyWireM.endTransmission(); // Beenden der I2C Kommunitkation
HourRead(); // RTC Funktion lesen der aktuellen zeit Stunden
MinuteRead(); // RTC Funktion lesen der aktuellen zeit Minuten
RTC_Start(); // Start der Uhr
}
void loop(){
/*=>Routine OneButton Control<=*/
druck=digitalRead(BUTTON); // Einlesen des Button (Achtung invertierte Logik da intrener Pull Up Widerstand aktiviert)
if (druck==false&&ldruck==true){ // Steigende Flanke des Button
start=millis(); // Startzeit des Bettätigen
ldruck=false; // Hilfsflag zur Flanken erkennung
}
if (druck==true&&ldruck==false){ // Falende Flanke des Buttons
ptime=millis()-start; // Die Länge in ms des Gedückten Zustandes
ldruck=true;
}
if (ptime>=TIME){ // Wenn der Druck länger (Hier750ms)
longpress=true; // War ein Langer druck
ptime=0; // Zeit wieder Zurücksetzten
}
if (ptime<TIME&&ptime>=50) { // Wenn der Druck kürzer 750ms und länger 50ms (gegen prellen)
shortpress=true; // War ein kurzer Durck
ptime=0; // Zeit wieder zurücksetzuten
}
/*One Button End*/
puls=digitalRead(RTCPuls); // Einlessen des RTC Sekunden Puls
if (puls==true&&lpuls==false){ // wenn Sekundenpuls da und vorher nicht da war (steigende Flanke)
lpuls=true;
ss++; // intern Sekunden zählen
}
if (ss>=60&&setmode==0){ // Nach 60 Sekunden
HourRead(); // RTC Funktion lesen der aktuellen zeit Stunden
MinuteRead(); // RTC Funktion lesen der aktuellen zeit Minuten
ss=0; // Rücksetzzeten internen Sekunden Zähler auf 0
}
if (puls==false){ // RTC Sekunden Hilfspuls
lpuls=false;
}
if (shortpress==true){ // Routine Kurzes drücken
if (setmode==0){ // In Normalmodus
Pointer++; // ändern des Pointer der Helligkeit
if (Pointer>=6){ // Bei Pointer 6 und größer auf Pointer Null
Pointer=0;
}
}
if (setmode==1){ // Minuten stellen
mm++;
if (mm>=60){
mm=0;
}
}
if (setmode==2){ // Stunden stellen
hh++;
if(hh>=24){
hh=0;
}
}
shortpress=false;
}
if (longpress==true){ // Routine Langes drücken
setmode++; // Stellmodus erhöhen
if (setmode==3){ // Bei erreichen des Modus 3
RTC_Set(); // Neue Uhrzeit übernehmen in die RTC
RTC_Start(); // RTC Starten
setmode=0; // Rücksetzten des Setmodes auf 0 (Normale Anzeige)
}
longpress=false; // Rücksetzten des Flags Langes Drücken
}
if (millis()-lmillis>=500){ // Aktalisiernung alle halbe Sekunden
blinktakt= !blinktakt; // Blinktakt der Stellen anzeige
minuten=SDec2Shift(mm);
stunden=SDec2Shift(hh);
if (blinktakt==false){ // Blinkroutine des Stellmodus
if(setmode==1){ // Minuten stellen
me=0;
mz=0;
}
if (setmode==2){ // Stunden Stellen
he=0;
hz=0;
}
}
digitalWrite(Shiftlatch, LOW); // Latch aussetzten um in den Storage speicher zu schreiben
shiftOut(Shiftdata, Shiftclock, MSBFIRST, stunden); // Shift out der einzelenen Puffer wobei im letzten
shiftOut(Shiftdata, Shiftclock, MSBFIRST, minuten); // Shift out der einzelenen Puffer wobei im letzten
digitalWrite(Shiftlatch, HIGH); // Aktiverien des Latches (Schieben des Shift ind Storageregister) zum Anzeigen
lmillis=millis();
}
if (hh==22&&hell==true){ // wenn Später 22Uhr und Früher als 8Uhr und es vorher Hell war dann dunkelschlaten
Pointer=0;
hell=false;
}
if (hh==10&&hell==false){ // Wenn vor 22Uhr und nach 8 Uhr und vorher dunkel war dann Hell Schalten
Pointer=5;
hell=true;
}
analogWrite(PWMOUT,PWMArray[Pointer]);
}
byte Dec2Shift(byte x){
byte shiftdata[11]={
63,6,91,79,102,109,125,7,127,111 };
return shiftdata[x];
}
void HourRead(){
TinyWireM.beginTransmission(RTC_ADDRESS);
TinyWireM.send(0x02); // Pointer auf Sekunden
TinyWireM.endTransmission();
TinyWireM.requestFrom(RTC_ADDRESS, 1);
hh= bcdToDec(TinyWireM.receive());
}
void MinuteRead(){
TinyWireM.beginTransmission(RTC_ADDRESS);
TinyWireM.send(0x01); // Pointer auf Sekunden
TinyWireM.endTransmission();
TinyWireM.requestFrom(RTC_ADDRESS, 1);
mm= bcdToDec(TinyWireM.receive());
}
void RTC_Start(){
TinyWireM.beginTransmission(RTC_ADDRESS);
TinyWireM.send(0x00);
TinyWireM.send(decToBcd(ss)); // 0 to bit 7 starts the clock
TinyWireM.endTransmission();
}
void RTC_Set(){
TinyWireM.beginTransmission(RTC_ADDRESS);
TinyWireM.send(0x01);
TinyWireM.send(decToBcd(mm));
TinyWireM.send(decToBcd(hh)); // If you want 12 hour am/pm you need to set
TinyWireM.endTransmission();
}
byte decToBcd(byte val)
{
return ((val/10)<<4)+(val%10);
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
return ((val>>4)*10)+val%16;
}
In diesem Code fehlt noch das Blinken der LED unter den Nixies im Normalbetrieb leuchten die Dauerhaft oder sind aus (vorwählbar)
Bei stellen Minuten Blinken beide LED unter den Minuten bei stellen Stunden die unter den Stunden. Meine IDE mit Hilfe eines LDRs die Helligkeit zu regulieren habe ich verworfen. Die Uhr wird nur auf der Arbeit am schreibtisch stehen deswegen bekommt sie noch eine Schaltung die die Uhr nachts ausschaltet (kann ja eh keiner sehen).
Gruß
Der Dani

![IMG_0586[1].jpg](https://europe1.discourse-cdn.com/arduino/original/3X/6/0/60e0135adac8ee1ffa8d8eb257358754addb5da5.jpg)
![IMG_0584[1].jpg](https://europe1.discourse-cdn.com/arduino/original/3X/0/3/03d2174fe45b154d834a3c6c7897a1c2ac4ca26f.jpg)