LocoNet på Arduino - att koda en "Multi-dongel"

Boostrar, dekodrar, signaler, m.m. Montering av dekodrar i lok. Datorprogram och programmering.
Användarvisningsbild
AlexanderEhn
Inlägg: 1153
Blev medlem: 2017-07-11, 23:47
Kontakt:

LocoNet på Arduino - att koda en "Multi-dongel"

Inlägg av AlexanderEhn »

Som en spinoff på tidigare tråd skapar jag en ny tråd för att inte blanda ämnena för mycket. viewtopic.php?f=30&t=3826



Behovsspecifikation
- Behovet är att kunna köra två eller fler lok/motorvagnar som en mult
- Multen ska enkelt och med få minimala instruktioner kunna brytas och loken därefter köras separat
- Två eller flera lok/motorvagnar ska enkelt köras som en mult från att tidigare körts separat.


Lösningsidéer
- Loken kan köras med Advance Consist via CV19 och när multen behöver brytas så sätts CV19 till 0 för åtminstone ett av loken
- Två körhandtag används för att att köra loken på varsin lokadress
- En körkontroll används som kan hantera styra två lokadresser simultant
- En hårdvara med mjukvara sätts i ett Loconet-uttag som replikerar kommandon från en specifik adress till en annan


Vald lösning
En hårdvara med mjukvara sätts i ett Loconet-uttag som replikerar kommandon från en specifik adress till en annan

Mer utförlig behovsspec:
  • När Loconetkommandon skickas till en specifik lokadress ska dessa kommandon replikeras på en annan address
  • Initialt kan både källadress och replika-adress vara hårdkodade.
    • En framtida version kan ha konfigurerbara adresser, antingen genom fysisk knapp eller genom dispatch av adress liknande metoden för att skicka en adress från en UT4'a till en FREDI
  • Hårdvaran ska vara LocoNet-kompatibel
  • Lösningen ska ge så liten ökad belastning på LocoNet, centralenhet och DCC som möjligt.
  • Funktioner replikeras rakt av.
    • Om exv. F2 aktiveras för käll-adressen ska F2 aktiveras på replika-adressen.
    • Ingen kontroll av replika-adressens funktioner görs
    • Ingen funktionalitet för scenarion eller beroende lokadresserna sinsemellan krävs.
  • Ingen specifik programmering för denna lösning av respektive lokdekoder ska behövas
  • När Multi-dongeln inte längre används ska loken/motorvagnarna kunna köras enskilt på respektive adress. (Käll- eller replikaadress kan i sig vara en Advance Consist, men det pårverkar inte funktionaliteten för Mulit-dongeln)

Teknisk lösning
Hårdvara
En paneldekoder från MGP har valts som hårdvara. Anledningen till valet av hårdvara var att det var lättillgängligt och enklaste vägen för att få hårdvara för arudino och LocoNet ihop.

Mjukvara
- LocoNet-biblioteket "Model Railroading for Arduino" används.
- Arduino IDE används för kodutveckling.


Det är självklart uppskattat med input och kommentarer kring ovanstående.
Senast redigerad av 1 AlexanderEhn, redigerad totalt 2019 gånger.
Pågående byggprojekt just nu:
"Kombihamnen", blir ingen hamn, men väl en kombiterminal i N-skala med svensk förebild Byggtråd här!
"Glassfabriken" blir en industrimodul med genomgående linje, N-Re.
Användarvisningsbild
AlexanderEhn
Inlägg: 1153
Blev medlem: 2017-07-11, 23:47
Kontakt:

Re: LocoNet på Arduino - att koda en "Multi-dongel"

Inlägg av AlexanderEhn »

daniel skrev: 2019-03-20, 13:26
AlexanderEhn skrev: 2019-03-20, 11:51 Kan någon vänlig själ vägleda mig i hur kommunikationen funkar mellan Loconet och arduinon? Eller innehåller ett "LocoNet-kort" även logiken och översättning från LocoNet till Arduino? Och inte bara hårdvaran?
Dokumentet LocoNet Personal Edition beskriver protokollet på LocoNet. Dokumentet är inte helt enkelt att förstå, men vi är några som programmerar mot LocoNet på forumet och som kan hjälpa dig.

LocoNet-centralen har ett antal "slots". Varje slot har ett antal bytes av data som anger status, lokadress, m.m. För att styra ett lok börjar man med att fråga vilken slot som har den aktuella lokadressen med kommandot OPC_LOCO_ADR. Kommandot har fyra bytes:
Byte 0: 0xBF
Byte 1: (adress / 128) & 127
Byte 2: adress & 127
Byte 3: Checksumma (denna räknas ut av biblioteket som du använder, se inlägget från LLJ)

Som svar får du SLOT DATA READ (OPC_SL_RD_DATA), 10 bytes.
Byte 0: 0xE7
Byte 1: 0x0E
Byte 3: Slot-nummer
Övriga bytes har olika data, t ex lokets hastighet.

Sedan styr du lokets hastighet med OPC_LOCO_SPD och lokets riktning med OPC_LOCO_DIRF.
AlexanderEhn skrev: 2019-03-26, 01:52
PerEklund skrev: 2019-03-20, 12:54 Här finns mer info runt Arduino och LocoNet
https://mrrwa.org/loconet-interface/

Jag har svårt att hitta någon dokumentation på LocoNet-biblioteket.
Exemplena finns, men det hade vart gött med en lista på alla objekt och metoder.

Någon som vet om det finns?
LLJ skrev: 2019-03-26, 11:49 Osäker på om det finns, men mycket förstår man genom att läsa koden.
Det underlättar om man har tillgång till dokumentet "LocoNet Personal edition" från Digitrax. Det förklarar de olika meddelanden som finns i LocoNet. Finns dock några felaktigheter och dokumentet är gammalt.

/Lars

Jag har läst "LocoNet personal edition" parallellt med att jag har tittat på exemplena i Aruinobiblioteket, men det är svårt att se sambanden.
Det hade underlättat med en dokumentation som beskriver vilka objekt och metoder i biblioteket motsvarar vad i LocoNet.
Pågående byggprojekt just nu:
"Kombihamnen", blir ingen hamn, men väl en kombiterminal i N-skala med svensk förebild Byggtråd här!
"Glassfabriken" blir en industrimodul med genomgående linje, N-Re.
Användarvisningsbild
LLJ
Inlägg: 4297
Blev medlem: 2012-05-08, 10:27

Re: LocoNet på Arduino - att koda en "Multi-dongel"

Inlägg av LLJ »

Som jag ser det så behöver inte CV19 ändras. Däremot bör man aktivt välja "mult" på/av "Multidongeln" så att sloterna för respektive fordon kan tas över/frigöras.

/Lars
Användarvisningsbild
AlexanderEhn
Inlägg: 1153
Blev medlem: 2017-07-11, 23:47
Kontakt:

Re: LocoNet på Arduino - att koda en "Multi-dongel"

Inlägg av AlexanderEhn »

LLJ skrev: 2019-03-26, 15:28 Som jag ser det så behöver inte CV19 ändras. Däremot bör man aktivt välja "mult" på/av "Multidongeln" så att sloterna för respektive fordon kan tas över/frigöras.

/Lars
Korrekt, lösningen bygger inte på användning av CV19.

Är sloterna i LocoNet kopplade till ett specifikt körhandtag menar du?
Pågående byggprojekt just nu:
"Kombihamnen", blir ingen hamn, men väl en kombiterminal i N-skala med svensk förebild Byggtråd här!
"Glassfabriken" blir en industrimodul med genomgående linje, N-Re.
Användarvisningsbild
LLJ
Inlägg: 4297
Blev medlem: 2012-05-08, 10:27

Re: LocoNet på Arduino - att koda en "Multi-dongel"

Inlägg av LLJ »

Ja. Varje handtag har ett id.

/Lars
Användarvisningsbild
AlexanderEhn
Inlägg: 1153
Blev medlem: 2017-07-11, 23:47
Kontakt:

Re: LocoNet på Arduino - att koda en "Multi-dongel"

Inlägg av AlexanderEhn »

Aha.... hmm. Det får jag kolla upp. Lär återkomma med frågor. :)
Pågående byggprojekt just nu:
"Kombihamnen", blir ingen hamn, men väl en kombiterminal i N-skala med svensk förebild Byggtråd här!
"Glassfabriken" blir en industrimodul med genomgående linje, N-Re.
Användarvisningsbild
daniel
Inlägg: 3545
Blev medlem: 2012-05-08, 10:15

Re: LocoNet på Arduino - att koda en "Multi-dongel"

Inlägg av daniel »

Alexander:

Innehållet i varje slot finns beskriven i LocoNet personal edition, sidorna 11-12.

Byte 0: Slot nr. Värde 0-7F hexadecimalt, 0 - 127 decimalt.

Byte 1: Slot status.
Bit 0-2: Dekodertyp.
Bit 3: Om någon annan slot är länkad till denna för consist
Bit 4-5: Viktig: 0=Ingen data, 3=Slot:en används. Vad 1 och 2 betyder är jag lite osäker på.
Bit 6-7: Consist

Byte 2: De 7 minsta bitarna i lokadressen, alltså (address & 0x7F)

Byte 3: Lokets hastighet (0=stop, 1=emergency stop, 2-127 hastighet)

Byte 4: Riktning och funktioner. Bit 0: F1, Bit 1: F2, Bit 2: F3, Bit 3: F4, Bit 4: F0 (lyse), Bit 5: lokets riktning, bit 6-7 är reserverade för framtida bruk.

Byte 5-6 är jag osäker på

Byte 7: De 7 högsta bitarna i lokadressen, alltså (address >> 7)
Operatorn >> betyder att shifta värdet ett antal bitar åt höger.

Byte 8: Samma som byte 4, men för funktionerna F5-F8.

Byte 9-10 är jag osäker på.
BoA
Inlägg: 94
Blev medlem: 2017-10-20, 17:55

Re: LocoNet på Arduino - att koda en "Multi-dongel"

Inlägg av BoA »

Eftersom tomten kom med en Digikeijs DR5000 har jag äntligen fått möjligt att fördjupa mig i Alexander:s liksom som min egen tanke runt multipelkörning.

Med hjälp av ett egenhändigt loconetkort med en Arduino Nano och kod fixas det hela

Givet två FLM 7368 DU2 lok med adresserna 5172 resp. 5173 och concist-adress 5174 så kan jag utföra följande senario:

UT4:an satt till adress 5172.
Lok 5172 backar till ett antal godsvagnar.
UT4:an satt till adress 5173.
Lok 5173 backar till ovanstående lok.
UT4:an sätts till adress 5174.
Tågsättet med två drivande lok kör iväg!

Bör vara möjligt att använda någon modul från Möllehem, där man via BT-gränssnittet ev. kan sätta adresserna för Concist-, Head- och Tail-throttle.

Koden bygger på en Throttle klass som håller koll på de slot resp adresser som vi vill använda!

Vid uppstart och anslutning av loconet efterfrågas slots och registrerar throttlar baserat på de vi önskar köra i mult plus den registrerade concist-adressen,

Hastighet, riktning och F kommandon från concist-throttle repeteras till Head och Tail throtttle.

Jag har inte stoppat in någon checksumma i meddelanden, men det verkar fungera ändå.

Kod: Markera allt

#include <LocoNet.h>

class ThrottleClass 
{
  private:
      uint8_t     mySlot ;
      uint16_t    slotAddress;

  public:      
      void init(uint8_t slot, uint16_t address);    
      uint8_t getSlot();
      uint16_t getAddress();
};

void ThrottleClass::init(uint8_t slot, uint16_t address)
{
  mySlot = slot;
  slotAddress = address;
}

uint8_t ThrottleClass::getSlot()
{
  return mySlot;
}

uint16_t ThrottleClass::getAddress()
{
  return slotAddress;
}


static lnMsg  *RxPacket;
static lnMsg  *TxPacket = new lnMsg();

ThrottleClass  ConcistThrottle;
ThrottleClass  HeadThrottle ;
ThrottleClass  TailThrottle;

uint16_t consist_Address = 5174;
uint16_t head_Address    = 5173;
uint16_t tail_Address    = 5172;

int currentSlot = 0;

void setup() 
{  
  LocoNet.init(6);
  Serial.begin(9600);

  LocoNet.send(OPC_RQ_SL_DATA, currentSlot++, 00);
}

void loop() {

  RxPacket = LocoNet.receive();

  if( RxPacket )
  {
      if(RxPacket->sd.command == OPC_SL_RD_DATA)
      {
        uint8_t slot = RxPacket->sd.slot;
        uint16_t address = (uint16_t) (( RxPacket->sd.adr2 << 7 ) + RxPacket->sd.adr );

        if(address == consist_Address)
        {
          ConcistThrottle.init(slot, address);
          Serial.print("Consist Slot: ");
          Serial.println(ConcistThrottle.getSlot());
          Serial.print("Consist Address: ");
          Serial.println(ConcistThrottle.getAddress());
        }
        if(address == head_Address)
        {
          HeadThrottle.init(slot, address);
          Serial.print("Head Slot: ");
          Serial.println(HeadThrottle.getSlot());
          Serial.print("Head Address: ");
          Serial.println(HeadThrottle.getAddress());
        }
        if(address == tail_Address)
        {
          TailThrottle.init(slot, address);
          Serial.print("Tail Slot: ");
          Serial.println(TailThrottle.getSlot());
          Serial.print("Tail Address: ");
          Serial.println(TailThrottle.getAddress());
        }
         LocoNet.send(OPC_RQ_SL_DATA, currentSlot++, 00);
      }
      if(RxPacket->sd.command == OPC_LOCO_SPD)
      {
        uint8_t slot = RxPacket->lsp.slot;
        if(slot == ConcistThrottle.getSlot())
        {         
          TxPacket->lsp.command = OPC_LOCO_SPD;
          TxPacket->lsp.slot = HeadThrottle.getSlot();
          TxPacket->lsp.spd = RxPacket->lsp.spd;
          LocoNet.send(TxPacket);
          
          TxPacket->lsp.command = OPC_LOCO_SPD;
          TxPacket->lsp.slot = TailThrottle.getSlot();
          TxPacket->lsp.spd = RxPacket->lsp.spd;
          LocoNet.send(TxPacket);
        }
      }

      if(RxPacket->sd.command == OPC_LOCO_DIRF)
      {
        uint8_t slot = RxPacket->ldf.slot;
        if(slot == ConcistThrottle.getSlot())
        {
          TxPacket->ldf.command = OPC_LOCO_DIRF;
          TxPacket->ldf.slot = HeadThrottle.getSlot();
          TxPacket->ldf.dirf = RxPacket->ldf.dirf;
          LocoNet.send(TxPacket);
          
          TxPacket->ldf.command = OPC_LOCO_DIRF;
          TxPacket->ldf.slot = TailThrottle.getSlot();
          TxPacket->ldf.dirf = RxPacket->ldf.dirf;
          LocoNet.send(TxPacket);
        }
      }

      if(RxPacket->sd.command == OPC_LOCO_SND)
      {
        uint8_t slot = RxPacket->ls.slot;
        if(slot == ConcistThrottle.getSlot())
        {
          TxPacket->ls.command = OPC_LOCO_SND;
          TxPacket->ls.slot = HeadThrottle.getSlot();
          TxPacket->ls.snd = RxPacket->ls.snd;
          LocoNet.send(TxPacket);
          
          TxPacket->ls.command = OPC_LOCO_SND;
          TxPacket->ls.slot = TailThrottle.getSlot();
          TxPacket->ls.snd = RxPacket->ls.snd;
          LocoNet.send(TxPacket);
        }
      }
  }
}
/Bosse
DagCatoSkårvik
Inlägg: 52
Blev medlem: 2013-09-07, 00:51

Re: LocoNet på Arduino - att koda en "Multi-dongel"

Inlägg av DagCatoSkårvik »

Jeg er ikke så skarp i tysk, men i Zimos siste softwareversion (37.0) synes dette å være innebygget i dekoderen. Du kan da veksle mellom normaladresse og consistadresse via en funskjonstast.
http://www.zimo.at/web2010/documents/MX ... ecoder.pdf
CV97, side 17.

DC
MVH
Dag Cato
Användarvisningsbild
daniel
Inlägg: 3545
Blev medlem: 2012-05-08, 10:15

Re: LocoNet på Arduino - att koda en "Multi-dongel"

Inlägg av daniel »

BoA skrev: 2020-01-01, 22:59 Jag har inte stoppat in någon checksumma i meddelanden, men det verkar fungera ändå.
Kommandot

Kod: Markera allt

LocoNet.send(TxPacket);
räknar ut checksumman innan paketet skickas.
Skriv svar

Återgå till "El, elektronik och programvara"