Pages: [1]   Go Down
Author Topic: 7 Segement Uhr 100mm Bauhöhe mit Attiny84  (Read 799 times)
0 Members and 1 Guest are viewing this topic.
AREA COLOGNE
Offline Offline
Edison Member
*
Karma: 21
Posts: 1146
I am 1 of 10 who understands binary
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Mein Projektvorstellung:
Eine 4 Ziffern 7Segementuhr mit 100mm Bauhöhe der Segemente.
Benötigte Hardware:
1* Attiny84
1* DS1307 RTC von Maxim
1* Batteriehalter
4* 74HC595 Schieberegister
4* ULN2803 Darlington Array
1* IRFL024 N-Channel Mosfet
1* 7805CV  Festspannungregler 5V
1* Batteriehalter CR20xx
1* Ribbon IKEA Bilderrahmen
Möbefolie weiß zu Beziehen des Glases.

Ziel war es alles auf einen Attiny84(44) CPU umzusetzten. Die Dateien der Cores sind von hier http://hlt.media.mit.edu/?p=1695 Diese laufen aber nur unter der 1.0.1 auf der 1.0.2 habe ich es durch einiges an probieren nicht hinbekommen.
Ich nutzte die TinyWireM-Libraries mit Erweiterungen von mir der defines für die x4er Serie, da die USI Interface auf anderen Pins bzw. Ports sitzt als bei den x5ern. Die Kommuniktion zu RTC läuft über I2C, wobei die externen Pullups zwingend erforderlich sind.
Ich wollte kein Multiplexing nutzten damit ich die volle Helligkeit der Anzeigen nutzten kann, deswegen die 4 Schieberegister+ 4 ULN2803.
Mit dem IRFD024 Mosfet habe ich die Output-Enable der Schiebregister mit PWM angesteuert um die Helligkeit der Segemente zu handlen.
Die Steuerung läuft via One-Button Steuerung.
Kurzer Druck im Normalmodus stellt die Helligkeit in 6 Stufen regeln. Ein Langer Druck bewirkt die beiden Setmodes (1= Stellen Minuten 2= Stellen Stunden).
Gruß
Der Dani

Hier  der Code



* Uhr1.jpg (405.54 KB, 1600x1200 - viewed 63 times.)

* Schaltplan.JPG (877.57 KB, 1600x1200 - viewed 69 times.)

* Übersicht Platine.JPG (171.99 KB, 1054x858 - viewed 99 times.)

* Rueckseite.JPG (914.52 KB, 1600x1200 - viewed 71 times.)
« Last Edit: November 12, 2012, 02:56:34 am by volvodani » Logged

So ist das Leben:
Manchmal bis du das Denkmal, manchmal die Taube!

AREA COLOGNE
Offline Offline
Edison Member
*
Karma: 21
Posts: 1146
I am 1 of 10 who understands binary
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
/*
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
« Last Edit: November 12, 2012, 05:26:00 am by volvodani » Logged

So ist das Leben:
Manchmal bis du das Denkmal, manchmal die Taube!

Pages: [1]   Go Up
Jump to: