Doel:€250.00
Donaties:€50.00

Per saldo:€-200.00

Steun ons nu!

Laatst bijgewerkt
op 03-01-2024

Vacature: secretaris bestuur
Algemeen

De stichting

Recente berichten

Mijn eerste H0-modeltreinbaan in aanbouw door puntenglijder
Vandaag om 21:15:13
welk jaar ging Marklin OVP voor wagons van blauw naar wit door Keska
Vandaag om 21:14:54
LokSound 4 decoders, files verbeteren (voor Roco b.v. TEE RAm, NS2400, etc) door mamory
Vandaag om 21:13:06
Bouw van materieel 40 treinstellen door Rob Bennis
Vandaag om 21:09:04
Gebruik je Arduino zonder te "programmeren" ;) door Menno
Vandaag om 20:58:29
30 maart Modelspoorbeurs Houten & HCC Kennisdag door basjuh1981
Vandaag om 20:54:43
De Hondsrugbaan door basjuh1981
Vandaag om 20:53:58
US diorama in H0 door basjuh1981
Vandaag om 20:52:48
Raadplaatje door eemstede
Vandaag om 20:43:38
NS GLY omspuiten en opschriften door orientexpress
Vandaag om 20:42:10
Engelse wagon uit 1930 opgegraven in Antwerpen door Entity
Vandaag om 20:37:25
Hengelo in 1981-1982, maar dan anders: Kassenberg in N door 1200blauw
Vandaag om 20:32:41
Onlangs gespot - gefotografeerd, de foto's door eemstede
Vandaag om 20:31:17
Welke Vallejo kleur voor drijfstangen van een DB stoomlocomotief? door Ronald69
Vandaag om 20:00:39
Toon hier je nieuwe (model-) spooraanwinst(en)... door arnout
Vandaag om 19:53:27
Punt- en hartstukken door Klaas Zondervan
Vandaag om 19:41:21
MARDEC, de Multifunctionele ARduino dcc DECoder. door bord4kop
Vandaag om 19:34:37
De (3d) knutsels van Ronald. door gdh
Vandaag om 19:22:56
Piko NS 2015 stroomafname probleem door Ben
Vandaag om 19:08:30
Bauarbeiten im gange door ruudns
Vandaag om 18:50:26
HSM D1715 door vpeters1984
Vandaag om 17:34:25
Beekdaelen in H0 door Stieven76
Vandaag om 17:17:41
Al mijn goede ideeën... door Monobrachius
Vandaag om 17:10:33
Ombouw/Pimpen Bolle neuzen door bollen neus
Vandaag om 15:58:15
Kleine Baan in H0 (≤ 0.5m²) door Jack Black (NS1220)
Vandaag om 15:06:14
U-vorm beperkte ruimte (H0 C-rails) door Jelmer
Vandaag om 14:58:04
Onlangs gespot - gefotografeerd, de links door Jeroen Water
Vandaag om 14:33:00
N spur scenery elementen maken van gips of klei? door Dave.......
Vandaag om 14:30:06
De overeenkomst tussen een Ovaalramer en een Motorpost. door RK
Vandaag om 14:28:54
BMB-Module: “Corfe Castle Station” door Hans van de Burgt
Vandaag om 14:07:52
  

Auteur Topic: Zelf gemaakte DCC-centrale werkt niet helemaal  (gelezen 13776 keer)

bask185

  • Offline Offline
  • Berichten: 4007
Zelf gemaakte DCC-centrale werkt niet helemaal
« Gepost op: 24 maart 2019, 16:32:32 »
Beste modelspoor fanaten,

Ik ben afgelopen week druk bezig geweest met het uitpluizen van DCC pakketjes voor een zelf gemaakte arduino centrale.

Vandaag wilde ik testen en helaas de trein wilt niet rijden  :(

De hardware bestaat uit; een 15V DC voeding die ik nog had rondslingeren, een arduino nano, een 2.5A H-brug en een schakelende voeding van 15V naar 5V voor de arduino. Er zit ook nog een printje voor de Rs485 bus maar deze is nog niet gebruik. Ik heb het met 2 treinen geprobeerd en het spoor is schoon.


Het grootste probleem is dat ik nog werk met een iet wat antieke oscilloscoop en niet makkelijk het hele signaal kan aanschouwen.

Wel heb ik dmv data te dumpen op het scherm bevestigd dat de geassembleerde bit reeks klopt, althans dat hij is wat ik denk dat het moet zijn.
//11111111111111 0 00001001 0 01110101 0 10011001 0 10110000 0 10111001 1 0000
//14 bit preable   address 9  speed 9       ^  ^      F5-F8    checksum   4 trailing 0's
//                                          |  |
//                                        headlight 
//                                             |
//                                           F1-F4
Ik klok alles uit van links naar rechts.
Ik heb dit adhv de nmra website samengesteld:
Speed and Direction Packet For Locomotive Decoders
111111111111 0 0AAAAAAA 0 01DCSSSS 0 EEEEEEEE 1

Preamble Byte One Byte Two Byte Three (Error Detection Data Byte)

Dus mijn eerste vraag: stel ik de data pakketten goed samen?

Tweede vraag: de checksum byte. De nmra website is niet bijzonder duidelijk. Het komt er op neer dat je alle data adress bytes met de data bytes moet XOR'en. Maar nu heb ik 1 adres byte en 3 data bytes. Moet ik nu voor de checksum 1 byte sturen of 3 bytes? En als het 3 bytes zijn, moet er dan ook nog een '0' bit hier tussen? (Ik dacht dat er tussen bytes altijd en immer een 0 bit moet zitten  ???)

De software heb ik zo simpel als mogelijk gehouden. Via de seriele bus stuur ik van de computer een pakketje van 5 bytes. Een * om door te geven dat ik een instructie stuur. Een adres byte, een snelheid byte, een byte voor de koplampen en nog een byte voor F1 t/m F8. Ik heb er bewust voor gekozen om te beperken tot slechts 8 functies.

Ik stuur continu pakketten voor adres 1 t/m 80.
Als een pakket verstuurd is, incrementeer ik het adres, prepareer een nieuw pakket en begin opnieuw.

In deze functie worden de pakketten samengesteld. Ik heb een struct array 'train' gemaakt. Elke 'train' bestaat uit 3 bytes voor de snelheid en functies.
void assemblePackets() {
  byte speed_tmp;                                              // make local variable for speed to calculate with

  /******  ADDRES  *******/ 
  packetAddres = addres;

  /******  SPEED  *******/ 
  speed_tmp = train[addres].speed;                                    // store speed in 'speed_tmp' to calculate with
  packetSpeed = 0;                                                    // clear byte for re-usage
  if(speed_tmp < 0) {
    packetSpeed |= REVERSE;                                           // set flag for reverse speed direction
    speed_tmp ^= 0xff;                                                // invert the byte if is negative to positive using XOR
    speed_tmp++; }                     
  else {
    packetSpeed |= FORWARD; }                                         // set flag for forward speed direction
                     
  packetSpeed |= (speedTable[speed_tmp + 4] & 0b11111l);             
  // first 4 speed steps are (E)stop commands, the last 5 bytes contain the speed information

  /******  FUNCTIONS F1 - F4  *******/ 
  packetFunctions1 = 0;                                               // clear byte for re-usage
  packetFunctions1 |= FUNCTIONS1;                                     // mark this as instructions byte
  if(train[addres].headLight) packetFunctions1 |= (1<<4);             // turns on headlight
  packetFunctions1 |= (train[addres].functions & 0x0F);               // F1 - F4

  /******  FUNCTIONS F5 - F8  *******/ 
  packetFunctions2 = 0;                                               // clear byte for re-usage
  packetFunctions2 |= FUNCTIONS2;                                     // mark this as instructions byte
  packetFunctions1 |= ((train[addres].functions & 0xF0) >> 4);        // F5 - F8

  /***** CHECKSUM *******/   
  packetChecksum = packetAddres ^ packetFunctions2;                   
  //packetAddres ^ packetSpeed  also tried..  must I send 3 checksum bytes?

  /***** SHIFT PACKETS FOR TRACK SIGNAL *******/
  bitArray[0] = 0xFF;
  bitArray[1] = 0xFC;  // pre-amble + 2 0 bits
  bitArray[2] = packetAddres << 1;
  bitArray[3] = packetSpeed;
  bitArray[4] = packetFunctions1 >> 1;
  bitArray[5] = packetFunctions1 << 7 | packetFunctions2 >> 2;
  bitArray[6] = packetFunctions2 << 6 | packetChecksum >> 3;
  bitArray[7] = packetChecksum   << 5 | 1<<4;
}

De kern van de code ziet er als volgt uit:
ISR(TIMER1_COMPB_vect)
{
  if(ISR_state == 0){                                       // pick a bit and set duration time accordingly 
    ISR_state = 1;
    Bit = (*ptr & (0x80 >> bitCounter)) >> (7-bitCounter);  // select the next bit out of bitArray

    if(Bit == 1) OCR1A=DCC_ONE_BIT;                         // '1' 58us
    else         OCR1A=DCC_ZERO_BIT;                        // '0' 116us

    // Serial.print(Bit);
    // enabling this, showed me that the the variable 'Bit' is always what it should be
    bitCounter++;
    if(bitCounter==8) {
      bitCounter = 0;

      ptr++;                                                // select the next byte from bitArray
      if(ptr == (&bitArray[7] + 1)) {                       // if last byte is done
        ptr = &bitArray[0];
        OCR1A = 0xFFFF;                                     
        // temporarily susppend ISR by setting compare register at 0xfff untill the main routine has assembled a new package       
        packetSent = 1;} } }

  else {
    ISR_state = 0;
    PORTB ^= 0X3; } // toggle pin 8 and 9 for direction
}
Dit is het ISR. Het is de bedoeling dat 'Bit' of een 0 of een 1 is en adhv dit, wordt de ISR tijd op 58 of 116us gezet. De 2e keer dat het ISR wordt doorlopen, worden de 2 richtings I/O (voor de H-brug) getoggled. Als ik de Serial.print instructie uit commentaar haal (wat eigenlijk niet gewenst is in een ISR), zie ik dus wel alle bits in de (hopelijk) juiste volgorde op het scherm worden geprint.

Ik heb met mijn primitieve scope wel kunnen bevestigen dat de ISR tijden (compare match register) kloppen. Nadat ik ze had berekend, zag ik dezelfde waardes in een ander stukje arduino code van iemand anders.

void nextPacket()
{
  packetSent = 0;
    ptr = &bitArray[0];               // set the pointer back to the first bit
    bitCounter = 0;
    addres++;                         // if it is sent, increment addres
    if(addres > 10) addres = 1;       // address range is 1-80
    assemblePackets();                // assemble a new package
    Serial.println();
    Serial.println(addres);
    OCR1A=927; 
}

void loop()
{
  readSerialBus();
  shortCircuit();
  EstopPressed();
 
  if(packetSent) nextPacket();
}
Dit is de rest van het programma. Ik gebruik een pointer ptr, die wijst naar 1 van de bytes uit bitArray. De bitCounter wordt gebruikt om de indivuele bits te benaderen.

Kan iemand mij vertellen wat het precies is dat ik verkeerd doe?  ::)

Met voorbaat dank,

Bas.






« Laatst bewerkt op: 26 maart 2019, 22:38:56 door Bert van Gelder »
Train-Science.com
Train-Science github
It ain't rocket science ;-)

Remco_Nzo

  • Offline Offline
  • Berichten: 274
Re: Zelf gemaakte DCC centrale werkt niet helemaal
« Reactie #1 Gepost op: 24 maart 2019, 17:00:30 »
Je kunt ook een andere manier gebruiken om te checken.
Pak een tweede arduino, laad daar de standaard DCC-monitor-sketch op zet en sluit hem aan op de rails (via de opto zoals bij de documentatie is uitgelegd. Is hetzelfde schematje als Mardec gebruikt)
Dan zie je of standaard NMRA software jouw berichtenstroom kan decoderen.
Is geen 100% garantie voor alle consumers - maar zegt in iedergeval iets.

Remco.
N-spoor in de koelkast gezet - nu heerlijk bezig met LGB op zolder (dcc, multimaus, massoth, mardec, arloco)

Timo

  • Team encyclopedie
  • Offline Offline
  • Berichten: 4656
Re: Zelf gemaakte DCC centrale werkt niet helemaal
« Reactie #2 Gepost op: 24 maart 2019, 17:39:10 »
Hoi Bas,

Leuk bezig! (y) Maar nog een bijzondere reden dat je niet een van de standaard libraries wilt gebruiken?

Dus mijn eerste vraag: stel ik de data pakketten goed samen?
Dat is ff puzzelen. Je quote de layout van een baseline pakket maar je wilt zo te zien een extended pakket sturen.

Dus nee, volgens mij is dat niet juist. Volgens mij moet je snelheid en functie als twee losse pakketjes sturen
Snelheid
{preamble}     0 AAAAAAAA 0 CCCDDDDD 0 EEEEEEEE 1
11111111111111 0 00001001 0 01110101 0 01111100 1
Preamble       | |          |  |       |        |
               start        |  |       |        |
                 addres 9   |  |       |        |
                            011 = Speed and Direction Instruction for forward operation
                               Speed 8 |        |
                                       Error = XOR
                                                Stop
Functies
{preamble}     0 AAAAAAAA 0 CCCDDDDD 0 EEEEEEEE 1
11111111111111 0 00001001 0 10011001 0 10010000 1
Preamble       | |          |  ||      |        |
               start        |  ||      |        |
                 addres 9   |  ||      |        |
                            Function Group One Instruction
                               F0 = on |        |
                                F4 = on, F3 = off, F2 = off, F1 = on
                                       Error = XOR
                                                Stop

Moet ik nu voor de checksum 1 byte sturen of 3 bytes?
Altijd 1 byte met de XOR van alle voorgaande bytes.

Niet heel hard naar de code gekeken maar toch paar vragen:

Voor de ISR, ik zie dat je een aantal variabelen gebruikt. Zijn deze als volatile gedeclareerd? En benader je ze ook nog extern? Volgens mij zijn ze allen alleen in de ISR nodig dus zou het handiger / veiliger zijn ze als local static te definiëren.

Bit: Waarom niet bit?
ISR_state: Probeer zelf altijd één stijl aan te houden, dus waarom niet IsrState?
DCC_ONE_BIT / DCC_ZERO_BIT: ziet er uit als een macro, weet dat C++ ook const kent ;)
(&bitArray[7] + 1)) mag ook zijn &bitArray[8] maar zou het denk ik zelf als constante buiten de IRS om definiëren om flexibel te blijven.
ptr: gebruik je deze ook nog buiten de ISR? Zo ja, dan moet je de ISR uitschakelen tijdens het lezen. Als anders de ISR vuurt als je aan het lezen bent ben je namelijk in de aap gelogeerd daar een pointer niet atomic is ;)

En ow
        packetSent = 1;} } }Het maakt niet uit welke stijl van C je schrijft, dat is een doodzonde ;D :police: Sluithaken altijd op een nieuwe regel in lijn met het begin van de regel waar de openingshaak staat. Maakt het ook zooooo veel leesbaarder ;)

Timo
« Laatst bewerkt op: 24 maart 2019, 18:04:55 door Timo »
Verzonden vanaf mijn desktop met Firefox

Timo

  • Team encyclopedie
  • Offline Offline
  • Berichten: 4656
Re: Zelf gemaakte DCC centrale werkt niet helemaal
« Reactie #3 Gepost op: 24 maart 2019, 19:11:53 »
Ow, en gooi deze maar in je winkelwagen ;) Mooie aanvulling op je scope voor dit werk. Let wel, 5V max maar dat is zo opgelost met een opto (y)


Timo
Verzonden vanaf mijn desktop met Firefox

bask185

  • Offline Offline
  • Berichten: 4007
Re: Zelf gemaakte DCC centrale werkt niet helemaal
« Reactie #4 Gepost op: 24 maart 2019, 19:55:50 »
Bit: Waarom niet bit?
Naja, da's een makkelijke. Ik maak dit in de arduino ide en dat komt zo heel af en toe met een haak en een oog. 'bit' wordt namelijk gehighlight in de ide. 'speed' die ik ook gebruik, wordt ook gehighlight alleen die kan je wel gebruiken. Arduino's ide kennende, zal bit wel bedoeld zijn om een soort bit variabele te maken of weet ik veel waar het 'bit' keyword voor gebruikt wordt

ISR_state: Probeer zelf altijd één stijl aan te houden, dus waarom niet IsrState?
Je hebt gelijk meestal begin ik met een kleine letter en elk nieuw woord met een hoofdletter, ik weet eigenlijk niet waarom ik hier een uitzondering gemaakt heb. Woorden als ISR tik ik wel altijd in hoofdletters, kwenie waarom ik dat doe. Ik denk dat ik dat voor afkortingen doe. Dus hiervan maak ik dan ISRstate van. Ik gebruik _ meestal voor _bool en _prev.

DCC_ONE_BIT / DCC_ZERO_BIT: ziet er uit als een macro, weet dat C++ ook const kent ;)

(&bitArray[7] + 1)) mag ook zijn &bitArray[8] maar zou het denk ik zelf als constante buiten de IRS om definiëren om flexibel te blijven.
Ja ik dacht er aan dat het hier wel kon, maar ik ben schurftig om buiten de vastgelegde array grenzen te treden  ;D. Die dingen op mijn werk crashen altijd als ik dat probeer. Net als dat ik nooit bit en boolean variabele gebruik. Mijn 8051 core kan ook met bits werken (hij gebruikt dan ook echt 1 bit in het geheugen ).  Maar ik deed er ooit iets mee wat niet kon en niet werkte icm een if statement. Dat was de laatste keer dat ik een bit gebruikte. Ik werk alleen met hele bytes


ptr: gebruik je deze ook nog buiten de ISR? Zo ja, dan moet je de ISR uitschakelen tijdens het lezen. Als anders de ISR vuurt als je aan het lezen bent ben je namelijk in de aap gelogeerd daar een pointer niet atomic is ;)
Ja, maar voordat ik dat doe set ik de compare match register op 0xFFFF ik weet niet hoe lang dat precies is. Ik meen iets rond de 65535 /16000000 = 4ms. Dan stel ik een nieuwe pakket samen en zet ik het ISR weer op 58us. Ik weet niet 100% hoe deze timers werken, maar als die 58us al voorbij zijn, zal die wss wel meteen het ISR uitvoeren, maar dit is gis werk. Maar ik denk wel dat ik dat ombouw naar echt de ISR uitzetten, dat is zeker veel beter en veiliger.

En ow
        packetSent = 1;} } }Het maakt niet uit welke stijl van C je schrijft, dat is een doodzonde ;D :police: Sluithaken altijd op een nieuwe regel in lijn met het begin van de regel waar de openingshaak staat. Maakt het ook zooooo veel leesbaarder ;)
Dit is echt mijn beste uitvinding ooit. Ik had ooit ff in Python gespeeld en daar waren geen accolades. Die bestonden net zo min als end of line markers ;

Zodoende heb ik mijn eigen accolade gebruik ontworpen. Want ja we hebben tabs en we hebben wit regels, waarom zou je per sluitings accolade een aparte regel nemen als je aan de tabs ook al kan zien wat waar bij hoort. Als ik 3 accolades heb staan, dan weet ik precies dat de volgende regel 3 tabs naar voren begint. Ik heb daar geen 3 aparte wit regels voor nodig.

Weet dat, omdat je het nog nooit gezien heb of dat omdat het door de grote menigte niet is aangenomen of omdat het je raar lijkt, het niet noodzakelijk iets slechts is. Ik ben er al een lange tijd achter dat de beslissingen die de grote groepen nemen of beslissingen die lange tijden zijn genomen niet ook meteen de beste of goede beslissingen waren.

Als je deze stijl eenmaal gewend ben, wil je nooit meer anders  :P.

iig erg bedankt voor je antwoord. Ik dacht dat ik zoveel instructie bytes kon sturen als ik wilde. Dat leek me ook logisch omdat de decoder kan synchorniseren na elke byte en je niet telkens de pre-amble hoeft te versturen.

Ik zal mijn code aanpassen. En misschien dat ik de andere kant van de H-brug ga gebruiken omdat deze kant misschien niet helemaal meer werkt  ::)
Train-Science.com
Train-Science github
It ain't rocket science ;-)

bask185

  • Offline Offline
  • Berichten: 4007
Re: Zelf gemaakte DCC centrale werkt niet helemaal
« Reactie #5 Gepost op: 24 maart 2019, 20:00:30 »
also

Ik heb in de libraries gekeken, maar er staat erg erg erg veel in en het is niet allemaal even duidelijk wat alles doet. Ik wil graag weten wat ik precies aan het doen ben. En dan maak ik liever de keuze om zelf dingen uit te puzzelen en code te schrijven.

Ik kan wss wat ik wil met 1/20 van de code van die libraries
Train-Science.com
Train-Science github
It ain't rocket science ;-)

Timo

  • Team encyclopedie
  • Offline Offline
  • Berichten: 4656
Re: Zelf gemaakte DCC centrale werkt niet helemaal
« Reactie #6 Gepost op: 24 maart 2019, 20:51:29 »
iig erg bedankt voor je antwoord. Ik dacht dat ik zoveel instructie bytes kon sturen als ik wilde. Dat leek me ook logisch omdat de decoder kan synchorniseren na elke byte en je niet telkens de pre-amble hoeft te versturen.
Nee, volgens mij dus niet. Versterkt door:
Citaat
a packet using the extended packet format definition may have a length of between 3 and 6 data bytes each separated by a "0" bit. 
Bekeken vanuit een decoder is dat ook wel logisch.
- Preamble => alle decoders gaan weer opletten
- Adres => decoder met dat adres blijft opletten, rest haakt af
- CCC => Okay, prima, dat gaan we doen dus ik verwacht x bytes of dat commando ken (/ondersteun) ik niet, ik haak af
- DDDDD => weten gelijk waar dat moet

En daarnaast kan een pakket dus max 6 bytes zijn, je weet dus altijd hoeveel ruimte je moet hebben voor voor het ontvangen (maar ook voor het verzenden) van een pakket. En dat is ook handig voor de XOR.

Tuurlijk, er zijn wel omwegen maar die houdt het lekker makkelijk. Vooral als decoders bepaalde CCC's niet ondersteunen, dan zouden ze opvolgende data (met wel ondersteunde CCC) niet meer zien.

Eerste over libraries, zelf uitpuzzelen heeft zeker ook voordelen, dat ben ik met je eens.  (y) Maar je zou ook die verder kunnen uitpluizen. Toegegeven, zelf iets maken is leuker werk ;D

Maar dat er veel code in staat die je niet wilt gebruiken is niet zo erg. Als jij vervolgens die code ook niet aanroept zal die ook niet in de uC terecht komen  ;)

Wat betreft namen, iedereen heeft zijn eigen voorkeuren en dat is prima. Denk alleen dat het belangrijkste is dat je consistent bent anders kan je echt niet onthouden hoe je ook al weer iets genoemd had. Ik ga daarmee door op hoe Arduino dat doet: camelCaseVoorVariabelen UpperCamelCaseVoorConstants (en classes), ALL_CAP_UNDERSCORE voor macro's (die ik zo veel mogelijk niet gebruik maar C++ alternatieven). Dingen met afkortingen zoals ISR zijn dan wel een twijfelgeval inderdaad. Maar ik ga dan voor IRSStatus (elke hoofdletter een los deel aan in uitspraak Ie eR eS Status). Maar nogmaals, consistent zijn is belangrijker!

Naja, da's een makkelijke. Ik maak dit in de arduino ide en dat komt zo heel af en toe met een haak en een oog. 'bit' wordt namelijk gehighlight in de ide. 'speed' die ik ook gebruik, wordt ook gehighlight alleen die kan je wel gebruiken. Arduino's ide kennende, zal bit wel bedoeld zijn om een soort bit variabele te maken of weet ik veel waar het 'bit' keyword voor gebruikt wordt
Mja, de highlight functie uit de IDE is %^$&^*$%^$%^&*$$%^. Er wordt niet gekeken naar welke libraries je gebruikt maar alle keyword.txt's worden op één hoop gegooid. De reden dat FadeLed dus geen keywords.txt heeft.

Maar goed, bit is misschien gebruikt ja. Maar zeer lokaal is een korte naam ook niet zo erg
const bool b= (*ptr & (0x80 >> bitCounter));  // select the next bit out of bitArray
//laatste shift is niet nodig
of je doet het gewoon in de if(). Toegegeven, voor debug kan het even handig zijn hem wel te hebben (maar een serial print is niet zo slim daar het een grote kans is dat die faalt).

Of een methode met minder schuiven:
ISR(TIMER1_COMPB_vect){
  static byte bitMask = 0x80;
 
  if(ISR_state == 0){                                       // pick a bit and set duration time accordingly
    ISR_state = 1;

    if(*ptr & bitMask){
      OCR1A = DCC_ONE_BIT;                         // '1' 58us
    }
    else{
      OCR1A = DCC_ZERO_BIT;                        // '0' 116us
    }

   // Serial.print(Bit);                                    // enabling this, showed me that the the variable 'Bit' is always what it should be
   //BUT a serial print from a ISR is a bad idea and fails A LOT
   
    bitMask >>= 1;
    if(!bitMask) {
      bitMask = 0x80;;

Ja ik dacht er aan dat het hier wel kon, [...]
Nouwja, ging meer om de onflexibele definitie van het einde van je array. Ik zou gewoon een eind pointer definiëren.

En daarnaast is de baan bitArray best wel verwarrend daar het een array van bytes is ;D En dat daar bitjes in zitten is nogal wiedes 8) Zou dus ook eerder spreken van packetArray ofzo.
byte packetArray[7];
byte * const PacketEndPtr = &packetArray[sizeof(packetArray)];

//of waarom eigenlijk nog losse pointers aanmaken, een array is al een pointer constructie
const byte PacketArraySize = 7;
byte packetArray[PacketArraySize];
//en gewoon een iterator in de ISR

[...]Maar ik denk wel dat ik dat ombouw naar echt de ISR uitzetten, dat is zeker veel beter en veiliger.
Dit is echt mijn beste uitvinding ooit. Ik had ooit ff in Python gespeeld en daar waren geen accolades. Die bestonden net zo min als end of line markers ;
Haha, ja. Bugs door non-atonic operaties op ISR variabelen is meestal een nachtmerrie om te debuggen.

Zodoende heb ik mijn eigen accolade gebruik ontworpen. Want ja we hebben tabs en we hebben wit regels, waarom zou je per sluitings accolade een aparte regel nemen als je aan de tabs ook al kan zien wat waar bij hoort. Als ik 3 accolades heb staan, dan weet ik precies dat de volgende regel 3 tabs naar voren begint. Ik heb daar geen 3 aparte wit regels voor nodig.

Weet dat, omdat je het nog nooit gezien heb of dat omdat het door de grote menigte niet is aangenomen of omdat het je raar lijkt, het niet noodzakelijk iets slechts is. Ik ben er al een lange tijd achter dat de beslissingen die de grote groepen nemen of beslissingen die lange tijden zijn genomen niet ook meteen de beste of goede beslissingen waren.
Haha, klopt. Maar als voorbeeld daarvan zie ik nu juist het niet gebruiken van haken in Python ;D :angel: Toegegeven, het forceren van indentatie helpt wel voor de leesbaarheid. En inderdaad, voor de compiler maken nieuwe regels überhaupt geen fluit uit, ook al zet je alles op één regel. Maar weet dat je, ondanks de grote hoeveelheid strijd binnen C++ omtrent stijl, zeeeeeeee weinig bijval krijgt ;D Zeker omdat je er met de definitie van functies zelf opeens weer van af wijkt  ;)

Ik zal mijn code aanpassen. En misschien dat ik de andere kant van de H-brug ga gebruiken omdat deze kant misschien niet helemaal meer werkt  ::)
Busje magic smoke nodig? ;D


Timo
Verzonden vanaf mijn desktop met Firefox

bask185

  • Offline Offline
  • Berichten: 4007
Re: Zelf gemaakte DCC centrale werkt niet helemaal
« Reactie #7 Gepost op: 24 maart 2019, 21:31:59 »
Ik ga gebruik maken van je bit mask idee, minder rekenwerk & minder lijntjes code -> meer performance & leesbaarheid

Mijn eerste 2 treintjes die rijden!!  (y)

Het minder goede nieuws is dat de snelheden niet zijn wat ik verwachtte. Ik vermoed dat dit ligt in het 5e snelheids bitje maar daar ben ik nog niet uit. Er klopt iig helemaal niks aan de snelheden.

Morgen maar weer verder spelen. Ben iig blij dat de basis werkt

Train-Science.com
Train-Science github
It ain't rocket science ;-)

Timo

  • Team encyclopedie
  • Offline Offline
  • Berichten: 4656
Re: Zelf gemaakte DCC centrale werkt niet helemaal
« Reactie #8 Gepost op: 24 maart 2019, 22:13:45 »
Top!

Dat snelheid blobje is inderdaad een chaos :-\
Maar iets als
byte speedBlob = speedStep + 3;
speedblob = (speedBlob >> 1) | ((speedBlob & 0x01) << 4);


Timo
Verzonden vanaf mijn desktop met Firefox

Reinout van Rees

  • Team forummoderators
  • Offline Offline
  • Berichten: 7361
  • Forummoderator
    • Persoonlijke website + weblog
Re: Zelf gemaakte DCC centrale werkt niet helemaal
« Reactie #9 Gepost op: 24 maart 2019, 22:50:38 »
Half-moderator-opmerkinkje: ik heb in de eerste post wat commentaar (in de code) op een nieuwe regel gezet in de hoop de breedte binnen de perken te houden omdat het op m'n scherm over ging lopen. Nog niet helemaal gelukt.

a) Volgens mij heb ik het C-technisch goed gedaan en geen syntax errors veroorzaakt :)

b) Ik weet niet wat voor breedbekkikker je als monitor hebt, maar kijk voor het posten van code hier op het forum even naar de lijnlengte. Met m'n pythonachtergrond krijg ik toch al de vlekkenkoorts van alles wat over de 80 karakters heen gaat, maar goed :D

Reinout-beetje-als-moderator
Bouw v/d EifelBurgenBahn (h0, zijlijn in de Eifel)
Eifelgeschiedenis (verhalen en video's over de Eifelburgenbahn)

bask185

  • Offline Offline
  • Berichten: 4007
Re: Zelf gemaakte DCC centrale werkt niet helemaal
« Reactie #10 Gepost op: 25 maart 2019, 08:32:51 »
Top!

Dat snelheid blobje is inderdaad een chaos :-\
Maar iets als
byte speedBlob = speedStep + 3;
speedblob = (speedBlob >> 1) | ((speedBlob & 0x01) << 4);


Timo

Ik had een lookup table gemaakt adhv nmra website

byte speedTable[] = {
 0b00000/*Stop */ ,0b00100/*  5  */  ,0b01000/* 13  */ ,0b01100/* 21  */
,0b10000/*Stop1*/ ,0b10100/*  6  */  ,0b11000/* 14  */ ,0b11100/* 22  */
,0b00001/*Estop*/ ,0b00101/*  7  */  ,0b01001/* 15  */ ,0b01101/* 23  */
,0b10001/*Estop*/ ,0b10101/*  8  */  ,0b11001/* 16  */ ,0b11101/* 24  */
,0b00010/*  1  */ ,0b00110/*  9  */  ,0b01010/* 17  */ ,0b01110/* 25  */
,0b10010/*  2  */ ,0b10110/* 10  */  ,0b11010/* 18  */ ,0b11110/* 26  */
,0b00011/*  3  */ ,0b00111/* 11  */  ,0b01011/* 19  */ ,0b01111/* 27  */
,0b10011/*  4  */ ,0b10111/* 12  */  ,0b11011/* 20  */ ,0b11111/* 28  */};

Als index gebruikte ik de snelheid die ik decimaal heb opgeslagen als een signed char van -28 t/m +28.

#define FORWARD 0b01100000
#define REVERSE 0b01000000

speed_tmp = train[addres].speed;                                    // store speed in 'speed_tmp' to calculate with
  packetSpeed = 0;                                                    // clear byte for re-usage
  if(speed_tmp < 0) {
    packetSpeed |= REVERSE;                                           // set flag for reverse speed direction
    speed_tmp ^= 0xff;                                                // invert the byte if is negative to positive using XOR
    speed_tmp++; }                     
  else {
    packetSpeed |= FORWARD; }                                         // set flag for forward speed direction
                     
  packetSpeed |= (speedTable[speed_tmp + 3]);
Ik kijk eerst of de trein achteruit of vooruit moet. Dan OR ik betreffende instructies FORWARD of REVERSE aan packetSpeed. Als de snelheid negatief is dan xor ik hem met 0xff en tel ik er 1 bij op. Dit resulteert dat een negatieve snelheid positief wordt. En dan haal ik ahdv van de ingestelde snelheid een waarde op uit de tabel.

Maar ik ga het eerst met 14 snelheidsstapjes proberen
Train-Science.com
Train-Science github
It ain't rocket science ;-)

Timo

  • Team encyclopedie
  • Offline Offline
  • Berichten: 4656
Re: Zelf gemaakte DCC centrale werkt niet helemaal
« Reactie #11 Gepost op: 25 maart 2019, 10:16:12 »
@Reinout-beetje-als-moderator, misschien kan het verzoek gedaan worden de CSS van de website daarvoor correct te maken? Tijdens het schrijven van code zullen de meeste gewoon word-wrap aan hebben staan namelijk.

@bask185, lookup kan ook maar de logica is dus niet zo heel lastig. Dus een lookup (zeker in een non-const tabel) lijkt me wat overkill. Paar punten over de huidige implementatie:

- Klopt niet voor speedStep 0 (okay, die van mij ook niet ;D)
- Ipv zelf 2-complement om te zetten zou je ook gewoon abs() kunnen gebruiken
- Of het opslaan als 1-complement
- Ipv eerst 'packetSpeed' te clearen en dan te OR'en met FORWARD of REVERSE zou je ook gewoon een asign daarvan kunnen maken. Twee vliegen in één klap.
- En ik gebruik liever C++ functionaliteit dan macro's :angel:

Ow, LOLLL ;D Toen wilde ik send drukken maar zie ik je fout ;D ;D ;D Je hebt de speed tabel letterlijk overgenomen uit het DCC document. Maar C/C++ leest natuurlijk niet boven naar beneden, links naar rechts 8) Die leest van links naar rechts, van boven naar beneden ;D Dus als je speedstep 10 hebt kom je uit bij '0b10101/*  8  */' Geen wonder dat je loc bokkensprongen staat te maken!


Timo
Verzonden vanaf mijn desktop met Firefox

bask185

  • Offline Offline
  • Berichten: 4007
Re: Zelf gemaakte DCC centrale werkt niet helemaal
« Reactie #12 Gepost op: 25 maart 2019, 11:32:46 »
Ow, LOLLL ;D Toen wilde ik send drukken maar zie ik je fout ;D ;D ;D Je hebt de speed tabel letterlijk overgenomen uit het DCC document. Maar C/C++ leest natuurlijk niet boven naar beneden, links naar rechts 8) Die leest van links naar rechts, van boven naar beneden ;D Dus als je speedstep 10 hebt kom je uit bij '0b10101/*  8  */' Geen wonder dat je loc bokkensprongen staat te maken!

omg ik ben zooooo'n noob  ;D ;D ;D
Train-Science.com
Train-Science github
It ain't rocket science ;-)

Timo

  • Team encyclopedie
  • Offline Offline
  • Berichten: 4656
Re: Zelf gemaakte DCC centrale werkt niet helemaal
« Reactie #13 Gepost op: 25 maart 2019, 12:44:05 »
Haha, gebeurt de beste ;D ;D


Timo
Verzonden vanaf mijn desktop met Firefox

Illya Vaes

  • Offline Offline
  • Berichten: 1913
  • H0 NS 1953-nu, H0m Bernina, H0e Ybbstal/MzB
Re: Zelf gemaakte DCC centrale werkt niet helemaal
« Reactie #14 Gepost op: 26 maart 2019, 12:46:07 »
Ik weet niet of het is wat jullie met "de standaard libraries" bedoelen, maar waarom gebruik je niet DCC++ https://dccwiki.com/DCC_Plus_Plus?
Dat blaas je zo op een Arduino met Motor Shield (overigens wilde het bij mij een enkele decoder niet helemaal lezen/schrijven, waar het de Digikeijs DR5000 wel lukte).