Hallo Allemaal,
Ik heb een seriele communicatie tussen twee pics gemaakt op basis van het domotica project op picbasic.nl. Uiteindelijk is het mijn bedoeling om meerdere pics met elkaar over deze bus met elkaar te laten communiceren.
De data die overgezonden moet worden zijn maximaal word variabelen, maar ook een identificatie (wat stelt de variabele voor). Ik heb waarschijnlijk niet meer dan 256 verschillende items die ik wil overzenden.
Het "protocol" wat ik bedacht had is een Byte voor de identificatie en een Word voor de data. De totale ontvangstvariabele is dan een Dword. Er staat in de handleiding dat dit niet groter mag zijn dan een Word variabele maar het werkt goed (tussen twee pics).
Het relevante stuk zendcode:
SYMBOL SerieelUit = PORTB.2
DIM trip1 AS WORD
SYMBOL Baud2400 = 396
hoofdlus:
SEROUT SerieelUit, Baud2400, [trip1, 1]
goto hoofdlus
Het relevate stuk Ontvangstcode:
HSERIAL_BAUD = 2400 ;Transmissiesnelheid van de data over de bus
HSERIAL_RCSTA = %10010000 ;Bit7:Enable serial port / Bit4:Continu ontvangen
HSERIAL_TXSTA = %00000000 ;Bit5:Transmitpin uitgeschakeld (TXEN (Transmit ENable) = 0)
DIM OntvangenData AS DWORD
DIM Trip1 AS WORD
DIM Ident AS OntvangenData.BYTE2
DIM Waarde AS OntvangenData.WORD0
hoofdlus:
HSERIN 300, Verder, [OntvangenData]
verder:
IF Ident= 1 AND Waarde <> Trip1 THEN
Trip1 = Waarde
endif
;Trip1 wordt hier omgerekend en dmv een interrupt op 4*7 segementen gemultiplexed
goto hoofdlus
Als ik nu via een derde pic een ander serieel signaal erdoorheen stuur, gaat het fout. Er verschijnen allerlei getallen etc op mijn display.
Nu heb ik twee vragen:
1. hoe kan ik er voor zorgen dat de signalen "zuiver" blijven? Hoe gaat dit met het domotica project?
2. Is de code zoals hier beschreven een goede manier, werken met een Dword, of hoe kan het beter? Een DWord past toch niet in de UASRT Buffer..
Twee "zelf" bedachte mogelijke oplossingen, maar wil ik graag jullie mening over:
Opl1: met een willekeurige poort (die ik niet veel over heb op sommige pics) een lijn hoog zetten en houden terwijl er gezonden wordt. Er moet dan gewacht worden met zenden door een andere pic totdat deze lijn laag is. (Waarom is dit niet nodig bij het Domotica project??)
Opl2. om een word variabele te zenden eerst (met een identifier) het lage gedeelte sturen en hierna met een identifier het hoge gedeelte. Dit kost mij dan wel het dubbele aantal identifiers en ik weet niet of ik dan aan 256 genoeg ga hebben als er per word variabele 2 gebruikt dienen te worden.
Frits Kieftenbelt
Ohm sweet Ohm | www.picbasic.nl
In het domotica project van picbasic.nl wordt een buffer gebruikt (zie de tweede .bas listing in het artikel).
hallo Frits,
Bedankt voor de reactie!(just the man I was looking for!)
Ik weet dat jij een (software)buffer hebt gebruikt maar ik ben niet zozeer perse geinteresseerd in alle informatie, maar meer in de huidige informatie. ( als er een keertje info verloren gaat is niet zo erg..). Daarom heb ik de buffer eruit gehaald.
maar , voorkomt de buffer dan dat als er een pic een serieel signaal stuurt terwijl een andere pic tegelijk een serieel signaal stuurt, het een zooitje wordt?
wat vindt jij van het werken met een Dword of heb jij een betere manier voor het oversturen van een Word Variabele?
PS, Ik heb je nooit gezegd wat een super site je hebt gemaakt!! Veel dank!!!
Frits Kieftenbelt
Ohm sweet Ohm | www.picbasic.nl
Om het zo eenvoudig mogelijk te houden wordt er bij mij thuis niet gekeken of een andere PIC iets aan het verzenden is.
Theoretisch kan dat een keer mis gaan natuurlijk, maar ik heb dat nog niet meegemaakt.
De bus door het huis heeft bij mij vrijwel niets te doen, als er bijvoorbeeld een opdracht "raam openen" over de bus gaat (16-bits, WORD variabele), dan gebeurt dat in minder dan 7mSec (langzame snelheid 2400 Baud).
Het zou wel heel toevallig zijn als op dat moment ook een andere PIC gaat zenden.
Anders wordt het natuurlijk als zich er druk dataverkeer over de bus bevindt (bij mij niet van toepassing dus).
De software buffer had ik echter wel nodig, want als een (ontvangende) PIC met een opdracht bezig is die relatief lang duurt (bijvoorbeeld raam openen, 3 seconden), en ik stuur in die tijd een andere opdracht, dan zou de PIC die bezig is met (PWM) raam openen, deze tweede opdracht missen.
__________________________________________________________________________
Als elke PIC met een buffer werkt, dan zou je het zo kunnen maken dat áls zich er data in de buffer bevindt, dan mag de ontvangende PIC zelf niet gaan zenden.
En een DWORD kun je beter splitsen in twee WORDS die meteen na elkaar in de softwarebuffer van de ontvangende PIC worden opgeslagen (zie het programma van het domotica artikel).
Je kunt de softwarebuffer er dus wel uithalen maar dan maak je het jezelf lastig omdat de PIC hardwarematig maar één WORD buffer heeft.
Hoi Frits,
Bedankt! Ik denk dat ik inderdaad de software buffer ook in ga bouwen, sowieso om de zendopdracht "tegen te houden". dit is een geweldig idee.
Om twee WORD vars ipv 1 Dword variabele achter elkaar te ontvangen en in de softwarebuffer te zetten, blijft het zendcommando zoals boven (code uit eerste post) toch gelijk?
In 1 van mijn programmas draait al een stopwatch en een meterteller op de interrupt. (zie volgende code). Wat de interrupt genereerd wordt onderscheiden door een "identificatie flag". (if Pir1.0 = 1 of intcon.2 =1). Wat moet ik voor de ontvangst van de data gebruiken? Ik heb ergens gelezen dat PIR1.5 wordt geset, maar dit is volgens mij als alle data binnen is en de interrupt wordt toch gegenereerd als de seriele data begint (daarom de 7ms delay?). ik weet niet of een 7ms delay in de interrupt mijn andere interrupts in gevaar zal brengen..
Als de interrupt pas gegenereerd wordt wanneer de ontvangst is gedaan (in de hardware buffer) dan zouden twee (bijna) gelijktijdig verzonden signalen nog een probleem kunnen zijn..toch?
INTERRUPT_ROUTINE:
IF PIR1.0= 1 THEN ; TMR1 voor de stopwatch
CLEAR T1CON.0 ' STOP TMR1
TIMER1REG = TIMER1REG + TMR1_VAL ' LOAD TMR1
SET T1CON.0 ' START TMR1
INC swTijdophoging ;verhoog de tijd met 1 (dit is iedere 0,25 seconde)
CLEAR PIR1.0 ' CLEAR TMR1 INTERRUPT FLAG
ENDIF
IF INTCON.2 = 1 THEN ;TMR0 voor de tripmeter
INTCON.2 = 0 ; clear overflow flag
TMR0 = 0
OverFlowVar = OverFlowVar + 256
ENDIF
CONTEXT RESTORE
Nieuwsgierigheid; Waarom heb jij gekozen om de eerste en tweede byte software matig te scheiden en niet zoals ik heb gedaan met een extra variabele? Werkt dit niet goed?
Bedankt voor alle hulp. Ik ga deze week eens flink testen en stoeien met deze nieuwe ideeen. Keep you posted.
Frits Kieftenbelt
Ohm sweet Ohm | www.picbasic.nl
Ik splits de WORD in twee BYTEs om de simpele reden dat de eerste 8 bits een 'Opdracht' zijn en de tweede 8 bits een eventuele meegezonden 'Waarde' (lees de tekst bij het artikel).
Zoals je ook in het artikel kunt lezen duurt een WORD verzenden bij 2400 Baud iets minder dan 7mSec.
Als ik de time-out korter zet, dan springt het programma bij 'Interruptafhandeling' naar label 'Verder' vanwege de timeout, omdat de data niet op tijd binnen is (logisch, want die duurt dus zo'n 6,7mSec, ik kan hem dus niet korter zetten dan 7mSec).