Doel:€250.00
Donaties:€88.00

Per saldo:€-162.00

Steun ons nu!

Laatst bijgewerkt
op 03-06-2025

Vacature: secretaris bestuur
Algemeen

De stichting

Recente berichten

Set met 2 VAM GFT en 1 VAM potgrond exclusief MTE door Mug
Vandaag om 21:02:21
Bentheimer Eisenbahn, gisteren, vandaag en morgen. door deBult
Vandaag om 20:58:55
Reizigersmaterieel Twentelijn in de jaren '70 door Jeronimos
Vandaag om 20:57:05
meer wissels invoeren in Z21 door astrantia
Vandaag om 20:41:56
Time-of-flight module door janvanbemmel
Vandaag om 20:31:48
Gekke/vreemde/rare filmpjes en video's met treinen erin. door prutser
Vandaag om 20:27:32
Toon hier je nieuwe (model-) spooraanwinst(en)... door Remco vM
Vandaag om 20:13:33
Werkt de Yamorc software op Ubuntu? door reinderlf
Vandaag om 20:10:28
Mijn Ned. N. Spoorbaan ''Echthoven'' door raymond erdtsieck
Vandaag om 20:04:58
US diorama in H0 door Frank 123
Vandaag om 20:00:16
Onlangs gespot - gefotografeerd, de foto's door Modellbahnwagen
Vandaag om 19:43:42
Vijfhuis (v.h. Frotterdam) door Ronald Halma
Vandaag om 19:13:34
Piko 2025 door Benelux795
Vandaag om 18:51:43
keerlusproblemen door astrantia
Vandaag om 18:04:38
Mijn eerste H0-modeltreinbaan in aanbouw door RetroJack
Vandaag om 17:30:04
De Projecten van RetroJack door RetroJack
Vandaag om 17:07:25
De IJmuider spoorlijn - korte geschiedenis en plaatjes door Vislijn
Vandaag om 16:33:50
Bauarbeiten im gange door spoorijzer
Vandaag om 16:31:53
De modeltreinen van Spoorijzer door spoorijzer
Vandaag om 16:30:43
Een nieuw begin door dreezy
Vandaag om 16:23:56
Br 41 Weinert, loop of sloop ? door Wim Vink
Vandaag om 15:43:26
Ombouw/Pimpen Bolle neuzen door Montanbahn
Vandaag om 15:19:31
Bouw NTM Stationsgebouw Lemmer door Dave.......
Vandaag om 15:05:55
Gelders Smalspoormuseum / Gelderse Smalspoor Stichting stelt zich voor door spoorijzer
Vandaag om 14:26:22
Modules van Kees Gorter (vervolg) door ca.gorter
Vandaag om 14:18:38
Aanluiting tussen tender en stoomlok door Klaas Zondervan
Vandaag om 12:44:13
Klein baantje 1200x1200mm door spoorijzer
Vandaag om 12:38:46
20 jaar BNLS door Hans Reints
Vandaag om 12:31:00
Rheinburg, TP V/VI door tijgernootje
Vandaag om 12:16:39
Nederland jaren 50 op basis van mijn roots door Eric B
Vandaag om 11:16:39
  

Auteur Topic: Arduino en Selectrix  (gelezen 30416 keer)

Dompie

  • HerIntreder
  • Offline Offline
  • Berichten: 149
Re: Arduino en Selectrix
« Reactie #105 Gepost op: 06 February 2025, 22:54:49 »
Oh dat is een hele goede verbetering.
Ik ben heel zeker in de source geïnteresseerd!

NEM682 heb ik ook nog nooit online kunnen vinden, bestaat die wel digitaal?
N Selectrix/Müt - TrainController7Gold met +4D Sound, +SmartHand - Stärz SX-hardware

ronaldhelder

  • Offline Offline
  • Berichten: 13
Re: Arduino en Selectrix
« Reactie #106 Gepost op: 07 February 2025, 01:10:20 »
Oke, Zal de sourcecode posten. Ik ben wel wat lui geweest: er wordt niet (meer) gelezen van de Sx bus, en ik heb maar 1 bus geïmplementeerd, gewoon omdat ik niet meer nodig heb. Maar beide zijn eenvoudig toe te voegen.

Hier de sourcecode (zie nu wel dat tabs en spaties door elkaar heen gebruikt zijn....):

De .ino:

/*
   SX1 centrale

   Creator: Gerard van der Sel / R. Helder
   Version: 2.0
   Date: 05-02-2025
   
   This software forms a bridge between a DCC signal and the Selectrix SX bus on an Arduino.
   I originally tried to run the complete code on one Arduino Nano, but the frequent interrupts from the DCC signal
   made this impossible, probably also because there are in my case other protocols on the track

   This means that the code runs on 2 Arduino Nano board that are connected to each other by Tx/Rx pin.
   One board receives the DCC signals. This code is complete based on the NMRA DCC library. When a valid DCC accesory
   command is received, the function notifyDccAccTurnoutOutput() is called and a message with format S<adress> or
   R<adress> is sent from the Tx pin to the other board. Adress is in the DCC range 0 < a < 800

   The second board generates the Sx Signal. It has a buffer of 112 adresses, pre formatted for the bus signal.
   When the S or R command is received, the function serialEvent() interprets the message and alters this buffer
   with the new data, which is one bit in this buffer for a specific adress.

   To compile for the DCC board, uncomment DCCSIDE below
   To compile for the SX board,  uncomment SXSIDE below
   Remeber to disconnect the Tx-Rx line before uploading new code !

   Extra hardware needed is de DCC-Arduino board which contains the hardware to read from the DCC-bus: the DCC signal
   is read through an opto-coupler on pin D2

   Extra hardware needed is de SX-Arduino board which contains the hardware to communicate with the SX-bus:
   Connect Arduino pin D3 to pin 1 and 3 of a SN74HCT04. Pin 2 and 4 are connected through a 220 Ohm resistor each to
   the Sx T0 line. Connect Arduino pin D4 to pin 5 of a SN74HCT04. Pin 6 is connected through a 220 Ohm resistor  to
   the Sx T1 line. Gnd must also be connected.


*/

#include <Arduino.h>
#include "SXcentrale.h"
#include <NmraDcc.h>

NmraDcc    Dcc;          // Interface to the DCC track for reading
SXcentrale SXcntrl;      // Interface to the SX-bus and track

//#define DCCSIDE          // uncomment to compile for the DCC board
#define SXSIDE         // uncomment to compile for the SX board

ISR(TIMER1_OVF_vect)
{   // interrupt service routine
    SXcntrl.isr();
}

//------------------------------------------------------------------------------
void setup()
// put your setup code here, to run once:
//------------------------------------------------------------------------------
{
#ifdef DCCSIDE
  // initialize Nmra DCC communication
  // for info: https://github.com/mrrwa/NmraDcc/blob/master/NmraDcc.h
  Dcc.pin(0, 2, 1);
  Dcc.init(MAN_ID_DIY, 10, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, 0);
#endif

  // initialize serial:
  Serial.begin(115200);
  //Serial.println("Start SxBridge");
  //delay(1000);

#ifdef SXSIDE
  // initialize SX-bus
  SXcntrl.init();
#endif
  // initialize application
  pinMode(LED_BUILTIN, OUTPUT);
}

//------------------------------------------------------------------------------
void serialEvent()
{
uint8_t dccAdres[2];
uint8_t cmd;
static bool on = false;

#ifdef SXSIDE
  // Read all the data. Data is sent in a frame that starts with 0xFD for synchronisation
  // Format: S001 for setting adres 1
  //         R001 for resetting adres 1
  while (Serial.available())
  {
    cmd = (uint8_t)Serial.read();
    Serial.print(".");
    if (cmd == 'S' || cmd == 'R')
    {
      uint8_t nr = Serial.readBytes(dccAdres, 3);
      if (nr == 3)
      {
        uint16_t adres = 100*(dccAdres[0]-'0') + 10*(dccAdres[1]-'0') + dccAdres[2]-'0';
        Serial.print(cmd);Serial.println(adres);

        if (adres < 8*SX_ADDRESS_NUMBER)
        {
          if (cmd == 'S')
            SXcntrl.setbit(0, adres, 1);
          else 
            SXcntrl.setbit(0, adres, 0);
          digitalWrite(LED_BUILTIN, on);
          on = !on;
        }
      }
    }
  }
#endif
}

//------------------------------------------------------------------------------
void loop()
// put your main code here, to run repeatedly:
//------------------------------------------------------------------------------
{
#ifdef DCCSIDE
  // DCC-Kommandos empfangen
  Dcc.process();
#endif


/* DEBUG: Blink 2 outputs on Sx decoder
  SXcntrl.set(0, 1, 2);
  delay(1000);                      // wait for a second
  SXcntrl.set(0, 1, 4);
  delay(1000);                      // wait for a second
*/
}

//------------------------------------------------------------------------------
void notifyDccAccTurnoutOutput (uint16_t Addr, uint8_t Direction, uint8_t OutputPower)

/*  notifyDccAccTurnoutOutput() Output oriented callback for a turnout accessory decoder.
 *                              Most useful when CV29_OUTPUT_ADDRESS_MODE IS set.
 *                              OutputPower is 1 if the power is on, and 0 otherwise.
 *
 *  Inputs:
 *    Addr        - Per output address. There will be 4 Addr addresses
 *                  per board for a standard accessory decoder with 4 output pairs.
 *    Direction   - Turnout direction. It has a value of 0 or 1.
 *                  Equivalent to bit 0 of the 3 DDD bits in the accessory packet.
 *    OutputPower - Output On/Off. Equivalent to packet C bit. It has these values:
 *                  0 - Output is off.
 *                  1 - Output is on.
 *
 *  Returns:
 *    None
 */
//------------------------------------------------------------------------------
{
uint8_t SxAddress;   // calculated Selectrix address
uint8_t SxData[4];

static uint8_t prevAddr      = -1;
static uint8_t prevDirection = -1;


  if (!OutputPower)
    return;
 

  if (prevAddr != Addr || prevDirection != Direction)
  {
    // Centrale zend meerdere pakketten achter elkaar, filter deze
      prevAddr = Addr;
      prevDirection = Direction;
      if (Direction)
        SxData[0] = 'S';
      else
        SxData[0] = 'R';
      SxData[1] = (Addr / 100) + '0';
      SxData[2] = (Addr % 100) / 10 + '0';
      SxData[3] = (Addr % 10) + '0';
      Serial.write(SxData, 4);
  }
}



ronaldhelder

  • Offline Offline
  • Berichten: 13
Re: Arduino en Selectrix
« Reactie #107 Gepost op: 07 February 2025, 01:10:37 »
En de rest.

De .cpp file met de code voor de generatie van het Selectrix protocol

/*
 * SXmaster.cpp
 *
 *  Version:    0.2
 *  Copyright:  Gerard van der Sel / Ronald Helder
 *
 *  Changed on: 27-01-2025
 *  Version:   0.2
 *  Changes:   Complete rewritten for efficiency, but only for Sx0
 *
 *
 *  interface hardware needed !

 Interface SX-bus voor de centrale:
 - SX T0 (Clock) must be connected to D3 ;
 - SX T1 must be connected to Pin D4 ;
 - SX D must be connected to Pin D5 .
 
 SX-bus interface (NEM 681)

 De clock lijn (T0) is verbonden met een interruptingang, zodat op
 de flanken van dit signaal een interrupt gegenereerd kan worden.
 Hierna kan data gelezen worden van T1 of data geschreven worden naar D.

 Klok:
  --    ----------------    ----------------    ----------------    ------
    |  |                |  |                |  |                |  |
     --                  --                  --                  --

 Data:
  -- ------------------- ------------------- ------------------- ---------
    X                   X                   X                   X
  -- ------------------- ------------------- ------------------- ---------

    ^  ^                ^  ^                ^  ^                ^  ^
    W  R                W  R                W  R                W  R

Opbouw telegram (96 bits):
  0  0 0  1  S 1 A3 A2 1 A1 A0 1     synchronisatie 'byte'
 D0 D1 1 D2 D3 1 D4 D5 1 D6 D7 1
 D0 D1 1 D2 D3 1 D4 D5 1 D6 D7 1
 D0 D1 1 D2 D3 1 D4 D5 1 D6 D7 1         7 data 'bytes'
 D0 D1 1 D2 D3 1 D4 D5 1 D6 D7 1   ieder 'byte' is de inhoud
 D0 D1 1 D2 D3 1 D4 D5 1 D6 D7 1         van een adres
 D0 D1 1 D2 D3 1 D4 D5 1 D6 D7 1
 D0 D1 1 D2 D3 1 D4 D5 1 D6 D7 1

 0 = Logische 0
 1 = Logische 1
 S = Spanning rails (0 = uit, 1= aan)
 Ax = Gezamelijk het nummer van het telegram
 Dx = D0 t/m D7 vormen de data op een Selectrix adres.

 Verdeling adressen over de verschillende telegrammen:
 telegram  '0' : 111, 95, 79, 63, 47, 31, 15
 telegram  '1' : 110, 94, 78, 62, 46, 30, 14
 telegram  '2' : 109, 93, 77, 61, 45, 29, 13
 telegram  '3' : 108, 92, 76, 60, 44, 28, 12
 telegram  '4' : 107, 91, 75, 59, 43, 27, 11
 telegram  '5' : 106, 90, 74, 58, 42, 26, 10
 telegram  '6' : 105, 89, 73, 57, 41, 25,  9
 telegram  '7' : 104, 88, 72, 56, 40, 24,  8
 telegram  '8' : 103, 87, 71, 55, 39, 23,  7
 telegram  '9' : 102, 86, 70, 54, 38, 22,  6
 telegram '10' : 101, 85, 69, 53, 37, 21,  5
 telegram '11' : 100, 84, 68, 52, 36, 20,  4
 telegram '12' :  99, 83, 67, 51, 35, 19,  3
 telegram '13' :  98, 82, 66, 50, 34, 18,  2
 telegram '14' :  97, 81, 65, 49, 33, 17,  1
 telegram '15' :  96, 80, 64, 48, 32, 16,  0

 In deze versie worden alle 16 telegrammen volgens bovenstaand
 patroon bij initialisatie al opgebouwd, zodat in de isr geen
 test of rekenwerk hoeft plaats te vinden, en de isr dus erg
 efficient wordt. Bij het schrijven naar de database set()
 wordt gelijk al in dit patroon geschreven.

** SX Timing **
1   Bit             50 us
1   Kanal          600 us (= 12 Bit)
1   Grundrahmen    ca. 4,8 ms
1   Gesamtrahmen   ca.  80 ms (= 16 Grundrahmen)
0  0  0  1  S   1  A3  A2  1  A1  A0  1 == sync frame of 12 bits



This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
 License as published by the Free Software Foundation; either
 version 2.1 of the License, or (at your option) any later version.
 
 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 Lesser General Public License for more details.
 
 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

 */
 
#include <Arduino.h>
#include "SXcentrale.h"

SXcentrale::SXcentrale()
{
}

//------------------------------------------------------------------------------
void SXcentrale::init()
// initialize function
//------------------------------------------------------------------------------
{
  // Initialize pins and variables
  pinMode(SX_T0, OUTPUT);                                  // SX-T0 is an output
  pinMode(SX0_T1, OUTPUT);                                  // SX0_T1 is also an output
  pinMode(SX0_D, INPUT_PULLUP);                            // SX0_D is an input
digitalWrite(SX_T0, LOW);
digitalWrite(SX0_T1, LOW);

  // Create the datastructure that will be send 1:1 to the bus, bit by bit
  for (uint8_t sx_frame = 0; sx_frame < SX_TELCOUNT; sx_frame++)
  {
    // Fill first row with (LSB->MSB):   0 0 0 1 S 1 A3 A2 1 A1 A0 1     synchronisatie 'byte'
    int idx = sx_frame*SX_DATACOUNT;
    uint16_t adres = (sx_frame);
    sxbusSX0[idx]  = 0x0928;                    // 1's: B0000100100101000
    sxbusSX0[idx] |= 0x0010;                    // PWR: B0000000000010000
    sxbusSX0[idx] |= (adres & 0x0008) <<  3; // A3
    sxbusSX0[idx] |= (adres & 0x0004) <<  5; // A2
    sxbusSX0[idx] |= (adres & 0x0002) <<  8; // A1
    sxbusSX0[idx] |= (adres & 0x0001) << 10; // A0

    for (uint8_t sx_telgram = 1; sx_telgram < SX_DATACOUNT; sx_telgram++)
    {
      // Fill each datarow with D0 D1 1 D2 D3 1 D4 D5 1 D6 D7 1, with every D = 0 (for now)
      sxbusSX0[idx + sx_telgram] = 0x0924;
    }
  }

  /* DEBUG
  for (int i=0; i<48; i++)
  {
    Serial.println(sxbusSX0[i], BIN);
    delay(100);
  }

  Serial.println("---------------------------------------");
  delay(2000);
  */


  // initialize timer1
uint8_t oldSREG = SREG;
  noInterrupts();                                           // disable all interrupts

  // Set timer1 to the correct value for our interrupt interval
  TCCR1A  = 0;
  TCCR1B  = (1 << CS10);
  TCNT1   = Timer1_40;                                      // preload timer with 40usec delay
  TIMSK1 |= (1 << TOIE1);                                   // enable timer overflow interrupt
SREG = oldSREG;                                           // restore interrupts
}

void SXcentrale::initVar(void)
{
}

// Local functions

//------------------------------------------------------------------------------
void SXcentrale::writeT0(void)
// Write clock line high (inverted because hardware (TTL 7404) inverts again)
//------------------------------------------------------------------------------
{
  uint8_t port = (SX_T0_PORT & B11110111);
  SX_T0_PORT = port;
}

//------------------------------------------------------------------------------
void SXcentrale::writeT0T1(void)
// Write clock low and transmit line according to data
// (inverted because hardware (TTL 7404) inverts again)
//------------------------------------------------------------------------------
{
  static uint16_t *pData = sxbusSX0;     // pointer to data to be sent (for efficiency)
  static uint16_t sx_sendmask = 0x0001;  // Start with sending LSB

  /* DEBUG
  x = 0; //(pData == &sxbusSX0[119]);
  if (x) Serial.print("Data:");
  if (x) Serial.print(*pData, BIN);
  if (x) Serial.print(" SM:");
  if (x) Serial.print(sx_sendmask, BIN);
  if (x) Serial.print(":");
  if (x) Serial.println((*pData & sx_sendmask) ? 1:0);
  */

  uint8_t port = (SX_T0_PORT & B11100111);
  if (*pData & sx_sendmask)
    port |= B00001000;
  else
    port |= B00011000;
  SX_T0_PORT = port;
  sx_sendmask = sx_sendmask << 1;

  if (sx_sendmask & 0x1000)
  {
    // End of group (line / adres)
    sx_sendmask = 0x0001;
    pData++;  // point to next channel
    if (pData >= (&sxbusSX0[SX_TELCOUNT * SX_DATACOUNT]))
    {
      pData = sxbusSX0; // been round all channels/adresses, start again     
      // Serial.println("****** ROUND *******");
    }
  }
}

//------------------------------------------------------------------------------
void SXcentrale::readD(void)
// Read data line
// Data reading is not done in this version [because I don't need it ;-) ]
//------------------------------------------------------------------------------
{
}

//------------------------------------------------------------------------------
void SXcentrale::isr(void)
// Interrupt service routine (AVR OVERFLOW T1)
//------------------------------------------------------------------------------
{
  static bool _writeFase = true;
if (_writeFase)
  {
// 10 usec fase (make clock low and write data)
writeT0T1();                                    // Clock low and write 1 databit
_writeFase = false;
TCNT1 += Timer1_10;                             // reload timer
}
  else
  {
// 40 usec fase (make clock high and read data)
writeT0();                                     // Clock high
    readD();
_writeFase = true;
TCNT1 += Timer1_40;                             // reload timer

}

//------------------------------------------------------------------------------
uint8_t SXcentrale::calcIndex(uint8_t SXadr)
// Convert from SX-bus addresses to index in array.
//------------------------------------------------------------------------------
{
uint8_t frame = 15 - (SXadr & 0x0F);       // Get the frame number
uint8_t offset = 7 - (SXadr >> 4);         // Get the offset in the frame
//    Serial.print(SXadr);
//    Serial.print("=");
//    Serial.print(frame);
//    Serial.print(".");
//    Serial.println(offset);
return frame * 8 + offset;                  // Calculate the index in the array

}

// functions 'accessing' the SX-bus

//------------------------------------------------------------------------------
int SXcentrale::get(uint8_t bus, uint8_t adr)
// Read data from the array, filled by the isr.
// In:
// bus: 0 - 3, bus to read from.
// adr: 0 - 111, address value read from.
// Return value:
// -1: Address out of range
// -3: SX-bus out of range
// 0 - 255: Value from SX-bus
//------------------------------------------------------------------------------
{
     // returns the value of a SX address
if (adr < SX_ADDRESS_NUMBER)
  {
switch (bus)
    {
case 0:
return sxbusSX0[calcIndex(adr)] & 0xff; // Return value

  default:
return -3;      // Report bus out of range
}
}
return -1;                                           // Report address out of range
}

//------------------------------------------------------------------------------
int SXcentrale::set(uint8_t bus, uint8_t adr, uint8_t data)
// Write data to the array, writing to the SX-bus is done by the isr.
// In:
// bus:  0 - 3, bus to send value to, only 0 is a valid number in this version.
// adr:  0 - 111, address value send to.
// data: 0 - 255, value send
// Return value:
//  0: Success
// -1: Address out of range
// -3: SX-bus out of range
//------------------------------------------------------------------------------
{
if (adr < SX_ADDRESS_NUMBER && bus == 0) 
  {
    // store in pattern  D0 D1 1 D2 D3 1 D4 D5 1 D6 D7 1 (D0 = LSB)
    uint8_t idx = calcIndex(adr);
    sxbusSX0[idx]  = 0x0924;
    sxbusSX0[idx] |= data & 0x03;
    sxbusSX0[idx] |= (data & 0x0C) << 1;
    sxbusSX0[idx] |= (data & 0x30) << 2;
    sxbusSX0[idx] |= (data & 0xC0) << 3;
return 0;    // success
}
return -1;    // address out of range
}

//------------------------------------------------------------------------------
int SXcentrale::setbit(uint8_t bus, uint16_t dccAdr, uint8_t data)
// Write one bit to the array, writing to the SX-bus is done by the isr.
// In:
// bus:    0 - 3, bus to send value to, only 0 is a valid number in this version.
// dccAdr: 0 - 895, DCC bit-address value send to (adres * 8 + bitnummer).
// data:   0 - 1, reset or set
// Return value:
//  0: Success
// -1: Address out of range
// -3: SX-bus out of range
//------------------------------------------------------------------------------
{
if (dccAdr < 8*SX_ADDRESS_NUMBER && bus == 0) 
  {
    // store in pattern  D0 D1 1 D2 D3 1 D4 D5 1 D6 D7 1 (D0 = LSB)
    uint16_t adres = dccAdr / 8;
    uint16_t bit   = dccAdr % 8;
    uint8_t  idx   = calcIndex(adres);

    if (data)
    {
      // Set bit
      data = (0x01 << bit);
      sxbusSX0[idx] |= data & 0x03;
      sxbusSX0[idx] |= (data & 0x0C) << 1;
      sxbusSX0[idx] |= (data & 0x30) << 2;
      sxbusSX0[idx] |= (data & 0xC0) << 3;
      //Serial.print(" a:");Serial.print(adres);Serial.print(" b:");Serial.print(data);
    }
    else
    {
      // Reset bit
      uint16_t mask = 0;
      data = (0x01 << bit);
      mask |= data & 0x03;
      mask |= (data & 0x0C) << 1;
      mask |= (data & 0x30) << 2;
      mask |= (data & 0xC0) << 3;
      sxbusSX0[idx] &= ~mask;
      //Serial.print(" a:");Serial.print(adres);Serial.print(" m:");Serial.print(mask);
    }
return 0;    // success
}
return -1;    // address out of range
}

//------------------------------------------------------------------------------
uint8_t SXcentrale::getPWR()
// Read POWER status from the SX-bus
// Return value:
//  0: Power off
//  1: Power on
//------------------------------------------------------------------------------
{
    return (sxbusSX0[0] & SX_BIT_PWR);
}

//------------------------------------------------------------------------------
int SXcentrale::setPWR(uint8_t val)
// Write POWER status to the SX-bus and control a connected central.
// Return value:
//  0: Success
// -2: Illegal power value
//------------------------------------------------------------------------------
{
for (uint8_t sx_frame = 0; sx_frame < SX_TELCOUNT; sx_frame++)
  {
    int idx = sx_frame*SX_DATACOUNT;
    if (val == 1)
      sxbusSX0[idx] |= SX_BIT_PWR;
    else
      sxbusSX0[idx] &= (~SX_BIT_PWR);
  }
}


en de .h file

/*
 * SXcentrale.cpp
 *
 *  Version:    0.2
 *  Copyright:  Gerard van der Sel / Ronald Helder
 *
 *  Changed on: 27-01-2025
 *  Version:   0.2
 *  Changes:   Complete rewritten for efficiency, but only for Sx0
 *
 *
 *  interface hardware needed !

 Hardware:
   Connect T0 (Timing Signal) to D3
   Connect T1 (Write Data) to D4
   Connect D (Read Data) to D5
 
 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
 License as published by the Free Software Foundation; either
 version 2.1 of the License, or (at your option) any later version.
 
 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 Lesser General Public License for more details.
 
 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA


 */

#ifndef SXcentrale_H_
#define SXcentrale_H_

#include <Arduino.h>

// Define arduino pins and ports
// The io pins for the busses
#if (1)

#define SX_T0           3                 // Clock (for all)
#define SX_T0_PORT PORTD
#define SX_T0_PORTPIN PORTD3

#define SX0_T1          4                 // Data write
#define SX0_T1_PORT PORTD
#define SX0_T1_PORTPIN PORTD4

#define SX0_D           5                 // Data read
#define SX0_D_INPORT PIND
#define SX0_D_INPORTPIN PIND5

#else

#define SX_T0           8                 // Clock (for all)
#define SX_T0_PORT PORTB
#define SX_T0_PORTPIN PORTB0

#define SX0_T1          9                 // Data write
#define SX0_T1_PORT PORTB
#define SX0_T1_PORTPIN PORTB1

#define SX0_D           10                 // Data read
#define SX0_D_INPORT PINC
#define SX0_D_INPORTPIN PINB2

#endif

// defines for Selectrix constants
#define SX_DATACOUNT    8                  // 7 dataframes in 1 SYNC Channel
#define SX_TELCOUNT    16                  // 16 SYNC Channels to transmit all data
#define SX_BIT_PWR     0x0010

#define SX_ADDRESS_NUMBER 112              // number SX channels

#define Timer1_10 -160                     // 10 usec delay
#define Timer1_40 -640                     // 40 usec delay
//#define Timer1_10 -160                     // 20 usec delay
//#define Timer1_40 -960                     // 60 usec delay
//#define Timer1_10 60000                    // 10 usec delay (debug, also set CS12)
//#define Timer1_40 60000                    // 40 usec delay (debug, also set CS12)

class SXcentrale
{
public:
SXcentrale();
void init(void);
int  get(uint8_t, uint8_t);
int  set(uint8_t, uint8_t, uint8_t);
int  setbit(uint8_t, uint16_t, uint8_t);
  uint8_t getPWR(void);
int  setPWR(uint8_t);
void isr(void);

private:
  void writeT0(void);
void writeT0T1(void);
void readD(void);
void initVar(void);
uint8_t calcIndex(uint8_t adr);

uint16_t sxbusSX0[SX_TELCOUNT * SX_DATACOUNT];  // to store the SX-bus data in signal format (see .cpp file), with D0 LSB in _sxbus (same as normal var)
  uint16_t sx_sendmask;                           // specifies bit to be sent

};

#endif /* SXcentrale_H_ */

Dompie

  • HerIntreder
  • Offline Offline
  • Berichten: 149
Re: Arduino en Selectrix
« Reactie #108 Gepost op: 07 February 2025, 10:36:18 »
Dank je wel!! Hier gaan we eens lekker opkauwen en analyseren.
Nogmaals bedankt!
N Selectrix/Müt - TrainController7Gold met +4D Sound, +SmartHand - Stärz SX-hardware

gvandersel

  • HCC!m maar toch Selectrix (RMX)
  • Offline Offline
  • Berichten: 3603
  • Als het maar elektrisch is.
    • Homepage Gerard van der Sel
Re: Arduino en Selectrix
« Reactie #109 Gepost op: 07 February 2025, 10:58:16 »
Hi Ronald,

Puik stukje werk.  Ga kijken of ik er nog wat snelheidswinst mee kan bereiken.


PS: De normen staan hier (https://www.morop.org/index.php/en/nem-the-norms.html), het zijn 680 en 681.

Groet,

Gerard van der Sel.
« Laatst bewerkt op: 07 February 2025, 11:00:28 door gvandersel. Reden: Link normen toegevoegd »
Holzburg (IIIb/IVa) schaal N.
Kijk ook eens bij de bouw en lees de avonturen.