Automatische dimmer tijdklok

Wie kan mij helpen met een programma in pic die tevens op diverse tijden verschillende PWM waardes uitstuurd, het klokje graag met een RTC zoals de DS1307.
De tjden en waardes die uitgestuurd worden moeten instelbaar zijn dus een lcd display moet er ook in zitten.
IK denk aan een DS1307, pic 16F628 en een 2regelig LCD schermpje

Lambiek

Special Member

Ten eerste welkom op het forum.

Hier heb je vast de code voor de RTC DS1307, je moet het wel even aanpassen voor de 16F628.

pic basic code:


Device 16F887                               ; Processor type

Xtal 10                                     ; Cristal 10Mhz

Asm                                         ; Config settings
CONFIG_REQ            
__CONFIG _CONFIG1, HS_OSC & WDT_OFF & DEBUG_OFF & FCMEN_OFF & LVP_OFF & IESO_OFF & BOR_OFF & CPD_OFF & CP_OFF & MCLRE_OFF & PWRTE_ON 
__CONFIG _CONFIG2, WRT_OFF & BOR40V 
EndAsm
   
All_Digital true                  ; Alle poorten digitaal

Declare LCD_RSPin PORTD.2         ; Reset display poort D.2
Declare LCD_ENPin PORTD.3         ; Enable display poort D.3
Declare LCD_DTPin PORTD.4         ; Data display poort D.4 t/m D.7

Declare SCL_Pin PORTC.3           ; I2C klok pin
Declare SDA_Pin PORTC.4           ; I2C data pin
Declare I2C_SLOW_BUS 1            ; I2C bus op 100KHz

Symbol MODE_KNOP  = PORTA.0       ; Ingang select uur, minuut, seconde
Symbol KNOP_OP    = PORTA.1       ; Ingang optellen uur, minuut, seconde
Symbol KNOP_NEER  = PORTA.2       ; Ingang aftellen uur, minuut, seconde

Dim SECONDE As Byte               ; Variabele seconde
Dim MINUUT As Byte                ; Variabele minuut
Dim UUR As Byte                   ; Variabele uur

Dim DUMMY As Byte                 ; Variabele dummy

Dim MODE As Byte                  ; Variabele mode

Cls                               ; Wis display

DelayMS 500                       ; Pauze 0.5 sec 

Clear                             ; Wis geheugen


         ;543210                  ; Hulpregel poort A
PORTA  = %000000                  ; Maak poort A laag
TRISA  = %111111                  ; Poort_A I/O

         ;543210                  ; Hulpregel poort B
PORTB  = %000000                  ; Maak poort B laag
TRISB  = %000000                  ; Poort_B I/O

         ;76543210                ; Hulpregel poort C
PORTC  = %00000000                ; Maak poort C laag
TRISC  = %00000000                ; Poort_C I/O

         ;76543210                ; Hulpregel poort D
PORTD  = %00000000                ; Maak poort D laag
TRISD  = %00000000                ; Poort_D I/O

         ;210                     ; Hulpregel poort E 
PORTE  = %000                     ; Maak poort E laag
TRISE  = %111                     ; Poort_E I/O

         ;76543210                ; Hulpregel analoog
ADCON0 = %00000001                ; ADCON0 register analoog

         ;543210                  ; Hulpregel analoog poort_B
ANSELH = %000000                  ; ANSEL register analoog poort_B

;------------------------------------
; LEZEN EN SCHRIJVEN NAAR DE DS1307.
;------------------------------------

BStart                            ; Bus start
BusIn %11010001,0,[SECONDE]       ; Lees seconde + bit7 (is osc. aan/uit)
DelayMS 10                        ; Wacht 10ms
Clear SECONDE.7                   ; Zet oscillator aan
BusOut %11010000,[SECONDE]        ; Schrijf naar rtc
DelayMS 10                        ; Wacht 10ms
BusIn %11010001,2,[UUR]           ; Lees uur
DelayMS 10                        ; Wacht 10ms
Clear UUR.6                       ; Select 24 uur klok
BusOut %11010000,2,[UUR]          ; Schrijf naar rtc
BStop                             ; Bus stop

;-------------------------------------------------
; PROGRAMMA UNIVERSELE REAL TIME KLOK MET DS1307.
;-------------------------------------------------

;-------------------------
; LEES RTC ALS MODE 0 IS.
;-------------------------

RUN:

    If MODE = 0 Then
      BStart                 
      BusIn %11010001,0,[SECONDE,MINUUT,UUR] 
      BStop 
      DUMMY = SECONDE & %01110000                 
      GoSub BEREKEN_WAARDE
      SECONDE = SECONDE & %00001111
      SECONDE = SECONDE + DUMMY
    
      DUMMY = MINUUT & %11110000
      GoSub BEREKEN_WAARDE
      MINUUT = MINUUT & %00001111
      MINUUT = MINUUT + DUMMY
    
      DUMMY = UUR & %00110000
      GoSub BEREKEN_WAARDE
      UUR = UUR & %00001111
      UUR = UUR + DUMMY
    End If

;-----------------------------
; PRINT UUR, MINUUT, SECONDE.
;-----------------------------

    Print At 1,1,Dec2 UUR,":",Dec2 MINUUT,":",Dec2 SECONDE

;------------------------------------------
; UREN, MINUTEN, EN SECONDEN GELIJKZETTEN.
;------------------------------------------

    If MODE_KNOP = 1 Then
     DelayMS 10
      Inc MODE
       If MODE > 3 Then  
        MODE = 0
        GoSub SCHRIJF_RTC          
       End If 
      Repeat                          
     Until MODE_KNOP = 0 
    End If

;--------------------
; UUR GELIJK ZETTEN.
;--------------------

    If MODE > 0 Then                      
     DelayMS 300
     
      Select Case MODE      
       Case 1
         Print At 1,1,"  "
        DelayMS 300
        
        If KNOP_OP = 1 Then
         DelayMS 10
          Inc UUR
           If UUR > 23 Then
            UUR = 0
           End If
       End If
       
       If KNOP_NEER = 1 Then
        DelayMS 10
         Dec UUR
          If UUR > 254 Then            
           UUR = 23
          End If
       End If
              
;-----------------------
; MINUUT GELIJK ZETTEN.
;-----------------------
       
       Case 2
        Print At 1,4,"  "
        DelayMS 300
        
        If KNOP_OP = 1 Then
         DelayMS 10
          Inc MINUUT
           If MINUUT > 59 Then
            MINUUT = 0
           End If
       End If
       
       If KNOP_NEER = 1 Then
        DelayMS 10
         Dec MINUUT
          If MINUUT > 254 Then             
           MINUUT = 59
          End If
       End If
           
;------------------------
; SECONDE OP NUL ZETTEN.
;------------------------

       Case 3
        Print At 1,7,"  "
         DelayMS 300
         
       If KNOP_OP = 1 Or KNOP_NEER = 1 Then
        DelayMS 10
        SECONDE = 0
       End If 
               
      End Select
    End If 
       
GoTo RUN

;----------------------------
; WAARDE BEREKENEN VOOR RTC.
;----------------------------

BEREKEN_WAARDE:

    DUMMY = (DUMMY/16)*10               
    Return
    
;--------------------------
; SCHRIJF WAARDE NAAR RTC.
;--------------------------

SCHRIJF_RTC:

    DUMMY = SECONDE / 10                 
    DUMMY = DUMMY * 16                
    SECONDE = SECONDE // 10                 
    SECONDE = SECONDE | DUMMY            

    DUMMY = MINUUT / 10
    DUMMY = DUMMY * 16
    MINUUT = MINUUT // 10
    MINUUT = MINUUT | DUMMY

    DUMMY = UUR / 10
    DUMMY = DUMMY * 16
    UUR = UUR // 10
    UUR = UUR | DUMMY
    
    BStart
    BusOut %11010000,0,[SECONDE,MINUUT,UUR]   
    BStop
    Return

End

En zoiets voor je HPWM uitgang.

pic basic code:


;-------------------------------------
; JE ZOU ER ZOIETS VAN KUNNEN MAKEN -
; DE KLOK BLIJFT GEWOON DOORLOPEN.
;-------------------------------------

    If UUR = 8 Then
     If MINUUT = 50 Then
      If SECONDE = 0 Then
       HPWM 1,127,1000
      EndIf
     EndIf
    EndIf

Dit moet dan in de RUN lus komen te staan, je kan net zoveel van zulke stukjes maken als je zelf wil. Moet wel in je pic passen natuurlijk.

Als je haar maar goed zit, GROETEN LAMBIEK.

Okay, hier ga ik mee aan de slag, eerst maar het schema tekenen

Lambiek

Special Member

Dat schema is ook niet zo spannend, 3 ingangen om je klok gelijk te zetten, 6 uitgangen voor je LCD en 2 signalen voor je I2C om te communiceren met je DS1307. En natuurlijk je HPWM uitgang voor je PWM signaal. En vergeet je pull up weerstanden niet bij je I2C lijnen.

Wat ga je maken?, lijkt iets voor een terrarium of zo.

Als je haar maar goed zit, GROETEN LAMBIEK.

Het schema nog zonder de stuurtrap voor de leds welke vanuit de OUT worden gestuurd.
De pic is de 16F628 en niet wat er nu in het schema staat.
Het is bedoeld om verlichting te simuleren tijdens afwezigheid, ik maak er dan ook 3 stuks.

[Bericht gewijzigd door JohnAN op zondag 9 april 2017 11:03:43 (24%)

Mooi met "veiligheid" en zo, maar persoonlijk maak ik liever de software iets ingewikkelder dan dat ik meer hardware moet bouwen. Dus ik zou het signaal niveau van de schakelaars omdraaien (schakelaar ingedrukt -> signaal wordt laag) en dan de interne pullup gebruiken. En ook de debounce (condensatoren) zou ik in software doen. Scheelt 3 componenten per schakelaar.

Ik heb uit een datasheet van een MCPxxxx chipje wat DS1307 compatible is de hint gehaald om een diode en een 1k weerstand bij de batterij te zetten. Dat is dan weer een "beveiliging" die ik dan weer wel doe.

[Bericht gewijzigd door rew op zondag 9 april 2017 11:37:10 (22%)

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Lambiek

Special Member

Ik heb slechte ervaring met die interne pull up weerstanden, zelf zet ik altijd 10K pull down bij iedere pin (in de vorm van een sil weerstand, lekker klein)

Die condensatoren bij je schakelaars is niet echt nodig, kan software matig. Zit ook al in het programma. Die 1K weerstanden zijn ook niet echt nodig.

Voor de batterij zou ik een CR2025 nemen met bijbehorende batterijhouder, die zijn 3V precies wat je nodig hebt.

Als je haar maar goed zit, GROETEN LAMBIEK.

Als je over de duivel praat....

Projectje, interne pullup op een schakelaar... Werkt niet goed. Externe pullup geplaatst... Nog steeds ten onrechte dat ie gezien wordt als soms geactiveerd.... Raar...

Ohja, Zelfde print, ander exemplaar werkt wel betrouwbaar.....

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Lambiek

Special Member

Wat voor waarde gebruik je dan als externe pull up rew?

Als je haar maar goed zit, GROETEN LAMBIEK.

Ik heb er een 4k7 op gesoldeerd.

Maar kennelijk is er wat anders aan de hand want het werkt niet. Het lijkt er op alsof ik hem als AFx instel en dat ie dan dingen gaat doen, maar dat ik hem dan alsnog ga inlezen als knop. Maar ook dat kan niet, want precies dezelfde software werkt op andere hardware wel gewoon. Statisch meet ie netjes 3.3V, maar als de boel draait meet ik inderdaad zo nu en dan onder de 1V met de multimeter. tzt een keer de scoop op hangen. Hopelijk geeft dat een hint van wat er mis gaat.

Mogelijk "gezeik" met de voeding. De "foute" hangt aan een 30V labvoeding, de goede hangt aan een 30 jaar oude (m'n eerste) voeding (20V, 1A, LM317). Mogelijk is er iets met de belasting van de 7 segmenten displays. De "foute" heeft nog geen 7segmenten displays gemonteerd.

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Lambiek

Special Member

Je zou zeggen dat het met 4K7 toch goed moet werken, zit er soms lange bedrading aan?

Als je haar maar goed zit, GROETEN LAMBIEK.

Nee joh! Het printje is 10x10, de CPU zit ongeveer in het midden, en de knop wordt gewoon op de PCB gesoldeerd. Kortom max 5cm lange bedrading.

Ik heb met de scoop gekeken. Het patroon herkende ik meteen: Ik knipper met een led op dat ritme. (de code knippert een nummer, in een ander project is dat de state van de belangrijke statemachine, maar hier is het getal "vier"). Op de CPU blijkt de led op de pin naast die van de switch te zitten. En daar zat kennelijk een kortsluiting. Na wat prutsen met een bout is het probleem weg.

De 4k7 pullup die ik gemonteerd had... was trouwens fout. Ik had er een pulldown van gemaakt. Dan gaat dat knopje het nooit meer doen....

four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Lambiek

Special Member

Nou, in ieder geval heb je het gevonden. Probleem opgelost. :)

@ TS,
Wil het lukken met je RTC?
Ik heb ook nog een voorbeeld met datum, maand en jaar.

Als je haar maar goed zit, GROETEN LAMBIEK.

Dat gaat redelijk goed,
Gebruik nu de 16F678 met meer io lijnen zodat ik alles met 1 processor kan afhandelen.
Zit alleen nog te klooien met de menu stuctuur.
De bedoeling is om zeg maar om 1 uitgang om te beginnen op 6 verschillende tijden een verschillende pwm waarde te geven maar die dan wel als ik niets ingeef bij bijvoorbeeld de 5e en 6e tijd hij wel de pwm waarde blijft geven van de laat ingestelde tijd blijft geven ik weet niet hoe dit werkt.
Tevens voor dit verhaal 3 x hierin te verwerken.

buckfast_beekeeper

Golden Member

Je kan dit op verschillende manieren aanpakken. Zorgen dat een waarde nooit null is maar default de vorige waarde zo lang je niets wijzigt.

Met een if x = null then y?

Bijhouden hoeveel waardes er zijn ingesteld kan ook nog. if x <= aantal then

Het is maar hoe je het zelf bekijkt.

Van Lambiek wordt goede geuze gemaakt.
Lambiek

Special Member

....bijvoorbeeld de 5e en 6e tijd hij wel de pwm waarde blijft geven van de laat ingestelde tijd blijft geven ik weet niet hoe dit werkt.

Als je de HPWM functie gebruikt, dan blijft de laatste waarde gewoon staan tot dat je een nieuwe waarde ingeeft.

Je kan dat zo doen:

pic basic code:

         
 
    If UUR = 8 Then
     If MINUUT = 50 Then
      If SECONDE = 0 Then
       HPWM 1,50,1000
      EndIf
     EndIf
    EndIf

    If UUR = 10 Then
     If MINUUT = 20 Then
      If SECONDE = 0 Then
       HPWM 1,100,1000
      EndIf
     EndIf
    EndIf

    If UUR = 12 Then
     If MINUUT = 10 Then
      If SECONDE = 0 Then
       HPWM 1,127,1000
      EndIf
     EndIf
    EndIf

    If UUR = 14 Then
     If MINUUT = 50 Then
      If SECONDE = 0 Then
       HPWM 1,30,1000
      EndIf
     EndIf
    EndIf


    If UUR = 15 Then
     If MINUUT = 15 Then
      If SECONDE = 0 Then
       HPWM 1,200,1000
      EndIf
     EndIf
    EndIf

    If UUR = 20 Then
     If MINUUT = 50 Then
      If SECONDE = 30 Then
       HPWM 1,175,1000
      EndIf
     EndIf
    EndIf
 

Dus de pwm waarde blijft 175 na 20:50:30 tot 8:50:00, dan wordt de pwm waarde weer 50.

De 16F678 ken ik niet. De 16F687 wel, maar die heeft geen HPWM aan boord. Dan moet je dus zelf je pwm signaal maken.

Als je haar maar goed zit, GROETEN LAMBIEK.

Allereerst zowel Lambiek alsook buckfast_beekeeper bedankt zover.
Dit is allemaal duidelijk en ook niet het echte probleem.
DE gebruikte processor is 16F876 sorry voor mijn fout in de vorige post deze heeft ook de HPWM (2x)

Het display moet aangeven de huidige tijd en de uitgestuurde waarde( dit is geen probleem )
Echter ik moet een menu krijgen als er op de Mode knop wordt gedrukt waarna zichtbaar op het display de uren en minuten kunnen worden ingesteld van stap 1 (tijd 1), de instelling opslaan met Set voor zowel uren, minuten en waarde, vervolgens voor stap 2 enz, enz. Menu weer verlaten met Mode.

Het display geeft dus op regel 1 altijd de huidige tijd aan en op regel 2 de stap die op dat moment geldig is.

Tijdens het instellen na het drukken op Mode op regel 1 weer de huidige tijd en op regel 2 Stap 1 00:00 00%
zodat met set en de pijltjes toetsen alles wordt ingesteld en bevestigd.

Lambiek

Special Member

Dat kan toch het zelfde als het instellen van de uren, minuten en seconden. Maak een paar variabele aan met bijv. tijd_1, tijd_2, tijd_3, enz. Of geef het zelf een naampje.

Dan maak je een nieuwe case........ aan, en dat doe je op de zelfde manier als hoe het gedaan is met uur, minuut en seconde. Je moet wel case 1, case 2, en case 3 opschuiven, dit komt er dus voor te staan en de instelling voor seconde weer als het laatst.

EDIT:
Trouwens, veranderen die tijden iedere keer dat er een pwm signaal uitgestuurd wordt?, zoniet dan kun je dat toch vast in je programma zetten.

Als je haar maar goed zit, GROETEN LAMBIEK.