vrijdag 23 september 2011

experimenteren met de pcf8574

Voor het basisstation hebben we ook een toetsen nodig. Je kunt natuurlijk ze rechtstreeks aan de pic koppelen, maar het kan ook via een chip. In mijn geval met de pcf8574. Het mooie van dit ic is dat het een interrupt uitgang heeft. Het uitlezen is heel makkelijk, Zodra er een toets is ingedrukt springen we naar de uitleesroutine en zetten de waarde op het scherm. Het grootste probleem is het instellen van de interrupts daarvoor moet je echt de datasheet van de pic lezen.
In dit geval heb ik 'on interrupt' gebruikt maar je zou de afhandeling ook na het sleep commando kunnen doen (nap 7).  In het basisstation gaan we meerdere interrupts gebruiken. De toetsen op rb0, de ook ontvanger op rb1 en een timer interrupt voor het tonen van de tijd.

Device 18F4620
Xtal 20   
                  
ADCON1=7
   
LCD_DTPin PORTB.4
LCD_ENPin PORTB.3
LCD_RSPin PORTB.2

SCL_Pin    = PORTC.3   ' i2c
SDA_Pin    = PORTC.4 


'portB rb0 input
TRISB = 000001

INTCON.4 = 1
INTCON2.6 = 0
INTCON2.7 = 0  

Dim bus As Byte

Cls

DelayMS 100

On Interrupt GoTo keyin

' voor de zekerheid alle poorten hoog zetten.
BusOut $70,[255]  'adres voor pcf8574ap met a0,a1,a2 op 0


While 1=1
INTCON.1=0
nap 7
Wend

Disable
keyin:
BusIn $70,[bus]
DelayMS 50
Print At 1,1,Bin bus
Resume
Enable


End

donderdag 22 september 2011

DS1307 klok in combinatie met DCF77

In het basisstation wil ook graag een nauwkeurig klok het liefst met DCF77
Op het internet vind je verschillende beschrijvingen voor een DCF77 klok.
Ik ben hiermee aan het experimenteren gegaan met de bedoeling om een
DS1307 met de juiste tijd in te stellen. Ik ontvang twee keer een minuut van de dcf77
ontvanger zit hier een idd een minuut tussen dan zetten we de dcf77 tijd in de ds1307
en zijn we klaar. De tijd word alleen gezet als de ds1307 nog niet gestart is.
Wat er verder nog moet gebeuren is dat de tijd op een bepaald tijdstip op de dag
de ds1307 weer gesynchroniseerd word met de dcf77 ontvanger.



Device 18F4620
Xtal 20                       

ADCON1=7
   
LCD_DTPin PORTB.4    'lcd 16x2 op portb
LCD_ENPin PORTB.3
LCD_RSPin PORTB.2

'I2c op c.3 en c.4
SCL_Pin    = PORTC.3   '
SDA_Pin    = PORTC.4


Symbol ds1307       = %11010000   'adres ds1307
Symbol Dcfin        = PORTC.0     'portc.0 dcf77 ontvanger ingang (positief)
Symbol Blok         = 255

Dim SignaalCheck    As Word
Dim    Teller            As Word
Dim    Bittijdtel        As Word

Dim Sec             As Byte
Dim Minuut          As Byte
Dim Uur             As Byte     
Dim    Startbyte        As Byte
Dim    Ontvbyte        As Byte
Dim    Dag             As Byte
Dim    Week            As Byte
Dim    Maand              As Byte
Dim    Jaar            As Byte
Dim    I                As Byte
Dim    N                 As Byte
Dim Dcfmin          As Byte

Dim Fout            As Bit
Dim    Ontvbit            As Bit
Dim ParBit          As Bit
Dim Loops           As Bit

DelayMS 100   ' opstarttijd disp

BusIn ds1307,$00,[Sec]           'controleer of de klok loopt zo niet instellen met dcf77
If Sec.7=1 Then Call setklok

Cls

' tijd uitlezing met ds1307

main:

BusIn ds1307,0,[Sec,Minuut,Uur,Week,Dag,Maand,Jaar]

Print At 1,1,Hex2 Dag, "-", Hex2 Maand, "-", Hex2 Jaar
Print At 2,9,Hex2 Uur, ":", Hex2 Minuut, ":", Hex2 Sec

GoTo main


setklok:

Cls
Clear

Print At 1,1, "DCF77"
Print At 2,1, "Wacht op start"

GoSub Wachtopstartbit

'we hebben de startbit gevonden
init:

Print At 1,7, Rep " " \ 10
Print At 2,1,"Wacht op tijd "

Clear Sec
Clear ParBit

For I = 0 To 20            '0 TOT 20 OVERSLAAN
      GoSub Eenbitontv
Next   
   
N = 7
GoSub Bytesontv            '21-27 MINUUT
Minuut = Ontvbyte
           
GoSub Eenbitontv        '28 PARITY
If ParBit = 1 Then setklok

       
N = 6
GoSub Bytesontv            '29-34 UUR
Uur = Ontvbyte   
           
GoSub Eenbitontv        '35 PARITY
If ParBit = 1 Then setklok
       
N = 6
GoSub Bytesontv            '36-41 DAG
Dag = Ontvbyte       
       
N = 3
GoSub Bytesontv            '42-44 WEEK
Week = Ontvbyte
   
N = 5
GoSub Bytesontv            '45-49 MAAND
Maand = Ontvbyte
       
N = 8
GoSub Bytesontv            '50-57 JAAR
Jaar = Ontvbyte
       
GoSub Eenbitontv        '58 PARITY

If ParBit = 1 Then setklok     ' fout opgetreden

' we gaan twee keer de tijd binnenhalen en controleren of er een minuut
' verschil is. zo ja dan gaan we tijd in de ds1307 zetten.
' we nemen de overgang van 59 naar 0 voor lief

Select Case Loops
    Case 0
        Dcfmin = Minuut
        Loops = 1
        GoTo init
    Case 1
        If Dcfmin <> Minuut - 1 Then setklok 
End Select       

DelayMS 1000       ' 1 seconde wachten (sec59)
BusOut ds1307,$00,[0,Minuut,Uur,Week,Dag,Maand,Jaar]
Return                              


Wachtopstartbit: 

' routine voor opstart tijd voor de DCF77 ontvanger bij power-on

Clear Teller
While Dcfin = 0
  Inc Teller
  DelayMS 1
  If Teller > 50000 Then ErrorOntvangst 
Wend
  
Clear Sec  
Clear Startbyte
While Startbyte = 0
    Clear Bittijdtel
    Clear Teller
    While Dcfin = 1
       Inc Teller
       DelayMS 1
       If Teller > 5000 Then ErrorOntvangst ' meer dan 5 seconden een 1 dan error
    Wend
    While Dcfin = 0
       Bittijdtel = Bittijdtel + 1
       DelayMS 10
       If Bittijdtel > 500 Then ErrorOntvangst ' meer dan 5 sec een 0 dan error
    Wend
    If Bittijdtel > 100 Then Startbyte = 1  
    Inc Sec
    If Sec > 65 Then Clear Sec ' langer bezig dan 65 sec dan geen blokjes meer
    Print At 1,7+(Sec/7),Blok
Wend
Return       
       
Eenbitontv:
        Clear Teller   
        Clear Bittijdtel
        While Dcfin = 0
          DelayMS 1
          Inc Teller
          If Teller > 3000 Then ErrorOntvangst         
        Wend
        While Dcfin = 1
            Bittijdtel = Bittijdtel + 1
            DelayMS 10
        Wend
        If Bittijdtel > 16 Then
            Ontvbit = 1
        Else
            Ontvbit = 0
        EndIf
        ParBit = ParBit + Ontvbit
        Inc Sec
        Print At 1,7+(Sec/6),Blok
        Return
       
Bytesontv:

Clear    Ontvbyte
For I = 0 To N - 1
GoSub Eenbitontv
If Ontvbit = 1 Then SetBit Ontvbyte,  I
Next I
Return

       
ErrorOntvangst:

Print At 1,7, Rep " " \ 10
Print At 2,1, "Ontvangst slecht"       
Repeat
   Clear
   Fout = Dcfin
   While Dcfin = Fout    ;Wacht op signaal verandering
     Inc SignaalCheck
     DelayMS 1
   Wend
   Fout = Fout ^ 1
   While Dcfin = Fout    ;Wacht op signaal verandering
     Inc SignaalCheck
     DelayMS 1
   Wend
Until SignaalCheck < 500
      
GoTo setklok

       

zaterdag 17 september 2011

Vervolg onweer detector.

Inmiddels draait de onweer detector alweer een tijdje.
Hij hangt op zolder met een stukje draad verticaal als antenne. Het bereik is ca 50km. Ik heb de software uitgebreid met een aflezing per minuut en het totale aantal strikes. Het totale aan strikes word opgeslagen in het eeprom van de pic. Op portb.1 kun je een speaker aansluiten, zodra  er meer dan 25strikes zijn per 5 minuten hoor je een piepje elke minuut. Tevens wordt de data draadloos verstuurd. Hier de source.


Device 16F628A
   
Xtal 4   

LCD_DTPin PORTA.0
LCD_ENPin PORTB.3
LCD_RSPin PORTB.4

TRISB=000001 ' PortB.0  as input
                          
'ANSEL = 0       ' all Portb.7 digital

CMCON = 7

PORTB.7 = 0
 

Dim teller As Byte
Dim zendtel As Byte
Dim mantel As Byte
Dim strikes[5] As Word
Dim strikes5m As Word
Dim strikestotal As Dword
Dim strikesmc As Word
Dim manchestin As Byte
Dim manchestout As Word
Dim tempdata As Bit
Dim manchestsl As Word
Dim manchestsh As Word
Dim manchests5h As Word
Dim manchests5l As Word
Dim manchestst0 As Word
Dim manchestst1 As Word
Dim manchestst2 As Word
Dim manchestst3 As Word
Dim manchestck As Word
Dim manchestzd As Word
Dim checksum As Byte

Symbol zender       = 2
Symbol adres        = 1
Symbol zendout      = PORTB.7
Symbol startman     = $55
Symbol dataman      = $aa


Clear

manchestin = zender
Call manchesterdata
manchestzd = manchestout

strikestotal = ERead adres

Cls
DelayMS 100
Print At 1,1,"Lightning"
Print At 2,1,"Detector 1.0"

main:

For teller = 0 To 4

strikes[teller] = Counter PORTB.0,60000
strikes5m = strikes[0] + strikes[1] + strikes[2] + strikes[3] + strikes[4]

Print At 1,1,Dec3 strikes[teller]," S/m ",Dec3 strikes5m," S/5m"

If strikes5m > 25 Then Sound PORTB.1,[122,25]
If strikes[teller] > 2 Then strikestotal = strikestotal+strikes[teller]

Print At 2,1,Dec6 strikestotal," Tstrikes"

strikesmc = strikes[teller]

manchestin = strikesmc.HighByte
Call manchesterdata
manchestsh = manchestout

manchestin = strikesmc.LowByte
Call manchesterdata
manchestsl = manchestout

manchestin = strikes5m.HighByte
Call manchesterdata
manchests5h = manchestout

manchestin = strikes5m.LowByte
Call manchesterdata
manchests5l = manchestout

manchestin = strikestotal.Byte0
Call manchesterdata
manchestst0 = manchestout

manchestin = strikestotal.Byte1
Call manchesterdata
manchestst1 = manchestout

manchestin = strikestotal.Byte2
Call manchesterdata
manchestst2 = manchestout

manchestin = strikestotal.Byte3
Call manchesterdata
manchestst3 = manchestout

checksum = zender + strikes[teller] + strikes5m + strikestotal.Byte0 + strikestotal.Byte1 + strikestotal.Byte2 + strikestotal.Byte3 - 1

manchestin = checksum
Call manchesterdata
manchestck = manchestout

For zendtel = 1 To 3

SerOut zendout, 49965,[startman,dataman,manchestzd.HighByte,manchestzd.LowByte,manchestsh.HighByte,manchestsh.LowByte,manchestsl.HighByte,manchestsl.LowByte,manchests5h.HighByte,manchests5h.LowByte,manchests5l.HighByte,manchests5l.LowByte]
SerOut zendout, 49965,[manchestst0.HighByte,manchestst0.LowByte,manchestst1.HighByte,manchestst1.LowByte,manchestst2.HighByte,manchestst2.LowByte,manchestst3.HighByte,manchestst3.LowByte,manchestck.HighByte,manchestck.LowByte]

DelayMS 10
Next zendtel
Next teller

EWrite adres,[strikestotal]

GoTo main

manchesterdata:
For mantel = 0 To 7
tempdata = GetBit manchestin,mantel
If tempdata = 0 Then
        ClearBit manchestout,(mantel*2)
        SetBit manchestout,(mantel*2+1)
    Else
        SetBit manchestout,(mantel*2)           
        ClearBit manchestout,(mantel*2+1)
    EndIf
Next mantel
Return


End

woensdag 31 augustus 2011

Vervolg radio met tea5767

De radio werkt met een lcd, Het adres was fout, overkomt me wel vaker met i2c, het moet zijn %11000000, Verder is het beter om niet continu de freq in de tea te zetten en dat 1 keer te doen in plaats van een loop. Dit geeft veel minder storing.  Nu nog de signaalsterkte en een stereo indicator.  Maar ik laat het hierbij het audio is namelijk nogal vervormd, er heeft 5v over de de mpx uitgang gestaan ik vermoed dat het ic niet niet kon waarderen.

    Device 18F2620
    Declare Xtal = 20  
   
     ' i2c
   
    SCL_Pin    = PORTB.0  
    SDA_Pin    = PORTB.1
   
    ' aansluitingen lcd
   
    LCD_DTPin PORTB.4
    LCD_ENPin PORTB.3
    LCD_RSPin PORTB.2   
   
    ' adres  tea5767
   
    Symbol tea5767 = %11000000
   
    ' up en down toets

    Symbol Toetsup   = PORTA.0
    Symbol Toetsdown = PORTA.1
   
    ' Variabelen
   
    Dim Frequentie As Word 
    Dim Pll As Dword
   
    TRISA= %00000011
   
    Declare All_Digital = True
   
    Clear

    ' Init lcd  
   
    Cls
   
    DelayMS 100
                      
   ' init opstart freq (waterstad fm)
        
    Frequentie = 932
    GoSub displayfreq
    GoSub progtea
   
main:
    If Toetsup = 0 Then GoSub frequp
    If Toetsdown = 0 Then GoSub freqdown
    GoTo main

frequp:
    DelayMS 100
    Frequentie = Frequentie + 1
    If Frequentie > 1080 Then Frequentie = 1080
    GoSub displayfreq
    GoSub progtea
    Return

freqdown:
    DelayMS 100
    Frequentie = Frequentie - 1
    If Frequentie < 875 Then Frequentie = 875
    GoSub displayfreq
    GoSub progtea
    Return

progtea:
    Pll = Frequentie * 100000 + 225000    
    Pll = Pll * 4 / 32768
    BusOut tea5767,[Pll.Byte1,Pll.Byte0,$10,$10,$00]
    Return
   
displayfreq:
    Print At 1,1,Dec Frequentie / 10,".",Dec1 Frequentie // 10," Mhz "
    Return
   



maandag 29 augustus 2011

FM radio met TEA5767

Op Ebay had ik een FM radio module gevonden met de TEA5767 voor €2,50. Ik had het idee om hier met een MAX7219 als displaydriver 4 displays aan te sturen, nou dat was niet echt een succes.
De MAX7219 zorgt er voor dat ik alleen een piep hoor, de multiplexfrequentie stoort enorm.
Display dan maar uit en kijken of ik geluid kreeg. Maar ook dat zit tegen. Toch wat fout in het i2c gedeelte? Eerst een LCD en dan maar weer eens proberen. Met het lcd is het ook wat makkelijker om de inhoud van de registers van de tea5756 weer te geven. Voor de aardigheid heb ik de source toegevoegd.



    Device 18F2620
    Declare Xtal = 20  
   
     ' i2c
   
    SCL_Pin    = PORTC.3  
    SDA_Pin    = PORTC.4
   
    ' aansluitingen max7219
   
    Symbol Clk  = PORTB.0  
    Symbol Dta  = PORTB.1  
    Symbol Load = PORTB.2  
   
    ' adres  tea5767
   
    Symbol tea5767 = %01100000    
   
    ' up en down toets

    Symbol Toetsup   = PORTB.3
    Symbol Toetsdown = PORTB.4
   
    ' Variabelen
   
    Dim Frequentie As Word 
    Dim Pll As Dword
    Dim Register As Byte
    Dim Waarde As Byte  
    Dim Digit As Byte   
    Dim Positie As Byte 
   
    TRISB= %00011000
   
    Declare All_Digital = True

    ' Init MAX7219  zie datasheet  
   
    Register = 11       ' aantal displays 0-3 (4)   
    Waarde = 3                          
    GoSub waardenaarMax                            
    Register = 10       ' Helderheid          
    Waarde = 9                          
    GoSub waardenaarMax
    Register = 9        ' BCD voor 4 disp         
    Waarde = 15              
    GoSub waardenaarMax                     
    Register = 12       'Display aan          
    Waarde = 1                          
    GoSub waardenaarMax
    Register = 15       ' Disp test uit          
    Waarde = 0                          
    GoSub waardenaarMax                     
                                 
    Frequentie = 932
  
main:
    If Toetsup = 0 Then GoSub frequp
    If Toetsdown = 0 Then GoSub freqdown
    GoSub displayfreq
    GoSub progtea
    GoTo main

frequp:
    DelayMS 100
    Frequentie = Frequentie + 1
    If Frequentie > 1080 Then Frequentie = 1080
    Return

freqdown:
    DelayMS 100
    Frequentie = Frequentie - 1
    If Frequentie < 875 Then Frequentie = 875
    Return

progtea:
    Pll = Frequentie * 100000 + 225000    
    Pll = Pll * 4 / 32768
    BusOut tea5767,[Pll.Byte1,Pll.Byte0,$10,$10,$00]  'zie datasheet tea
    Return
   
displayfreq:
    Digit = 0                                               ' eerste disp
    For Positie = 4 To 1 Step -1                            ' bepaal reg max
    Register = Positie                         
    Waarde = Dig Frequentie,Digit                           ' bepaal disp waarde
    If Frequentie < 1000 And Positie = 1 Then Waarde = 15   ' onder 100 mhz geen 0 op laatste digit
    If Digit = 1 Then Waarde.7 = 1                          ' punt op digit 1
    GoSub waardenaarMax
    If Digit >= 3 Then Digit = 0                            ' 4  digits gehad ?
    Digit = Digit + 1                                      
    Next                                                   
    Return                                                 

waardenaarMax:                              
    SHOut Dta,Clk,MsbFirst,[Register,Waarde]   'Waarde via spi naar max  
    High Load                                  'enable transfer
    DelayUS 2                               
    Low Load                                
    Return                                  

dinsdag 23 augustus 2011

Vervolg onweer detector.

Na het lezen van wat info, heb ik aan de onweer detector een counter aangesloten die het aantal strikes per 5 minuten weergeeft, maar het wordt wel elke minuut bijgewerkt. Verder heb ik de puls van de ne555 verkort tot 0.2 seconden, Het werkt prima, helaas ontwijkt het onweer Friesland, en heb dus nog niet echt veel strikes per 5 minuten gezien, De detector is nu aangesloten op een inverted V voor de 20m amateurband de antenne zit onderdak. Ongeveer richting zuid/noord dat scheelt behoorlijk in de gevoeligheid, het onweerde in Overijssel dit kon ik duidelijk waarnemen. Onder de foto's staat de source welk nog verder kunnen uitbreiden. De detector is aangesloten op portb.0.



Device 16F88
   
Xtal 4   

LCD_DTPin PORTA.0
LCD_ENPin PORTB.3
LCD_RSPin PORTB.4

TRISB=%00000001 ' PortB.0  as input
                          
ANSEL = 0       ' all Portb.7 digital

Dim teller As Byte
Dim strikes[5] As Word
Dim strikeslcd As Word

Cls
DelayMS 100
Print At 1,1,"Initializing"
Clear

main:
For teller = 0 To 4
strikes[teller] = Counter PORTB.0,60000
strikeslcd = strikes[0] + strikes[1] + strikes[2] + strikes[3] + strikes[4]
Print At 1,1,Dec4 strikeslcd," Strikes/5m"
Next teller
GoTo main

End

vrijdag 19 augustus 2011

Basisontvanger wireless temperatuur sensor

In juli heb ik een temperatuur sensor beschreven met 12f683 en een ds1820, hierbij de ontvanger. Als ontvanger gebruik ik een AM ontvanger van conrad, de data uitgang is aangesloten op portb.1.Het lcd zit ook op portb zie source. De werking. De PIC kijkt in een loop of er een $55 word ontvangen.
Is dit het geval dan gaan we naar de volgende routine waarbij de data ontvangen word. Mocht hier iets niet goed gaan gaan we terug naar de hoofdroutine. Is er wel goede data dan springen we als de zender 1 is naar de display routine. De errorchecking zit er nog niet in. Het is een bassis en de ontvangst gaat prima. Voor de pic heb ik gekozen voor een 18f2620
Ik heb drie tellers er in zitten die aangeven hoeveel keer er $55 is ontvangen, hoeveel keer data ontvangen is en hoeveel keer er iets op het lcd is gezet.


Device 18F2620
Xtal 20                       


ADCON1=7
   
LCD_DTPin PORTB.4
LCD_ENPin PORTB.3
LCD_RSPin PORTB.2

Print  $FE, $40, $08, $14, $08, $03, $04, $04, $03, $00 ' celcius

Dim telontv As Word
Dim tempser As Byte
Dim teller As Byte
Dim teldoor As Word
Dim telzend As Word
Dim regel As Byte
Dim tempdata As Bit
Dim manchest1 As Word
Dim manchest2 As Word
Dim manchest3 As Word
Dim manchest4 As Word
Dim manchest5 As Word
Dim manchest6 As Word
Dim manchestck As Word
Dim manchestin As Word
Dim byteout As Byte
Dim zender As Byte
Dim decode1 As Byte
Dim decode2 As Byte
Dim decode3 As Byte
Dim decode4 As Byte
Dim decode5 As Byte
Dim checksum As Byte
Dim templcd As Byte
Dim tempture As Word


Cls


telontv = 0
teldoor = 0
telzend = 0


main:     
SerIn PORTB.1,49965,1,geendata, [tempser]
If tempser =$55 Then GoTo rest
GoTo main

geendata:
tempser=$ff
GoTo main

rest:
teldoor = teldoor + 1
Print At 2,1 , Dec3 teldoor
SerIn PORTB.1,49965, 10, geendata,[Wait($AA), manchest1.HighByte,manchest1.LowByte, manchest2.HighByte, manchest2.LowByte,manchest3.HighByte,manchest3.LowByte]
SerIn PORTB.1,49965,[manchest4.HighByte, manchest4.LowByte,manchest5.HighByte,manchest5.LowByte, manchest6.HighByte, manchest6.LowByte,manchestck.HighByte, manchestck.LowByte]
telontv = telontv + 1
Print At 2,5, Dec3 telontv
GoSub decodeall
If zender = 1 Then GoSuB showtemp
GoTo main

showtemp:
telzend = telzend + 1
Print At 2,9,Dec3 telzend
tempture.HighByte= decode2
tempture.LowByte = decode1
Print At 1,1, Dec2 (tempture / 100),".",Dec2 tempture,0
Return

decodeall:
manchestin = manchest1
GoSub decodmanchester
zender = byteout

manchestin = manchest2
GoSub decodmanchester
decode1 = byteout

manchestin = manchest3
GoSub decodmanchester
decode2 = byteout

manchestin = manchest4
GoSub decodmanchester
decode3 = byteout

manchestin = manchest5
GoSub decodmanchester
decode4 = byteout

manchestin = manchest6
GoSub decodmanchester
decode5 = byteout

manchestin = manchestck
GoSub decodmanchester
checksum = byteout
Return

decodmanchester:
byteout=$00
For teller=7 To 0 Step -1
    tempdata = GetBit manchestin,(teller*2)
    If tempdata = 1 Then
         tempdata = GetBit manchestin,(teller*2+1)
         If tempdata = 0 Then
            SetBit byteout,teller
         EndIf
    EndIf
Next teller
Return