RE: Arduino Weichenpult - Sketch korrektur

#1 von Bettbahner ( gelöscht ) , 26.09.2015 00:05

Hallo,

Ich bin momentan am ausprobieren was man alles mit einem Arduino Board bewerkstelligen kann, ich beschäftige mich seid 2Wochen mit diesem Thema.
Mein Ziel für die (leider noch) ferne Zukunft ist es die 24 Weichen meiner Anlage mit Tastern zu stellen und eine passive (Passiv weil der Anker stand der spulen antriebe nicht überprüft wird) Rückmeldung auf einem Stellpult zu visualisieren mihilfe von LEDs.

Das bedeutet ich brauche 2Ports für die LED Ansteuerung 2 Ports für die Taster und 2Ports für den Weichenantrieb. Macht in Summe 144 Ports. Leider hat dies kein Arduino Daher muss ich mir die Ports beschaffen indem ich Schieberegister einsetzte(74hc595).

Den Schaltvorgang der Weichen stelle ich mir momentan so vor:

Taster wird betätigt --> Arduino erkennt dies --> ändert das Bit des Schieberegisters welches für die LED Rückmeldung ist und gleichzeitig wird in einem anderen Schieberegister für einen kurzen Moment durchgeschaltet um den Weichenantrieb umzupolen damit die Weiche sich bewegt.
{http://1drv.ms/1f4eOc5 hier ist ein Link in mein Notizbuch eine Skizze wie ich mir den Ablauf/Aufbau vorstelle findet ihr unter dem gerade genannten Link unter \Spur_N_Öffentlich_StummiforumArduinosteuerungSchaltplan.}

So viel zur Einleitung.

: Mein Problem ist folgendes, ich weiß nicht wie ich Bitmanipulationen innerhalb eines Schieberegisters machen kann. :
Bei dieser Frage würde ich mir Wünschen das jemand mit mehr Erfahrung mir da einige Tipps geben könnte wie ein solcher Code auszusehen hätte.



Auf eine schnelle Antwort hoffe ich

(Edit: Link geändert)


Bettbahner

RE: Arduino Weichenpult - Sketch korrektur

#2 von Der Ruinenbaumeister , 26.09.2015 08:32

Ein Schieberegister heißt Schieberegisster, weil die Bits von vorne nach hinten durchgeschoben werden. Also etwa so:

00000000
10000000
01000000
00100000
10010000
01001000
00100100
etc.

Man steuert die einzelnen Bits nicht direkt an. Für deine Zwecke ist das nicht nützlich. Was du brauchst sind Multiplexer und Demultiplexer.


Gruß
Clemens

Mein Blog.


 
Der Ruinenbaumeister
EuroCity (EC)
Beiträge: 1.191
Registriert am: 01.04.2011


RE: Arduino Weichenpult - Sketch korrektur

#3 von spielbahn ( gelöscht ) , 26.09.2015 09:02

Es geht mit Schieberegistern.
Du musst für jedes Bit, das du ausgeben willst, eine Variable (byte) anlegen, sinnvollerweise ein Array z.B. "led[i]". Dann änderst du bei Bedarf die entsprechende Variable. Die Routine, die das Schieberegister bedient, gibt dann alle Werte von z.B. led[i] an das Schieberegister. Das Schieberegister wirkt dann wie eine Porterweiterung.
Falls weitere Info gewünscht wird, einfach melden....


spielbahn

RE: Arduino Weichenpult - Sketch korrektur

#4 von MicroBahner , 26.09.2015 10:17

Hallo Peter,
144 Ausgangsports ist natürlich schon eine Hausnummer . Da sind Schieberegister schon eine passende Lösung, die am Arduino nur wenig Anschlüsse erfordert. So wie Uli beschrieben hat kannst Du es machen. Ein Byte-Array in dem Du die Bits zusammensetzt, und dann rausschieben.
Wobei der Arduino dafür auch ein HW-Schieberegister eingebaut hat: die SPI-Schnittstelle. Damit geht das Rausschieben einfach und schnell.

P.S. Wenn ich auf deinen Link klicke, bekomme ich nur eine Meldung, dass das Element nicht verfügbar ist


viele Grüße
Franz-Peter
Ein 'elektromechanisches' Stellwerk
Der (ehemalige) 'Eisberg'


 
MicroBahner
Metropolitan (MET)
Beiträge: 2.833
Registriert am: 28.11.2012
Ort: Mittelfranken
Gleise Tillig Elite
Steuerung Eigenbau
Stromart Analog


RE: Arduino Weichenpult - Sketch korrektur

#5 von thoern , 26.09.2015 10:29

Hi,

wie bereits die Vorredner geschrieben haben, sind Schieberegister schon das richtige Mittel zur Porterweiterung.

Zitat von Bettbahner

Das bedeutet ich brauche 2Ports für die LED Ansteuerung 2 Ports für die Taster und 2Ports für den Weichenantrieb. Macht in Summe 144 Ports. Leider hat dies kein Arduino Daher muss ich mir die Ports beschaffen indem ich Schieberegister einsetzte(74hc595).



Für die Eingabe brauchst du allerdings ein anderes, z.B. 74xx165
Ich habe mich bisher nicht wirklich mit Arduinos beschäftigt, aber die haben ja auch AVR's on board.
Für AVR's und Porterweiterung gibt es hier gute Infos (Codebeispiele sind aber Assembler):

https://www.mikrocontroller.net/articles...Schieberegister
bzw hier
https://www.mikrocontroller.net/articles...iterung_mit_SPI

Gruß,
thoern


thoern  
thoern
InterRegio (IR)
Beiträge: 107
Registriert am: 29.12.2011


RE: Arduino Weichenpult - Sketch korrektur

#6 von Bettbahner ( gelöscht ) , 26.09.2015 11:42

Hallo an alle,

@Clemens
So hatte ich die Funktion von einem Schieberegister auch verstanden.

Zitat von DerRuinenbaumeister
Was du brauchst sind Multiplexer und Demultiplexer.


Von Multiplexern lese ich jetzt zum ersten mal hatte sie daher auch nicht auf dem Schirm beim nachdenken, muss ich mir mal googeln damit ich weiß was die machen.

@Uli
Da habe ich direkt eine Frage, das Array muss dann so lang sein wie die Summe aller kaskadierten Schieberegister, also bei einem 8 variablen lang, bei 2 16 variablen lang etc.?

Zitat von spielbahn
Falls weitere Info gewünscht wird, einfach melden....


Das werde ich aufjedenfall wenn es dann zur Entwicklung meines Sketches für den Arduino geht.

@Franz-Peter

Zitat von MicroBahner
die SPI-Schnittstelle


Bei einem UNO ist das doch die Schnittstelle die mit dem Befehl Serial.print("xy"); ein xy auf dem seriellen Monitor in der Programmierumgebung erscheinen lässt?

Ja 144 Ports das sind schon eine ganze Menge, allerdings sind davon nur 96 Ausgangsports, weil ich hier die Schalter für die Weichen mit rein gerechnet hatte. Also sind 48 Ports Eingangsports für Taster.

Der Link in meinem ersten Post ist inzwischen durch den Link in mein Notizbuch aus der Signatur ersetzt mit der Beschreibung wie man dorthin findet, also in welchem Abschnitt diese Skizze zu finden ist.

@thoern
Danke für den Hinweis das ich für die Eingabe andere Schieberegister brauche, habe das bisher nicht bedacht.

Vielen Dank für die Links! Sie erläutern das Schieberegister sehr gut.


@Alle
Vielen Dank für die schnellen und informativen Antworten

Ich werde versuchen einen Sketch zu erstellen und ein Foto von meiner "Übungsschaltung", damit man eine neue Grundlage für Fragen schaffen kann, halte euch auf dem laufenden.
Beim 'Kommentare erstellen gibt es neben der "Quote" Schaltfläche auch eine "Code" kann man mit dieser Programmcode einfügen das er auch als solcher ersichtlich wird?


Bettbahner

RE: Arduino Weichenpult - Sketch korrektur

#7 von MicroBahner , 26.09.2015 12:21

Hallo Peter,

Zitat von Bettbahner
Bei einem UNO ist das doch die Schnittstelle die mit dem Befehl Serial.print("xy"); ein xy auf dem seriellen Monitor in der Programmierumgebung erscheinen lässt?

Nein, das ist die asynchrone serielle Schnittstelle (USART) an den pins 0 und 1 (TXD, RXD ).

Die SPI-Schnittstelle wird vom Arduino im normalen Betrieb nicht benutzt. Man kann sie zum Programmieren ('flashen') der Bausteine benutzen (am ICSP-Anschluß).

In den Links von thoern ist der Anschluß der Schieberegister an die SPI-Schnittstelle gut beschrieben. Zur Ansteuerung musst Du nicht auf die Assemblerebene hinunter . Es gibt eine Arduino-Library 'SPI' mit der Du auf diese Schnittstelle zugreifen kannst (Senden und Empfangen).


viele Grüße
Franz-Peter
Ein 'elektromechanisches' Stellwerk
Der (ehemalige) 'Eisberg'


 
MicroBahner
Metropolitan (MET)
Beiträge: 2.833
Registriert am: 28.11.2012
Ort: Mittelfranken
Gleise Tillig Elite
Steuerung Eigenbau
Stromart Analog


RE: Arduino Weichenpult - Sketch korrektur

#8 von mgcss ( gelöscht ) , 26.09.2015 14:03

für die Ansteuerung von Schieberegistern gibt in den Arduino-Libraries den Befehl ShiftOut. Dabei werden die einzelnen Pins für Data und Clock übergeben sowie ein ganzes Byte mit den Daten. In einem weiteren Parameter wird spezifiziert, mit welchem Bit die Sendung begonnen werden soll - also ob das Byte "von rechts nach links" oder anders herum gesendet werden soll.

Die Programmierung mit ShiftOut ist super einfach - allerdings braucht man dann noch die Funktionen zum setzen und Löschen einzelner Bits (bitSet() und bitClear() ). Als Variablen zum Speichern der Werte nimmst Du in dem Fall also statt des Bit-Arrays ganze Byte Werte und setzt die einzelnen Bits mit bitSet() und bitClear(). Anschließend werden die Bytes dann mit shiftOut ins Schieberegister geschrieben.

Ein paar Infos zum Aufbau - insbesondere zum Kaskadieren der Schieberegister- und ein einfaches Beispiel mit ShiftOut (allerdings ohne bitSet() und BitClear() ) findest Du auch hier: http://cboden.de/mikro-controller/grundl...schieberegister

Im Gegensatz zur SPI-Methode hat ShiftOut den Vorteil, dass man auch mehrere Schieberegister-Gruppen unabhängig von einander an je zwei beliebigen Pins des Arduino betreiben kann. Man muss ShiftOut nur die entsprechenden Pins mit übergeben. Das hätte den Vorteil, dass man gerade bei sehr vielen Schieberegistern nicht immer alle Werte bis zum letzten Register durchschieben muss sondern halt immer nur für die einzelne Gruppe.


mgcss

RE: Arduino Weichenpult - Sketch korrektur

#9 von MicroBahner , 26.09.2015 14:56

Hallo,
es gibt immer viele Wege nach Rom - und beim Programmieren wahrscheinlich noch ein paar mehr

Nachteil des ShiftOut ist halt, dass es nur immer einzelne Bytes schieben kann. Die SPI-Library erlaubt auch ein ganzes Array in einem Rutsch rauszuschieben. Ausserdem ist SPI viel schneller. In der Zeit, in der ShiftOut ein einziges Bit! schiebt, sind über SPI bei vollem Tempo seine ganzen 96 Bits draussen. Das relativiert den Vorteil mit den mehreren Gruppen - die ja auch verwaltet werden wollen - wieder etwas. Wobei die Zeiten insgesamt wohl eher nicht in einem kritischen Bereich liegen.
Allerdings erwartet SPI beim gleichzeitigen raus- und reinschieben eben gleich viele Bits fürs Empfangen wie fürs Senden. Das ist hier ja nicht gegeben, da müsste man 'dummy-Register' einbauen oder auf 2x schieben, was ja auch nicht so toll ist .

Vielleicht fürs Senden SPI und fürs Lesen (was ja weniger Bits sind) ShiftIn() ?? Die Bitmanipulationen braucht er in jedem Fall.

Letzendlich muss Peter entscheiden. Wie gesagt - es gibt viele Wege.....


viele Grüße
Franz-Peter
Ein 'elektromechanisches' Stellwerk
Der (ehemalige) 'Eisberg'


 
MicroBahner
Metropolitan (MET)
Beiträge: 2.833
Registriert am: 28.11.2012
Ort: Mittelfranken
Gleise Tillig Elite
Steuerung Eigenbau
Stromart Analog


RE: Arduino Weichenpult - Sketch korrektur

#10 von Bodo , 26.09.2015 16:52

Hallo,

für meine Beleuchtungssteuerung habe ich 10 Schieberegister (also 80 Ports) bereits erfolgreich getestet. Ich sehe auch keinen Grund, warum es nicht auch mit mehr funktionieren sollte (s.a. http://moba.noethlich.info/?page_id=297 ).

In meinen Programmen habe ich das so realisiert, dass in der Loop die Bytes pro Schieberegister als Funktionsaufruf berechnet werden und dann als "Paket" über die Funktion shiftoutLEDs() ausgegeben werden (das Byte für das letzte Schieberegister zuerst, das für das erste zuletzt).

1
2
3
4
5
6
7
8
9
10
11
12
 
void loop()  {
potVal_0 = analogRead(potPin_0); // Auslesen Sensor-Eingang 0
potVal_1 = analogRead(potPin_1); // Auslesen Sensor-Eingang 1

shiftVal_A = SegmentAnzeige(potVal_0); // Unterprogramm Segementanzeige für Schieberegister A
shiftVal_B = SegmentAnzeige(potVal_1); // Unterprogramm Segementanzeige für Schieberegister B
shiftVal_C = Lauflicht8x1(200); // Unterprogramm Lauflicht für Schieberegister C

...

shiftoutLEDs(); // Unterprogramm zur Ausgabe der Daten an die Schieberegister
 
 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 
void shiftoutLEDs() {
// nur falls Änderung seit letztem Schreibvorgang ...
if(shiftVal_A != preVal_A || shiftVal_B != preVal_B || shiftVal_C != preVal_C || shiftVal_D != preVal_D ||
shiftVal_E != preVal_E || shiftVal_F != preVal_F || shiftVal_G != preVal_G || shiftVal_H != preVal_H) {
digitalWrite(latchPin, LOW); // latchPin LOW so LEDs don't change while sending data
shiftOut(dataPin, clockPin, MSBFIRST, shiftVal_H); // Ausgabe der Bits für Schieberegister H
shiftOut(dataPin, clockPin, MSBFIRST, shiftVal_G); // Ausgabe der Bits für Schieberegister G
shiftOut(dataPin, clockPin, MSBFIRST, shiftVal_F); // Ausgabe der Bits für Schieberegister F
shiftOut(dataPin, clockPin, MSBFIRST, shiftVal_E); // Ausgabe der Bits für Schieberegister E
shiftOut(dataPin, clockPin, MSBFIRST, shiftVal_D); // Ausgabe der Bits für Schieberegister D
shiftOut(dataPin, clockPin, MSBFIRST, shiftVal_C); // Ausgabe der Bits für Schieberegister C
shiftOut(dataPin, clockPin, MSBFIRST, shiftVal_B); // Ausgabe der Bits für Schieberegister B
shiftOut(dataPin, clockPin, MSBFIRST, shiftVal_A); // Ausgabe der Bits für Schieberegister A
digitalWrite(latchPin, HIGH); // latchPin HIGH so LEDs will light up
preVal_H = shiftVal_H; // Sichern des aktuellen Werts für Schieberegister H
preVal_G = shiftVal_G; // Sichern des aktuellen Werts für Schieberegister G
preVal_F = shiftVal_F; // Sichern des aktuellen Werts für Schieberegister F
preVal_E = shiftVal_E; // Sichern des aktuellen Werts für Schieberegister E
preVal_D = shiftVal_D; // Sichern des aktuellen Werts für Schieberegister D
preVal_C = shiftVal_C; // Sichern des aktuellen Werts für Schieberegister C
preVal_B = shiftVal_B; // Sichern des aktuellen Werts für Schieberegister B
preVal_A = shiftVal_A; // Sichern des aktuellen Werts für Schieberegister A
}
}
 
 



Die Funktionen bitSet() und bitClear() erlauben die einfache Manipulation eines einzelnen Bits in dem betreffenden Byte.

Mit der Eingabe über Schieberegister (x165) habe ich mich bisher nicht näher beschäftigt.

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


 
Bodo
InterCityExpress (ICE)
Beiträge: 2.471
Registriert am: 28.04.2005
Homepage: Link
Gleise C-Gleis, Lenz 0
Spurweite H0, 0
Steuerung MS2 & CS2
Stromart Digital


RE: Arduino Weichenpult - Sketch korrektur

#11 von spielbahn ( gelöscht ) , 26.09.2015 22:11

Es geht auch ganz elementar ohne shiftout und ohne Bitmanipulationen. Auf Wunsch dazu mehr.
Aber: das Ganze wird ein ordentlicher Drahtverhau...
Wäre es da nicht sinnvoller, über Digitalisierung nachzudenken?


spielbahn

RE: Arduino Weichenpult - Sketch korrektur

#12 von Der Ruinenbaumeister , 27.09.2015 09:26

Wenig Drahtverhau hätte man mit Kippschaltern und Kondensatoren. Ist natürlich ganz weit weg vom ursprünglichen Plan, aber es erfüllt die gleichen Funktionen: Weichenbedienung, auch ohne Endabschaltung kein Durchbrennen der Spulen, letzter Stellbefehl wird angezeigt.





Mit mehrpoligen Kippschaltern kann man auch nebenher Herzstücke polarisieren, Kontroll-LEDs schalten etc. Nur einen Arduino braucht man dann nicht.


Gruß
Clemens

Mein Blog.


 
Der Ruinenbaumeister
EuroCity (EC)
Beiträge: 1.191
Registriert am: 01.04.2011


RE: Arduino Weichenpult - Sketch korrektur

#13 von Bettbahner ( gelöscht ) , 28.09.2015 00:55

Ein herzliches Hallo an alle und einen guten Start in die neue Woche,

@Franz-Peter

Zitat von MicroBahner
Nachteil des ShiftOut ist halt, dass es nur immer einzelne Bytes schieben kann. Die SPI-Library erlaubt auch ein ganzes Array in einem Rutsch rauszuschieben. Ausserdem ist SPI viel schneller. In der Zeit, in der ShiftOut ein einziges Bit! schiebt, sind über SPI bei vollem Tempo seine ganzen 96 Bits draussen.


Vielen Dank für die Erläuterung

Zitat von MicroBahner
Allerdings erwartet SPI beim gleichzeitigen raus- und reinschieben eben gleich viele Bits fürs Empfangen wie fürs Senden. Das ist hier ja nicht gegeben, da müsste man 'dummy-Register' einbauen oder auf 2x schieben, was ja auch nicht so toll ist .


Die von dir erwähnten dummy-Register brauche ich die auch wenn ich über SPI nur sende?
[code="MicroBahner"]es gibt viele Wege.....[/code]
Das merke ich langsam auch das es komplizierter wird als ich dachte, aber ich hab ja Zeit es muss nicht sofort fertig sein und wird es wohl auch nicht.

@Günther

Zitat von mgcss
Die Programmierung mit ShiftOut ist super einfach - allerdings braucht man dann noch die Funktionen zum setzen und Löschen einzelner Bits (bitSet() und bitClear() ). Als Variablen zum Speichern der Werte nimmst Du in dem Fall also statt des Bit-Arrays ganze Byte Werte und setzt die einzelnen Bits mit bitSet() und bitClear(). Anschließend werden die Bytes dann mit shiftOut ins Schieberegister geschrieben.


Könntest du mir erklären was du meinst mit ganzen Byte werten anstelle von dem Bit-Array :
Ich glaube deswegen wird auch an meinem Code (Siehe unten) vom Kompiler gemeckert(siehe weiter unten).
Dein Link hat mir sehr geholfen insbesondere das Code Beispiel. Ich finde es einfacher neue (für mich neu) Befehle (ist das der richtige Begriff für Shiftout etc?) anhand eines Beispiels zu lernen und zu verstehen, davon gerne mehr wenn du noch Nützliche Links hast.

Nach einem stressigen Wochenende (Freundin hatte frei, Gartenarbeit und die Leber wollte auch mal wieder belastet werden ) bin ich in der letzten Stunde dazu gekommen einen Code zu schreiben bei dem der Kompiler meckert leider bisher ohne der ISP schnittstelle, die sich sehr interessant anhört

Zitat von MicroBahner
Nachteil des ShiftOut ist halt, dass es nur immer einzelne Bytes schieben kann. Die SPI-Library erlaubt auch ein ganzes Array in einem Rutsch rauszuschieben. Ausserdem ist SPI viel schneller. In der Zeit, in der ShiftOut ein einziges Bit! schiebt, sind über SPI bei vollem Tempo seine ganzen 96 Bits draussen.



@Bodo
Vielen Dankk für das posten deines Codes. Er sieht interessant aus und so ganz anders wie meiner. Naja deiner Funktionert und meiner noch nicht :/
Eine Frage habe ich aber dazu in der loop, wird durch

Zitat von Bodo
potVal_0 = analogRead(potPin_0);

ein Wert zwischen 0 und 255 als potVal_0 bezeichnet, der dann später

Zitat von Bodo
shiftVal_A = SegmentAnzeige(potVal_0);

irgendwas mit der Segmentanzeige macht und als shiftVal_A umbenannt wird. Dieses shiftVal_A wird dann später an die Schieberegister übergeben. Wir verhält sich währenddessen der eingelesene Wert von dem Poti, weil der ja zwischen 0 und 255 liegen kann und die 0 entspricht einem LOW also Segmentanzeige zeigt nichts an und 1=HIGH die Segementanzeige zeigt etwas an was ist mit den Werten >1, also einer 128 oder einer 12?
Vielleicht ein dämliche Frage, aber mit Potis habe ich bisher nichts gemacht.

Deiner Website gefällt mir sehr gut, werde ich mir nach dem schlafen mal genauers ansehen.

@Uli

Zitat von spielbahn
ordentlicher Drahtverhau...


Das will ich gerade vermeiden zu produzieren und dann an meiner Modellbahn zu haben. Aber wenn du Lust und die Zeit hast kannst du es mir bitte erläutern wie die alternative aussehen könnte :
[quote="spielbahn]Wäre es da nicht sinnvoller, über Digitalisierung nachzudenken?[/quote]
Ich weiß nicht ob das vom Verdratungsaufwand weniger ist wie ein Arduino mit Schieberegistern auf Leiterplatten die ich mir von einem Kumpel fräsen lassen werde. Und vom Kostenpunkt betrachtet hatte mich die Digitalisierung bisher eher abgeschreckt wie begeistert :/ (http://www.conrad.de/ce/de/product/24855...0150927223730:s ein jeder dieser Decoder würde 4 Weichen steuern bedeutet ich würde Minimum 6 von diesen brauchen weil ich 24 Weichen habe. Folglich würden Kosten von über 140€ entstehen und ich hätte noch nichts mit dem ich die ansteuern kann, da finde ich die alternative mit dem Arduino momentan noch ansprechender.)

@Clemens
Diese Art der Verdrahtung ist für mich neu. Werde ich mir mal zum Merken aufschreiben.

@Alle
Vielen Dank für die vielen Kommentare in so kurzer Zeit.
Hoffentlich bleibt das so

Im Folgenden der Code:
Zu Begin die Definition des Arrays sowie der Ports des µC.

In void Loop wird in meinem Code jeder Taster nach einander abgefragt, wen einer der Taster gedrückt ist und erkannt wurde, wird durch bitWrite das jeweilige Bit im Array auf HIGH gesetzt.
In der Funktion Fuellenw wird mittels shiftout das Array in das Schieberegister verschoben (soweit die Theorie, hier meckert der Kompiler). Nach dem Füllen wird 250ms das HIGH im Schieberegister gelassen, damit der Weichenantrieb schalten kann, danach wird dieses wieder aus LOW gesetzt mittels der Funktion Leerenw. Die beiden digitalWrite mit LED1 und LED2 sind bitte vorerst zu Ignorieren sie dienen mir Gedanklich als Platzhalter für den Platz des zweiten Schieberegisters für die LED Rückmeldung.

(Falls nach der Datei verlangt wird werde ich sie Hochladen und zum download freigeben.)

[code]/* Peters Versuch Nummer 1
*
*/

//Muster für die Ausgabe
byte Arrayweiche[] = {0,0,0,0,0,0,0,0} ; //Variable geändert durch Taster von LOW auf HIGH
//byte ArrayLED[] = {0,0,0,0,0,0,0,0};
/*
* Arrayweiche von links betrachtet
* Stelle 1 = Weiche 1 Gerade aus
* Stelle 2 = Weiche 1 abbiegen
* Stelle 3 = Weiche 2 Gerade aus
* Stelle 4 = Weiche 2 abbiegen
* Stelle 5 = Weiche 3 Gerade aus
* Stelle 6 = Weiche 3 abbiegen
* Stelle 7 = Weiche 4 Gerade aus
* Stelle 8 = Weiche 4 abbiegen
*/


//Taster
int TST1=9; //Gerade aus Weiche 1
int TST2=10; //abbiegen von Weiche 1


//LED
int LED1=2; //Rueckmeldung 1 noch ohne Schieberegister
int LED2=3; //Rueckmeldung 2 noch ohne Schieberegister

//Schieberegister Weichenantrieb
int shiftPinw = 4; //Pin verbunden mit SH_CP des 74HC595 (clockpin)
int storePinw = 3; //Pin verbunden mit ST_CP des 74HC595 (latchpin)
int dataPinw = 2; //Pin verbunden mit DS des 74HC595 (datapin)
//Schieberegister LED Rückeldung
int shiftPinl = 7; //Pin verbunden mit SH_CP des 74HC595
int storePinl = 6; //Pin verbunden mit ST_CP des 74HC595
int dataPinl = 5; //Pin verbunden mit DS des 74HC595

void setup() {


//Taster definition mit internen Pull Up
//TST1
pinMode(TST1,INPUT);
digitalWrite(TST1,HIGH);

//TST2
pinMode(TST2,INPUT);
digitalWrite(TST2,HIGH);

//LED
pinMode(LED1,OUTPUT);
pinMode(LED2,OUTPUT);

//Schieberegister Weiche
pinMode(shiftPinw,OUTPUT);
pinMode(storePinw,OUTPUT);
pinMode(dataPinw,OUTPUT);

//Schieberegister LED
pinMode(shiftPinl,OUTPUT);
pinMode(storePinl,OUTPUT);
pinMode(dataPinl,OUTPUT);
}

void loop() {

//Taster 1 wird abgefragt und Funktion Taster 1 wird ausgeführt
if(!digitalRead(TST1)){
delay(50);
if(!digitalRead(TST1)){
bitWrite(Arrayweiche,7,HIGH); //Gerade aus von Weiche 1 auf HIGH Stellen, also bit 7, da von Links gezählt wird
Fuellenw(); // schreibt Variable in Schieberegister
delay(250); //Impuls zum schalten der Weiche
Leerenw(); // setzt alles auf LOW

digitalWrite(LED1,HIGH); //Rückmeldungs LED
digitalWrite(LED2,LOW); //Rückmeldungs LED
}
}

//Taster 2 wird abgefragt und Funktion Taster 2 wird ausgeführt
if(!digitalRead(TST2)){
delay(50);
if(!digitalRead(TST2)){
bitWrite(Arrayweiche,6,HIGH); //abbiegen von Weiche 1, also bit 6 da links gezählt
Fuellenw(); // schreibt Variable in Schieberegister
delay(250); //Impuls zum schalten der Weiche
Leerenw(); // setzt alles auf LOW

digitalWrite(LED1,LOW); //Rückmeldungs LED
digitalWrite(LED2,HIGH); //Rückmeldungs LED
}

}
//weitere Taster hier einfügen.
}

void Fuellenw() {
digitalWrite(storePinw,LOW);

shiftOut(dataPinw,shiftPinw,MSBFIRST,Arrayweiche); //shiftet von rechts nach links
digitalWrite(storePinw,HIGH);

}



void Leerenw() //setzt alles Variablen auf LOW, damit keine Dauerspannung an dem Weichenantrieb anliegt.
{
bitClear(Arrayweiche,0); //Setzt Bit 0 auf 0
bitClear(Arrayweiche,1);
bitClear(Arrayweiche,2);
bitClear(Arrayweiche,3);
bitClear(Arrayweiche,4);
bitClear(Arrayweiche,5);
bitClear(Arrayweiche,6);
bitClear(Arrayweiche,7);

digitalWrite(storePinw,LOW);

shiftOut(dataPinw,shiftPinw,MSBFIRST,Arrayweiche); //shiftet von rechts nach links
digitalWrite(storePinw,HIGH);

}

[/code]


Und das gemeckere vom Kompiler:
Vermutlich nur Anfänger Fehler oder irgendetwas total Falsch gemacht, hoffe Ihr könnt mich darauf hinweisen was es ist.
(Falls nach der Datei verlangt wird werde ich sie Hochladen und zum download freigeben.)


[code]Arduino: 1.6.5 (Windows 7), Platine: "Arduino/Genuino Uno"

In file included from _0_Programm_Modellbahn_Array.ino.ino:7:0:
_0_Programm_Modellbahn_Array.ino.ino: In function 'void loop()':
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:104:37: error: invalid operands of types 'byte [8] {aka unsigned char [8]}' and 'long unsigned int' to binary 'operator|'
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
^
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:106:52: note: in expansion of macro 'bitSet'
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
^
_0_Programm_Modellbahn_Array.ino.ino:73:6: note: in expansion of macro 'bitWrite'
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:104:37: error: in evaluation of 'operator|=(byte [8] {aka unsigned char [8]}, long unsigned int)'
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
^
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:106:52: note: in expansion of macro 'bitSet'
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
^
_0_Programm_Modellbahn_Array.ino.ino:73:6: note: in expansion of macro 'bitWrite'
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:105:39: error: invalid operands of types 'byte [8] {aka unsigned char [8]}' and 'long unsigned int' to binary 'operator&'
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
^
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:106:73: note: in expansion of macro 'bitClear'
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
^
_0_Programm_Modellbahn_Array.ino.ino:73:6: note: in expansion of macro 'bitWrite'
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:105:39: error: in evaluation of 'operator&=(byte [8] {aka unsigned char [8]}, long unsigned int)'
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
^
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:106:73: note: in expansion of macro 'bitClear'
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
^
_0_Programm_Modellbahn_Array.ino.ino:73:6: note: in expansion of macro 'bitWrite'
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:104:37: error: invalid operands of types 'byte [8] {aka unsigned char [8]}' and 'long unsigned int' to binary 'operator|'
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
^
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:106:52: note: in expansion of macro 'bitSet'
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
^
_0_Programm_Modellbahn_Array.ino.ino:87:5: note: in expansion of macro 'bitWrite'
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:104:37: error: in evaluation of 'operator|=(byte [8] {aka unsigned char [8]}, long unsigned int)'
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
^
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:106:52: note: in expansion of macro 'bitSet'
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
^
_0_Programm_Modellbahn_Array.ino.ino:87:5: note: in expansion of macro 'bitWrite'
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:105:39: error: invalid operands of types 'byte [8] {aka unsigned char [8]}' and 'long unsigned int' to binary 'operator&'
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
^
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:106:73: note: in expansion of macro 'bitClear'
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
^
_0_Programm_Modellbahn_Array.ino.ino:87:5: note: in expansion of macro 'bitWrite'
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:105:39: error: in evaluation of 'operator&=(byte [8] {aka unsigned char [8]}, long unsigned int)'
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
^
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:106:73: note: in expansion of macro 'bitClear'
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
^
_0_Programm_Modellbahn_Array.ino.ino:87:5: note: in expansion of macro 'bitWrite'
_0_Programm_Modellbahn_Array.ino.ino: In function 'void Fuellenw()':
_0_Programm_Modellbahn_Array.ino:103: error: invalid conversion from 'byte* {aka unsigned char*}' to 'uint8_t {aka unsigned char}' [-fpermissive]
In file included from _0_Programm_Modellbahn_Array.ino.ino:7:0:
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:139:6: error: initializing argument 4 of 'void shiftOut(uint8_t, uint8_t, uint8_t, uint8_t)' [-fpermissive]
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
^
_0_Programm_Modellbahn_Array.ino.ino: In function 'void Leerenw()':
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:105:39: error: invalid operands of types 'byte [8] {aka unsigned char [8]}' and 'long unsigned int' to binary 'operator&'
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
^
_0_Programm_Modellbahn_Array.ino.ino:112:3: note: in expansion of macro 'bitClear'
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:105:39: error: in evaluation of 'operator&=(byte [8] {aka unsigned char [8]}, long unsigned int)'
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
^
_0_Programm_Modellbahn_Array.ino.ino:112:3: note: in expansion of macro 'bitClear'
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:105:39: error: invalid operands of types 'byte [8] {aka unsigned char [8]}' and 'long unsigned int' to binary 'operator&'
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
^
_0_Programm_Modellbahn_Array.ino.ino:113:3: note: in expansion of macro 'bitClear'
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:105:39: error: in evaluation of 'operator&=(byte [8] {aka unsigned char [8]}, long unsigned int)'
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
^
_0_Programm_Modellbahn_Array.ino.ino:113:3: note: in expansion of macro 'bitClear'
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:105:39: error: invalid operands of types 'byte [8] {aka unsigned char [8]}' and 'long unsigned int' to binary 'operator&'
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
^
_0_Programm_Modellbahn_Array.ino.ino:114:3: note: in expansion of macro 'bitClear'
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:105:39: error: in evaluation of 'operator&=(byte [8] {aka unsigned char [8]}, long unsigned int)'
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
^
_0_Programm_Modellbahn_Array.ino.ino:114:3: note: in expansion of macro 'bitClear'
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:105:39: error: invalid operands of types 'byte [8] {aka unsigned char [8]}' and 'long unsigned int' to binary 'operator&'
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
^
_0_Programm_Modellbahn_Array.ino.ino:115:3: note: in expansion of macro 'bitClear'
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:105:39: error: in evaluation of 'operator&=(byte [8] {aka unsigned char [8]}, long unsigned int)'
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
^
_0_Programm_Modellbahn_Array.ino.ino:115:3: note: in expansion of macro 'bitClear'
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:105:39: error: invalid operands of types 'byte [8] {aka unsigned char [8]}' and 'long unsigned int' to binary 'operator&'
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
^
_0_Programm_Modellbahn_Array.ino.ino:116:3: note: in expansion of macro 'bitClear'
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:105:39: error: in evaluation of 'operator&=(byte [8] {aka unsigned char [8]}, long unsigned int)'
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
^
_0_Programm_Modellbahn_Array.ino.ino:116:3: note: in expansion of macro 'bitClear'
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:105:39: error: invalid operands of types 'byte [8] {aka unsigned char [8]}' and 'long unsigned int' to binary 'operator&'
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
^
_0_Programm_Modellbahn_Array.ino.ino:117:3: note: in expansion of macro 'bitClear'
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:105:39: error: in evaluation of 'operator&=(byte [8] {aka unsigned char [8]}, long unsigned int)'
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
^
_0_Programm_Modellbahn_Array.ino.ino:117:3: note: in expansion of macro 'bitClear'
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:105:39: error: invalid operands of types 'byte [8] {aka unsigned char [8]}' and 'long unsigned int' to binary 'operator&'
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
^
_0_Programm_Modellbahn_Array.ino.ino:118:3: note: in expansion of macro 'bitClear'
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:105:39: error: in evaluation of 'operator&=(byte [8] {aka unsigned char [8]}, long unsigned int)'
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
^
_0_Programm_Modellbahn_Array.ino.ino:118:3: note: in expansion of macro 'bitClear'
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:105:39: error: invalid operands of types 'byte [8] {aka unsigned char [8]}' and 'long unsigned int' to binary 'operator&'
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
^
_0_Programm_Modellbahn_Array.ino.ino:119:3: note: in expansion of macro 'bitClear'
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:105:39: error: in evaluation of 'operator&=(byte [8] {aka unsigned char [8]}, long unsigned int)'
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
^
_0_Programm_Modellbahn_Array.ino.ino:119:3: note: in expansion of macro 'bitClear'
_0_Programm_Modellbahn_Array.ino:123: error: invalid conversion from 'byte* {aka unsigned char*}' to 'uint8_t {aka unsigned char}' [-fpermissive]
In file included from _0_Programm_Modellbahn_Array.ino.ino:7:0:
C:Program Files (x86)Arduinohardwarearduinoavrcoresarduino/Arduino.h:139:6: error: initializing argument 4 of 'void shiftOut(uint8_t, uint8_t, uint8_t, uint8_t)' [-fpermissive]
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
^
invalid conversion from 'byte* {aka unsigned char*}' to 'uint8_t {aka unsigned char}' [-fpermissive][/code]


Freue mich schon auf die nächsten Antworten!


Bettbahner

RE: Arduino Weichenpult - Sketch korrektur

#14 von MicroBahner , 28.09.2015 10:04

Hallo Peter,

Zitat von Bettbahner
Die von dir erwähnten dummy-Register brauche ich die auch wenn ich über SPI nur sende?

Nein, dann ignorierst Du die empfangenen Daten einfach. Ich hab's mir auch nochmal genauer durchgelesen: solange Du mehr rausschiebst wie einliest ( das ist bei dir ja gegeben ), brauchst Du gar keine Dummy-Register.

Zu deinem Sketch und den Fehlermeldungen: Wie Du selbst ja schon vermutet hast, verwechselst Du Bits und Bytes noch ein bisschen . Hier:

1
2
 
byte Arrayweiche[] = {0,0,0,0,0,0,0,0} ; //Variable ge&#228;ndert durch Taster von LOW auf HIGH
 
 

definierst Du ein Array aus 8 Bytes. Jedes Byte beinhaltet 8 Bits. Was Du da festlegst, sind also insgesamt 64 Bits, gruppiert in 8 Bytes. Was du dann kommentierst:

1
2
3
4
5
6
7
8
9
10
 
 * Arrayweiche von links betrachtet
* Stelle 1 = Weiche 1 Gerade aus
* Stelle 2 = Weiche 1 abbiegen
* Stelle 3 = Weiche 2 Gerade aus
* Stelle 4 = Weiche 2 abbiegen
* Stelle 5 = Weiche 3 Gerade aus
* Stelle 6 = Weiche 3 abbiegen
* Stelle 7 = Weiche 4 Gerade aus
* Stelle 8 = Weiche 4 abbiegen
 
 

wäre also nicht der Inhalt des ganzen Arrays, sondern der Inhalt des ersten Bytes des Arrays.

In dieser Zeile:

1
 
     bitWrite(Arrayweiche,7,HIGH); //Gerade aus von Weiche 1 auf HIGH Stellen, also bit 7, da von Links gez&#228;hlt wird
 

adressierst Du das gesamte Byte-Array 'Arrayweiche'. Das versteht der Befehl 'bitWrite' aber nicht, der will ein einzelnes Byte, in dem er dann die Bits manipulieren kann. Das gilt für alle bit-Befehle in deinem Sketch. Wenn Du in deinem Programm überall da, wo du 'Arrayweiche' angegeben hast, 'Arrayweiche[0]' einsetzt, kompiliert es fehlerfrei. Du manipulierst dann die Bits im ersten Byte des Bytearrays 'Arrayweiche'.


P.S. noch ein kleiner Tip: Wenn Du die Pinnummern festlegst:

1
2
 
int shiftPinw = 4; //Pin verbunden mit SH_CP des 74HC595 (clockpin)
 
 

ist das so zwar nicht falsch, aber besser ist es, das so zu machen:

1
2
 
const byte shiftPinw = 4; //Pin verbunden mit SH_CP des 74HC595 (clockpin)
 
 

Zum einen ist ein 'int' für die Portnummern Verschwendung, die passen auch in ein Byte (ok, ist nicht schlimm solange genug Platz im Ram ist ... ). Zum anderen ist es ein guter Hinweis an den Compiler, wenn man Werte, die sich im Programm nicht ändern, mit dem Schlüsselwort 'const' kennzeichnet. Er kann dann besseren Code erzeugen, belegt dafür gar kein Ram und erzeugt auch einen Fehler, fals man versehentlich den Wert doch verändert.

P.P.S. noch ein Tip (hoffentlich nerv ich nicht zu sehr ):
Den Pull-Up Widerstand bei einem INPUT kannst Du in der IDE 1.6 auch direkt einschalten. Statt

1
2
 
pinMode(TST1,INPUT);
digitalWrite(TST1,HIGH);
 

kannst Du schreiben:

1
 
pinMode(TST1,INPUT_PULLUP);
 


viele Grüße
Franz-Peter
Ein 'elektromechanisches' Stellwerk
Der (ehemalige) 'Eisberg'


 
MicroBahner
Metropolitan (MET)
Beiträge: 2.833
Registriert am: 28.11.2012
Ort: Mittelfranken
Gleise Tillig Elite
Steuerung Eigenbau
Stromart Analog


RE: Arduino Weichenpult - Sketch korrektur

#15 von Bettbahner ( gelöscht ) , 28.09.2015 11:22

Hallo Franz-Peter,

Die Fehlermeldungen sind jetzt behoben.
Und das mit den Bits und Bytes ist mir jetzt klarer wie davor, ich dachte ich definiere 8 Bits anstelle von 8 Bytes.

Eine Frage noch zu der Festlegung von Pinnummern. Kann man alle Festlegungen von Pinnummern über dieses 'const' präfix festlegen? Und bei den LEDs und Tastern verwende ich momentan auch ein 'int' wo liegt da der Unterschied wenn ich diese durch ein 'const byte' ersetze? (Hab ich im aktuellen Code mal gemacht, weil weniger Speicher verbrauch ist ja eigentlich immer was gutes und besserer Code noch besser )


Mit Tipps nervt man nicht also immer her mit diesen Tipps Ich werde sie beherzigen.
Wenn man den Pullup direkt im pinMode aktiviert sieht es aufjedenfall deutlich eleganter aus und leicht verständlich ist es auch.
Vielen Dank für diesen Tipp!

Hier noch mein Aktueller Code, noch ohne SPI Kommunikation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
 
/* Peters Versuch Nummer 1
*
*/
 
//Muster f&#252;r die Ausgabe
byte Arrayweiche[] = {0, //Weiche 1-4
/*
* Gilt f&#252;r die erste Null, da diese 8Bit "gro&#223;" ist
* Arrayweiche von links betrachtet
* Stelle 1 = Weiche 1 Gerade aus
* Stelle 2 = Weiche 1 abbiegen
* Stelle 3 = Weiche 2 Gerade aus
* Stelle 4 = Weiche 2 abbiegen
* Stelle 5 = Weiche 3 Gerade aus
* Stelle 6 = Weiche 3 abbiegen
* Stelle 7 = Weiche 4 Gerade aus
* Stelle 8 = Weiche 4 abbiegen
* Innerhalb dieses Bytes wird der Taster von LOW auf HIGH stellen
*/
0, //8Bit Weiche 5-8
0, //8Bit Weiche 9-12
0, //8Bit Weiche 13-16
0, //8Bit Weiche 17-20
0,} ; //8Bit Weiche 21-24
//byte ArrayLED[] = {0,0,0,0,0,0,0,0};
 

//Taster
const byte TST1=9; //Gerade aus Weiche 1
const byte TST2=10; //abbiegen von Weiche 1
 

//LED
const byte LED1=2; //Rueckmeldung 1 noch ohne Schieberegister
const byte LED2=3; //Rueckmeldung 2 noch ohne Schieberegister
 
//Schieberegister Weichenantrieb
const byte shiftPinw = 4; //Pin verbunden mit SH_CP des 74HC595 (clockpin)
const byte storePinw = 3; //Pin verbunden mit ST_CP des 74HC595 (latchpin)
const byte dataPinw = 2; //Pin verbunden mit DS des 74HC595 (datapin)
//Schieberegister LED R&#252;ckeldung
const byte shiftPinl = 7; //Pin verbunden mit SH_CP des 74HC595
const byte storePinl = 6; //Pin verbunden mit ST_CP des 74HC595
const byte dataPinl = 5; //Pin verbunden mit DS des 74HC595
 
void setup() {
 

//Taster definition mit internen Pull Up
//TST1
pinMode(TST1,INPUT_PULLUP);
//digitalWrite(TST1,HIGH); &#252;berfl&#252;ssig, weil Pullup wird schon in pinmode aktiviert.
 
//TST2
pinMode(TST2,INPUT_PULLUP);
//digitalWrite(TST2,HIGH); &#252;berfl&#252;ssig, weil Pullup wird schon in pinmode aktiviert.
 

//LED
pinMode(LED1,OUTPUT);
pinMode(LED2,OUTPUT);
 
//Schieberegister Weiche
pinMode(shiftPinw,OUTPUT);
pinMode(storePinw,OUTPUT);
pinMode(dataPinw,OUTPUT);
 
//Schieberegister LED
pinMode(shiftPinl,OUTPUT);
pinMode(storePinl,OUTPUT);
pinMode(dataPinl,OUTPUT);
}
 
void loop() {
 
//Taster 1 wird abgefragt und Funktion Taster 1 wird ausgef&#252;hrt
if(!digitalRead(TST1)){
delay(50);
if(!digitalRead(TST1)){
bitWrite(Arrayweiche[0],7,HIGH); //Gerade aus von Weiche 1 auf HIGH Stellen, also bit 7, da von Links gez&#228;hlt wird
Fuellenw(); // schreibt Variable in Schieberegister
//delay(250); //Impuls zum schalten der Weiche
delay(1000); //zum testen auf 1000ms erh&#246;ht
Leerenw(); // setzt alles auf LOW

digitalWrite(LED1,HIGH); //R&#252;ckmeldungs LED
digitalWrite(LED2,LOW); //R&#252;ckmeldungs LED
}
}
 
//Taster 2 wird abgefragt und Funktion Taster 2 wird ausgef&#252;hrt
if(!digitalRead(TST2)){
delay(50);
if(!digitalRead(TST2)){
bitWrite(Arrayweiche[0],6,HIGH); //abbiegen von Weiche 1, also bit 6 da links gez&#228;hlt
Fuellenw(); // schreibt Variable in Schieberegister
// delay(250); //Impuls zum schalten der Weiche
delay(1000); //zum testen des sketches wird auf 1000ms erh&#246;ht
Leerenw(); // setzt alles auf LOW
 
digitalWrite(LED1,LOW); //R&#252;ckmeldungs LED
digitalWrite(LED2,HIGH); //R&#252;ckmeldungs LED
}
 
}
//weitere Taster hier einf&#252;gen.
}
 
void Fuellenw() {
digitalWrite(storePinw,LOW);
 
shiftOut(dataPinw,shiftPinw,MSBFIRST,Arrayweiche[0]); //shiftet von rechts nach links
digitalWrite(storePinw,HIGH);

}
 

 
void Leerenw() //setzt alles Variablen auf LOW, damit keine Dauerspannung an dem Weichenantrieb anliegt.
{
bitClear(Arrayweiche[0],0); //Setzt Bit 0 auf 0
bitClear(Arrayweiche[0],1);
bitClear(Arrayweiche[0],2);
bitClear(Arrayweiche[0],3);
bitClear(Arrayweiche[0],4);
bitClear(Arrayweiche[0],5);
bitClear(Arrayweiche[0],6);
bitClear(Arrayweiche[0],7);
 
digitalWrite(storePinw,LOW);
 
shiftOut(dataPinw,shiftPinw,MSBFIRST,Arrayweiche[0]); //shiftet von rechts nach links
digitalWrite(storePinw,HIGH);

}
 

 


Bettbahner

RE: Arduino Weichenpult - Sketch korrektur

#16 von Der Ruinenbaumeister , 28.09.2015 18:11

Zitat von Bettbahner
@Clemens
Diese Art der Verdrahtung ist für mich neu. Werde ich mir mal zum Merken aufschreiben.



Ich habe dazu mal einen Artikel geschrieben: http://mobatechnikblog.blogspot.com/2015...-schaltern.html

Da findest du auch die restlichen Infos, die für einen Nachbau nötig sind.


Gruß
Clemens

Mein Blog.


 
Der Ruinenbaumeister
EuroCity (EC)
Beiträge: 1.191
Registriert am: 01.04.2011


RE: Arduino Weichenpult - Sketch korrektur

#17 von Bettbahner ( gelöscht ) , 28.09.2015 18:32

Hallo,

@Clemens vielen Dank für den Link!

Ein Bild meiner Momentanen Testschaltung:




Die kleinen Steckbretter Links sollen die Rückmelde LEDs sein und die zwei großen Steckbretter sind die LEDs welche momentan noch die Weichenantriebe simulieren.

So viel von mir Heute, morgen geht es weiter mit einem neuen Sketch, aber der muss noch fertig geschrieben werden.


Bettbahner

RE: Arduino Weichenpult - Sketch korrektur

#18 von spielbahn ( gelöscht ) , 28.09.2015 19:52

Hallo!
Eigentlich soll man einen Einsteiger nicht daran hindern, seine eigenen Erfahrungen und Fehler zu machen: So lernt man recht effektiv.
Deshalb möchte ich auch nicht zu sehr ins Detail gehen.
Zum Aufwand:
Für die RückmeldeLEDs reicht die Hälfte der Ausgänge, d.h. pro Weiche ist nur ein Ausgang nötig. Entweder leuchtet die eine oder die andere LED. Wie auf dem Steckbrett zu sehen, sind den Schieberegistern Treiberbausteine nachgeschaltet, mit einem weiteren Transistor kann dann die komplementäre LED angesteuert werden.
Ob die Treiberbausteine dann auch für den Weichenantrieb ausreichen, hängt von den Weichen ab, evtl. sind auch hier Treibertransistoren nötig.
Bei 24 Weichen wird der Aufwand an ICs schon recht hoch, da könnte man auch an einen Arduino-Mega denken, der hat 70 Ein-Ausgänge, davon können 16 als Analogeingänge benutzt werden. Werden die 48 Weichentaster über Schieberegister eingelesen, sind 48 Pullup-Widerstände nötig. Ein Analogeingang kann über eine Widerstandsleiter locker vier Taster einlesen, das wären dann 12 Analogeingänge. Der Aufwand an Widerständen für die Widerstandsleiter ist auch nicht größer als für die Pullups, aber man braucht keine Schieberegister. Damit sind noch 58 Ports des Arduino-Mega frei. Davon könnte man 24 für die LED-Anzeige verwenden (Treiber entfallen dann, da der Arduino eine LED direkt treiben kann) oder gleich 48, dann benötigt man keine Transistortreiber für die komplementäre LED. Die restlichen 8 Ports reichen für die 6 Schieberegister zum Schalten der Weichen.
Wobei ich hier nochmal auf den Verkabelungsaufwand hinweisen möchte: Es müssen sämtlich Leitungen der Weichen bis zu den Treibern an den Schieberegistern geführt werden - ziemlich viel Kabelsalat.
Denkt man an eine digitale Steuerung zum Schalten, würde nur der Bus auf die Platte führen, dort würden nahe an den Weichen die Schaltdekoder sitzen, die Kabel zu den Weichen wären kurz.
Zum finanziellen Aufwand:
Man benötigt eine (kleine) Zentrale, die Schaltdekoder können selbst aus Arduinos (genauer: nur den AVRs) hergestellt werden. Ich persönlich habe nur Erfahrung mit dem Selbstbau einer Selectrix-Anlage. Hier benötigt man eine Zentrale (Ich würde die FCC von MTTM für ca. 150 EUR empfehlen - die ist zukunftssicher, falls man doch mal mehr will...) und einige AVRs (Stückpreis mit Bootloader für die Arduinoumgebung ca. 3 EUR). Eine Lib für SX ist vorhanden. Bei dieser Lösung würde man gar keine Schieberegister benötigen, da die Infos über den SX-Bus laufen und die selbstgebauten Dekoder (für eine Weiche würde schon ein AVR-Tiny reichen) ortsnah die Weichen schalten. Dieses System ließe sich später problemslos auf Rückmelder, auf Schalten von beliebigen Artikel und Signalen usw. erweitern. Falls man irgendwann doch noch digital fahren möchte aber SX nicht mag, kann die FCC weitere Protokolle, z.B. auch DCC.
Nebenbei hat sie noch einen recht schnellen USB-Port, falls man doch mal einen PC anschließen möchte. Die Wünsche werden wachsen....
Den Arduino-Uno kann man dann immer noch gebrauchen: nämlich als Programmer für die AVRs. Dies wäre dann eine Lösung ganz ohne Schieberegister.


spielbahn

RE: Arduino Weichenpult - Sketch korrektur

#19 von MicroBahner , 28.09.2015 21:53

Hallo Peter,

Zitat von Bettbahner
ich dachte ich definiere 8 Bits anstelle von 8 Bytes.

Du definierst halt immer genau das, was Du auch davorschreibst :

Zitat von Bettbahner
byte Arrayweiche[] =



Zitat von Bettbahner
Kann man alle Festlegungen von Pinnummern über dieses 'const' präfix festlegen?

Du kannst den 'const' Präfix immer verwenden, wenn du bei einer Variablendefinition einen Startwert zuweist, und Du sicher bist, dass sich dieser Wert im Programmablauf nie verändern wird.
Mit

1
 
int LED1 = 2
 

definierst Du zunächst mal einfach eine Variable und ordnest ihr den Anfangswert 2 zu. In dem Fall geht der Compiler davon aus, dass 2 zwar der Anfangswert ist, sich der Wert im Laufe des Programmablaufes aber noch ändern kann. Schreibst Du nun ein 'const' davor

1
 
const int LED1 = 2
 

, geht der Compiler davon aus, dass sich dieser Wert nie ändert. Wenn Du nun z.B.

1
 
pinMode( LED1, OUTPUT );
 

schreibst, erzeugt der Compiler den gleichen Code als wenn Du gleich

1
 
pinMode( 2, OUTPUT );
 

geschrieben hättest. Ohne const würde der Wert tatsächlich jedes Mal aus dem RAM-Speicher gelesen.
Da für mit 'const' definierte Werte auch kein Speicherplatz belegt wird, ist es da eigentlich auch egal, ob du 'byte', 'int' oder gar 'long' nimmst.

Übrigends - noch ein Tipp . Wenn Du alle Bits zurücksetzen willst

1
2
3
4
5
6
7
8
9
10
11
 
void Leerenw() //setzt alles Variablen auf LOW, damit keine Dauerspannung an dem Weichenantrieb anliegt.
{
bitClear(Arrayweiche[0],0); //Setzt Bit 0 auf 0
bitClear(Arrayweiche[0],1);
bitClear(Arrayweiche[0],2);
bitClear(Arrayweiche[0],3);
bitClear(Arrayweiche[0],4);
bitClear(Arrayweiche[0],5);
bitClear(Arrayweiche[0],6);
bitClear(Arrayweiche[0],7);
 
 

Kannst Du dann natürlich auch einfach das Byte zu 0 setzen

1
2
3
4
 
void Leerenw() //setzt alles Variablen auf LOW, damit keine Dauerspannung an dem Weichenantrieb anliegt.
{
Arrayweiche[0]=0; //Setzt alle Bits auf 0
 
 



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

Zitat von spielbahn
Für die RückmeldeLEDs reicht die Hälfte der Ausgänge, d.h. pro Weiche ist nur ein Ausgang nötig. Entweder leuchtet die eine oder die andere LED. Wie auf dem Steckbrett zu sehen, sind den Schieberegistern Treiberbausteine nachgeschaltet, mit einem weiteren Transistor kann dann die komplementäre LED angesteuert werden.

Wenn man lowCurrent (2mA) Leds verwendet geht es sogar noch sparsamer, die kann der HC595 mit seinen symmetrischen Bufferausgängen nämlich direkt treiben. Eine LED gegen Gnd so anschliessen, so dass sie bei HIGH am Ausgang leuchtet, die andere gegen +5V, so dass sie bei LOW leuchtet. Dann braucht man noch nichtmal einen Transistor.

Zitat von spielbahn
Wobei ich hier nochmal auf den Verkabelungsaufwand hinweisen möchte: Es müssen sämtlich Leitungen der Weichen bis zu den Treibern an den Schieberegistern geführt werden - ziemlich viel Kabelsalat.

Man kann natürlich auch die Schieberegister an die Weichen führen . Der im Digitalbereich verwendete S88-Bus ist ja auch nichts anderes - nur für die umgekehrte Datenflussrichtung.


viele Grüße
Franz-Peter
Ein 'elektromechanisches' Stellwerk
Der (ehemalige) 'Eisberg'


 
MicroBahner
Metropolitan (MET)
Beiträge: 2.833
Registriert am: 28.11.2012
Ort: Mittelfranken
Gleise Tillig Elite
Steuerung Eigenbau
Stromart Analog


RE: Arduino Weichenpult - Sketch korrektur

#20 von Bettbahner ( gelöscht ) , 30.09.2015 01:19

Hallo,

@Uli

Zitat von spielbahner
mit einem weiteren Transistor kann dann die komplementäre LED angesteuert werden.


wie müsste da dann die Schaltung aussehen? Habe mit Transistoren bisher wenig zu tun gehabt :/

Zitat von spielbahner
Ob die Treiberbausteine dann auch für den Weichenantrieb ausreichen


Ich hatte bei meinem gegoogle bevor ich mit diesem Projekt begonnen hatte auf 1zu160 ein Thread hierzu gefunden in diesem hatte jemand ähnliches vor wie ich und dort wurden die Weichenantriee mit dem Treiberbaustein uln2803 gesteuert, diesen verwende ich auch. Er kann 500mA (kurzzeitige Spitzenlast 600mA) pro Ausgang zur Verfügung stellen bei Spannungen bis zu 50V. In diesem Thread wurde erörtert wie viel Strom eine Weiche zum schalten brauchen würde, dabei wurden ~250mA bei 20Volt Gleichspannung genannt, nach einem Kurzen Test am Labornetzgerät von meinem Vater und zwischengeschaltetem Amperemeter konnte ich mir diese Zahlen bestätigen. Von daher denke ich sollte es dort keine Probleme geben. Werde aber morgen mal einen "Langzeittest" mit dem Treiberbaustein und einem Weichenantrieb machen.
Dabei soll der Weichenantrieb pro Minute 2 mal gestellt werden, bedeutet 100ms Strom um auf abbiegen zu wechseln, 29900ms Stromlos, 100ms Strom um auf Gerade aus zu stellen und wieder 29900ms Stromlos. Wenn der Test dann erfolgreich absolviert ist wird weiter geplant und/oder die Hardware optimiert.

Zitat von spielbahner
Ein Analogeingang kann über eine Widerstandsleiter locker vier Taster einlesen, das wären dann 12 Analogeingänge.


Was ist den eine Widerstandsleiter? (Vielleicht ein blöde Frage, aber davon hab ich noch nichts gelesen)
Die Analogeingänge sind mir noch nicht bekannt, habe bisher noch nichts mit denen gemacht habe nur herausgefunden das man mit denen keine Schieberegister ansteuern kann.

[quote"spielbahner"]Es müssen sämtlich Leitungen der Weichen bis zu den Treibern an den Schieberegistern geführt werden [/quote]
Ich stell mir das Momentan so vor, das der Arduino sowie die Schieberegister für die Weichen einen festen Platz unter der Anlagenplatte bekommen, also dort fixiert werden. Von dem Arduino gehen dann 6 Leitungen ab, von denen jeweils 3 an die Schieberegister für die Taster und Rückmelde LEDs gehen. Diese Schieberegister befinden sich dann unter einem noch nicht vorhandenen Gleisbildstellpult (oder vergleichbares, wie das dann realisiert werden wird steht noch in den Sternen ops: )

[quote"spielbahner"]Davon könnte man 24 für die LED-Anzeige verwenden (Treiber entfallen dann, da der Arduino eine LED direkt treiben kann) oder gleich 48, dann benötigt man keine Transistortreiber für die komplementäre LED[/quote]
Wenn ich die Treiber weglasse könnte ich vielleicht ein Problem bekommen, weil ich verwende LEDs die 20mA haben wollen, ich verwende diese weil ich von denen noch sehr viele zuhause habe und deswegen kein Geld ausgeben musste, sind überbleibsel von einem Pojekt aus der Schulzeit (ein 8x8x8 LED Würfel). Die Schieberegister die verwendet werden sind ebenfalls aus dieser"Restekiste".

[quote"spielbahner"]Zum finanziellen Aufwand:[/quote]
Der wäre für mich zur Zeit leider sehr hoch :/
FCC ~149€
Netzgerät für FCC ~35€
AVRs ~72€
______________________
Summe= >200€

Und momentan habe ich mir nur ein Lernpaket von FRANZIS kaufen müssen um die Grundlagen zu kapieren und gut erklärt zu bekommen für ~40€, die Kosten der Arduino Variante lägen nur darin mir Leiterplatten zu kaufen die dann vom Kumpel bearbeitet werden würden.
Als Student muss man leider auf das Geld acht geben, davon gibts leider nicht genug
Die Anmerkung das es für die Zukunft ausbaufähig wäre bzgl. Digital fahren, ist für mich leider kein Ardument für eine solche Zentrale, weil die meisten meiner Loks sehr alt sind und diese dann umzurüsten würde finanziell ein großer aufwand werden sowie auch zeitlich.

Zitat von spielbahner
nämlich als Programmer für die AVRs


Für eine solche Aufgabe schlummert der ATMEL mkII im Schrank


@Franz-Peter

Zitat von MicroBahner
Übrigends - noch ein Tipp . Wenn Du alle Bits zurücksetzen willst


Vielen Dank für den Tipp.
Gerne mehr davon!



Nachdem mich EAGLE jetzt ziemlich gefrustet hat beim Layouten von 3 Schieberegistern mit Treiberbausteinen habe ich mal Versucht die SPI Kommunikation für das Weichen Array mit einzubinden in meinen Code. Aufgrund der Uhrzeit allerdings leider noch nicht dazu gekommen diesen zu testen.
Zur Verkabelung beim Verwenden von dem SPI habe ich noch eine Frage, muss ich zwangsweise aus dem Port 10 dieses Signal abgreifen oder geht das auch aus der ISP (im System Programmieren) Schnittstelle die der Arduino hat? Weil das rausgeben der Bits aus dem Arduino geschieht so wie ich es verstanden habe über die MOSI Schnittstelle und diese ist ebenso wie GND und VCC auf den ISP Pins zu finden.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
 
/* Peters Versuch Nummer 2
* SPI steuert Weichenantrieb
* Schieberegister LED R&#252;ckmeldung,
*/
 

#include &lt;SPI.h&gt;; //SPI Lib einbinden
//SPI Port
const byte slaveselectPin=10;
 

 
//Muster f&#252;r die Ausgabe
byte Arrayweiche[] = {0, //Weiche 1-4
/*
* Gilt f&#252;r die erste Null, da diese 8Bit "gro&#223;" ist
* Arrayweiche von links betrachtet
* Stelle 1 = Weiche 1 Gerade aus
* Stelle 2 = Weiche 1 abbiegen
* Stelle 3 = Weiche 2 Gerade aus
* Stelle 4 = Weiche 2 abbiegen
* Stelle 5 = Weiche 3 Gerade aus
* Stelle 6 = Weiche 3 abbiegen
* Stelle 7 = Weiche 4 Gerade aus
* Stelle 8 = Weiche 4 abbiegen
* Innerhalb dieses Bytes wird der Taster von LOW auf HIGH stellen
*/
0, //8Bit Weiche 5-8
0, //8Bit Weiche 9-12
0, //8Bit Weiche 13-16
0, //8Bit Weiche 17-20
0,} ; //8Bit Weiche 21-24
byte ArrayLED[] = {0,
/*
* Gilt f&#252;r die erste Null, da diese 8Bit "gro&#223;" ist
* ArrayLED von links betrachtet
* Stelle 1 = Weiche 1 Gerade aus, LED an wenn HIGH
* Stelle 2 = Weiche 1 abbiegen,LED an wenn HIGH
* Stelle 3 = Weiche 2 Gerade aus, LED an, wen HIGH
* Stelle 4 = Weiche 2 abbiegen, LED an wenn HIGH
* Stelle 5 = Weiche 3 Gerade aus, LED an wen HIGH
* Stelle 6 = Weiche 3 abbiegen, LED an wen HIGH
* Stelle 7 = Weiche 4 Gerade aus, LED an wen HIGH
* Stelle 8 = Weiche 4 abbiegen, LED an wen HIGH
* Innerhalb dieses Bytes wird der Taster von LOW auf HIGH stellen
*/
0,0,0,0,0,0,0};
 

//Taster
const byte TST1=8; //Gerade aus Weiche 1
const byte TST2=9; //abbiegen von Weiche 1
 

//LED
const byte LED1=2; //Rueckmeldung 1 noch ohne Schieberegister
const byte LED2=3; //Rueckmeldung 2 noch ohne Schieberegister
/*
//Schieberegister Weichenantrieb
const byte shiftPinw = 4; //Pin verbunden mit SH_CP des 74HC595 (clockpin) Pin 11
const byte storePinw = 3; //Pin verbunden mit ST_CP des 74HC595 (latchpin) Pin 12
const byte dataPinw = 2; //Pin verbunden mit DS des 74HC595 (datapin) Pin 14
*/
 
//Schieberegister LED R&#252;ckeldung
const byte shiftPinl = 7; //Pin verbunden mit SH_CP des 74HC595 Pin 11
const byte storePinl = 6; //Pin verbunden mit ST_CP des 74HC595 Pin 12
const byte dataPinl = 5; //Pin verbunden mit DS des 74HC595 Pin 14
 
void setup() {
 
//SPI
pinMode(slaveselectPin,OUTPUT);
SPI.begin();
 

//Taster definition mit internen Pull Up
//TST1
pinMode(TST1,INPUT_PULLUP);
//digitalWrite(TST1,HIGH); &#252;berfl&#252;ssig, weil Pullup wird schon in pinmode aktiviert.
 
//TST2
pinMode(TST2,INPUT_PULLUP);
//digitalWrite(TST2,HIGH); &#252;berfl&#252;ssig, weil Pullup wird schon in pinmode aktiviert.
 

//LED
pinMode(LED1,OUTPUT);
pinMode(LED2,OUTPUT);
/*
//Schieberegister Weiche
pinMode(shiftPinw,OUTPUT);
pinMode(storePinw,OUTPUT);
pinMode(dataPinw,OUTPUT);
*/
//Schieberegister LED
pinMode(shiftPinl,OUTPUT);
pinMode(storePinl,OUTPUT);
pinMode(dataPinl,OUTPUT);
}
 
void loop() {
 
//Taster 1 wird abgefragt und Funktion Taster 1 wird ausgef&#252;hrt
if(!digitalRead(TST1)){
delay(50);
if(!digitalRead(TST1)){
bitWrite(Arrayweiche[0],7,HIGH); //Gerade aus von Weiche 1 auf HIGH Stellen, also bit 7, da von Links gez&#228;hlt wird
Fuellenw(); // schreibt Variable in Schieberegister &#252;ber SPI
delay(250); //Impuls zum schalten der Weiche
//delay(1000); //zum testen auf 1000ms erh&#246;ht
Leerenw(); // setzt alles auf LOW

bitWrite(ArrayLED[0],7,HIGH); //setzt R&#252;ckmeldungsLED von Gerade aus auf an
bitWrite(ArrayLED[0],6,LOW); //setzt R&#252;ckmeldungsLED von abbiegen auf aus
Fuellenl();
}
}
 
//Taster 2 wird abgefragt und Funktion Taster 2 wird ausgef&#252;hrt
if(!digitalRead(TST2)){
delay(50);
if(!digitalRead(TST2)){
bitWrite(Arrayweiche[0],6,HIGH); //abbiegen von Weiche 1, also bit 6 da links gez&#228;hlt
Fuellenw(); // schreibt Variable in Schieberegister
delay(250); //Impuls zum schalten der Weiche
//delay(1000); //zum testen des sketches wird auf 1000ms erh&#246;ht
Leerenw(); // setzt alles auf LOW
 
bitWrite(ArrayLED[0],7,LOW); //setzt R&#252;ckmeldungsLED von Gerade aus auf an
bitWrite(ArrayLED[0],6,HIGH); //setzt R&#252;ckmeldungsLED von abbiegen auf aus
Fuellenl();
}
 
}
//weitere Taster hier einf&#252;gen.
}
 
void Fuellenw() {
digitalWrite(slaveselectPin,LOW);
 
SPI.transfer(Arrayweiche[8]);
 
digitalWrite(slaveselectPin,HIGH);
 

}
 
void Fuellenl() {
digitalWrite(storePinl,LOW);
 
shiftOut(dataPinl,shiftPinl,MSBFIRST,ArrayLED[0]); //shiftet ArrayLED aus
 
digitalWrite(storePinl, HIGH);
}
 
void Leerenw() //setzt alles Variablen auf LOW, damit keine Dauerspannung an dem Weichenantrieb anliegt.
{
Arrayweiche[0]=0;
//setzt alle Bits des 2 Bytes auf LOW
Arrayweiche[1]=0;
 
digitalWrite(slaveselectPin,LOW);
 
SPI.transfer(Arrayweiche[8]);
 
digitalWrite(slaveselectPin,HIGH);

}
 

 



Falls jemand Fehler entdeckt oder etwas für Verbesserungswürdig hält, dann darf dies gerne mitgeteilt werden


Bettbahner

RE: Arduino Weichenpult - Sketch korrektur

#21 von spielbahn ( gelöscht ) , 30.09.2015 11:22

Zitat von Bettbahner

Zitat von spielbahner
mit einem weiteren Transistor kann dann die komplementäre LED angesteuert werden.


wie müsste da dann die Schaltung aussehen? Habe mit Transistoren bisher wenig zu tun gehabt :/



Bei kleinen europäischen NPN-Transistoren (du kannst jeden x-beliebigen nehmen) ist eine Seite des Gehäuses abgeflacht. Schaust du auf die abgeflachte Seite, dann ist links der Kollektor, in der Mitte die Basis und rechts der Emitter. Vom Pluspol über einen Vorwiderstand geht es zur LED und von da zum Kollektor. Die Basis geht über einen Widerstand von einigen 10k an den Ausgang, der die zugehörige LED ansteuert. Der Emitter ist mit GND (Minuspol) verbunden.

Zitat von Bettbahner

Zitat von spielbahner
Ein Analogeingang kann über eine Widerstandsleiter locker vier Taster einlesen, das wären dann 12 Analogeingänge.


Was ist den eine Widerstandsleiter? (Vielleicht ein blöde Frage, aber davon hab ich noch nichts gelesen)
Die Analogeingänge sind mir noch nicht bekannt, habe bisher noch nichts mit denen gemacht habe nur herausgefunden das man mit denen keine Schieberegister ansteuern kann.



Die Analogeingänge liefern je nach angelegter Spannung (0 bis 5V) einen Wert zwischen 0 und 1023. Mit Widerstandsleiter ist ein mehrstufiger Spannungsteiler gemeint. Der erste Widerstand ist an 5V angeschlossen und geht an den Analogeingang (In Ruhe liegt der Analogeingang somit auf 5V), dann folgen (drei) weitere Widerstände, die (vier) Taster legen dann den Analogeingang - je nach Widerstand an dem sie angschlossen sind - auf unterschiedliche Spannungswerte. Je nach eingelesenem Wert weiß man, welcher Taster betätigt wurde.
Die Analogeingänge können mit pinMode() wie ganz gewöhnliche Ein- und Ausgänge benutzt werden, können also genausogut Schieberegister ansteuern.

Zitat von Bettbahner

Wenn ich die Treiber weglasse könnte ich vielleicht ein Problem bekommen, weil ich verwende LEDs die 20mA haben wollen, ich verwende diese weil ich von denen noch sehr viele zuhause habe


Deine LEDs wollen maximal 20mA, nichts spricht dagegen mit einem entsprechenden Vorwiderstand den Strom zu verkleinern. Ein Arduino-Ausgang kann übrigends 20mA - der gesamte Chip jedoch nur 200mA, da wird es eng....


spielbahn

RE: Arduino Weichenpult - Sketch korrektur

#22 von Bettbahner ( gelöscht ) , 04.10.2015 20:01

Hallo,
komme leider erst jetzt wieder dazu hier rein zu schauen

@Spielbahner
Vielen Dank für die Erklärung der Transistorbeschaltung und den Begriff der Widerstandsleiter.

Zitat
Die Analogeingänge können mit pinMode() wie ganz gewöhnliche Ein- und Ausgänge benutzt werden, können also genausogut Schieberegister ansteuern.



Das habe ich bisher noch nicht gewusst! Vielen Dank

Ich habe mal probiert 27LEDs (weil 27Weichen) leuchten zu lassen, die dann zusammen maximal 190mA Strom "verbrauchen", damit ich unter den von dir genannten 200mA die der gesammte Chip kann zu bleiben.
Das Ergebnis hat mir leider nicht gefallen daher werde ich wohl nicht drumrum kommen die Treiber zu verbauen.

Ich habe jetzt mal alles geordert was ich für die Realisation einer Steuerung für 6 Weichen (alle Weichen meines Timesafers) um es mal in Aktion auszuprobieren.
Leider kommen die bestellten teile erst in 2-3 Wochen bei mir an :/
Bauen werde ich es mit Schieberegistern für INPUT und OUTPUT Pins, alle OUTPUT Pins bekommen Treiberstufen nachgeschaltet.

Werde von meinem Fortschritt berichten.

Deshalb werde ich mich damit beschäftigen wie ich ein LCD Typ 1602 mit meinem vorhaben kombinieren kann, wiel ich davon auch noch eins rum liegen habe



Bezüglich dem Thema mit SPI, das werde ich in meinem Vorhaben nicht weiter verfolgen, weil ich gesehen habe dass das Ethernet Shield ebenfalls diese Schnittstelle nutzt.
Und ich das vielleicht mal (in naher/ferner) Zukunft mit einbinden möchte um auch über einen Browser meine Weichen stellen zu können.

Wie ich schon vorher geschrieben habe, habe ich einen Weichenlangzeittest durchgeführt, dabei habe ich innerhalb von 5 Sekunden einmal auf abbiegen und einmal auf gerade aus geschaltet. Dies habe ich 3 Stunden lang durchlaufen lassen (rund 5000 Schaltzyklen) einmal mit 18Volt und einmal mit 15 Volt, bei dem Weichenantrieb mit 18 Volt wurde die Weiche leider nicht mehr zuverlässig gestellt, bei dem Weichenantrieb mit 15Volt wurde noch zuverlässig gestellt. Der Strom der Verwendet wurde lag bei beiden weit unter den 500mA die der ULN2803 maximal verkraftet.
Mein Ergebnis hiervon ist das ich den Praxis Test mit 15Volt betreiben möchte.


Bettbahner

RE: Arduino Weichenpult - Sketch korrektur

#23 von Bodo , 05.10.2015 11:08

Hallo,

Zitat von Bettbahner

@Bodo
Vielen Dankk für das posten deines Codes. Er sieht interessant aus und so ganz anders wie meiner. Naja deiner Funktionert und meiner noch nicht :/
Eine Frage habe ich aber dazu in der loop, wird durch

Zitat von Bodo
potVal_0 = analogRead(potPin_0);

ein Wert zwischen 0 und 255 als potVal_0 bezeichnet, der dann später

Zitat von Bodo
shiftVal_A = SegmentAnzeige(potVal_0);

irgendwas mit der Segmentanzeige macht und als shiftVal_A umbenannt wird. Dieses shiftVal_A wird dann später an die Schieberegister übergeben. Wir verhält sich währenddessen der eingelesene Wert von dem Poti, weil der ja zwischen 0 und 255 liegen kann und die 0 entspricht einem LOW also Segmentanzeige zeigt nichts an und 1=HIGH die Segementanzeige zeigt etwas an was ist mit den Werten >1, also einer 128 oder einer 12?
Vielleicht ein dämliche Frage, aber mit Potis habe ich bisher nichts gemacht.




sorry - die Frage hatte ich irgendwie überlesen ... der Wert, den das Poti liefert, soll ja (in 100er-Schritten) auf der 7-Segment-Anzeige dargestellt werden (die mit ihren 7 Balken + Punkt genau die 8 Ausgänge des Schieberegisters belegt). Welchen Wert die Funktion zurückliefern muss, hängt natürlich davon ab, wie die LEDs der Segmentanzeige an die Ausgänge des Schieberegisters angeschlossen sind. Vielleicht hilft der Code trotzdem ... Am einfachsten nachvollziehbar ist die Darstellung der "8" - da müssen alle Segmente leuchten, der Rückgabewert also 255 (=B11111111).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 
// ***********************************************************************************************************************
// Der Wert des Potentiometers (potVal_0) am Sensor-Eingang (potPin_0) wird auf das Intervall 0 bis 9 (+E) umgesetzt
// und auf einer Siebensegmentanzeige dargestellt (Ausgabewerte abh&#228;ngig von der Zuordnung der Ausg&#228;nge zu den Pins der
// Segmentanzeige).
// ***********************************************************************************************************************
byte SegmentAnzeige(int potVal) {
byte shiftVal = 0;

if (potVal &lt; 100){ // Segmentanzeige 0
shiftVal = 239;
}
else if (potVal &lt; 200){ // Segmentanzeige 1
shiftVal = 131;
}
else if (potVal &lt; 300){ // Segmentanzeige 2
shiftVal = 221;
}
else if (potVal &lt; 400){ // Segmentanzeige 3
shiftVal = 215;
}
else if (potVal &lt; 500){ // Segmentanzeige 4
shiftVal = 179;
}
else if (potVal &lt; 600){ // Segmentanzeige 5
shiftVal = 119;
}
else if (potVal &lt; 700){ // Segmentanzeige 6
shiftVal = 127;
}
else if (potVal &lt; 800){ // Segmentanzeige 7
shiftVal = 195;
}
else if (potVal &lt; 900){ // Segmentanzeige 8
shiftVal = 255;
}
else if (potVal &lt; 1000){ // Segmentanzeige 9
shiftVal = 247;
}
else { // Segmentanzeige E
shiftVal = 124;
}
return shiftVal;
}
// ***********************************************************************************************************************
 



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


 
Bodo
InterCityExpress (ICE)
Beiträge: 2.471
Registriert am: 28.04.2005
Homepage: Link
Gleise C-Gleis, Lenz 0
Spurweite H0, 0
Steuerung MS2 & CS2
Stromart Digital


RE: Arduino Weichenpult - Sketch korrektur

#24 von Bettbahner ( gelöscht ) , 13.10.2015 21:11

Hallo,

Bodo, danke für die erläuterung! Jezt hab ich es Verstanden

Ein kleines Lebenszeichen von mir.


Momentan warte ich noch auf meine Bestellungen mit denen in ich dann endlich anfangen kann das Weichenstellpult aufzubauen.

Um mir die Wartezeit zu verkürzen habe ich mir eine L298 H Brücke gekauft und mit einem nachbau Arduino betrieben. Momentan bin ich noch am herum experimentieren ob das Fahren mittels PWM Steuerung was für mich ist oder ob ich bei meinen "alten" Trix Trafos bleibe.
Ich muss zugeben dass ich hier momentan mehr abgeschaut wie selber gemacht hab. ops:
Allerdings gefällt mir das was ich kopiert habe sehr gut
Ich habe die schaltung von Uli

Zitat von spielbahn
http://www.spielbahn-z.de/arduino_fahrregler.htm

nachgebaut, den Sketch aufgespielt und schon einige meiner Lokomotiven damit Probegefahren und ich muss sagen es beginnt mich zu überzeugen! Obwohl es bisher nur auf einem Steckboard aufgesteckt und von einem 9V Block gespeist wird. So langsam habe ich meine Loks noch nie fahren sehen
Bilder davon werde ich versuchen morgen zu zeigen, sowie ein mein erstes Video von Testfahrten zu drehen und ebenfalls hier einzubinden.

@Uli, wenn es dich stört das ich deine Website hier verlinkt habe dann gib mir bitte bescheid, ich werde den Link dann entfernen.


Bettbahner

RE: Arduino Weichenpult - Sketch korrektur

#25 von spielbahn ( gelöscht ) , 14.10.2015 23:12

Zitat von Bettbahner
......@Uli, wenn es dich stört das ich deine Website hier verlinkt habe dann gib mir bitte bescheid, ich werde den Link dann entfernen.


Es steht dir frei, meine Seiten nach Belieben zu verlinken.


spielbahn

   


  • Ähnliche Themen
    Antworten
    Zugriffe
    Letzter Beitrag
Xobor Einfach ein eigenes Forum erstellen
Datenschutz