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
Arduino und NmraDcc
27.02.2020, 22:54 (Dieser Beitrag wurde zuletzt bearbeitet: 28.02.2020 16:09 von Bitklopfer.)
Beitrag #25
RE: Arduino und NmraDcc
Hallo Christian,
(27.02.2020 18:23)Christian_Moba-Arduino schrieb:  Ich hatte mir vorgestellt, die Software Saleae Logic liest den Kanal permanent ein und gibt das DCC Signal auf dem Monitor wieder, sodass wenn ich einen Weichenbefehl sende, diesen Befehl sehe. Tut es leider nicht, denn die Software macht nur Standbilder vom Protokoll , wenn ich auf die Schaltfläche "Start" drücke.
Hallo Christian,
ein LA ist dafür gemacht, Logik-Signale zu analysieren. Das sind in aller Regel keine sich gleichmässig wiederholenden Signale, die man - wie auf einem Oszi - als 'Lifebild' darstellen könnte. Auf dem DCC-Bus kommen ja ständig irgendwelche Signale, wie soll da etwas 'ansehbares' als Lifebild dargestellt wrden? Das geht nur als Standbild. Du siehst aber auf jeden Fall, dass das DCC-Signal ordentlich am Arduino ankommt.
Was da die Weichenbefehle sind, kann der LA nicht erkennen. Normalerweise stellt man eine 'Triggerbedingung' ein. Also eine Flanke auf einem Kanal und/oder eine bestimmte Signalkombination. Wenn Du dann auf 'Start' klickst, werden alle Kanäle ständig aufgezeichnet. Sobald die 'Triggerbedingung' auftritt läuft die Aufzeichnung noch eine voreinstellbare Zeit, und dann wird das Ergebnis angezeigt. Da siehst Du dann auch einen einstellbaren Bereich der Signale vor der Triggerbedingung.
Standardmäßig reagiert er auf eine beliebige Flanke auf irgendeinem Kanal - damit startet die Aufzeichnung sofort.
Als Triggerbedingung könnte man auch einen Ausgang vom Arduino nehmen, den man schaltet, wenn ein Telegramm erkannt wird.

Was da auf deinem seriellen Monitor ankommt, sieht mir nach Lok-Telegrammen aus ( Multifunktionsdecoder oder speed/Richtungsbefehle ). Die werden ja auf dem Bus ständig gesendet, damit auch eine neu aufgegleiste Lok gegebenenfalls gleich ihr Signal bekommt. D.h. aber auf jeden Fall mal, dass die Decodierung funktioniert.
Weichentelegramme werden nur bei Bedarf gesendet und ein paar mal wiederholt. Die werden also in den ständigen Strom der Lok-Befehle eingestreut. Man müsste sie auf dem seriellen Monitor aber kurz erkennen können.

P.S. ich hatte mal eine Version der Software, die die DCC-Signale auch decodieren konnte. Allerdings nur die Hex-Werte, so wie Du sie jetzt auch auf dem seriellen Monitor siehst. Seit der letzten Neuinstallation meines PC's geht das aber auch nicht mehr. Ich müsste mal schauen, wo ich das her hatte.

Gruß, Franz-Peter
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
28.02.2020, 09:32 (Dieser Beitrag wurde zuletzt bearbeitet: 28.02.2020 16:09 von Bitklopfer.)
Beitrag #26
RE: Arduino und NmraDcc
Hallo Christian,
ich habe jetzt auch den Analyser für DCC-Signale wiedergefunden. Auf dieser Webseite kanst Du ihn herunterladen. Dann wie beschrieben, die richtige Version ( 64 oder 32 Bit ) in das 'Analysers' Verzeichnis der Saleae-Installation kopieren.
Danach kannst Du dann in der LA-Oberfläche rechts unter 'Analysers' den DCC Interpreter dem Kanal zuweisen, an dem das DCC-Signal anliegt. Dann kennzeichnet die Software die entsprechenden Bereiche des Datenstroms ( Preambel, Start/Stopbits, Datenbytes und Prüfbyte ). Was die jeweiligen Datenbytes bedeuten, musst Du allerdings selbst interpretieren - so wie auch die Anzeige auf dem ser. Monitor.

Du kannst auch das Beispiel der NmraDcc Lib etwas modifizieren, indem Du in notifyDccMsg einen Impuls auf einem Pin erzeugst. Den kannst Du dann als Triggerbedingung für den LA nutzen. Wenn Du den Impuls noch davon abhängig machst, dass das erste Byte im Telegramm ( Msg->Data[0] ) NICHT 0xC0 ist, dann siehst Du wenn ein anderes Telegramm auf dem Bus erscheint ( die Abfrage könntest Du auch für die serielle Ausgabe machen, dann unterdrückst Du diese ständig gesendeten Telegamme und siehst besser was sonst noch erscheint ).

Gruß, Franz-Peter
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
28.02.2020, 16:12 (Dieser Beitrag wurde zuletzt bearbeitet: 28.02.2020 16:14 von Christian_Moba-Arduino.)
Beitrag #27
RE: Arduiono und NmraDcc
Hallo Franz-Peter,
Danke für ausführliche Antwort. Ich werde mich am Wochenende an das Problem ransetzen. Malschauen wie weit ich komme.

Du schreibst,
"ich hatte mal eine Version der Software, die die DCC-Signale auch decodieren konnte. Allerdings nur die Hex-Werte, so wie Du sie jetzt auch auf dem seriellen Monitor siehst. Seit der letzten Neuinstallation meines PC's geht das aber auch nicht mehr. Ich müsste mal schauen, wo ich das her hatte. "


Dazu noch eine kleine Frage, im Eingangspost meines Beitrages hast Du geschrieben das es bei Dir funktioniert, aber im letzten Beitrag schreibst Du gegenteilig das es nach einer Neuinstallation deines PC's nun auch nicht mehr funktioniert.
Ist das ein Windows 10 64Bit Problem ?

Ich habe mir die NMRA Bibliothek über IDE > Werkzeuge> Bibliothek verwalten>
NmraDcc installiert. Version 2.0
Hatte diese als einzige runtergeladen.

Kann es sein, das vielleicht beim Installieren der Bibliothek immer noch auf etwas Altem zurückgegriffen wird, und es dadurch nicht funktioniert ?


Das war es erstmal mit meinen Fragen, ich melde mich, wenn ich ein Ergebnis am Wochenende finde. Werde Dich dann nochmal anschreiben, wg.
( Msg->Data[0] ) NICHT 0xC0) das habe ich noch nicht so richtig verstanden, werde es aber verstehen lernen. Muss sehen, ob die Zentrale immer diese Zeile notifyDccMsg: C0 5F 9F sendet.


Vielen Dank
VG
Christian

p.s. Bist Du Franz-Peter Müller , der die NmraDcc mitentwickelt hat ?
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
28.02.2020, 17:13 (Dieser Beitrag wurde zuletzt bearbeitet: 28.02.2020 17:21 von MicroBahner.)
Beitrag #28
RE: Arduino und NmraDcc
(28.02.2020 16:12)Christian_Moba-Arduino schrieb:  Dazu noch eine kleine Frage, im Eingangspost meines Beitrages hast Du geschrieben das es bei Dir funktioniert, aber im letzten Beitrag schreibst Du gegenteilig das es nach einer Neuinstallation deines PC's nun auch nicht mehr funktioniert.
Ich glaube da hast Du etwas missverstanden. Das Beispiel der NmraDcc Lib auf dem Arduino funktioniert bei mir - es hat vor der Neuinstallation funktioniert, und auch jetzt nachdem ich es aufgrund deines Beitrages nochmal mit Arduino 1.8.12 getestet habe, funktioniert es.
Das, was nach der Neuinstallation erstmal nicht funktioniert hat, war die Auswertung des DCC Signals in der LA-Software von Saleae. Da habe ich aber inzwischen herausgefunden, wie man das wieder aktiviert, und den Link hatte ich im vorigen Post mitgeschickt. Dann sieht das Bild im LA so aus:
   
In der ersten Zeile ist das DCC-Signal, in der 2. das TX0-Signal an den seriellen Monitor. Über dem DCC-Signal wird die Bedeutung der jeweiligen Abschnitte angezeigt. Jedes Telegramm beginnt mit einer Preambel, dann kommen die Datenbytes und zu Schluß das Prüfbyte. Man sieht schön, wie nach jedem empfamgenen Telegramm die Ausgabe an den seriellen Monitor startet. Die Bedeutung der Datenbytes muss man dann allerdings selbst auswerten und interpretieren. Dazu braucht es dann schon etwas tiefere Kenntnisse des DCC-Protokolls.

(28.02.2020 16:12)Christian_Moba-Arduino schrieb:  wg. ( Msg->Data[0] ) NICHT 0xC0) das habe ich noch nicht so richtig verstanden,
Du änderst das Beispiel ein klein wenig ab:
Code:
void notifyDccMsg( DCC_MSG * Msg)
{
  if ( Msg->Data[0] != 0xC0) {
    Serial.print("notifyDccMsg: ") ;
    for(uint8_t i = 0; i < Msg->Size; i++)
    {
      Serial.print(Msg->Data[i], HEX);
      Serial.write(' ');
    }
    Serial.println();
  }
}
Dann werden nur Telegramm auf den Monitor ausgegeben, die nicht mit C0 anfangen. Du erkennst dann leichter, wenn etwas anderes ( z.B. ein Weichentelegramm ) gesendet wird.

(28.02.2020 16:12)Christian_Moba-Arduino schrieb:  Bist Du Franz-Peter Müller , der die NmraDcc mitentwickelt hat ?
ja, ich habe da ein klein wenig die Finger mit im Spiel Wink

Gruß, Franz-Peter
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
28.02.2020, 21:31 (Dieser Beitrag wurde zuletzt bearbeitet: 28.02.2020 21:43 von Christian_Moba-Arduino.)
Beitrag #29
RE: Arduino und NmraDcc
Hallo Franz Peter,
nach einigen Versuchen, habe ich scheinbar wieder eine Beispieldatei gefunden die funktioniert.
Mir ist unklar wieso das vorher nicht funktioniert hat, jetzt klappt es.
Habe mir den u.g. Quellcode auf den MEGA2560 hochgeladen mit der Version IDE 1.8.12

Code:
#include <NmraDcc.h>

// This Example shows how to use the library as a DCC Accessory Decoder or a DCC Signalling Decoder
// It responds to both the normal DCC Turnout Control packets and the newer DCC Signal Aspect packets
// You can also print every DCC packet by uncommenting the "#define NOTIFY_DCC_MSG" line below

NmraDcc  Dcc ;
DCC_MSG  Packet ;

struct CVPair
{
  uint16_t  CV;
  uint8_t   Value;
};

CVPair FactoryDefaultCVs [] =
{
  {CV_ACCESSORY_DECODER_ADDRESS_LSB, 1},
  {CV_ACCESSORY_DECODER_ADDRESS_MSB, 0},
};

uint8_t FactoryDefaultCVIndex = 0;

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);
};

const int DccAckPin = 3 ;

// This function is called by the NmraDcc library when a DCC ACK needs to be sent
// Calling this function should cause an increased 60ma current drain on the power supply for 6ms to ACK a CV Read
void notifyCVAck(void)
{
  Serial.println("notifyCVAck") ;
  
  digitalWrite( DccAckPin, HIGH );
  delay( 6 );  
  digitalWrite( DccAckPin, LOW );
}

// Uncomment to print all DCC Packets
//#define NOTIFY_DCC_MSG
#ifdef  NOTIFY_DCC_MSG
void notifyDccMsg( DCC_MSG * Msg)
{
  Serial.print("notifyDccMsg: ") ;
  for(uint8_t i = 0; i < Msg->Size; i++)
  {
    Serial.print(Msg->Data[i], HEX);
    Serial.write(' ');
  }
  Serial.println();
}
#endif

// This function is called whenever a normal DCC Turnout Packet is received
void notifyDccAccState( uint16_t Addr, uint16_t BoardAddr, uint8_t OutputAddr, uint8_t State)
{
  Serial.print("notifyDccAccState: ") ;
  Serial.print(Addr,DEC) ;
  Serial.print(',');
  Serial.print(BoardAddr,DEC) ;
  Serial.print(',');
  Serial.print(OutputAddr,DEC) ;
  Serial.print(',');
  Serial.println(State, HEX) ;
}

// This function is called whenever a normal DCC Turnout Packet is received
void notifyDccAccTurnoutBoard( uint16_t BoardAddr, uint8_t OutputPair, uint8_t Direction, uint8_t OutputPower )
{
  Serial.print("notifyDccAccTurnoutBoard: ") ;
  Serial.print(BoardAddr,DEC) ;
  Serial.print(',');
  Serial.print(OutputPair,DEC) ;
  Serial.print(',');
  Serial.print(Direction,DEC) ;
  Serial.print(',');
  Serial.println(OutputPower, HEX) ;
}

// This function is called whenever a normal DCC Turnout Packet is received
void notifyDccAccTurnoutOutput( uint16_t Addr, uint8_t Direction, uint8_t OutputPower )
{
  Serial.print("notifyDccAccTurnoutOutput: ") ;
  Serial.print(Addr,DEC) ;
  Serial.print(',');
  Serial.print(Direction,DEC) ;
  Serial.print(',');
  Serial.println(OutputPower, HEX) ;
}

// This function is called whenever a DCC Signal Aspect Packet is received
void notifyDccSigState( uint16_t Addr, uint8_t OutputIndex, uint8_t State)
{
  Serial.print("notifyDccSigState: ") ;
  Serial.print(Addr,DEC) ;
  Serial.print(',');
  Serial.print(OutputIndex,DEC) ;
  Serial.print(',');
  Serial.println(State, HEX) ;
}

void setup()
{
  Serial.begin(115200);
  
  // Configure the DCC CV Programing ACK pin for an output
  pinMode( DccAckPin, OUTPUT );

  Serial.println("NMRA DCC Example 1");
  
  // Setup which External Interrupt, the Pin it's associated with that we're using and enable the Pull-Up
  Dcc.pin(0, 2, 1);
  
  // Call the main DCC Init function to enable the DCC Receiver
  Dcc.init( MAN_ID_DIY, 10, CV29_ACCESSORY_DECODER | CV29_OUTPUT_ADDRESS_MODE, 0 );

  Serial.println("Init Done");
}

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);
  }
}

Der ArduionoIDE Serial Monitor zeigt folgendes an, wenn ich Weichenadresse "15" mit meiner RocoMulti Maus (angeschlossen an der DR5000 am XN/FB Buchse).

Code:
21:24:10.552 -> notifyDccAccState: 15,4,5,8
21:24:10.552 -> notifyDccAccTurnoutBoard: 4,2,1,1
21:24:10.599 -> notifyDccAccTurnoutOutput: 15,1,1
21:24:10.599 -> notifyDccAccState: 15,4,5,8
21:24:10.599 -> notifyDccAccTurnoutBoard: 4,2,1,1
21:24:10.599 -> notifyDccAccTurnoutOutput: 15,1,1
21:24:10.599 -> notifyDccAccState: 15,4,5,8
21:24:10.599 -> notifyDccAccTurnoutBoard: 4,2,1,1
21:24:10.599 -> notifyDccAccTurnoutOutput: 15,1,1
21:24:10.599 -> notifyDccAccState: 15,4,5,8
21:24:10.599 -> notifyDccAccTurnoutBoard: 4,2,1,1
21:24:10.646 -> notifyDccAccTurnoutOutput: 15,1,1
21:24:10.646 -> notifyDccAccState: 15,4,5,8
21:24:10.646 -> notifyDccAccTurnoutBoard: 4,2,1,1
21:24:10.646 -> notifyDccAccTurnoutOutput: 15,1,1
21:24:10.646 -> notifyDccAccState: 15,4,5,8
21:24:10.646 -> notifyDccAccTurnoutBoard: 4,2,1,1
21:24:10.646 -> notifyDccAccTurnoutOutput: 15,1,1
21:24:10.646 -> notifyDccAccState: 15,4,5,0
21:24:10.646 -> notifyDccAccTurnoutBoard: 4,2,1,0
21:24:10.693 -> notifyDccAccTurnoutOutput: 15,1,0
21:24:10.693 -> notifyDccAccState: 15,4,5,0
21:24:10.693 -> notifyDccAccTurnoutBoard: 4,2,1,0
21:24:10.693 -> notifyDccAccTurnoutOutput: 15,1,0
21:24:10.693 -> notifyDccAccState: 15,4,5,0
21:24:10.693 -> notifyDccAccTurnoutBoard: 4,2,1,0
21:24:10.693 -> notifyDccAccTurnoutOutput: 15,1,0
21:24:10.693 -> notifyDccAccState: 15,4,5,0
21:24:10.693 -> notifyDccAccTurnoutBoard: 4,2,1,0
21:24:10.740 -> notifyDccAccTurnoutOutput: 15,1,0
21:24:10.740 -> notifyDccAccState: 15,4,5,0
21:24:10.740 -> notifyDccAccTurnoutBoard: 4,2,1,0
21:24:10.740 -> notifyDccAccTurnoutOutput: 15,1,0
21:24:10.740 -> notifyDccAccState: 15,4,5,0
21:24:10.740 -> notifyDccAccTurnoutBoard: 4,2,1,0
21:24:10.740 -> notifyDccAccTurnoutOutput: 15,1,0
21:24:10.740 -> notifyDccAccState: 15,4,5,0
21:24:10.740 -> notifyDccAccTurnoutBoard: 4,2,1,0
21:24:10.787 -> notifyDccAccTurnoutOutput: 15,1,0
21:24:10.787 -> notifyDccAccState: 15,4,5,0
21:24:10.787 -> notifyDccAccTurnoutBoard: 4,2,1,0
21:24:10.787 -> notifyDccAccTurnoutOutput: 15,1,0
21:24:10.787 -> notifyDccAccState: 15,4,5,0
21:24:10.787 -> notifyDccAccTurnoutBoard: 4,2,1,0
21:24:10.787 -> notifyDccAccTurnoutOutput: 15,1,0


Wichtig sind ja zum Auswerten diese Zeilen
1:24:10.787 -> notifyDccAccTurnoutOutput: 15,1,0 // Weiche 15 Abzweig
21:24:10.646 -> notifyDccAccTurnoutOutput: 15,1,1 // Weiche 15 Geradeaus

Was sind das für Zeilen und deren Bedeutung ?
21:24:10.787 -> notifyDccAccTurnoutBoard: 4,2,1,0
bzw.
21:24:10.646 -> notifyDccAccTurnoutBoard: 4,2,1,1

Die scheinen von der Roco Maus zu stammen, die "4" darin ändert sich auch im Wert, wenn ich eine anderen Weichenadresse schalte.

Werde nun im Step by Step wieder alles in Ruhe programmieren und weiter verstehen lernen. Es ist toll solch eine gute Hilfe bei Euch zu bekommen.

Schönen Abend
wünscht Christian
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
28.02.2020, 22:52
Beitrag #30
RE: Arduino und NmraDcc
Hallo Christian,
jetzt hast Du dir aber wieder eine alte Version der NmraDcc Lib installiert.
die Ausgaben
Code:
21:24:10.787 -> notifyDccAccState: 15,4,5,0
21:24:10.787 -> notifyDccAccTurnoutBoard: 4,2,1,0
21:24:10.787 -> notifyDccAccTurnoutOutput: 15,1,0
sind alles Reaktionen auf dasselbe Telegram, das nur etwas unterschiedlich interpretiert wird.
In der aktuellen Versionn wird da nur noch
notifyDccAccTurnoutBoard oder notifyDccAccTurnoutOutput ausgegeben, je nachdem wie das Bit 6 in CV29 steht:
Bit 6 - 0: 9-bit Decoder-Addressing, 1=11-bit output-addressing
Dieses Bit entscheidet, wie die Adressinformation für die Weiche ausgewertet wird.
Entweder als Decodernummer eines 4-fach Weichendecoders ( und der Weichennummer 0..3 dieses Decoders ), oder als durchgehend numerierte Weichennummer.

(28.02.2020 21:31)Christian_Moba-Arduino schrieb:  Wichtig sind ja zum Auswerten diese Zeilen
1:24:10.787 -> notifyDccAccTurnoutOutput: 15,1,0 // Weiche 15 Abzweig
21:24:10.646 -> notifyDccAccTurnoutOutput: 15,1,1 // Weiche 15 Geradeaus
Das ist nicht ganz richtig. Zwischen Abzeig und Geradeaus eintscheidet nicht der letzte Wert, sondern der in der Mitte:
notifyDccAccTurnoutOutput: 15,1,1 // Weiche 15 Abzweig
notifyDccAccTurnoutOutput: 15,0,1 // Weiche 15 Geradeaus
Der letzte Wert ist für das Ein/Ausschalten der Antriebsspule in der Weiche.

Gruß, Franz-Peter
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
08.03.2020, 11:43 (Dieser Beitrag wurde zuletzt bearbeitet: 08.03.2020 11:44 von Christian_Moba-Arduino.)
Beitrag #31
RE: Arduino und NmraDcc
Hallo Franz-Peter,

ich habe heute zwei Projekte erfolgreich erstellt bekommen.
1x den Zubehördecoder
1x den Lokdecoder

Beim Lokdecoder konnte ich auch die CV 1 (Lokadresse auf "23" statt "24") umstellen. Damit funktioniert auch die CV Programmierung.

Ich verwende jetzt die Portable Arduino Version 1.8.10 und die NMRA Bibliothek
Version 2.0.0

Eine Frage,
Eine Frage, warum funktioniert das Decoder-Projekt mit dem Servo nicht ?
Ich weiß leider nicht, woher ich diese Bibliothek her komme.
Ich würde mich freuen, wenn Du mir dabei weiterhelfen kannst.

Vielen Dank
Christian


Angehängte Datei(en) Thumbnail(s)
   
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
03.10.2020, 11:35 (Dieser Beitrag wurde zuletzt bearbeitet: 03.10.2020 11:41 von Christian_Moba-Arduino.)
Beitrag #32
RE: Arduino und NmraDcc
Hallo Arduino Freunde, ich melde mich nach der langen Sommerpause bei Euch zurück.
Es ist viel passiert in meinen Projekten und möchte Euch den aktuellen Stand nennen und zeigen.
Ich betreibe den AVR ATMEGA328P-AU 8-bit Mikrocontroller TQFP als TQFP im Standalone mit einem 16Mhz Quarz und 2x20pF

Vieles läuft damit schon sehr gut damit.
Ich habe aber noch ein Problem mit der Richtungserkennung der Fahrrichtung der Lokadresse (DIR) mit zwei Projekten und hoffe Ihr könnt mir hier weiterhelfen:
Dazu die Beispiele aus der #include <NmraDcc.h> vers. 2.0.5 mit IDE Portable 1.6.13
1.) Beispiel läuft "NmraDccMultiFunctionMotorDecoder"
2.) Beispiel läuft nur auf dem Arduino-Uno mit AVR ATMEGA328P-AU 8-bit Mikrocontroller TQFP
"Dec_Dir_and_Fade"

Wenn ich mit dem UNO das zweite Projekt auf UNO lade, dann Schalten die Ausgänge Richtungsabhängig.
Wenn ich das zweite Projekt auf meine Standalone Variante Lade, dann Schalten die Ausgänge gar nicht.

Das Beispiel 1 läuft auf beider Hardware (UNO und Standalone).
Damit kann ich Hardwareprobleme ausschließen.

Wisst ihr einen Rat ?
Vielen Dank Viele Grüße
Christian

Beispiel 1:
Code:
// NMRA Dcc Multifunction Motor Decoder Demo
//
// Author: Alex Shepherd 2019-03-30
//
// This example requires these Arduino Libraries:
//
// 1) The NmraDcc Library from: http://mrrwa.org/download/
//
// These libraries can be found and installed via the Arduino IDE Library Manager
//
// This is a simple demo of how to drive and motor speed and direction using PWM and a motor H-Bridge
// It uses vStart and vHigh CV values to customise the PWM values to the motor response
// It also uses the Headling Function to drive 2 LEDs for Directional Headlights
// Apart from that there's nothing fancy like Lighting Effects or a function matrix or Speed Tables - its just the basics...
//

#include <NmraDcc.h>
// Uncomment any of the lines below to enable debug messages for different parts of the code
//#define DEBUG_FUNCTIONS
//#define DEBUG_SPEED
//#define DEBUG_PWM
//#define DEBUG_DCC_ACK
//#define DEBUG_DCC_MSG

#if defined(DEBUG_FUNCTIONS) or defined(DEBUG_SPEED) or defined(DEBUG_PWM) or defined(DEBUG_DCC_ACK) or defined(DEBUG_DCC_MSG)
#define DEBUG_PRINT
#endif

// This is the default DCC Address
#define DEFAULT_DECODER_ADDRESS 24

// This section defines the Arduino UNO Pins to use
#ifdef __AVR_ATmega328P__

#define DCC_PIN     2

#define LED_PIN_FWD 5
#define LED_PIN_REV 6
#define MOTOR_DIR_PIN 4
#define MOTOR_PWM_PIN 3

// This section defines the Arduino ATTiny85 Pins to use
#elif ARDUINO_AVR_ATTINYX5

#define DCC_PIN     2

#define LED_PIN_FWD 0
#define LED_PIN_REV 1
#define MOTOR_DIR_PIN 3
#define MOTOR_PWM_PIN 4

#else
#error "Unsupported CPU, you need to add another configuration section for your CPU"
#endif

// Some global state variables
uint8_t newLedState = 0;
uint8_t lastLedState = 0;

uint8_t newDirection = 0;
uint8_t lastDirection = 0;

uint8_t newSpeed = 0;
uint8_t lastSpeed = 0;
uint8_t numSpeedSteps = SPEED_STEP_128;

uint8_t vStart;
uint8_t vHigh;

// Structure for CV Values Table
struct CVPair
{
  uint16_t  CV;
  uint8_t   Value;
};

// CV Addresses we will be using
#define CV_VSTART  2
#define CV_VHIGH   5

// Default CV Values Table
CVPair FactoryDefaultCVs [] =
{
    // The CV Below defines the Short DCC Address
  {CV_MULTIFUNCTION_PRIMARY_ADDRESS, DEFAULT_DECODER_ADDRESS},

  // Three Step Speed Table
  {CV_VSTART, 120},
  {CV_VHIGH, 255},

  // These two CVs define the Long DCC Address
  {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0},
  {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, DEFAULT_DECODER_ADDRESS},

// ONLY uncomment 1 CV_29_CONFIG line below as approprate
//  {CV_29_CONFIG,                                      0}, // Short Address 14 Speed Steps
  {CV_29_CONFIG,                       CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps
//  {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long  Address 28/128 Speed Steps  
};

NmraDcc  Dcc ;

uint8_t FactoryDefaultCVIndex = 0;

// This call-back function is called when a CV Value changes so we can update CVs we're using
void notifyCVChange( uint16_t CV, uint8_t Value)
{
  switch(CV)
  {
    case CV_VSTART:
      vStart = Value;
      break;
      
    case CV_VHIGH:
      vHigh = Value;
      break;
  }
}

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);
};

// This call-back function is called whenever we receive a DCC Speed packet for our address
void notifyDccSpeed( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Speed, DCC_DIRECTION Dir, DCC_SPEED_STEPS SpeedSteps )
{
  #ifdef DEBUG_SPEED
  Serial.print("notifyDccSpeed: Addr: ");
  Serial.print(Addr,DEC);
  Serial.print( (AddrType == DCC_ADDR_SHORT) ? "-S" : "-L" );
  Serial.print(" Speed: ");
  Serial.print(Speed,DEC);
  Serial.print(" Steps: ");
  Serial.print(SpeedSteps,DEC);
  Serial.print(" Dir: ");
  Serial.println( (Dir == DCC_DIR_FWD) ? "Forward" : "Reverse" );
  #endif

  newDirection = Dir;
  newSpeed = Speed;
  numSpeedSteps = SpeedSteps;
};

// This call-back function is called whenever we receive a DCC Function packet for our address
void notifyDccFunc(uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState)
{
  #ifdef DEBUG_FUNCTIONS
  Serial.print("notifyDccFunc: Addr: ");
  Serial.print(Addr,DEC);
  Serial.print( (AddrType == DCC_ADDR_SHORT) ? 'S' : 'L' );
  Serial.print("  Function Group: ");
  Serial.print(FuncGrp,DEC);
  #endif

  if(FuncGrp == FN_0_4)
  {
    newLedState = (FuncState & FN_BIT_00) ? 1 : 0;
    #ifdef DEBUG_FUNCTIONS
    Serial.print(" FN 0: ");
    Serial.print(newLedState);
    #endif
  }
  #ifdef DEBUG_FUNCTIONS
  Serial.println();
  #endif
}

// This call-back function is called whenever we receive a DCC Packet
#ifdef  DEBUG_DCC_MSG
void notifyDccMsg( DCC_MSG * Msg)
{
  Serial.print("notifyDccMsg: ") ;
  for(uint8_t i = 0; i < Msg->Size; i++)
  {
    Serial.print(Msg->Data[i], HEX);
    Serial.write(' ');
  }
  Serial.println();
}
#endif

// This call-back function is called by the NmraDcc library when a DCC ACK needs to be sent
// Calling this function should cause an increased 60ma current drain on the power supply for 6ms to ACK a CV Read
// So we will just turn the motor on for 8ms and then turn it off again.

void notifyCVAck(void)
{
  #ifdef DEBUG_DCC_ACK
  Serial.println("notifyCVAck") ;
  #endif

  digitalWrite(MOTOR_DIR_PIN, HIGH);
  digitalWrite(MOTOR_PWM_PIN, HIGH);

  delay( 8 );  

  digitalWrite(MOTOR_DIR_PIN, LOW);
  digitalWrite(MOTOR_PWM_PIN, LOW);
}

void setup()
{
  #ifdef DEBUG_PRINT
  Serial.begin(115200);
  Serial.println("NMRA Dcc Multifunction Motor Decoder Demo");
  #endif

  // Setup the Pins for the Fwd/Rev LED for Function 0 Headlight
  pinMode(LED_PIN_FWD, OUTPUT);
  pinMode(LED_PIN_REV, OUTPUT);

  // Setup the Pins for the Motor H-Bridge Driver
  pinMode(MOTOR_DIR_PIN, OUTPUT);
  pinMode(MOTOR_PWM_PIN, OUTPUT);

  
  // Setup which External Interrupt, the Pin it's associated with that we're using and enable the Pull-Up
  Dcc.pin(DCC_PIN, 0);
  
  Dcc.init( MAN_ID_DIY, 10, FLAGS_MY_ADDRESS_ONLY | FLAGS_AUTO_FACTORY_DEFAULT, 0 );

  // Uncomment to force CV Reset to Factory Defaults
//  notifyCVResetFactoryDefault();

  // Read the current CV values for vStart and vHigh
  vStart = Dcc.getCV(CV_VSTART);
  vHigh = Dcc.getCV(CV_VHIGH);
}

void loop()
{
  // You MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation
  Dcc.process();

  // Handle Speed changes
  if(lastSpeed != newSpeed)
  {
    lastSpeed = newSpeed;

    // Stop if speed = 0 or 1
    
    if(newSpeed <= 1)
      digitalWrite(MOTOR_PWM_PIN, LOW);

    // Calculate PWM value in the range 1..255  
    else
    {
      uint8_t vScaleFactor;
      
      if((vHigh > 1) && (vHigh > vStart))
        vScaleFactor = vHigh - vStart;
      else
        vScaleFactor = 255 - vStart;

      uint8_t modSpeed = newSpeed - 1;
      uint8_t modSteps = numSpeedSteps - 1;
      
      uint8_t newPwm = (uint8_t) vStart + modSpeed * vScaleFactor / modSteps;

      #ifdef DEBUG_PWM
      Serial.print("New Speed: vStart: ");
      Serial.print(vStart);
      Serial.print(" vHigh: ");
      Serial.print(vHigh);
      Serial.print(" modSpeed: ");
      Serial.print(modSpeed);
      Serial.print(" vScaleFactor: ");
      Serial.print(vScaleFactor);
      Serial.print(" modSteps: ");
      Serial.print(modSteps);
      Serial.print(" newPwm: ");
      Serial.println(newPwm);
      #endif
            
      analogWrite(MOTOR_PWM_PIN, newPwm);
    }
  }
  
  // Handle Direction and Headlight changes
  if((lastDirection != newDirection) || (lastLedState != newLedState))
  {
    lastDirection = newDirection;
    lastLedState = newLedState;

    digitalWrite(MOTOR_DIR_PIN, newDirection);

    if(newLedState)
    {
      #ifdef DEBUG_FUNCTIONS
      Serial.println("LED On");
      #endif
      digitalWrite(LED_PIN_FWD, newDirection ? LOW : HIGH);
      digitalWrite(LED_PIN_REV, newDirection ? HIGH : LOW);
    }
    else
    {
      #ifdef DEBUG_FUNCTIONS
      Serial.println("LED Off");
      #endif
      digitalWrite(LED_PIN_FWD, LOW);
      digitalWrite(LED_PIN_REV, LOW);
    }
  }

  // Handle resetting CVs back to Factory Defaults
  if( FactoryDefaultCVIndex && Dcc.isSetCVReady())
  {
    FactoryDefaultCVIndex--; // Decrement first as initially it is the size of the array
    Dcc.setCV( FactoryDefaultCVs[FactoryDefaultCVIndex].CV, FactoryDefaultCVs[FactoryDefaultCVIndex].Value);
  }
}


Beispiel 2:
Code:
// LED control is dependent on direction of travel and Fade can be added

// ******** 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 [] = {3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};    //Defines all possible LED pins

//  IMPORTANT:
// The following list defines how each of the 17 function pins operate:
// a 0 allows for normal On/Off control with fade on and fade off
// a 1 allows for normal control when the decoder sees a forward speed setting, reverse turns the LED off
// a 2 allows for normal control when the decoder sees a reverse speed setting, forward turns the LED off
byte led_direction [] = {0,1,2,0,1,1,1,1,2,2,2,1,1,1,2,0,0};        //0=On/Off, 1=On Forward, 2=On Reverse

boolean led_last_state [] = {false,false,false,false,false,false,false,false,false,false,false,false,false,f​alse,false,false,false};  //last state of led
boolean Last_Function_State[] = {false,false,false,false,false,false,false,false,false,false,false,false,false,f​alse,false,false,false};  //These hold the last Fx assignments
uint8_t Decoder_direction = DCC_DIR_FWD;
uint8_t Last_Decoder_direction = 0;
int fade_time = 170;
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;

struct CVPair
{
  uint16_t  CV;
  uint8_t   Value;
};

#define This_Decoder_Address 24

CVPair FactoryDefaultCVs [] =
{
  {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address&0x7F },
  
  // These two CVs define the Long DCC Address
  {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, ((This_Decoder_Address>>8)&0x7F)+192 },
  {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address&0xFF },
  
  // ONLY uncomment 1 CV_29_CONFIG line below as approprate DEFAULT IS SHORT ADDRESS
//  {CV_29_CONFIG,          0},                                           // Short Address 14 Speed Steps
  {CV_29_CONFIG, CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps
//  {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION},   // Long  Address 28/128 Speed Steps  

  {CV_DECODER_MASTER_RESET, 0},
};
uint8_t FactoryDefaultCVIndex = 0;
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()
{
   //Serial.begin(115200);
   // initialize the digital pins as an outputs
    for (int i=0; i< numleds; i++) {
      pinMode(ledpins[i], OUTPUT);
      digitalWrite(ledpins[i], LOW);
     }
  for (int i=0; i< numleds; i++) {
     digitalWrite(ledpins[i], HIGH);
     delay (tim_delay/10);
  }
  delay( tim_delay);
  for (int i=0; i< numleds; i++) {
     digitalWrite(ledpins[i], LOW);
     delay (tim_delay/10);
  }
  delay( tim_delay);
  #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(ledpins[14], 1);
         delay (1000);
         digitalWrite(ledpins[14], 0);
     }  
  // 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, 601, FLAGS_MY_ADDRESS_ONLY, 0 );
}
void loop()
{
  // You MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation
  Dcc.process();
}
void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState)  {
int f_index;
switch (FuncGrp)  {
  case FN_0_4:    //Function Group 1 F0 F4 F3 F2 F1
    exec_function( 0, (FuncState & FN_BIT_00)>>4 );
    exec_function( 1, (FuncState & FN_BIT_01));
    exec_function( 2, (FuncState & FN_BIT_02)>>1);
    exec_function( 3, (FuncState & FN_BIT_03)>>2 );
    exec_function( 4, (FuncState & FN_BIT_04)>>3 );
    break;
    
  case FN_5_8:    //Function Group 1 S FFFF == 1 F8 F7 F6 F5  &  == 0  F12 F11 F10 F9 F8
    exec_function( 5, (FuncState & FN_BIT_05));
    exec_function( 6, (FuncState & FN_BIT_06)>>1 );
    exec_function( 7, (FuncState & FN_BIT_07)>>2 );
    exec_function( 8, (FuncState & FN_BIT_08)>>3 );
    break;
    
  case FN_9_12:
    exec_function( 9, (FuncState & FN_BIT_09));
    exec_function( 10,(FuncState & FN_BIT_10)>>1 );
    exec_function( 11,(FuncState & FN_BIT_11)>>2 );
    exec_function( 12,(FuncState & FN_BIT_12)>>3 );
    break;

  case FN_13_20:   //Function Group 2 FuncState == F20-F13 Function Control
      exec_function( 13, (FuncState & FN_BIT_13));
      exec_function( 14, (FuncState & FN_BIT_14)>>1 );
      exec_function( 15, (FuncState & FN_BIT_15)>>2 );
      exec_function( 16, (FuncState & FN_BIT_16)>>3 );
      break;

  }
}
void exec_function (int f_index, int FuncState)  {
       if ((FuncState==1) && (!Last_Function_State[f_index])) {
            Last_Function_State[f_index] = true;
            Set_LED (f_index,true);
          }
          else if ((FuncState==0) && Last_Function_State[f_index]) {
            Last_Function_State[f_index] = false;
            Set_LED (f_index,false);
          }
}
void notifyDccSpeed( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Speed, DCC_DIRECTION ForwardDir, DCC_SPEED_STEPS SpeedSteps )  {
  Last_Decoder_direction = Decoder_direction;
  Decoder_direction = ForwardDir;
  if ( Decoder_direction==Last_Decoder_direction) return;
  for (int i=0; i<numleds; i++) {
    if (Decoder_direction!=0 && led_direction[i]==1 && Last_Function_State[i] && led_last_state[i]==false ) Switch_LED (i);
    if (Decoder_direction!=0 && led_direction[i]==2 && Last_Function_State[i] && led_last_state[i]==true ) Switch_LED (i);
    if (Decoder_direction==0 && led_direction[i]==2 && Last_Function_State[i] && led_last_state[i]==false ) Switch_LED (i);
    if (Decoder_direction==0 && led_direction[i]==1 && Last_Function_State[i] && led_last_state[i]==true ) Switch_LED (i);    
  }
}
void Set_LED (int Function, boolean led_state) {
boolean start_state = !led_state;
boolean end_state = led_state;
    switch (led_direction[Function]) {
      case 0:                                      //0=On/Off
      if (led_last_state[Function] == led_state) return;
      Switch_LED (Function);
      break;
      case 1:                                     //1=On Forward
      if (Decoder_direction!=0) {
          if (led_last_state[Function] == led_state) return;
      Switch_LED (Function);
      }
      break;
      case 2:                                     //2=On Reverse
      if (Decoder_direction==0)  {
      if (led_last_state[Function] == led_state) return;
      Switch_LED (Function);
      }
      break;
      default:
      break;
    }
}

void Switch_LED (int Function) {
  float time_fraction;
  int del_temp;
  boolean start_state = led_last_state[Function];
  boolean end_state = !led_last_state[Function];
  for (int loop_time=0; loop_time<fade_time; loop_time++)  {
        time_fraction = (float (loop_time))/(float (fade_time));
        digitalWrite (ledpins[Function], start_state);
        del_temp = 1000 - (1000.*time_fraction);
        if (del_temp<0) del_temp=0;
        delayMicroseconds (del_temp);
        digitalWrite (ledpins[Function], end_state);
        delayMicroseconds (1000.*time_fraction);
        }
  led_last_state[Function] = end_state;
}


Angehängte Datei(en) Thumbnail(s)
       
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  Wert von einem Arduino zu einem zweiten Arduino senden Thorsten_S 9 3.312 14.10.2019 14:48
Letzter Beitrag: Thorsten_S
  Firmata (Daten senden an den Arduino und empfangen vom Arduino) comfan 6 6.073 29.04.2017 14:29
Letzter Beitrag: hotsystems
  Arduino Ethernet mit USB 2 Serial Converter/Welche Einstellungen im Arduino-Sketch lociluke 1 4.986 05.05.2015 13:40
Letzter Beitrag: Bitklopfer
  Arduino Mega-Projekt mit EEPROM auf Arduino Due portieren Foto-Ralf 17 13.383 16.03.2015 12:06
Letzter Beitrag: Foto-Ralf

Gehe zu:


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