/*
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 mEiner,mZehner,hEiner,hZehner=0;
byte setmode=0;
byte PWMArray[7]={
10,20,40,80,160,255};
byte Pointer=4;
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
mEiner=mm%10; // Einer Minuten
mZehner=(mm-mEiner)/10; // Zehner Minuten
hEiner=hh%10; // Einer Stunden
hZehner=(hh-hEiner)/10; // Zehner Stunden
hz=Dec2Shift(hZehner); // Wandeln der Zahlen in 7 Segment Ansteuerbytes
he=Dec2Shift(hEiner); // dto.
mz=Dec2Shift(mZehner); // dto.
me=Dec2Shift(mEiner); // dto
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, me); // Shift out der einzelenen Puffer wobei im letzten
shiftOut(Shiftdata, Shiftclock, MSBFIRST, mz); // Shift out der einzelenen Puffer wobei im letzten
shiftOut(Shiftdata, Shiftclock, MSBFIRST, he); // Shift out der einzelenen Puffer wobei im letzten
shiftOut(Shiftdata, Shiftclock, MSBFIRST, hz); // 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&&hh<=8&&hell==true){ // wenn Später 22Uhr und Früher als 8Uhr und es vorher Hell war dann dunkelschlaten
Pointer=1;
hell=false;
}
if (hh<22&&hh>8&&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}; // Daten für die 7 Segement anzeigen entspircht 0,1,2,3,4,5,6,7,8,9
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;
}
Kompiliert sind das 2980 bytes also passt auch auf einen Attiny44
Gruß
Der Dani