INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Lib für Modellbahn Digitalsteuerung?
12.07.2015, 23:22
Beitrag #1
Lib für Modellbahn Digitalsteuerung?
Hallo
Gibt es eine Lib für eine einfache Modellbahnsteuerung?
Z.B. DCC oder Motorola
Es würde reichen die Fahrzeuge zu Adressieren und Ein/Aus Vor/rück zu realisieren.

Nicht jeder Neuling in einem Forum hat keine Ahnung über die Materie!
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
29.11.2015, 13:41 (Dieser Beitrag wurde zuletzt bearbeitet: 29.11.2015 14:10 von fraju.)
Beitrag #2
RE: Lib für Modellbahn Digitalsteuerung?
Habe etwas gefunden!
Code:
// 23. November 2009
// works well with LMD18200 Booster !!!!!

/*Copyright (C) 2009 Michael Blank

This program is free software; you can redistribute it and/or modify it under the terms of the
GNU General Public License as published by the Free Software Foundation;
either version 3 of the License, or (at your option) any later version.

This program 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 General Public License for more details.
*/


#define DCC_PIN    4  // Arduino pin for DCC out
                      // this pin is connected to "DIRECTION" of LMD18200
#define DCC_PWM    5  // must be HIGH for signal out
                      // connected to "PWM in" of LMD18200
#define DCC_THERM  7  // thermal warning PIN
#define AN_SPEED   2  // analog reading for Speed Poti
#define AN_CURRENT 0  // analog input for current sense reading


//Timer frequency is 2MHz for ( /8 prescale from 16MHz )
#define TIMER_SHORT 0x8D  // 58usec pulse length
#define TIMER_LONG  0x1B  // 116usec pulse length

unsigned char last_timer=TIMER_SHORT;  // store last timer value
  
unsigned char flag=0;  // used for short or long pulse
unsigned char every_second_isr = 0;  // pulse up or down

// definitions for state machine
#define PREAMBLE 0    
#define SEPERATOR 1
#define SENDBYTE  2

unsigned char state= PREAMBLE;
unsigned char preamble_count = 16;
unsigned char outbyte = 0;
unsigned char cbit = 0x80;

// variables for throttle
int locoSpeed=0;
int dir;
int last_locoSpeed=0;
int last_dir;
int dirPin = 12;
int FPin[] = { 8,9,10,11};
int maxF =3;
int locoAdr=40;   // this is the (fixed) address of the loco

// buffer for command
struct Message {
   unsigned char data[7];
   unsigned char len;
} ;

#define MAXMSG  2
// for the time being, use only two messages - the idle msg and the loco Speed msg

struct Message msg[MAXMSG] = {
    { { 0xFF,     0, 0xFF, 0, 0, 0, 0}, 3},   // idle msg
    { { locoAdr, 0x3F,  0, 0, 0, 0, 0}, 4}    // locoMsg with 128 speed steps
  };               // loco msg must be filled later with speed and XOR data byte
                                
int msgIndex=0;  
int byteIndex=0;


//Setup Timer2.
//Configures the 8-Bit Timer2 to generate an interrupt at the specified frequency.
//Returns the time load value which must be loaded into TCNT2 inside your ISR routine.
void SetupTimer2(){

  //Timer2 Settings: Timer Prescaler /8, mode 0
  //Timmer clock = 16MHz/8 = 2MHz oder 0,5usec
  TCCR2A = 0;
  TCCR2B = 0<<CS22 | 1<<CS21 | 0<<CS20;

  //Timer2 Overflow Interrupt Enable  
  TIMSK2 = 1<<TOIE2;

  //load the timer for its first cycle
  TCNT2=TIMER_SHORT;

}

//Timer2 overflow interrupt vector handler
ISR(TIMER2_OVF_vect) {
  //Capture the current timer value TCTN2. This is how much error we have
  //due to interrupt latency and the work in this function
  //Reload the timer and correct for latency.  
  // for more info, see http://www.uchobby.com/index.php/2007/11/24/arduino-interrupts/
  unsigned char latency;
  
  // for every second interupt just toggle signal
  if (every_second_isr)  {
     digitalWrite(DCC_PIN,1);
     every_second_isr = 0;    
    
     // set timer to last value
     latency=TCNT2;
     TCNT2=latency+last_timer;
    
  }  else  {  // != every second interrupt, advance bit or state
     digitalWrite(DCC_PIN,0);
     every_second_isr = 1;
    
     switch(state)  {
       case PREAMBLE:
           flag=1; // short pulse
           preamble_count--;
           if (preamble_count == 0)  {  // advance to next state
              state = SEPERATOR;
              // get next message
              msgIndex++;
              if (msgIndex >= MAXMSG)  {  msgIndex = 0; }  
              byteIndex = 0; //start msg with byte 0
           }
           break;
        case SEPERATOR:
           flag=0; // long pulse
           // then advance to next state
           state = SENDBYTE;
           // goto next byte ...
           cbit = 0x80;  // send this bit next time first        
           outbyte = msg[msgIndex].data[byteIndex];
           break;
        case SENDBYTE:
           if (outbyte & cbit)  {
              flag = 1;  // send short pulse
           }  else  {
              flag = 0;  // send long pulse
           }
           cbit = cbit >> 1;
           if (cbit == 0)  {  // last bit sent, is there a next byte?
              byteIndex++;
              if (byteIndex >= msg[msgIndex].len)  {
                 // this was already the XOR byte then advance to preamble
                 state = PREAMBLE;
                 preamble_count = 16;
              }  else  {
                 // send separtor and advance to next byte
                 state = SEPERATOR ;
              }
           }
           break;
     }  

     if (flag)  {  // if data==1 then short pulse
        latency=TCNT2;
        TCNT2=latency+TIMER_SHORT;
        last_timer=TIMER_SHORT;
     }  else  {   // long pulse
        latency=TCNT2;
        TCNT2=latency+TIMER_LONG;
        last_timer=TIMER_LONG;
     }  
  }

}

void setup(void) {
  
  //Set the pins for DCC to "output".
  pinMode(DCC_PIN,OUTPUT);   // this is for the DCC Signal
  
  pinMode(DCC_PWM,OUTPUT);   // will be kept high, PWM pin
  digitalWrite(DCC_PWM,1);
  
  pinMode(DCC_THERM, INPUT);
  digitalWrite(DCC_THERM,1); //enable pull up
  
  pinMode(dirPin, INPUT);
  digitalWrite(dirPin, 1);  //enable pull-up resistor !!
  
  for (int i=0 ; i<=maxF; i++){
     pinMode(FPin[i], INPUT);
     digitalWrite(FPin[i], 1);  //enable pull-up resistor
  }  

  read_locoSpeed_etc();
  assemble_dcc_msg();
  
  //Start the timer
  SetupTimer2();  
  
}

void loop(void) {

  delay(200);
  
  if (read_locoSpeed_etc())  {
     // some reading changed
     // make new dcc message
     assemble_dcc_msg();
     ;
  }

}


boolean read_locoSpeed_etc()  {
   boolean changed = false;
   // read the analog input into a variable:
  
   // limit range to 0..127
   locoSpeed = (127L * analogRead(AN_SPEED))/1023;
  
   if (locoSpeed != last_locoSpeed) {
      changed = true;  
      last_locoSpeed = locoSpeed;
   }

   dir = digitalRead(dirPin);
  
   if (dir != last_dir)  {  
      changed = true;  
      last_dir = dir;
   }

   return changed;
}

void assemble_dcc_msg() {
   int i;
   unsigned char data, xdata;
  
   if (locoSpeed == 1)  {  // this would result in emergency stop
      locoSpeed = 0;
   }
  
   // direction info first
   if (dir)  {  // forward
      data = 0x80;
   }  else  {
      data = 0;
   }
  
   data |=  locoSpeed;
    
   // add XOR byte
   xdata = (msg[1].data[0] ^ msg[1].data[1]) ^ data;
  
   noInterrupts();  // make sure that only "matching" parts of the message are used in ISR
   msg[1].data[2] = data;
   msg[1].data[3] = xdata;
   interrupts();

}


Noch nicht von mir getestet!

Code:
/*Enhanced and edited by Dimitri Henning, based on code of 2009 Michael Blank
This program is free software; you can redistribute it and/or modify it under the terms of the
GNU General Public License as published by the Free Software Foundation;
either version 3 of the License, or (at your option) any later version.
This program 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 General Public License for more details.
*/
#include <LiquidCrystal.h>


#define RW_PIN  12 //yellow lcd cable
#define ENABLE_PIN 13 //white lcd cable

#define DCC_PIN    4  // Arduino pin for DCC out
                     // this pin is connected to "DIRECTION" of LMD18200
#define DCC_PWM    5  // must be HIGH for signal out
                      // connected to "PWM in" of LMD18200
#define joystick_1_x_PIN   3  // analog reading for joystick Poti
#define joystick_1_y_PIN   2  // analog reading for joystick Poti
#define clickPin 2   //input for switch

//Timer frequency is 2MHz for ( /8 prescale from 16MHz )
//Timmer clock = 16MHz/8 = 2MHz oder 0,5usec
#define TIMER_SHORT 0x8D  // 58usec pulse length
#define TIMER_LONG  0x1B  // 116usec pulse length

// definitions for state machine
#define PREAMBLE 0    
#define SEPERATOR 1
#define SENDBYTE  2

unsigned char last_timer=TIMER_SHORT;  // store last timer value  
unsigned char flag=0;  // used for short or long pulse
unsigned char every_second_isr = 0;  // pulse up or down
volatile int timer = 0;  //helping construct for stuff

boolean changed = false;
unsigned char state= PREAMBLE;
unsigned char preamble_count = 16;
unsigned char outbyte = 0;
unsigned char cbit = 0x80;


// variables for throttle
int locoSpeed=0;
int locoSpeed_temp=0;
volatile int direction  = 0;
int last_locoSpeed=0;
int last_direction;
int locoAdr=7;   // this is the (fixed) address of the loco

int joystick_1_x;
int joystick_1_y;
LiquidCrystal lcd(RW_PIN, ENABLE_PIN, 8, 9, 10, 11); //initialize display

// buffer for command
struct Message {
   unsigned char data[7];
   unsigned char len;
} ;

#define MAXMSG  2
// for the time being, use only two messages - the idle msg and the loco Speed msg

struct Message msg[MAXMSG] = {
    { { 0xFF,     0, 0xFF, 0, 0, 0, 0}, 3},   // idle msg
    { { locoAdr, 0x3F,  0, 0, 0, 0, 0}, 4}    // locoMsg with 128 speed steps
  };               // loco msg must be filled later with speed and XOR data byte
                                
int msgIndex=0;  
int byteIndex=0;


//Setup Timer2.
//Configures the 8-Bit Timer2 to generate an interrupt at the specified frequency.
//Returns the time load value which must be loaded into TCNT2 inside your ISR routine.
void SetupTimer2(){

  //Timer2 Settings: Timer Prescaler /8, mode 0
  //Timmer clock = 16MHz/8 = 2MHz oder 0,5usec
  TCCR2A = 0;
  TCCR2B = 0<<CS22 | 1<<CS21 | 0<<CS20;

  //Timer2 Overflow Interrupt Enable  
  TIMSK2 = 1<<TOIE2;

  //load the timer for its first cycle
  TCNT2=TIMER_SHORT;

}

//Timer2 overflow interrupt vector handler
ISR(TIMER2_OVF_vect) {
  //Capture the current timer value TCTN2. This is how much error we have
  //due to interrupt latency and the work in this function
  //Reload the timer and correct for latency.  
  // for more info, see http://www.uchobby.com/index.php/2007/11/24/arduino-interrupts/
  unsigned char latency;
  
  // for every second interupt just toggle signal
  if (every_second_isr)  {
     digitalWrite(DCC_PIN,1);
     every_second_isr = 0;    
    
     // set timer to last value
     latency=TCNT2;
     TCNT2=latency+last_timer;
    
  }  else  {  // != every second interrupt, advance bit or state
     digitalWrite(DCC_PIN,0);
     every_second_isr = 1;
    
     switch(state)  {
       case PREAMBLE:
           flag=1; // short pulse
           preamble_count--;
           if (preamble_count == 0)  {  // advance to next state
              state = SEPERATOR;
              // get next message
              msgIndex++;
              if (msgIndex >= MAXMSG)  {  msgIndex = 0; }  
              byteIndex = 0; //start msg with byte 0
           }
           break;
        case SEPERATOR:
           flag=0; // long pulse
           // then advance to next state
           state = SENDBYTE;
           // goto next byte ...
           cbit = 0x80;  // send this bit next time first        
           outbyte = msg[msgIndex].data[byteIndex];
           break;
        case SENDBYTE:
           if (outbyte & cbit)  {
              flag = 1;  // send short pulse
           }  else  {
              flag = 0;  // send long pulse
           }
           cbit = cbit >> 1;
           if (cbit == 0)  {  // last bit sent, is there a next byte?
              byteIndex++;
              if (byteIndex >= msg[msgIndex].len)  {
                 // this was already the XOR byte then advance to preamble
                 state = PREAMBLE;
                 preamble_count = 16;
              }  else  {
                 // send separtor and advance to next byte
                 state = SEPERATOR ;
              }
           }
           break;
     }  
     if (flag)  {  // if data==1 then short pulse
        latency=TCNT2;
        TCNT2=latency+TIMER_SHORT;
        last_timer=TIMER_SHORT;
     }  else  {   // long pulse
        latency=TCNT2;
        TCNT2=latency+TIMER_LONG;
        last_timer=TIMER_LONG;
     }  
  }
}

void setup(void) {
  //Set the pins for DCC to "output".
  pinMode(DCC_PIN,OUTPUT);   // this is for the DCC Signal
  pinMode(clickPin, INPUT);
  analogWrite(5, 255);
  assemble_dcc_msg();
  //Start the timer
  SetupTimer2();  
  
  lcd.begin(20, 4);

    lcd.home();
  
}

void loop(void) {

  if (timer > 0){
    timer=timer-1;
  }


   joystick_1_x = (127L * analogRead(joystick_1_x_PIN))/1023;
   joystick_1_y = (127L * analogRead(joystick_1_y_PIN))/1023;
   lcd.print("    ");
   if (joystick_1_x > 100) {
     locoSpeed = locoSpeed + 3;
   }
   if (joystick_1_x < 30) {
     locoSpeed = locoSpeed - 3;
   }
   if (locoSpeed >127) {
     locoSpeed = 127;
   }
   if (locoSpeed <-127) {
     locoSpeed = -127;
   }
   if (digitalRead(clickPin) == LOW) {
     locoSpeed=0;
   }

delay(10);
lcd.home();
    lcd.print("Geschwindigkeit:");
      lcd.print(locoSpeed);
      lcd.print("   ");
      lcd.setCursor(0,1);
      lcd.print("Richtung:");
      if (locoSpeed == 0)  {
        lcd.print("halt         ");
      }
       if (locoSpeed > 0)  {
        lcd.print("vorwaerts     ");
      }
       if (locoSpeed < 0)  {
        lcd.print("rueckwaerts    ");
      }
    lcd.setCursor(0,2);
    lcd.print("joystick:");
    lcd.print(joystick_1_x);

  assemble_dcc_msg();
}



void assemble_dcc_msg() {
   int i;
   unsigned char data, xdata;
   /*if (locoSpeed == 1)  {  // this would result in emergency stop
      locoSpeed = 0;
   }*/
   // direction info first

   if (locoSpeed < 0) {
     locoSpeed_temp = -locoSpeed;
     data = 0;
     direction = 0;
   } else {
     locoSpeed_temp = locoSpeed;
     data = 0x80; //forward
     direction = 1;
   }
   data |=  locoSpeed_temp;
   // add XOR byte
   xdata = (msg[1].data[0] ^ msg[1].data[1]) ^ data;
  
   noInterrupts();  // make sure that only "matching" parts of the message are used in ISR
   msg[1].data[2] = data;
   msg[1].data[3] = xdata;
   interrupts();

}

Werde erst einmal alles hier reinpacken.

getestet wird noch!

------------------------------------------------------------------------------------------


Code:
// Modified by Burns 2012
// Original 23. November 2009
// works well with LMD18200 Booster
// And with Märklin Delta 6604 66045 /Burns
/*Copyright (C) 2009 Michael Blank

This program is free software; you can redistribute it and/or modify it under the terms of the
GNU General Public License as published by the Free Software Foundation;
either version 3 of the License, or (at your option) any later version.

This program 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 General Public License for more details.
*/

//All pins
/*
0 Man/auto switch
1 Start/Stop switch
2
3 PWM Fire
4 DCC signal
5
6 Station 1
7 Station 2
8 Pre station 1
9 Pre station 2
10
11 Park 1
12 Park 2
13 LED

Analog
0 Gas 1
1 Gas 2
2
3
4
5

*/
#define SENSOR2    9  // Pre station sensor1
#define DCC_PIN    4  // Arduino pin for DCC out
                      // this pin is connected to "DIRECTION" of LMD18200
#define DCC_PWM    3  // must be HIGH for signal out
                      // connected to "PWM in" of LMD18200
#define DCC_THERM  3  // thermal warning PIN //never used
#define AN_SPEED   A2  // analog reading for Speed Poti
// never used #define AN_CURRENT 0  // analog input for current sense reading
#define TRAIN2_BTN 2  // ON-OFF train 2

//Timer frequency is 2MHz for ( /8 prescale from 16MHz )
#define TIMER_SHORT 0x8D  // 58usec pulse length
#define TIMER_LONG  0x1B  // 116usec pulse length

unsigned char last_timer=TIMER_SHORT;  // store last timer value
  
unsigned char flag=0;  // used for short or long pulse
unsigned char every_second_isr = 0;  // pulse up or down

// definitions for state machine
#define PREAMBLE 0    
#define SEPERATOR 1
#define SENDBYTE  2

unsigned char state= PREAMBLE;
unsigned char preamble_count = 16;
unsigned char outbyte = 0;
unsigned char cbit = 0x80;

// variables for throttle
int locoSpeed=0;
int dir;
int last_locoSpeed=0;
int last_dir;
int dirPin = 3;
int FPin[] = { 3,3,3,3};
int maxF =3;
int locoAdr=78;   // this is the (fixed) address of the loco

// Train nr2
int STATIONTIME = 50; // 100ms loop 5s = 50
int runtime2 = 0;
int stoptime2 = 0;
int locoSpeed2=0;
int dir2;
int last_locoSpeed2=0;
int last_dir2;
int dirPin2 = 3;
int FPin2[] = { 3,3,3,3};
int maxF2 =3;
int locoAdr2=72;   // this is the (fixed) address of the loco
boolean stopping2 = false;

// buffer for command
struct Message {
   unsigned char data[7];
   unsigned char len;
} ;

#define MAXMSG  4
// for the time being, use only two messages - the idle msg and the loco Speed msg

struct Message msg[MAXMSG] = {
    { { 0xFF,     0, 0xFF, 0, 0, 0, 0}, 3},   // idle msg
    { { locoAdr, 0x3F,  0, 0, 0, 0, 0}, 4},    // locoMsg with 128 speed steps
    { { locoAdr2, 0x3F,  0, 0, 0, 0, 0}, 4},
    { { locoAdr2, 0x90,  0, 0, 0, 0, 0}, 4}
  };               // loco msg must be filled later with speed and XOR data byte
                                
int msgIndex=0;  
int byteIndex=0;


//Setup Timer2.
//Configures the 8-Bit Timer2 to generate an interrupt at the specified frequency.
//Returns the time load value which must be loaded into TCNT2 inside your ISR routine.
void SetupTimer2(){

  //Timer2 Settings: Timer Prescaler /8, mode 0
  //Timmer clock = 16MHz/8 = 2MHz oder 0,5usec
  TCCR2A = 0;
  TCCR2B = 0<= MAXMSG)  {  msgIndex = 0; }  
              byteIndex = 0; //start msg with byte 0
           }
           break;
        case SEPERATOR:
           flag=0; // long pulse
           // then advance to next state
           state = SENDBYTE;
           // goto next byte ...
           cbit = 0x80;  // send this bit next time first        
           outbyte = msg[msgIndex].data[byteIndex];
           break;
        case SENDBYTE:
           if (outbyte & cbit)  {
              flag = 1;  // send short pulse
           }  else  {
              flag = 0;  // send long pulse
           }
           cbit = cbit >> 1;
           if (cbit == 0)  {  // last bit sent, is there a next byte?
              byteIndex++;
              if (byteIndex >= msg[msgIndex].len)  {
                 // this was already the XOR byte then advance to preamble
                 state = PREAMBLE;
                 preamble_count = 16;
              }  else  {
                 // send separtor and advance to next byte
                 state = SEPERATOR ;
              }
           }
           break;
     }  

     if (flag)  {  // if data==1 then short pulse
        latency=TCNT2;
        TCNT2=latency+TIMER_SHORT;
        last_timer=TIMER_SHORT;
     }  else  {   // long pulse
        latency=TCNT2;
        TCNT2=latency+TIMER_LONG;
        last_timer=TIMER_LONG;
     }  
  }

}

void setup(void) {
  
  //Set the pins for DCC to "output".
  pinMode(DCC_PIN,OUTPUT);   // this is for the DCC Signal
  pinMode(13,OUTPUT);
  pinMode(DCC_PWM,OUTPUT);   // will be kept high, PWM pin
  digitalWrite(DCC_PWM,1);
  
  pinMode(DCC_THERM, INPUT);
  digitalWrite(DCC_THERM,1); //enable pull up
  
  pinMode(dirPin, INPUT);
  digitalWrite(dirPin, 1);  //enable pull-up resistor !!
  
  pinMode(SENSOR2, INPUT);
  digitalWrite(SENSOR2, 1);  //enable pull-up resistor
  
  for (int i=0 ; i<=maxF; i++){
     pinMode(FPin[i], INPUT);
     digitalWrite(FPin[i], 1);  //enable pull-up resistor
  }  

  read_locoSpeed_etc();
  assemble_dcc_msg();
  assemble_dcc_msg2light();
  //Start the timer
  SetupTimer2();  
  
}

void loop(void) {

  delay(200);
  
  if (read_locoSpeed_etc())  {
     // some reading changed
     // make new dcc message
     assemble_dcc_msg();
     ;
  }
  if (read_locoSpeed_etc2())  {
     // some reading changed
     // make new dcc message
     assemble_dcc_msg2();
     ;
  }
  
}


boolean read_locoSpeed_etc()  {
   boolean changed = false;
   // read the analog input into a variable:
  
   // limit range to 0..127
   locoSpeed = (127L * analogRead(AN_SPEED))/1023;
  
   if (locoSpeed != last_locoSpeed) {
      changed = true;  
      last_locoSpeed = locoSpeed;
   }
  
   dir = digitalRead(dirPin);
  
   if (dir != last_dir)  {  
      changed = true;  
      last_dir = dir;
   }

   return changed;
}

void assemble_dcc_msg() {
   int i;
   unsigned char data, xdata;
  
   if (locoSpeed == 1)  {  // this would result in emergency stop
      locoSpeed = 0;
   }
  
   // direction info first
   if (dir)  {  // forward
      data = 0x80;
   }  else  {
      data = 0;
   }
  
   data |=  locoSpeed;
    
   // add XOR byte
   xdata = (msg[1].data[0] ^ msg[1].data[1]) ^ data;
  
   noInterrupts();  // make sure that only "matching" parts of the message are used in ISR
   msg[1].data[2] = data;
   msg[1].data[3] = xdata;
   interrupts();

}

boolean read_locoSpeed_etc2()  {
   boolean changed = false;
   // read the analog input into a variable:
  
   // limit range to 0..127
   //locoSpeed = (127L * analogRead(AN_SPEED))/1023;
   if (digitalRead(SENSOR2)) {
     if (runtime2 >= 200) {
       stopping2 = true;
     }
     digitalWrite(13,1);
   }
   else {
     digitalWrite(13,0);
   }
   if (stopping2) {
     locoSpeed2--;
     locoSpeed2--;
   }
   else {
     locoSpeed2++;
     runtime2++;
   }
   if (locoSpeed2 >=126) {
     locoSpeed2 = 126;
   }
   if (locoSpeed2 <=0) {
     locoSpeed2 = 0;
     stoptime2++;
   }
    if (stoptime2 >= STATIONTIME) {
      stopping2 = false;
      stoptime2 = 0;
      runtime2 = 0;
    }

   if (locoSpeed2 != last_locoSpeed2) {
      changed = true;  
      last_locoSpeed2 = locoSpeed2;
   }

   dir = digitalRead(dirPin);
  
   if (dir2 != last_dir2)  {  
      changed = true;  
      last_dir2 = dir2;
   }

   return changed;
}

void assemble_dcc_msg2() {
   int i;
   unsigned char data, xdata;
  
   if (locoSpeed2 == 1)  {  // this would result in emergency stop
      locoSpeed2 = 0;
   }
  
   // direction info first
   if (dir)  {  // forward
      data = 0x80;
   }  else  {
      data = 0;
   }
  
   data |=  locoSpeed2;
    
   // add XOR byte
   xdata = (msg[2].data[0] ^ msg[2].data[1]) ^ data;
  
   noInterrupts();  // make sure that only "matching" parts of the message are used in ISR
   msg[2].data[2] = data;
   msg[2].data[3] = xdata;
   interrupts();

}
void assemble_dcc_msg2light() {
   int i;
   unsigned char data, xdata;
  
   if (locoSpeed2 == 1)  {  // this would result in emergency stop
      locoSpeed2 = 0;
   }
  
   data = 0;
  
   // add XOR byte
   xdata = (msg[3].data[0] ^ msg[3].data[1]) ^ data;
  
   noInterrupts();  // make sure that only "matching" parts of the message are used in ISR
   msg[3].data[2] = data;
   msg[3].data[3] = xdata;
   interrupts();

}

Eine weitere Möglichkei, bin gespannt ob alles im Testaufbau läuft

Edit:
http://oscale.net/?q=simpledcc

Nicht jeder Neuling in einem Forum hat keine Ahnung über die Materie!
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
08.09.2016, 16:01
Beitrag #3
RE: Lib für Modellbahn Digitalsteuerung?
http://www.stummiforum.de/viewtopic.php?f=21&t=127899

Wenn ich etwas passendes finde, werde ich es mir hier merken.
Gruß

Nicht jeder Neuling in einem Forum hat keine Ahnung über die Materie!
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
23.07.2017, 09:59 (Dieser Beitrag wurde zuletzt bearbeitet: 23.07.2017 10:17 von fraju.)
Beitrag #4
RE: Lib für Modellbahn Digitalsteuerung?
Hallo
Nach langer Zeit , wieder mal Arduino!
Habe jetzt diesen DCC Decoder aufgebaut und getestet.
Hat sofort funktioniert!
Nur in der Case Anweisung

Zitat: case FN_0_4:
digitalWrite( FunctionPin0, (FuncState & FN_BIT_00)>>4 );
digitalWrite( FunctionPin1, (FuncState & FN_BIT_01) );
digitalWrite( FunctionPin2, (FuncState & FN_BIT_02)>>1 );
digitalWrite( FunctionPin3, (FuncState & FN_BIT_03)>>2 );
digitalWrite( FunctionPin4, (FuncState & FN_BIT_03)>>3 );
break;
Zeile
digitalWrite( FunctionPin4, (FuncState & FN_BIT_03)>>3 );
ändern!
digitalWrite( FunctionPin4, (FuncState & FN_BIT_04)>>3 );


Code:
// Production 17 Function DCC Decoder
// Version 5.4  Geoff Bunza 2014,2015,2016

// ******** UNLESS YOU WANT ALL CV'S RESET UPON EVERY POWER UP
// ******** AFTER THE INITIAL DECODER LOAD REMOVE THE "//" IN THE FOOLOWING LINE!!
//#define DECODER_LOADED

#include <NmraDcc.h>

int tim_delay = 500;
#define numleds  17
byte ledpins [] = {0,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};

const int FunctionPin0 = 3;
const int FunctionPin1 = 4;
const int FunctionPin2 = 5;
const int FunctionPin3 = 6;
const int FunctionPin4 = 7;

const int FunctionPin5 = 8;
const int FunctionPin6 = 9;
const int FunctionPin7 = 10;
const int FunctionPin8 = 11;

const int FunctionPin9 = 12;
const int FunctionPin10 = 13;
const int FunctionPin11 = 14;     //A0
const int FunctionPin12 = 15;     //A1

const int FunctionPin13 = 16;     //A2
const int FunctionPin14 = 17;     //A3
const int FunctionPin15 = 18;     //A4
const int FunctionPin16 = 19;     //A5
NmraDcc  Dcc ;
DCC_MSG  Packet ;
uint8_t CV_DECODER_MASTER_RESET = 120;
#define This_Decoder_Address 24

struct CVPair
{
  uint16_t  CV;
  uint8_t   Value;
};
CVPair FactoryDefaultCVs [] =
{
  {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address},
  {CV_ACCESSORY_DECODER_ADDRESS_MSB, 0},
  {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0},
  {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, 0},
  {CV_DECODER_MASTER_RESET, 0},
};

uint8_t FactoryDefaultCVIndex = 4;
void notifyCVResetFactoryDefault()
{
  // Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset
  // to flag to the loop() function that a reset to Factory Defaults needs to be done
  FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair);
};
void setup()
{
  // initialize the digital pins as an outputs
    for (int i=1; i<= numleds; i++) {
      pinMode(ledpins[i], OUTPUT);
      digitalWrite(ledpins[i], LOW);
     }
  for (int i=1; i<= numleds; i++) {
     digitalWrite(ledpins[i], HIGH);
     delay (tim_delay/10);
  }
  delay( tim_delay);
  for (int i=1; i<= numleds; i++) {
     digitalWrite(ledpins[i], LOW);
     delay (tim_delay/10);
  }
  delay( tim_delay);
  
  // Setup which External Interrupt, the Pin it's associated with that we're using and enable the Pull-Up
  Dcc.pin(0, 2, 0);
  // Call the main DCC Init function to enable the DCC Receiver
  Dcc.init( MAN_ID_DIY, 100, FLAGS_MY_ADDRESS_ONLY, 0 );
  delay(800);
#if defined(DECODER_LOADED)
  if ( Dcc.getCV(CV_DECODER_MASTER_RESET)== CV_DECODER_MASTER_RESET )
#endif
     {
       for (int j=0; j < FactoryDefaultCVIndex; j++ )
         Dcc.setCV( FactoryDefaultCVs[j].CV, FactoryDefaultCVs[j].Value);
         digitalWrite(13, 1);  //Blink the on board LED
         delay (1000);
         digitalWrite(13, 0);
     }
}
void loop()
{
  // You MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation
  Dcc.process();
  if( FactoryDefaultCVIndex && Dcc.isSetCVReady())
  {
    FactoryDefaultCVIndex--; // Decrement first as initially it is the size of the array
    Dcc.setCV( FactoryDefaultCVs[FactoryDefaultCVIndex].CV, FactoryDefaultCVs[FactoryDefaultCVIndex].Value);
  }
}

void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState)
{
  switch(FuncGrp)
  {
    case FN_0_4:
      digitalWrite( FunctionPin0, (FuncState & FN_BIT_00)>>4 );
      digitalWrite( FunctionPin1, (FuncState & FN_BIT_01) );
      digitalWrite( FunctionPin2, (FuncState & FN_BIT_02)>>1 );
      digitalWrite( FunctionPin3, (FuncState & FN_BIT_03)>>2 );
      digitalWrite( FunctionPin4, (FuncState & FN_BIT_03)>>3 );
      break;
      
    case FN_5_8:
      digitalWrite( FunctionPin5, (FuncState & FN_BIT_05) );
      digitalWrite( FunctionPin6, (FuncState & FN_BIT_06)>>1 );
      digitalWrite( FunctionPin7, (FuncState & FN_BIT_07)>>2 );
      digitalWrite( FunctionPin8, (FuncState & FN_BIT_08)>>3 );
      break;
      
    case FN_9_12:
      digitalWrite( FunctionPin9,  (FuncState & FN_BIT_09) );
      digitalWrite( FunctionPin10, (FuncState & FN_BIT_10)>>1 );
      digitalWrite( FunctionPin11, (FuncState & FN_BIT_11)>>2 );
      digitalWrite( FunctionPin12, (FuncState & FN_BIT_12)>>3 );
      break;

    case FN_13_20:
      digitalWrite( FunctionPin13, (FuncState & FN_BIT_13) );
      digitalWrite( FunctionPin14, (FuncState & FN_BIT_14)>>1 );
      digitalWrite( FunctionPin15, (FuncState & FN_BIT_15)>>2 );
      digitalWrite( FunctionPin16, (FuncState & FN_BIT_16)>>3 );
      break;
      
    case FN_21_28:
      break;
  }
}


Z.Z.Habe ich eine serielle Ausgabe mit Grafikdisplay an den Decoder.
Dieses zeigt mir Speed/Adresse/ Vor/Rück-LED und die 16 Leds an.
Später wird dies noch eine Anzeigetafel für ein Modellbahnhof.

Jetzt muss ich noch ein Sound Modul damit ansteuern, für Bahnhofansagen.
Meine "Digitalen" Modellbahnkollegen melden schon starke Interesse an, es einzusetzen.
Wenn es soweit ist werde ich das Geänderte Programm hier einstellen.

Gruß

Kleine Zeichnung werde ich noch machen.

Nicht jeder Neuling in einem Forum hat keine Ahnung über die Materie!
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
27.07.2017, 09:12
Beitrag #5
RE: Lib für Modellbahn Digitalsteuerung?
http://pgahtow.de/wiki/index.php?title=D...er_sch.png
https://github.com/mrrwa/NmraDcc
http://mrrwa.org/

Mit diesen habe ich experimentiert,aber mit dem NANO.
http://www.trainelectronics.com/DCC_Arduino/

Eingangschaltung etwas verändert und an TX hängt z.Z. noch ein Controller welcher das Grafikdisplay,MP3 Playe und Anderes Ansteuert.

Muss jetzt mal ein kleines Gebrauchsmuster fertigen.
, damit alles besser getestet werden kann.

https://www.google.de/search?q=arduino+d...SrqEAsFkM:
Bei der Minizentrale habe ich als Booster z.Z ein Modul mit dem L298N eingesetzt.
Mit einen DL100 die Eingänge angepasst.

Nicht jeder Neuling in einem Forum hat keine Ahnung über die Materie!
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
13.10.2017, 13:50
Beitrag #6
RE: Lib für Modellbahn Digitalsteuerung?
Hallo,
Habe die Mini Zentrale etwas erweitert, bleibt aber einfach .
Kann jetzt auch Licht(F0) und F1-F28 ansteuern.
CVs kann ich noch nicht senden, bin aber dabei.
Es geht nur um die ADR Änderung über CVs.
Will das Programm der Zentrale bissel sortieren damit vielleicht auch Andere es verstehen können.

Es soll sehr einfach werden, sehe ich als Mindestforderung.
Speed, Vor/Rück Loklicht Ein/Aus
Funktionstasten F1-F4
4 Loks

Der Lok oder Funktionsdecoder muss dann extern eingestellt werden.

..wird hier bestimmt erscheinen, da doch einige Interesse besteht!
Gruß

Nicht jeder Neuling in einem Forum hat keine Ahnung über die Materie!
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
13.10.2017, 14:25
Beitrag #7
RE: Lib für Modellbahn Digitalsteuerung?
Hallo fraju,
bist Du nur an der Zentrale und an Funktionsdecodern interessiert, oder auch an Zubehördecodern?
Ich habe mal ein frei konfigurierbaren Zubehördecoder geschrieben. Derzeit bin ich dabei, den auf Klassen für die unterstützen Funktionen umzuschreiben ( ist schon weitgehend fertig ). Dann ist es auch einfacher, die Funktionen zu erweitern, oder die Klassen in einem anderen Umfeld zu verwenden ( ich denke da z.B. auch an einen Funktionsdecoder ).

Gruß, Franz-Peter
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
13.10.2017, 16:19 (Dieser Beitrag wurde zuletzt bearbeitet: 13.10.2017 16:21 von fraju.)
Beitrag #8
RE: Lib für Modellbahn Digitalsteuerung?
@ MicroBahner
Das alles habe ich mir schon angeschaut, und natürlich noch mehr!
Ist für Anfänger nach meiner Meinung alles zu aufwändig.
Wobei ich nur DCC Anfänger bin!


Ich habe das Grundprogramm benutzt und dann feststellen müssen, das nur Speed und Vor/ Rück geht.

Daraus habe ich alles gemacht.
Jetzt kann ich Speed,Vor/Rück, Licht(F0) und F1-F28 ansteuern.

Auch das einfachste Decoder Programm genutzt und nur Verändert.

Suche jetzt nur die Sendesequenz für die einfache Zentrale um die ADR des Decoders zu ändern.

Nehme an das es ähnlich ist wie mit den Funktionstasten.
Das reicht dann erst mal für eine Kleinanlage!

@ MicroBahner
Das alles habe ich mir schon angeschaut, und natürlich noch mehr!
Ist für Anfänger nach meiner Meinung alles zu aufwändig.
Wobei ich nur DCC Anfänger bin!


Ich habe das Grundprogramm benutzt und dann feststellen müssen, das nur Speed und Vor/ Rück geht.

Daraus habe ich alles gemacht.
Jetzt kann ich Speed,Vor/Rück, Licht(F0) und F1-F28 ansteuern.

Auch das einfachste Decoder Programm genutzt und nur Verändert.

Suche jetzt nur die Sendesequenz für die einfache Zentrale um die ADR des Decoders zu ändern.

Nehme an das es ähnlich ist wie mit den Funktionstasten.
Das reicht dann erst mal für eine Kleinanlage!

Nicht jeder Neuling in einem Forum hat keine Ahnung über die Materie!
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste