Nieuws:

Nu in MSM 272 TEST: Märklin reeks 17 | L.S.Models 2707 Certus | Piko NS 7501 | P.I.R.A.T.A. NS-nachttrein

Hoofdmenu

Micro-PlC

Gestart door conducteur, 04 augustus 2014, 01:37:41 AM

conducteur

#105
Op basis van Geert zijn site al een hoop code in elkaar gestoken. Theorethisch zou mijn code "werken", maar dat zal allicht niet waar zijn.

Deze routine moet uitmaken of de puls "0" of "1" is, maar met gewoon delays zal ik voor dit programma allicht veel te veel tijd verliezen? Moet nu ook nog kijken voor een oplossing voor die controllers zonder interne klok : rc kring op het printje foefelen, of nieuwe?



procedure bitdetect is


while !dcc loop  ; wacht op dcc-puls
end loop


    _usec_delay(80)     ; wacht (58µs (1) <80µs <100µs (0)
      if dcc then        ;is puls "0" of "1"
          dccbit=false   ;ontvangen bit is 0
      else
          dccbit=true   ; ontvangen bit is 1
       end if
end procedure



rest programma:

-------------------------------------------------------------------------------
;wisseldecoder met uplc module
;pic 16f886
;v1.0
-------------------------------------------------------------------------------
include 16f886
pragma target osc INTOSC_NOCLKOUT    -- HS crystal or resonator
pragma target clock 8_000_000        -- oscillator frequency
pragma target WDT  control           -- WDT off
pragma target LVP  disabled           -- no low voltage programming


alias dcc is pin_c7
pin_c0_direction = input   ;dcc signaal op rc7


alias dipswitch is porta_low
porta_low_direction = input


alias wissels is portb
portb_direction = output


include delay
var bit dccbit
    var bit startbit
    var byte ontvangst ; bytes worden "ontvangen" door routine en opgeslaan in de variabele
    var byte adres     ; ingesteld adres
    var byte adresbyte ; byte met verzonden adres
    var byte databyte  ; byte met verzonden data
    var byte checksum  ;controlebyte


--------------------------------------------------------------------------------
;is puls "1" of "0"
--------------------------------------------------------------------------------
procedure bitdetect is


while !dcc loop  ; wacht op dcc-puls
end loop


    _usec_delay(80)     ; wacht (58µs (1) <80µs <100µs (0)
      if dcc then        ;is puls "0" of "1"
          dccbit=false   ;ontvangen bit is 0
      else
          dccbit=true   ; ontvangen bit is 1
       end if
end procedure
--------------------------------------------------------------------------------
;receive byte - ontvang 1 byte
--------------------------------------------------------------------------------
procedure receiveByte is
   ontvangst=0
  for 8 loop
  bitdetect
   ontvangst=(ontvangst+dccbit)<<1
   end loop
end procedure
--------------------------------------------------------------------------------
;procedure receive "0"; voor ontvangst "0" tussen bytes
---------------------------------------------------------------------------
procedure receive0 is
startbit=false
while !startbit loop
  bitdetect
  if dccbit then
  startbit=!startbit
  end if
end loop
end procedure
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
;procedure receive "1"- voor ontvangst "1" op einde pakket
--------------------------------------------------------------------------------
procedure receive1 is
startbit=false
while startbit loop
  bitdetect
  if dccbit then
  startbit=!startbit
  end if
end loop
end procedure




adres = 0x80 + dipswitch ;adres instellen 4 bit dip switch




forever loop
teller=0
  while (teller<=10) loop


   bitdetect
   if dccbit then
   teller=teller + 1
   else
   teller=0
   end if
  end loop
 
  receiveByte ; ontvang adres
  adresbyte=ontvangst
  receive0    ;ontvang 0
 
  receiveByte ;ontvang data
  databyte=ontvangst
  receive0
 
  receiveByte ;ontvang checksum
  checksum=ontvangst
  receive0
 
if ((adresbyte^databyte^checksum)==0)&&(adresbyte==adres) then
   case (databyte) of


   0xF8: block
   wissels=0x01
   end block
   
     0xF9: block
   wissels=0x02
   end block
   
     0xFA: block
   wissels=0x04
   end block
   
     0xFB: block
   wissels=0x08
   end block
   
   0xFC: block
   wissels=0x10
   end block


     0xFD: block
   wissels=0x20
   end block


     0xFE: block
   wissels=0x40
   end block


     0xFF: block
   wissels=0x80
   end block
   
   otherwise block
   end block


   end case
   delay_1ms(250)
   wissels=0
   
   
   
   end if




end loop


Rian 2-Rail DCC NMBS TPIII
Grote Modeltreinruilbeurs Blankenberge Pasen 2016
Zaal Forum

Sattrickske

Je kan de pulsdetectie van DCC op verschillende manieren bekomen.

Jouw manier is de simpelste, maar je verliest veel nuttige processor tijd door de delay routine.  De code die je hebt is correct (ben wel niet zeker van die 80 µsec, 'k zal thuis eens in de specs moeten gaan piepen).

De tweede manier is via 2 interrupts: één interrupt op de rising flank van het DCC signaal en één op een timer van 80 µsec (zelfde opm als hierboven, ben niet zeker).  Van zodra je de rising flank ziet (eerste interrupt), start je de timer die exact na 80 µsec de 2e interrupt genereert. Dan lees je het DCC signaal opnieuw en beslis je of het 0 of 1 was.

Een derde manier is zeer gelijkaardig: 1 interrupt en een free running timer.  De interrupt is op het DCC signaal, maar level based (ziet dus de overgang van 0 naar 1 en 1 naar 0).  Bij de overgang van 0 naar 1 registreer je de tijd van de free running timer.  Bij de overgang van 1 naar 0 neem je weer de tijd op en trek daarvan af de tijd voor de overgang van 0 naar 1.  Je hebt dan een exacte pulsbreedte en dus kan je weer beslissen of het een 0 of een 1 was.

Hier bestaan nog heel wat varianten op (hardware en software), maar het principe valt steeds terug op één van de hierboven beschreven methodes.

Mijn C-bibliotheek gebruikt de 2e methode, als je die code wil, stuur je me maar een PB...

Geert

Gewoon met delay kan dit zeker werken. Als je een correct data pakket hebt ingelezen (om wissels aan te sturen!), dan zal de DCC centrale een redelijke lange pauze (een lange nul) doorsturen. Dan kan je de data verwerken. Klopt het adres?, spoel aan, spoel uit enz... . Na verwerking begin je weer de eerste reeks préamblebits in te lezen, adresbyte, databyte en tenslotte errorbyte.

Wil je tegelijkertijd wel andere dingen doen, servopulsen opwekken bv. dan moet dit inlezen van de bits best via interrupt.

Geert
Schaal H0 - digitaal zelfbouw - Favoriete Lok: V200 DB

Sattrickske

Je 80µs is goed.  Heb hier de standaard gevonden en op pag. 1 paragraaf 3 en 4:
Citeer
In a "1" bit, the first and last part of a bit shall have the same duration, and that duration shall nominally be 58 microseconds2, giving the bit a total duration of 116 microseconds. Digital Command Station components shall transmit "1" bits with the first and last parts each having a duration of between 55 and 61 microseconds. A Digital Decoder must accept bits whose first and last parts have a duration of between 52 and 64 microseconds, as a valid bit with the value of "1".

In a "0" bit, the duration of the first and last parts of each transition shall nominally be greater than or equal to 100 microseconds. To keep the DC component of the total signal at zero as with the "1" bits, the first and last part of the "0" bit are normally equal to one another. Digital Command Station components shall transmit "0" bits with each part of the bit having a duration of between 95 and 9900 microseconds with the total bit duration of the "0" bit not exceeding 12000 microseconds. A Digital Decoder must accept bits, whose first or last parts have a duration between 90 and 10,000 microseconds, as a valid bit with the value of "0". Figure 1 provides
an example of bits encoded using this technique.
Dus elke delay of timer >64 µs én <90 µs is voldoende.

conducteur

Citaat van: Geert op 02 september 2014, 12:51:04 PM
Gewoon met delay kan dit zeker werken. Als je een correct data pakket hebt ingelezen (om wissels aan te sturen!), dan zal de DCC centrale een redelijke lange pauze (een lange nul) doorsturen. Dan kan je de data verwerken. Klopt het adres?, spoel aan, spoel uit enz... . Na verwerking begin je weer de eerste reeks préamblebits in te lezen, adresbyte, databyte en tenslotte errorbyte.

Wil je tegelijkertijd wel andere dingen doen, servopulsen opwekken bv. dan moet dit inlezen van de bits best via interrupt.

Geert
We blijven voorlopig eenvoudig. Het principe van die 80µs zou idd moeten werken, maar de vraag is: heb ik na die 80µs nog tijd genoeg over om de rest van de opdrachten in het programma uit te voeren? Riskeer ik op die manier niet de volgende puls te missen?
Rian 2-Rail DCC NMBS TPIII
Grote Modeltreinruilbeurs Blankenberge Pasen 2016
Zaal Forum

Geert

Als je een 1 inleest heb 58x2 is 116 microseconden. Dan blijft er na die 80 er nog 36 over. Bij 8Mhz zijn dat een 80 tal ASM instructies. C taal leunt daar dicht bij aan, dus ik denk geen probleem.

Geert
Schaal H0 - digitaal zelfbouw - Favoriete Lok: V200 DB

Havoc

Rian, die print ziet er toch goed gesoldeerd uit? Veel netter is dat bij mij ook niet.

Voor die pics kan je ook een kristal van 32.768 kHz gebruiken. Die bestaan in hel kleine afmetingen: bvb de 1009261 van Conrad. Die is 2x1.2x0.6 mm... Krijg je toch wel nog ergens in een hoekje. :D
Met vakantie voor onbepaalde duur.

conducteur

Ja, dat zijn die dingen om een real-time-clock mee op te bouwen. Ik vermoed dat het daarmee niet zal lukken? De 8 weerstandjes tussen de transistoren  zin goed gelukt, die andere 4 op een rijtje daarentegen ben ik niet zo content van.
Rian 2-Rail DCC NMBS TPIII
Grote Modeltreinruilbeurs Blankenberge Pasen 2016
Zaal Forum

Geert

Je kan op de µC ook gewoon een logische externe klok van bijvoorbeeld 4 MHz aanluiten. Deze kan dan weer afkomstig zijn van een ander printje waar wel plaats is voor een nauwkeurige kristal. Deze externe klok kan je voor meerdere µC gebruiken en via een extra pin op je printje plaatsen. Zie datasheet bij oscilator mogelijkheden µC ....

Geert
Schaal H0 - digitaal zelfbouw - Favoriete Lok: V200 DB

conducteur

Ik denk dat het eenvoudigste is gewoon kijken voor een µC met een interne klok aan te kopen, en die die ik heb nog even in het schuifje laten liggen ipv alle "gepruts". Volgende keer dan niet vergeten voor het kristal te plaatsen.
Rian 2-Rail DCC NMBS TPIII
Grote Modeltreinruilbeurs Blankenberge Pasen 2016
Zaal Forum

Havoc

Citaat van: conducteur op 02 september 2014, 14:05:05 PM
Ja, dat zijn die dingen om een real-time-clock mee op te bouwen. Ik vermoed dat het daarmee niet zal lukken? De 8 weerstandjes tussen de transistoren  zin goed gelukt, die andere 4 op een rijtje daarentegen ben ik niet zo content van.

Volgens de datasheet kan de pic daarmee werken.
Met vakantie voor onbepaalde duur.

Geert

Ik denk dat Rian bedoeld dat deze kristal gewoon te traag is  ;) voor DCC detectie

Geert
Schaal H0 - digitaal zelfbouw - Favoriete Lok: V200 DB

conducteur

#117
Inderdaad... 32768 is niet toevallig gelijk aan 2^15, wat het eenvoudig maakt om daarmee seconden te gaan tellen, met een 16 bit binaire teller. Elke keer deze een overflow genereert is (vrij) nauwkeurig 1 seconde verstreken.
Rian 2-Rail DCC NMBS TPIII
Grote Modeltreinruilbeurs Blankenberge Pasen 2016
Zaal Forum

Havoc

Citaat van: Geert op 02 september 2014, 14:56:19 PM
Ik denk dat Rian bedoeld dat deze kristal gewoon te traag is  ;) voor DCC detectie

Geert

Hoe? Heeft die rommel geen ingebouwde multiplier?
Met vakantie voor onbepaalde duur.

conducteur

Als ik het goed voor heb wordt de frequentie intern zelf gedeeld door 4. Wat het nut daarvan is moet je aan de experts hier vragen.
Rian 2-Rail DCC NMBS TPIII
Grote Modeltreinruilbeurs Blankenberge Pasen 2016
Zaal Forum