Arduino MobaTools: V2.3.1 released

Bereich für alle Themen rund um die Modellbahn-Elektronik und elektr. Umbauten für Analogbetrieb.
Benutzeravatar

digi_thomas2003
InterRegioExpress (IRE)
Beiträge: 299
Registriert: Di 3. Mai 2005, 21:25
Nenngröße: H0
Stromart: AC
Steuerung: TrainController
Gleise: meine Gleisen
Wohnort: Östlicher Enzkreis (irgendwo zwischen TPH und TS)

Re: Arduino: MobaTools - Update V0.6

#51

Beitrag von digi_thomas2003 »

Hallo Uwe,
UweS hat geschrieben:...
Warum der Kondensator und die beiden Widerstände?

Laut Thomas, funktioniert es auch ohne?
Die Antwort auf Deine erste Frage kam ja schon von den Fachleuten :D

Zur zweiten Frage: Ja, mein Prototyp funktioniert einwandfrei. Ich habe mich dabei an den Schaltplan von Rudys Seite gehalten: Dazu habe ich einen Arduino Uno mit einem Prototype Shield versehen, siehe hier:
Bild

Das dicke braune und rote Kabel kommen von der Digitalzentrale. An D2 hängt der Ausgang des Optokopplers (blaues Kabel).

Ich habe einen Servo an D3 und eine rote LED mit Vorwiderstand an D5 angeschlossen, den Sketch so angepasst, dass ich den Servo mit der Digitaladresse 6 und die LED mit der Digitaladresse 3 ein- und ausschalten kann.
Als Digitalzentrale verwende ich eine Tams EasyControl mit Tams Booster B-3.

Nun geht es daran, den Sketch für die BÜ-Steuerung mit Schrittmotoren (aus dem anderen Thread) von Franz-Peter an zwei Servomotoren anzupassen.

Mal sehen, ob mir das dieses WE gelingt...

Herzliche Grüße
Thomas
Thomas Arlitt
------------------
Anlage H0: U-Form, im kreativen Bau
Fahren: Tams MC
Schalten: IB
Melden: HSI 88
Steuern: TrainController 9.0 Gold
Denken: Brain 4.1
Benutzeravatar

Bodo
InterCityExpress (ICE)
Beiträge: 2368
Registriert: Do 28. Apr 2005, 08:59
Nenngröße: H0
Stromart: digital
Steuerung: IB1 & CS2
Gleise: C-Gleis
Kontaktdaten:
Deutschland

Re: Arduino: MobaTools - Update V0.6

#52

Beitrag von Bodo »

Hallo zusammenn
Bodo hat geschrieben:Mit einem Arduino Nano geht´s aber auf jeden Fall, da der ebenfalls den ATmega328 als Prozessor hat. Der ist auch sehr günstig zu bekommen und platzsparend. Allerdings muss man ihm einen "Sockel" verschaffen oder ihn auf ein Steckbrett setzen.
ich weiß nicht, ob es hier passend ist, aber ich will dafür (noch) keinen Extra-Beitrag aufmachen:
Bild

Das Test-Muster ist beauftragt - bei Interesse mache ich auch gerne eine Sammelbestellung (für die Platinen und die ggf. auch die Bauteile). In dem Fall bitte per PN ... nicht dass der Thread hier kaputt geht. Ich werde ggf. einen neuen starten, wenn´s vorzeigbar ist und funktioniert ... ;-).

Die Idee war, den Optokoppler zwischen den Beinen des Nano unterzubringen. Außerdem Stiftleisten oder Servo-Anschlusskabel. Stiftleisten müssten dann von der Rückseite eingelötet werden - sonst werden die Anschlüsse zu hoch.

D10, D11 und D13 können als SPI-Bus direkt mit den Schieberegister-Platinen zusammengesteckt werden, die ich mit einem Kollegen zusammen im letzten Jahr eigentlich für die ATtiny entworfen hatte:
Bild

Neben der Ansteuerung über "shiftout" können sie auch mit den MoBaTools zur Ansteuerung für bis zu vier kleinen Schrittmotoren (zwei pro Schieberegister) genutzt werden. Auf dem Video (siehe Seite 2 dieses Threads) ist die Schieberegister-Platine zusammen mit zwei Schrittmotoren an einem "Breadboard-Arduino" zu sehen.

Um alle Arduino-Ports zu nutzen, wird man weitere Kabel an der Sockelplatine anlöten müssen. Mir ging es darum, eine möglichst kleine Lösung für die "Standard-Anwendungen" (z.B. Servo-Dekoder) zu finden. Da Fritzing den Preis nach Quadratzentimetern berechnet (das sind jetzt schon etwa 6,50 Euro - aber dafür bekommt man eine doppelseitige durchkontaktierte Platine mit Lötstopp-Lack und Beschriftung ...), sind weitere Anschlüsse oder Bauteile außerhalb des Nano-Rahmens preislich nicht sinnvoll integrierbar - wenn Platz und Zeit keine Rolle spielen, nimmt man da besser eine Lochraster-Platine. Für eigene (Weiter-)Entwicklungen stelle ich aber auch die Fritzing-Datei gerne zur Verfügung, wenn das ganze fertig ist.

Meine Muster sollen Ende November kommen, d.h. Anfang Dezember weiß ich den genauen Preis und dann werde ich auch die bestückten Muster hier im Forum vorstellen.

Viele Grüße, Bodo
Zuletzt geändert von Bodo am Mo 16. Nov 2015, 07:44, insgesamt 2-mal geändert.
Die Freiheit des Menschen liegt nicht darin, dass er tun kann, was er will, sondern dass er nicht tun muss, was er nicht will. (Jean-Jacques Rousseau)

Meine Anlage - Meine Dauerbaustelle
Platinen für Modellbahn- und Arduino-Anwendungen
Benutzeravatar

digi_thomas2003
InterRegioExpress (IRE)
Beiträge: 299
Registriert: Di 3. Mai 2005, 21:25
Nenngröße: H0
Stromart: AC
Steuerung: TrainController
Gleise: meine Gleisen
Wohnort: Östlicher Enzkreis (irgendwo zwischen TPH und TS)

Re: Arduino: MobaTools - Update V0.6

#53

Beitrag von digi_thomas2003 »

Guten Morgen Bodo,

wie schon per PM geschrieben: Ein vielversprechender Ansatz! :D

Eine Verständnisfrage habe ich dazu: Der Nano wird doch auf Deine Platine aufgesteckt. Wie werden dann die Anschlüsse neben dem 6N137 genutzt? Hast Du da Pfostensrecker vorgesehen? Oder über die Unterseite?

Herzliche Grüße
Thomas
Thomas Arlitt
------------------
Anlage H0: U-Form, im kreativen Bau
Fahren: Tams MC
Schalten: IB
Melden: HSI 88
Steuern: TrainController 9.0 Gold
Denken: Brain 4.1
Benutzeravatar

UweS
InterRegioExpress (IRE)
Beiträge: 339
Registriert: Do 2. Feb 2012, 11:44
Nenngröße: 1
Stromart: DC
Steuerung: TC Gold
Wohnort: Saxonia
Alter: 65

Re: Arduino: MobaTools - Update V0.6

#54

Beitrag von UweS »

digi_thomas2003 hat geschrieben: Eine Verständnisfrage habe ich dazu: Der Nano wird doch auf Deine Platine aufgesteckt. Wie werden dann die Anschlüsse neben dem 6N137 genutzt? Hast Du da Pfostensrecker vorgesehen? Oder über die Unterseite?
Hallo Thomas,
also ich würde mal spontan sagen, auf Unterseite.

Hallo Bodo,

super Arbeit, habe auch in "Hinterduxheim" :D für 2,85€, Nano´s bestellt.
Wann die auch bei mir eintreffen :?:

Ich würde auch 2 Platinen bestellen. PN sende ich Dir.
Die sind doch unbestückt, oder?
Uwe

Lenz Digital seit 1993, seit 2020 Roco z21 und steuern mit der Z21 App, Traincontroller Gold, Mikromodellbau,
Benutzeravatar

Threadersteller
MicroBahner
Metropolitan (MET)
Beiträge: 2566
Registriert: Mi 28. Nov 2012, 14:24
Nenngröße: H0
Stromart: analog DC
Steuerung: Microprozessor-Eigenbau
Gleise: Tillig
Wohnort: Mittelfranken
Alter: 70

Re: Arduino: MobaTools - Update V0.6

#55

Beitrag von MicroBahner »

Hallo,
schöne Arbeit von Bodo - warum soll das hier nicht hinpassen, ist doch genau auf die MobaTools abgestimmt :wink:
Ich würde allerdings als Diode keine 1N4001 verwenden, die ist etwas überdimensioniert ( ok, wenn man sie gerade rumliegen hat... :roll: ). Eine 1N4148 Universaldiode tuts da genauso und für das kompakte Design ist deren deutlich kleineres Gehäuse optimal.
Ich gehe auch mal davon aus, dass die Anschlußpins auf die Rückseite (aus Sicht des Nano) gehören.
Benutzeravatar

Bodo
InterCityExpress (ICE)
Beiträge: 2368
Registriert: Do 28. Apr 2005, 08:59
Nenngröße: H0
Stromart: digital
Steuerung: IB1 & CS2
Gleise: C-Gleis
Kontaktdaten:
Deutschland

Re: Arduino: MobaTools - Update V0.6

#56

Beitrag von Bodo »

Hallo zusammen,

da es erfreulicherweise tatsächlich schon einige Rückmeldungen gab, habe ich meinen obigen Beitrag noch um ein paar Informationen ergänzt. Die 1N4148 hat sich bei mir beim Testaufbau deutlich erwärmt - vielleicht darf das so sein, aber ich habe sie deswegen durch die 1N4001 ersetzt.

Viele Grüße, Bodo
Die Freiheit des Menschen liegt nicht darin, dass er tun kann, was er will, sondern dass er nicht tun muss, was er nicht will. (Jean-Jacques Rousseau)

Meine Anlage - Meine Dauerbaustelle
Platinen für Modellbahn- und Arduino-Anwendungen
Benutzeravatar

Threadersteller
MicroBahner
Metropolitan (MET)
Beiträge: 2566
Registriert: Mi 28. Nov 2012, 14:24
Nenngröße: H0
Stromart: analog DC
Steuerung: Microprozessor-Eigenbau
Gleise: Tillig
Wohnort: Mittelfranken
Alter: 70

Re: Arduino: MobaTools - Update V0.6

#57

Beitrag von MicroBahner »

Hallo Bodo,
bist Du sicher, dass bei deinem Testaufbau alles in Ordnung war? Die 1N4148 ist für einen Maximalstrom von 200mA definiert. Mit dem 1K Vorwiderstand fliessen bei 20V 'Digitalspannung' maximal 20mA durch die Diode - und das auch nur während der Hälfte der Zeit. Effektiv also nur 10mA. Dss ist weit entfernt vom Maximalstrom - da sollte sie sich nicht deutlich erwärmen. Schon gar nicht, wenn sie mit gekürzten Beinchen in einer Platine eingelötet ist.
Mape71
Ehemaliger Benutzer

Re: Arduino: MobaTools - Update V0.6

#58

Beitrag von Mape71 »

Hallo Bodo, gibt es zu den von Dir erwähnten Schieberegister-Platinen einen eigenen Thread? Dort wäre ich auch an weiteren Informationen interessiert, könnte ich ggf. auch gut verwenden.
Danke und viele Grüße

Marko
Benutzeravatar

Bodo
InterCityExpress (ICE)
Beiträge: 2368
Registriert: Do 28. Apr 2005, 08:59
Nenngröße: H0
Stromart: digital
Steuerung: IB1 & CS2
Gleise: C-Gleis
Kontaktdaten:
Deutschland

Re: Arduino: MobaTools - Update V0.6

#59

Beitrag von Bodo »

Hallo Marco,

beim "Belebten Haus" hatte ich mal was eingestreut, und ein paar Infos unter http://moba.noethlich.info/?page_id=297 ;-).

Dort sind die Platinen bisher nur kurz zusammen mit dem ATtiny vorgestellt. Wenn die Nano-Platine da ist, werde ich das entsprechend erweitern (und hier im Forum die Vorstellung natürlich auch mit der Erweiterung). Von den Schieberegister-Platinen gibt es auch noch Restbestände - und neue könnte man auch machen lassen.

Viele Grüße, Bodo
Die Freiheit des Menschen liegt nicht darin, dass er tun kann, was er will, sondern dass er nicht tun muss, was er nicht will. (Jean-Jacques Rousseau)

Meine Anlage - Meine Dauerbaustelle
Platinen für Modellbahn- und Arduino-Anwendungen
Benutzeravatar

UweS
InterRegioExpress (IRE)
Beiträge: 339
Registriert: Do 2. Feb 2012, 11:44
Nenngröße: 1
Stromart: DC
Steuerung: TC Gold
Wohnort: Saxonia
Alter: 65

Re: Arduino: MobaTools - Update V0.6

#60

Beitrag von UweS »

Hallo,

hat etwas gedauert aber der DCC Decoder läuft jetzt auch bei mir recht ordentlich.

Der Servo Sketch von Franz- Peter funktioniert über Weichenadressen, aber ich wollte ja auch einen Arduino DCC Funktionsdecoder
und da habe ich den Sketch von Ruud Boer, welcher über eine Lokadresse und F- Tasten angesteuert wird etwas modifiziert.

Nun musste ich aber feststellen, dass LOW & HIGH perfekt klappt.
Aber wenn ich an verschiedenen Pin unterschiedliche Funktionen ausführen möchte, beeinflussen diese sich und ich habe keine Ahnung warum?

Woran mag das liegen?

Code: Alles auswählen

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//DCC Funktionsdecoder
// Autor: Ruud Boer - Oktober 2015
// Diese Skizze stellt sich ein Arduino in einen DCC-Funktionsdecoder für F0 - F12
// Output Pins verwendet: 3-19 (14-19 = A0-A5). Pin ist niedrig, wenn Funktion aktiviert ist.
// Die DCC-Signal eingespeist wird an Pin 2 (= Interrupt 0).
// Optokoppler Schaltpläne für die Umwandlung von DCC - 5V: www.rudysmodelrailway.wordpress.com/software
// Vielen Dank an www.mynabay.com für die Veröffentlichung ihrer DCC-Monitor und -Decoder Code.


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// IMPORTANT: GOTO lines 15 - 28 to configure some data!    WICHTIG: GOTO Linien 15-28 einige Daten zu konfigurieren!
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


int decoderAddress = 1830;         // Dies ist die Decoderadresse, Wechsel in der gewünschten Nummer.
#define F0_pin 14       // Die Ausgangspin für jeden Funktionsnummer in Gebrauch definieren
#define F0_pin2 15         // 2. Pin für dieselbe Funktion ist möglich. Können sich verwenden / Rückwärtsrichtung ... siehe Zeile 97.
#define F1_pin 13       // Verfügbar Pin-Nummern: 3-19 (14-19 = A0-A5)
#define F2_pin 0
#define F3_pin 0
#define F4_pin 0
#define F5_pin 0
#define F6_pin 0
#define F7_pin 0
#define F8_pin 7
#define F9_pin 0
#define F10_pin 0
#define F11_pin 0
#define F12_pin 0
/* F13-F28 commented out auskommentiert
#define F13_pin 0
#define F14_pin 0
#define F15_pin 0
#define F16_pin 0
#define F17_pin 0
#define F18_pin 0
#define F19_pin 0
#define F20_pin 0
#define F21_pin 0
#define F22_pin 0
#define F23_pin 0
#define F24_pin 0
*/

#include <DCC_Decoder.h>
#define kDCC_INTERRUPT 0

byte Func[4]; // 0=L F4-F1, 1=F9-F5, 2=F12-F9, 3=F20-F13, 4=F28-F21
byte instrByte1;
int Address;
byte forw_rev=1; //0=rücklauf, 1=vorwärts,  ändert das aus und einschalten der F-Tasten

boolean RawPacket_Handler(byte pktByteCount, byte* dccPacket) {
  Address=0;
  if (!bitRead(dccPacket[0],7)) { //bit7=0 -> Loc Decoder Short Address kurze Adresse
    Address = dccPacket[0];
    instrByte1 = dccPacket[1];
  }
  else if (bitRead(dccPacket[0],6)) { //bit7=1 AND bit6=1 -> Loc Decoder Long Address lange Adresse
    Address = 256 * (dccPacket[0] & B00000111) + dccPacket[1];
    instrByte1 = dccPacket[2];
  }

  if (Address==decoderAddress) {
    byte instructionType = instrByte1>>5;
    switch (instructionType) {
      case 2: // Reverse speed
        forw_rev=0;
        break;
      case 3: // Forward speed
        forw_rev=1;
        break;
      case 4: // Loc Function L-4-3-2-1
        Func[0]=instrByte1&B00011111;
        break;
      case 5: // Loc Function 8-7-6-5
        if (bitRead(instrByte1,4)) {
          Func[1]=instrByte1&B00001111;
        }
        else { // Loc Function 12-11-10-9
          Func[2]=instrByte1&B00001111;
        }
        break;
      /* F13-F28 commented out 
      case 6: // Future Expansions
        switch (instrByte1&B00011111) {
          case B00011110: // Loc Function F13-F20
            Func[3]=dccPacket[pktByteCount-1];
          break;
          case B00011111: // Loc Function F21-F28
            Func[4]=dccPacket[pktByteCount-1];
          break;
        }
      break;
      */
    }
    // F0 is an example of two output pins that alternate based on loc forw_rev driving direction.  F0 ist ein Beispiel von zwei Ausgangsanschlüssen, die auf loc forw_rev Fahrrichtung basierend abwechseln.
    if (Func[0]&B00010000) {digitalWrite(F0_pin,forw_rev); digitalWrite(F0_pin2,!forw_rev);} else digitalWrite(F0_pin,HIGH);
    
    if (Func[0]&B00000001) {digitalWrite(F1_pin,HIGH);delay(100);digitalWrite(F1_pin,LOW);}          else digitalWrite(F1_pin,LOW); //F-Taste schaltet ein und blinkt
    
    if (Func[0]&B00000010) {digitalWrite(F2_pin,HIGH);delay(300);digitalWrite(F2_pin,LOW);}            else digitalWrite(F2_pin,LOW);
    
    if (Func[0]&B00000100) digitalWrite(F3_pin,LOW); else digitalWrite(F3_pin,HIGH);//F-Taste schaltet aus
    if (Func[0]&B00001000) digitalWrite(F4_pin,LOW); else digitalWrite(F4_pin,HIGH);
    if (Func[1]&B00000001) digitalWrite(F5_pin,LOW); else digitalWrite(F5_pin,HIGH);
    if (Func[1]&B00000010) digitalWrite(F6_pin,LOW); else digitalWrite(F6_pin,HIGH);
    if (Func[1]&B00000100) digitalWrite(F7_pin,LOW); else digitalWrite(F7_pin,HIGH);
    
    if (Func[1]&B00001000) {digitalWrite(F8_pin,HIGH);delay(400);digitalWrite(F8_pin,LOW);}                  else digitalWrite(F8_pin,LOW);
    
    if (Func[2]&B00000001) digitalWrite(F9_pin,LOW); else digitalWrite(F9_pin,HIGH);
    if (Func[2]&B00000010) digitalWrite(F10_pin,LOW); else digitalWrite(F10_pin,HIGH);
    if (Func[2]&B00000100) digitalWrite(F11_pin,LOW); else digitalWrite(F11_pin,HIGH);
    if (Func[2]&B00001000) digitalWrite(F12_pin,LOW); else digitalWrite(F12_pin,HIGH);

    /*//Print DCC packet bytes for testing purposes
    for (byte n=0; n<5; n++) {
      Serial.print(Func[n],BIN);
      Serial.print(" ");
    }
    Serial.println(" ");
    */
  }
}

void setup() {
  DCC.SetRawPacketHandler(RawPacket_Handler);
  DCC.SetupMonitor( kDCC_INTERRUPT );
  for (byte n=3; n<20; n++) pinMode(n,OUTPUT);
}

void loop() {
  DCC.loop();
}

Uwe

Lenz Digital seit 1993, seit 2020 Roco z21 und steuern mit der Z21 App, Traincontroller Gold, Mikromodellbau,
Benutzeravatar

garti62
InterCity (IC)
Beiträge: 602
Registriert: Di 8. Nov 2011, 20:59
Nenngröße: H0
Stromart: digital
Steuerung: MS2
Gleise: Selbstbau
Wohnort: Harz
Alter: 58

Re: Arduino: MobaTools - Update V0.6

#61

Beitrag von garti62 »

Hallo Franz-Peter,

eigentlich habe ich meine bisherigen kleinen AVR-Projekte immer in BASIC realisiert, das war für mich relativ einfach und die auf 4Kbyte Flash begrenzte Demoversion des Compilers ausreichend. Mit C bzw. C++ hab ich mich eigentlich nie befasst. Angeregt durch Deinen Thread hier habe ich mir jetzt aber auch mal einige Nano-Klone für einen Spottpreis aus China bestellt. Dank Deiner eigentlich schon "idiotensicheren" Dokumentation und der vorhandenen Beispiele in diesem Thread habe ich jetzt nach nur einigen Stunden probieren einen maßgeschneiderten DCC-Decoder für meine DKW ( 2 Servos , 4 LED`s Weichenlaterne), der mit meiner MS2 perfekt funktioniert. Ich bin begeistert. Und so schlimm ist C gar nicht, wenn man erstmal ein wenig reingeschnuppert und sich an die Syntax gewöhnt hat. Und wenn ich mir den belegten Flash-Speicher ansehe, das hätte ich mit der Demoversion des Basic-Compilers so nicht hinbekommen.
An dieser Stelle vielen Dank von mir für Deine Arbeit hier. Mit Deinen MobaTools und der DCC-Lib kann man sich so ziemlich für jede Aufgabe auf der MoBa was zusammenbauen, auch ohne große Vorkenntnisse. Hoffentlich bleibt dieser Thread noch lange am Leben, wäre schade, wenn er in den Tiefen des Forums verschwindet.
( Vielleicht sollte er auch in die "Grundlagen" o.ä. verschoben werden? )

Schöne Grüße

Ulli
erste Versuche: Weichenbau
Benutzeravatar

Threadersteller
MicroBahner
Metropolitan (MET)
Beiträge: 2566
Registriert: Mi 28. Nov 2012, 14:24
Nenngröße: H0
Stromart: analog DC
Steuerung: Microprozessor-Eigenbau
Gleise: Tillig
Wohnort: Mittelfranken
Alter: 70

Re: Arduino: MobaTools - Update V0.6

#62

Beitrag von MicroBahner »

Hallo Ulli,
dein Posting geht natürlich runter wie Öl und motiviert weiterzumachen :D 8) . So war der Thread gedacht - dass man damit auch was anfangen kann.
garti62 hat geschrieben: Hoffentlich bleibt dieser Thread noch lange am Leben, wäre schade, wenn er in den Tiefen des Forums verschwindet.
Solange die MoBa-Lib genutzt wird, und sich die Nutzer auch ab und zu hier melden sollte er am Leben bleiben. Ich werde auch schauen dass es immer mal wieder ein neues Demo-Beispiel oder sogar ein Update gibt.
garti62 hat geschrieben:( Vielleicht sollte er auch in die "Grundlagen" o.ä. verschoben werden? )
Mmmh - ob der Thread dazu taugt :?: :?: - das müssen Andere entscheiden :roll:

Hallo Uwe,
der Sketch von Ruud Boer verwendet zur DCC-Decodierung die Mynabay-Library. Als ich zum erstem Mal meine MoBaTools mit DCC zusammen verwenden wollte, habe ich mir die u.a. auch mal angeschaut. Ich bin für mich aber zu dem Ergebnis gekommen, dass die NmraDCC Library für den Zweck besser und komfortabler ist. Deshalb habe ich mich mit der MynaBay-Lib dann auch nicht tiefer beschäftigt - vielleicht kann jemand anders etwas dazu sagen.

So schwer ist es aber auch nicht, meinen Weichendecoder-Sketch auf einen Mutifunktionsdecoder umzustellen. Bei der letzten Version des Bü wird der Bü ja auch schon als Multifunktionsdecoder angesprochen.

Ich werde demnächst mal den Weichendecodersketch als Multifunktionsdecodersketch umbauen. Dann gibt es hier auch wieder ein neues Demo-Beispiel für die MoBa-Tools - damit der Thread weiterlebt :wink:
Kann aber noch ein paar Tage dauern.
Benutzeravatar

UweS
InterRegioExpress (IRE)
Beiträge: 339
Registriert: Do 2. Feb 2012, 11:44
Nenngröße: 1
Stromart: DC
Steuerung: TC Gold
Wohnort: Saxonia
Alter: 65

Re: Arduino: MobaTools - Update V0.6

#63

Beitrag von UweS »

MicroBahner hat geschrieben: Hallo Uwe,
der Sketch von Ruud Boer verwendet zur DCC-Decodierung die Mynabay-Library.
Hallo Franz-Peter,

da ich hier noch schwer am lernen bin, fehlt mir einfach der Durchblick.

Der Sketch von RB erschien mir ideal, da es möglich ist, eine einfache Lokadresse einzurichten und dann mit den
F- Tasten die unterschiedlichen Funktionen Ein.- und Auszuschalten.

Nun habe ich versucht, hinter den Eingerichteten F- Tasten ( siehe den von mir eingestellten Sketch) in die geschweiften Klammern,
verschiedenen loop´s ablaufen zu lassen.
ZB eine blinkende LED, mit der F2 gestartet und gestoppt, geht gut.

Aber jetzt, wenn ich eine Blinkfrequenz auf eine weitere F- Taste einrichte und die Blinkfrequenz an dieser Taste eine Andere ist, dann
beeinflussen sich beide und beide blinken die langsamere Frequenz und ich weiß nicht warum?
Uwe

Lenz Digital seit 1993, seit 2020 Roco z21 und steuern mit der Z21 App, Traincontroller Gold, Mikromodellbau,
Benutzeravatar

Threadersteller
MicroBahner
Metropolitan (MET)
Beiträge: 2566
Registriert: Mi 28. Nov 2012, 14:24
Nenngröße: H0
Stromart: analog DC
Steuerung: Microprozessor-Eigenbau
Gleise: Tillig
Wohnort: Mittelfranken
Alter: 70

Re: Arduino: MobaTools - Eine Library für die MoBa

#64

Beitrag von MicroBahner »

Hallo Uwe,
in so einer Anwendung sind delay() Befehle tabu. Während des delay-Befehls ist der Prozessor blockiert und führt deinen Sketch nicht mehr aus. Er erkennt auch keine Telegramme mehr, die in dieser Zeit empfangen werden. Bei einer Led geht's evtl. noch, aber bei zweien versagt das delay-Konzept endgültig.
Wenn ich die Demo für einen Funktionsdecoder schreibe, werde ich mal sehen, dass ich deine Anforderung mit einbaue, dass eine Led beim aktivieren der Funktion nur blinkt, und nicht dauerhaft leuchtet. Da kannst Du dir dann mal anschauen, wie man sowas machen kann.
Benutzeravatar

UweS
InterRegioExpress (IRE)
Beiträge: 339
Registriert: Do 2. Feb 2012, 11:44
Nenngröße: 1
Stromart: DC
Steuerung: TC Gold
Wohnort: Saxonia
Alter: 65

Re: Arduino: MobaTools - Eine Library für die MoBa

#65

Beitrag von UweS »

Hallo Franz-Peter,

da bin ich sehr gespannt drauf.
Wenn es Dir nicht zu viel Mühe macht, wäre es nett wenn Du recht viel Erklärung in den Sketch reinschreiben könntest.
Ich muss noch viel dazulernen.
Schon mal vielen Dank dafür.
Uwe

Lenz Digital seit 1993, seit 2020 Roco z21 und steuern mit der Z21 App, Traincontroller Gold, Mikromodellbau,
Benutzeravatar

garti62
InterCity (IC)
Beiträge: 602
Registriert: Di 8. Nov 2011, 20:59
Nenngröße: H0
Stromart: digital
Steuerung: MS2
Gleise: Selbstbau
Wohnort: Harz
Alter: 58

Re: Arduino: MobaTools - Eine Library für die MoBa

#66

Beitrag von garti62 »

Hallo Franz-Peter,

ich bin mal so frei und hoffe, Du hast nichts dagegen, wenn ich mein Erstlingswerk in Sachen C++ hier mit einstelle. Aber letztendlich stammt es ja im wesentlichen aus Deiner Feder. Ist ein einfacher Weichendekoder für eine DKW. Es werden 2 Servos, 2 Relais für die Herzstückpolarisation und 4 LED-Paare für die Weichenlaterne angesteuert. Das DCC-Signal stammt von einer MS2. Eine Justierung der Endlagen habe ich nicht vorgesehen, da der Nano sowohl einen USB- als auch einen ISP-Anschluß hat und man die Einstellung eigentlich nur einmal vornehmen muß. Nur einen Taster habe ich vorgesehen, der die Servos für die Montage in Mittelstellung fährt. Beim Einschalten werden die beiden Servos und entsprechend die LED und Relais auf "abzweigend" gestellt, das entspricht bei meiner MS2 der Zubehörstellung "rot".

Code: Alles auswählen

// einfacher Dcc-Servodecoder für eine DKW 
// basierend auf den"MobaTools" und einem Demo-sketch vom Stummi "MicroBahner"
// http://www.stummiforum.de/viewtopic.php?f=21&t=127899
//------------------------------------------ //
// die NmraDcc - Library gibt es unter https://github.com/mrrwa/NmraDcc/archive/master.zip

#include <NmraDcc.h>
#include <MobaTools.h>


// anzupassende Konstante:
const byte weichenAdr[] =   {  1, 2};      // DCC-Weichenadressen 
const byte servoPins[]  =   {  3, 4};      // output-pins der Servos
const byte relaisPins[] =   {  5, 6};      // output-pins der Relais
const int geradeWinkel[] =   {60,60};      // Winkel geradeaus
const int abzweigWinkel[] =  {120,120};    // Winkel abzweigend
const int mitteWinkel[] =  {90,90};        // Winkel mittte
const int geradeLedPin[] =  { 8, 10};      // output-pins der DKW-Laterne geradeaus
const int abzweigLedPin[] =  { 7, 9};      // output-pins der DKW-Laterne abzweigend
const int tasterPin = 12;                  // Taster-pin für Mittelstellung
const int speed = 15;
const byte autoOff = 1;
const byte ServoZahl = sizeof(weichenAdr);
int richtung[ServoZahl];
int geradeLedWinkel[ServoZahl];
int abzweigLedWinkel[ServoZahl]; 
Servo8 weicheDkw[ServoZahl];
NmraDcc Dcc;
///////////////////////////////////////////////////////////////
void setup() {
    Dcc.init( MAN_ID_DIY, 15, FLAGS_OUTPUT_ADDRESS_MODE | FLAGS_DCC_ACCESSORY_DECODER, 0 );
    Dcc.pin(0, 2, 1);                                      // Dcc-Signal an Pin2 
    pinMode(tasterPin, INPUT_PULLUP);                      // Taster auf Platine für        
                                                           // Mittelstellung
    for ( byte i=0; i<ServoZahl; i++ ) {                
        weicheDkw[i].attach( servoPins[i], autoOff );      // Weichenservos initiieren
        weicheDkw[i].setSpeed( speed );
        pinMode(geradeLedPin[i],OUTPUT);                   // Led's und Relais
        pinMode(abzweigLedPin[i],OUTPUT);
        pinMode(relaisPins[i],OUTPUT);
        geradeLedWinkel[i] = mitteWinkel[i] - 10 ;         // Positionen für Umschaltung
        abzweigLedWinkel[i] = mitteWinkel[i] + 10 ;        // der Weichenlaterne
        
// nach dem Einschalten werden beide Weichen auf abzweigend gestellt, entspricht bei
// der MS2 der Stellung "rot"        
        weicheDkw[i].write( abzweigWinkel[i]);             // beide Weichen auf Abzweig
        digitalWrite(abzweigLedPin[i],HIGH);               // Laterne entsprechend
        digitalWrite(relaisPins[i],LOW);                   // Relais entsprechend
    }
   
}
////////////////////////////////////////////////////////////////
void loop() {
    Dcc.process();                      // Hier werden die empfangenen Telegramme analysiert

    int tasterStatus = digitalRead(tasterPin);             // wenn Taster gedrückt
      if (tasterStatus == LOW) {                           // alle Servos in Mittelstellung
         for ( byte i=0; i<ServoZahl; i++ ) {               
              weicheDkw[i].write( mitteWinkel[i]);
      }
    }
    
//  im folgenden wird in Abhängigkeit von der Stellrichtung die Weichenlaterne umgeschaltet,
//  kurz vor Mittelstellung eine LED an, kurz nach der Mittelstellung die andere Led aus   
  
    for ( byte i=0; i<ServoZahl; i++ ) {
      if (  weicheDkw[i].read() <=  abzweigLedWinkel[i] && richtung[i] == geradeWinkel[i]  ) {
              digitalWrite(geradeLedPin[i],HIGH);          
    }
      if (  weicheDkw[i].read() <=  geradeLedWinkel[i] && richtung[i] == geradeWinkel[i]  ) {        
              digitalWrite(abzweigLedPin[i],LOW);
    }
      if (  weicheDkw[i].read() >=  geradeLedWinkel[i] && richtung[i] == abzweigWinkel[i]  ) {
              digitalWrite(abzweigLedPin[i],HIGH);          
    }
      if (  weicheDkw[i].read() >=  abzweigLedWinkel[i] && richtung[i] == abzweigWinkel[i]  ) {         
              digitalWrite(geradeLedPin[i],LOW);
    }
  } 

// die Relais für die Herzstückpolarisation werden in der Mitte des Stellweges, auch in
// Abhängigkeit von der Stellrichtung umgeschaltet

   for ( byte i=0; i<ServoZahl; i++ ) {
      if (  weicheDkw[i].read() <=  mitteWinkel[i] && richtung[i] == geradeWinkel[i]  ) {
              digitalWrite(relaisPins[i],HIGH);          
    }
      if (  weicheDkw[i].read() >=  mitteWinkel[i] && richtung[i] == abzweigWinkel[i]  ) {        
              digitalWrite(relaisPins[i],LOW);
    } 
  } 
}
//////////////////////////////////////////////////////////////
// Unterprogramme, die von der DCC Library aufgerufen werden:
// Die folgende Funktion wird von Dcc.process() aufgerufen, wenn ein Weichentelegramm empfangen wurde
void notifyDccAccState( uint16_t Addr, uint16_t BoardAddr, uint8_t OutputAddr, uint8_t State ){
    // Testen ob eigene Weichenadresse
    for ( byte i = 0; i < ServoZahl; i++ ) {
        if (  Addr == weichenAdr[i] ) {                        // ist eigene Adresse, Servo ansteuern
            if ( OutputAddr & 0x1 ) {
                weicheDkw[i].write( geradeWinkel[i] );
                richtung[i] = geradeWinkel[i];                 // Stellrichtung wird benötigt für das    
           }                                                   // Umschalten der Led's und Relais
            else {
                weicheDkw[i].write( abzweigWinkel[i] );
                richtung[i] = abzweigWinkel[i];              
           }
           break; // Schleifendurchlauf abbrechen, es kann nur eine Weiche sein
        }
    }
}


Ist jetzt etwas speziell, aber vielleicht kann es ja wer gebrauchen. Mir haben die Beispiele weiter vorne jedenfalls für den Anfang sehr geholfen. Und ich werde meine paar Weichen wohl doch alle "digitalisieren", wenn das so einfach ist und auch noch Spaß macht.

Schöne Grüße
Ulli
Zuletzt geändert von garti62 am Mi 16. Dez 2015, 18:34, insgesamt 1-mal geändert.
erste Versuche: Weichenbau
Benutzeravatar

Threadersteller
MicroBahner
Metropolitan (MET)
Beiträge: 2566
Registriert: Mi 28. Nov 2012, 14:24
Nenngröße: H0
Stromart: analog DC
Steuerung: Microprozessor-Eigenbau
Gleise: Tillig
Wohnort: Mittelfranken
Alter: 70

Arduino: MobaTools - Demo: DCC-Multifunktionsdecoder

#67

Beitrag von MicroBahner »

Hallo Ulli,
warum sollte ich was dagegen haben, wenn Du deinen Sketch hier einstellst? Ist doch ein schönes Beispiel für den Einsatz der MoBaTools :gfm:

Eins vielleicht noch allgemein zu deinem Sketch:

Code: Alles auswählen

      if (  weicheDkw[i].read() ==  abzweigLedWinkel[i] && richtung[i] == geradeWinkel[i]  ) {
              digitalWrite(geradeLedPin[i],HIGH);         
      }
Bei solchen pollenden Abfragen sollte man grundsätzlich nicht auf '==' sondern - je nach Richtung - auf '<=' oder '>=' abfragen. Hier wird wohl nichts passieren, da das Pollen gegenüber der Winkeländerung so schnell ist, dass kein Wert verpasst wird. Das muss aber nicht immer so sein. Mit den Abfragen auf >= bzw <= bist Du aber immer auf der sicheren Seite. Es funktioniert dann auch, wenn beim Pollen mal der == Wert verpasst wird.

@all:
Wie angekündigt, habe ich jetzt mal ein kleines Demo für einen Multifunktionsdecoder geschrieben. Ist ähnlich wie der Weichendecoder, nur dass er eben auf die Funktionstelegramme reagiert. Aus Übersichtsgründen habe ich erstmal auf eine Parametrierbarkeit über CV's verzichtet - alles wird über Konstante im Programm eingestellt. Für Uwe sind auch blinkende Ausgänge enthalten :wink:

Code: Alles auswählen

/* Demo: ein einfacher Dcc-Multifunktionsdecoder 
 * ---------------------------------------------
 * Die Funktionen können Servos, Leds und blinkende Leds steuern
 * Die Leds müssen so angeschlossen sein, dass sie bei HIGH am Ausgang leuchten
 * Definiert werden die Funktionen aufsteigend ab Funktion 0.
 * Wieviel Funktionen genutzt werden, bestimmt die Länge der Arrays funktionsTyp bzw. funktionsPins
 * In diesem Sketch ist es noch nicht möglich, eine beliebige Auswahl von Funktionsnummern zu
 * verwenden. Es sollte aber nicht sehr schwierig sein, das nachzurüsten ;-))
 * 
 * Um den Sketch noch übersichlich zu halten, werden keine CV-Programmierungen verwendet.
 * Alle Festwerte werden am Anfang mit #define oder const-Anweisungen festgelegt.
 * 
 * Der Decoder arbeitet '2-stufig'. 
 * 1) Erkennen des Funktionsstatus in den empfangenen Telegrammen. Der Zustand der Funktion (EIN oder AUS)
 *    wird im Telegramm erkannt, und in einem Array 'funktionsWert'  hinterlegt. Eine weitere Bearbeitung 
 *    findet in der Telegrammauswertung nicht statt.
 * 2) Im Loop werden die Funktionen bearbeitet. Hier wird dann nur noch auf das Array zugegriffen um
 *    zu erkennen ob die jeweilige Funktion ein- oder ausgeschaltet ist. Dies erlaubt eine flexible
 *    Bearbeitung der Funktionsausgänge, unabhängig davon wann tatsächlich ein entsprechendes Telegramm
 *    empfangen wird (z.B. das Blinken an den Ausgängen)
*/

#include <MobaTools.h>

//----------------------------------------------------------------------------------------
#include <NmraDcc.h>
// Leider ist die neueste Version der NmraDcc Lib nicht mehr kompatibel zu Vorgängerversionen. Ich habe
// bisher noch keinen Weg gefunden, dies automatisch anhand der NmraDcc.h zu erkennen. 
// Deshalb muss bei Verwendung der älteren Versionen hier ein Flag gesetzt werden:
//#define OLD_NMRADCC

#ifndef NMRA_DCC_ENABLE_14_SPEED_STEP_MODE
    #define FN_0 255
#endif
// die NmraDcc - Library gibt es unter https://github.com/mrrwa/NmraDcc/archive/master.zip
//----------------------------------------------------------------------------------------

// ################ anzupassende Konstante: #####################################################
const byte dccInputP        = 2;      // Inputport für DCC-Signal
const word myAddr           = 1830;   // Adresse auf die der Decoder reagiert
#define FKTMAX   28  // höchste Funktionsnummer, die im Telegramm noch ausgewertet wird. Es werden
                     // im Telegramm mehr Funktionen ausgewertet, als aktiv verwendet werden. 'Auswerten'
                     // heisst hier lediglich, dass der Zustand der Funktion (EIN oder AUS) im Telegramm
                     // erkannt und im Array 'funktionsWert' hinterlegt wird. D.h. der Sketch kennt den Zustand 
                     // aller Funktionen  von 0...28, unabhängig davon, ob für diese Funktion auch ein Ausgang und
                     // eine entsprechende Bearbeitung definiert ist
                     // Das erleichtert eine spätere Erweiterung auf die Verwendung beliebig ausgewählter
                     // Funktionsnummern

// ------------ Definition der aktiv verwendeten Funktionen -----------------------------------------
// Genutzt werden die Funktionsnummern ab 0. Index in die folgenden Tabellen ist die Funktionsnummer.
// Der Tabelleninhalt gibt die Parameter für die jeweilige Funktion an.
// Der Funktionstyp wird im Array funktionsTyp festgelegt.
// Werte kleiner 16 sind ein Servoausgang ( Der Wert darf maximal SERVOANZAHL-1 sein )
#define FLED    16  // Der Ausgang wird entsprechend des Funktionswertes statisch ein- bzw. ausgeschaltet
#define FBLINK  17  // Bei aktiver Funktion wird der Ausgang in einem vorgegeben Takt ein- und ausgeschaltet

const byte funktionsTyp[]   = {FLED,   0,   1,   2,   3,FLED,FBLINK,FBLINK}; 
const byte funktionsPins[]  = {   4,   5,   6,   7,   8,   9,    10,    11};  // output-pin der Funktionen
const byte funktionsAnzahl = sizeof( funktionsTyp );

#define BLINKZAHL     2   // Zahl der Funktionen mit Blinken, muss zum obigen Typ-Array passen
const int blinkEin[BLINKZAHL] = { 500, 1000 };
const int blinkAus[BLINKZAHL] = { 500, 300  };

#define SERVOANZAHL   4   // 4 Servofunktionen - muss zum obigen Typ-Array passen
const int ausPuls[SERVOANZAHL]     = {1200,1200,1200,1200};  // Pulslänge Funktion aus
const int einPuls[SERVOANZAHL]     = {1800,1800,1800,1800};  // Pulslänge Funktion ein
const int servoSpeed[SERVOANZAHL]  = {   8,   1,  10,  20};  // Geschwindigkeit des Servo
const byte autoOff[SERVOANZAHL]    = {   1,   1,   0,   0};  // automatisch Abschalten nach erreichen der Endstellung

//###########################################################################################################
// Definition der Variablen und Objekte
boolean funktionsWert[FKTMAX+1];    // aktueller Wert der Funktion vom DCC-Tel. ( ein- oder ausgeschaltet )
Servo8 fServo[SERVOANZAHL];
NmraDcc Dcc;
EggTimer blinkerT[BLINKZAHL];
byte blinkState[BLINKZAHL];  // momentaner Status de FBLINK Ausgangs (LOW oder HIGH)

///////////////////////////////////////////////////////////////
void setup() {
    Dcc.pin(digitalPinToInterrupt(dccInputP), dccInputP, 1); // Dcc-Signal mit Pullup
    Dcc.init( MAN_ID_DIY, 01, 0, 0 );    // Multi-Funktionsdecoder, keine Adressauswertung

    // Funktionsausgänge initiieren
    for ( byte i=0; i<funktionsAnzahl; i++ ) {
        if ( funktionsTyp[i] < SERVOANZAHL ) {
            // ServoAusgang:
            byte servoNr = funktionsTyp[i];
            fServo[servoNr].attach( funktionsPins[i], autoOff[servoNr] );
            fServo[servoNr].setSpeed( servoSpeed[servoNr] );
        } else {
            // nur Digital Ausgang
            pinMode( funktionsPins[i],OUTPUT );
            digitalWrite( funktionsPins[i],LOW );
        }
    }
}

////////////////////////////////////////////////////////////////
void loop() {
    Dcc.process(); // Hier werden die empfangenen Telegramme analysiert
    
    // Bearbeiten der definierten Funktionen
    byte blinkIx = 0;   // Index für die Timer der Blinkfunktionen
    for ( byte fIx = 0; fIx < funktionsAnzahl; fIx++ ) {
        // Schleife über alle definierten Funktionen
        switch ( funktionsTyp[fIx] ) {
          // je nach Funktionstyp müssen unterschiedliche Bearbeitung aufgerufen werden 
          case FLED: //---------------------------------------------------------------------------
            // Ausgang entsprechend des Funktionswertes ein/ausschalten
            if ( funktionsWert[fIx] ) digitalWrite( funktionsPins[fIx], HIGH );
            else                     digitalWrite( funktionsPins[fIx], LOW );
            break;
          case FBLINK: //-------------------------------------------------------------------------
            // Ausgang blinkt bei aktiver Funktion
            if ( funktionsWert[fIx] ) {
                // Funktion ist aktiv, Led blinkt
                // Solange der jeweilige Timer noch läuft, passiert hier nichts, und die Led
                // verharrt im aktuellen Status (AUS oder EIN)
                if ( ! blinkerT[blinkIx].running() ) {
                    // Timer läuft nicht, Ausgang schalten und Zeitwert setzen.
                    if ( blinkState[blinkIx] == HIGH ) {
                        //aktueller Status ist EIN, also ausschalten
                        digitalWrite( funktionsPins[fIx], LOW );        // Ausgang abschalten
                        blinkerT[blinkIx].setTime( blinkAus[blinkIx] ); // Zeit für AUS setzen
                        blinkState[blinkIx] = LOW;                      // Status auf AUS
                    } else {
                        //aktueller Status ist AUS, also einschalten
                        digitalWrite( funktionsPins[fIx], HIGH );       // Ausgang einschalten
                        blinkerT[blinkIx].setTime( blinkEin[blinkIx] ); // Zeit für EIN setzen
                        blinkState[blinkIx] = HIGH;                     // Status auf EIN
                     }
                }
            } else {
                // Funktion ist inaktiv, Ausgang abschalten
                digitalWrite( funktionsPins[fIx], LOW );
            }
            blinkIx++; // Index für nächste Funktion mit Blinken. So erhält jeder Ausgang mit
                       // Blinkfunktion seinen eigenen Timer für die Blinkzeiten
            break;
          default: //---------------------------------------------------------------------------
            // Servoansteuerung, vorsichtshalber auf Zahl der Servos prüfen
            // Einträge die weder den Funktionstypen oben, noch der Zahl der Servos entsprechen
            // werden so ignoriert.
            if ( funktionsTyp[fIx] < SERVOANZAHL ) {
                byte servoNr = funktionsTyp[fIx];
                if ( funktionsWert[fIx] ) fServo[servoNr].write( einPuls[servoNr] );
                else                      fServo[servoNr].write( ausPuls[servoNr] );
            }
        } // Ende switch Funktionstyp -----------------------------------------------------------
    } // Ende der Schleife über die definierten Funktionen
} // Ende Loop ##############################################################################


//////////////////////////////////////////////////////////////
// Unterprogramme, die von der DCC Library aufgerufen werden:
// Die folgende Funktion wird von Dcc.process() aufgerufen, wenn ein Funktionstelegramm empfangen wurde
// Funktionstelegramm ======================================================================
#ifdef OLD_NMRADCC
void notifyDccFunc( uint16_t Addr, FN_GROUP FuncNum, uint8_t FuncState){
#else
void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncNum, uint8_t FuncState){
#endif
    if ( (Addr&0x3fff) == myAddr ) {
        // Funktionstelegramm  mit eigener Adresse erhalten
        // In einem Telegramm wird immer nur ein Teil der Funktionswerte übertragen. (Bitweise codiert
        // in der übergebenen Variable 'FuncState)
        // Die folgenden Tabellen enthalten - abhängig von der Funktionsgruppe (FuncNum)
        // jeweils die kleinste und höchste in FuncState übergebene Funktionsnummer
        static byte FGrStart[] = {0,1,5, 9,13,21}; // Offset Funktionsgruppe -> kleinste Funktionsnummer
        static byte FGrEnde[]  = {0,4,8,12,20,28}; // Offset Funktionsgruppe -> letzte Funktionsnummer
        uint8_t fMsk, i, fIxStart, fIxMax;
        if ( FuncNum == FN_0_4 || FuncNum == FN_0 ) {
            // Sonderfall Funktion0 ausfiltern
            funktionsWert[0] = FuncState&FN_BIT_00;
        }
        if ( FuncNum != FN_0 ) {
            // in der Gruppe FN_0 wird NUR die Funktion 0 übertragen, d.h. wir sind mit
            // der obigen Auswertung fertig. In allen anderen Gruppen werden
            // auch weitere Funktionen, codiert ab Bit0 übertragen, die in der folgenden
            // for-Schleife ausgewertet werden.
            fIxStart = FGrStart[FuncNum];
            fIxMax   = FGrEnde[FuncNum];
            fMsk= 0b00000001;    // Maske zum herausfiltern der Funktionsbits in FuncState
            for ( i=fIxStart; i<= fIxMax && i<=FKTMAX; i++ ) {
                // Funktionsstatus in das Array funktionsWert eintragen
                funktionsWert[i] = FuncState & fMsk;
                fMsk = fMsk<<1;     // Maske für nächste Bitposition
            }
        }
    }
}
Etwas aufpassen muss man mit den Versionen der NmraDcc Library. Der aktuelle Stand ist bezüglich der Geschwindigkeits- und Funktionstelegramme inkompatibel zu den Vorgängerversionen die in den bisherigen Demo's eingesetzt wurden. Ich halte das für etwas unglücklich, aber es ist nunmal nicht zu ändern. Da ich noch keine Möglichkeit gefunden habe, dass im Sketch automatisch herauszufinden, muss man im Sketch das #define OLD_NMRADCC nutzen oder auskommentieren, je nachdem ob man eine alte oder neue Version installiert hat.

viel Spaß damit
Benutzeravatar

garti62
InterCity (IC)
Beiträge: 602
Registriert: Di 8. Nov 2011, 20:59
Nenngröße: H0
Stromart: digital
Steuerung: MS2
Gleise: Selbstbau
Wohnort: Harz
Alter: 58

Re: Arduino: MobaTools - Demo: DCC-Multifunktionsdecoder

#68

Beitrag von garti62 »

Hallo Franz-Peter,

vielen Dank für den Tip! Ich habe den Code gleich mal entsprechend geändert.

Schönen Abend noch
Ulli
erste Versuche: Weichenbau
Benutzeravatar

UweS
InterRegioExpress (IRE)
Beiträge: 339
Registriert: Do 2. Feb 2012, 11:44
Nenngröße: 1
Stromart: DC
Steuerung: TC Gold
Wohnort: Saxonia
Alter: 65

Re: Arduino: MobaTools - Demo: DCC-Multifunktionsdecoder

#69

Beitrag von UweS »

Hallo Franz-Peter,

vielen Dank für die Realisierung meines Sonderwunsches, habe die neue NmraDcc Library geladen und der Sketch funktioniert.
Ausgiebig testen, kann ich erst am Wochenende.

Danke für Deine Mühe, ich melde mich.
Uwe

Lenz Digital seit 1993, seit 2020 Roco z21 und steuern mit der Z21 App, Traincontroller Gold, Mikromodellbau,
Benutzeravatar

Bodo
InterCityExpress (ICE)
Beiträge: 2368
Registriert: Do 28. Apr 2005, 08:59
Nenngröße: H0
Stromart: digital
Steuerung: IB1 & CS2
Gleise: C-Gleis
Kontaktdaten:
Deutschland

Re: Arduino: MobaTools - NANO Sockelplatine DCC-Decoder

#70

Beitrag von Bodo »

Hallo zusammen,

inzwischen sind meine Platinen-Muster (siehe http://www.stummiforum.de/viewtopic.php ... 9#p1457709 ) angekommen und bestückt/getestet. Die Bilder sind "auf die Schnelle" leider nicht optimal geworden, aber hoffentlich erkennbar. Hier die Ausführung mit rückseitig eingelöteten Steckern (alternativ lassen sich auch Verlängerungskabel von oben einlöten, mit Steckern passt das nicht):

Bild

Die Löcher passen für C-Gleis-Schrauben, für die rückseitig angesteckten Servostecker muss dann natürlich eine Aussparung vorgesehen werden. Das zweite Bild zeigt die Kombination mit angesteckter Schieberegister-Platine:

Bild

Bei Bestellung von mehr als 10 Stück (die werde ich auf jeden Fall bestellen) werden die Nano-Sockel-Platinen auf ca. 6,50 Euro kommen, die Schieberegister-Platine auf ca. 6,00 Euro. Bei Bedarf kann ich auch gerne die benötigten Bauteile zum Selbstkostenpreis mitliefern.

Zeitlich schaffe ich es vor Weihnachten nicht mehr - als Bestelldatum bei Fritzing plane ich den 04.01.2016, d.h. die Bestellungen sollten bei mir per PN bis 02.01.2016 vorliegen. Die Produktion dauert ca. 8 Tage ab Dienstag, mit etwas Glück sind die Platinen also am 16.01. bei mir. Den weiteren Versand würde ich dann natürlich schon vorbereiten und direkt erledigen.

Fragen gerne per PN - die Antworten werde ich dann zugunsten der Übersichtlichkeit in diesen Beitrag einarbeiten.

Ergänzung: Wenn man das ganze möglichst klein aufbauen möchte, passt der Nano auch nur mit seinen Stiftleisten in die Platine - dann muss der Optokoppler allerdings ebenfalls ohne Sockel eingelötet werden und man "verbaut" sich das rechte Schraubloch (und die Schraubklemmen passen vermutlich auch nicht mehr):
Bild

Viele Grüße, Bodo
Zuletzt geändert von Bodo am Mo 28. Dez 2015, 07:41, insgesamt 1-mal geändert.
Die Freiheit des Menschen liegt nicht darin, dass er tun kann, was er will, sondern dass er nicht tun muss, was er nicht will. (Jean-Jacques Rousseau)

Meine Anlage - Meine Dauerbaustelle
Platinen für Modellbahn- und Arduino-Anwendungen
Benutzeravatar

UweS
InterRegioExpress (IRE)
Beiträge: 339
Registriert: Do 2. Feb 2012, 11:44
Nenngröße: 1
Stromart: DC
Steuerung: TC Gold
Wohnort: Saxonia
Alter: 65

Re: Arduino: MobaTools - Demo: DCC-Multifunktionsdecoder

#71

Beitrag von UweS »

Hallo Franz-Peter,

habe den Multifunktiondecoder getestet.
Leider fehlt mir der Durchblick.
Wie bereits geschrieben, mit der neuen NmraDcc Lib lässt sich der Sketch ohne Fehlermeldung Hochladen.
Hochgeladen auf einen Nano Rev.3.

Die Lokadresse ist klar, was ich aber nicht nachvollziehen kann ist die Zuordnung der F-Tasten zu den
Pin Ausgängen des Arduino.
ZB. habe ich eine blinkende LED am Ausgang 10, schaltbar mit der F6?

Wo kann ich das im Sketch erkennen, oder die Zuordnung ändern?
Ebenso möchte ich gern beim betätigen einer F- Taste, zB. eine Schweißlicht Funktion einfügen können.

Kannst Du da bitte noch ein paar Erklärungen einfügen?
Ich weiß, Du hast schon viel Programmierarbeit geleistet, recht vielen Dank dafür.
Aber ich stehe zur Zeit noch ein wenig auf dem Schlauch. :shock:
Mir fehlt noch ein wenig das :idea: am Ende des Tunnels.
Uwe

Lenz Digital seit 1993, seit 2020 Roco z21 und steuern mit der Z21 App, Traincontroller Gold, Mikromodellbau,
Benutzeravatar

Threadersteller
MicroBahner
Metropolitan (MET)
Beiträge: 2566
Registriert: Mi 28. Nov 2012, 14:24
Nenngröße: H0
Stromart: analog DC
Steuerung: Microprozessor-Eigenbau
Gleise: Tillig
Wohnort: Mittelfranken
Alter: 70

Re: Arduino: MobaTools - Demo: DCC-Multifunktionsdecoder

#72

Beitrag von MicroBahner »

Hallo Uwe,
UweS hat geschrieben:ZB. habe ich eine blinkende LED am Ausgang 10, schaltbar mit der F6?
Wo kann ich das im Sketch erkennen, oder die Zuordnung ändern?
Die Funktionstastennummer ist der Index in diese Tabellen:

Code: Alles auswählen

const byte funktionsTyp[]   = {FLED,   0,   1,   2,   3,FLED,FBLINK,FBLINK};
const byte funktionsPins[]  = {   4,   5,   6,   7,   8,   9,    10,    11};  // output-pin der Funktionen
D.h. mit F0 schaltest Du das, was am Index 0 der Tabelle steht, mit F6 das, was am Index 6 steht. Dort steht beim Typ FBLINK und beim Pin '10'. Also schaltet F6 eine blinkende Led an Pin 10.

Ob die Funktion ein- oder ausgeschaltet ist, steht in dieser Tabelle (Array):

Code: Alles auswählen

boolean funktionsWert[FKTMAX+1];    // aktueller Wert der Funktion vom DCC-Tel. ( ein- oder ausgeschaltet )
Und auch da ist wieder die Funktionsnummer der Tabellenindex. Wenn also z.B. F6 aktiv ist, dann ist funktionsWert[6] == true. Das muss man dann im 'loop' beim Realisieren der jeweiligen Funktion abfragen.

Möchtest Du eine neue Funktion realisieren, dann must Du die Tabelle mit den Typen erweitern:

Code: Alles auswählen

// Werte kleiner 16 sind ein Servoausgang ( Der Wert darf maximal SERVOANZAHL-1 sein )
#define FLED    16  // Der Ausgang wird entsprechend des Funktionswertes statisch ein- bzw. ausgeschaltet
#define FBLINK  17  // Bei aktiver Funktion wird der Ausgang in einem vorgegeben Takt ein- und ausgeschaltet
#define BLITZ   18  // neue Funktion, z.B. Schweisslicht

Die kannst Du dann in der Tabelle funktionsTyp verwenden. z.B.

Code: Alles auswählen

const byte funktionsTyp[]   = {FLED,   0,   1,   2,   3,FLED,FBLINK,BLITZ};
const byte funktionsPins[]  = {   4,   5,   6,   7,   8,   9,    10,    11};  // output-pin der Funktionen
So wäre z.B. die neue Funktion mit F7 und Pin 11gekoppelt.

Was dann passieren soll, wenn Du die Funktion auslöst, musst Du im loop als neuen case in dem switchblock programmieren:

Code: Alles auswählen

.....
        switch ( funktionsTyp[fIx] ) {
          // je nach Funktionstyp müssen unterschiedliche Bearbeitungen aufgerufen werden
          case BLITZ: //-------------------------------------------------------------
             // hier muss der Programmcode für die 'BLITZ' Funktion stehen
             if ( funktionsWert[fIx] == true ) {
             	// Aktion wenn Funktion aktiv
             } else {
                 // Aktion wenn Funktion ausgeschaltet
             }
             
             break;
          case FLED: //---------------------------------------------------------------------------
.....
Du bist natürlich nicht gezwungen, in dem Code den oben festgelegten Ausgangspin zu verwenden. Du kannst dort auch den Ausgang fest einprogrammieren, z.B. wenn Du mehrere Ausgänge brauchst. Dann kannst Du den 'BLITZ' aber nur einer F-Taste zuordnen, weil es ja immer am gleichen Ausgang 'blitzt'. Auch musst Du dann im setup noch entsprechende Initiierungen machen. Derzeit werden im setup nur die in dem array 'funktionsPins' definierten Ausgänge auf OUTPUT geschaltet.
Die Realisierung mit den Tabellen ist vor allem dazu da, Funktionen mehrfach an unterschiedlichen Ausgängen verwenden zu können und eine bessere Übersicht über die verwendeten Pins zu haben.

Wie man ein Schweißlicht ohne delays programmiert, habe ich weiter oben schonmal gezeigt. Das könnte man jetzt hier anwenden.
Ist aber für den Anfang schon durchaus eine anspruchsvolle Aufgabe. Wenn's noch nicht klappt, kann ich ja noch etwas helfen :wink:
Benutzeravatar

garti62
InterCity (IC)
Beiträge: 602
Registriert: Di 8. Nov 2011, 20:59
Nenngröße: H0
Stromart: digital
Steuerung: MS2
Gleise: Selbstbau
Wohnort: Harz
Alter: 58

Re: Arduino: MobaTools - Demo: DCC-Multifunktionsdecoder

#73

Beitrag von garti62 »

Hallo Stummis,

heute möchte ich mal kurz von einem kleinen Problem berichten, das ich mit den in China bestellten Arduino-Nano-Klonen für 2,85€ hatte. Ich denke, das passt hier ganz gut hin, da sicher noch einige hier zum Nachmachen angeregt werden und dann vielleicht vor dem gleichen Problem stehen. Dann müssen sie nicht lange googeln. Bei meinen Nano-Klonen ist nicht der übliche USB/Seriell-Wandler von FTDI verbaut (das ist der Schaltkreis auf der Unterseite des Boards) sondern ein CH340 der Firma Winchiphead. Das tut der Funktion des Boards eigentlich keinen Abbruch, aber das Board wird am USB-Anschluß von der Arduino-IDE nicht erkannt und kann somit auch nicht über USB programmiert werden. Zuerst habe ich das Problem einfach ignoriert und das Board über die ISP-Schnittstelle programmiert, dazu braucht man aber einen separaten USB-Prorammer und den hat nicht jeder. Außerdem ist nach dem ersten Programmiervorgang über diesen Weg der Bootlader weg :D . Nach einigem Suchen hier die Lösung:
- von der Herstellerseite das passende Treiberpaket herunterladen (nicht an den Schriftzeichen stören, einfach "download" drücken :wink: )
- die heruntergeladenen Dateien entpacken
- im Unterordner "CH341SER" die Datei "SETUP" (ganz unten) ausführen
- wenn man jetzt seinen Nano an USB anschließt, findet man im "Gerätemanager" des PC einen neuen COM - Anschluß mit dem Namen "USB-SERIAL CH340 COM..."
- diesen in der Arduino-IDE unter "Werkzeuge" , "PORT" auswählen und fertig
Jetzt kann man seine Programme ganz normal und ohne Umwege auf das Board hochladen. Ich hoffe, daß ich damit einigen von Euch die Suche nach einer Lösung des Problems erspart habe.

Schöne und besinnliche Weihnachtsfeiertage noch

wünscht Ulli
erste Versuche: Weichenbau

Instandsetzung
InterCity (IC)
Beiträge: 784
Registriert: Fr 27. Feb 2009, 19:06
Wohnort: Revier

Re: Arduino: MobaTools - Demo: DCC-Multifunktionsdecoder

#74

Beitrag von Instandsetzung »

Hallo zusammen,
garti62 hat geschrieben: - von der Herstellerseite das passende Treiberpaket herunterladen (nicht an den Schriftzeichen stören, einfach "download" drücken :wink: )
Aktuell scheint es zu funktionieren.
Da das aber nicht immer der Fall war, hat da ein netter Kollege vorgesorgt und man kann ihn auch
von hier => http://www.jens-bretschneider.de/aktuel ... b-adapter/ <= runter laden.

MFG
Oliver
Doomsday
Ehemaliger Benutzer

Re: Arduino: MobaTools - Demo: DCC-Multifunktionsdecoder

#75

Beitrag von Doomsday »

Hallo zusammen, Franz-Peter,

Entschuldigt, wenn ich hier einfach mal so reinschneie (in Ermangelung von Schnee muß ich das halt selbst machen *g*).

Ich lese die MoBa-Tools mit großem Interesse, obwohl ich nicht in Arduino-Programmierung bewandert bin, und ich bin mir nicht sicher ob ich das auch je werde. Im Moment spiele ich mit einem Raspberry Pi B (Revision 2) und einer breakout-Platine herum, die mir 16 PWM Kanäle via I2C zur Verfügung stellt. Für 2.5 GBP aus China bestellt ist das ein echtes Schnäppchen!

Meine Frage geht aber eher an Franz-Peter, der die MoBa-Tools geschrieben hat, und damit sicher intime Kenntnisse von Servos und PWM hat - und meine Frage(n) gehen tief in die Pulsgenerierung und die Antworten von Servos ein - entsprechende Kommentare habe ich von Franz-Peter in den BoBa-Tools-Quellen gefunden:

PWM-Signale werden ja mit Hilfe eines Oszillators, sogenannten "prescalern" und einem simplen Counter erzeugt. Dabei gehe ich davon aus, daß das Oszillatorsignal (bei mir: 25 MHz) mit Hilfe eines prescalers auf eine niedrigere Frequenz dividiert wird, die wiederum steuert, wie schnell der PWM-counter zählt.

Frage 1: Stimmt meine Annahme, daß bei einer prescaler-Frequenz von 50 Hz der counter 50-Mal in der Sekunde durchläuft? Meine bisherigen Berechnungen und Versuche scheinen das zu bestätigen.

Servos benötigen Pulse von bestimmter Länge, um den Stellarm in eine definierte Position zu fahren. Die Dokumentation der Servos gibt das in der Regel an, z.B. für meine kleinen 9g-Servos, die ich für Testzwecke (auch aus China) bestellt habe, geben an, daß bei einer Taktfrequenz von 50 Hz ein Puls von 1 ms Länge der Arm in seine -90 Grad Position fährt, ein 1,5 ms langer Puls den Arm in die Mittelstellung fährt, und dementsprechend ein 2 ms-Puls den Arm in die 90 Grad position fahren läßt. Nach einigen Berechnungen (s.u.) habe ich die entsprechen Werte für den PWM-counter den ich verwende, herausbekommen, und in ein kleines Testprogramm eingebaut. Das Programm funktioniert auch ganz gut, und ich kann Servos hind- und her wackeln lassen. :-) Aaaaaber... Wenn ich die errechneten Werte benutze, ergibt das mit meinem Servo einen nutzbaren Kreisbogen von etwa 90 bis 100 Grad - doch deutlich weniger als die angegebenen 180 Grad. Wenn ich aber die Pulswerte entsprechend modifiziere, komme ich auf einen Kreisbogen von mehr als 180 Grad!

Frage 2: Ich habe in verschiedenen Quellen gelesen, daß ein nutzbarer ca. 100 Grad Kreisbogen von bei Servos eigentlich die Regel ist. Könnt ihr das bestätigen? Oder kann das eventuell auch an einem schlechten Oszillator liegen? Dem bei mir eingebauten Oszillator/prescaler System wurde bei einigen (wenigen) Quellen eine Abweichung von bis zu 15% angelastet, aber selbst das erklärt nicht die extremen Abweichungen bei meinen Servos: die ermittelten Minimal- bzw. Maximalpulslängen entsprechen 0,53 ms bzw. 2,46 ms! :bigeek:

Vielleicht hat sich aber auch der Wurm in meine Berechnungen eingeschlichen; das hängt mit Frage 1 und 2 zusammen. Hier nun meine Gedanken und wie ich zu meinen Werten gekommen bin:

Um den Servo in eine Position zu fahren, wird ein Ganzzahlwert angegeben, der dieser Position entspricht. Dieser Wert entspricht der Anzahl von counter "ticks", für die der Puls auf logisch 1 gesetzt sein soll. Dieser Wert aber hängt von zwei Faktoren ab, nämlich (a) der Generator-Frequenz, und (b) der counter "Auflösung". Ihr Zusammenspiel bestimmt, wie lang ein Puls von "2000" tatsächlich ist: Je höher Auflösung und Frequenz, desto kürzer dauert ein counter-"tick", und desto kürzer dauert der 2000 Puls in Realität. Umgekehrt muß die Pulszahl entsprechend erhöht werden, wenn Frequenz und Auflösung steigen, um die tatsächliche Pulsdauer konstant zu halten.

Beispiel: Mein PWM-Generator (NXP PCA9685) hat eine counter-Auflösung von 12 Bit, d.h. der counter zählt von 0 bis 4095, um dann wieder von Vorne anzufangen. Ich gehe davon aus, daß dies exakt einer Pulsperiode entspricht - siehe Frage 1. Was bedeutet, daß bei einer eingestellten Generatorfrequenz von 50 Hz der counter eben 50 Mal pro Sekunde von 0 bis 4096 zählt. Die tatsächliche Pulsdauer von "2000" errechnet sich also wie folgt: Dauer = 2000 / (4096 * 50) = 0,009765 s = 9,765 ms. Bei einer Frequenz von 100 Hz verkürzt sich diese auf ca. 4,88 ms, und bei einer Frequenz von 200 Hz - voreingestellt bei meinem Generator - entspricht dies lediglich 2,44 ms.

Finale Frage: Bin ich hier komplett auf dem Holzweg, oder macht mein (sehr langer) Beitrag vielleicht doch Sinn?

Frohes Neues Jahr, übrigens. :-)

LG,
Michel
Antworten

Zurück zu „Elektrik und Elektronik“