Guten Tag liebe Forengemeinde, ich möchte mich kurz vorstellen: Ich heiße Christian, bin 38 Jahre alt und habe Anfang der 2000er eine Ausbildung zum Energieelektroniker absolviert. In dieser Ausbildung waren Mikrocontroller noch kein Thema, ich weiß nicht wie es heute ist. Nun zu einer kurzen Einführung, wieso sich das geändert hat: Für einen mittelgroßen Bahnhof einer Modelleisenbahn möchte ich ein Stellwerk entwickeln. Die Planung sieht hierbei vor, sich an den Spurplanstellwerken der großen Bahn zu orientieren. Das bedeutet, die Gleisanlage wird in Bereiche zerlegt, die letztendlich jeden Meter Gleis abdecken (Weichen, Kreuzungen, Bereiche dazwischen). Für jeden Typ gibt es dann eine Standardschaltung, die letztendlich nur noch mittels genormten Kabels verbunden werden. Hierfür muss ich also letztendlich für jeden Typ die Standardschaltung entwickeln. Sobald diese Standardtypen funktionieren, benötige ich nur noch für jede Weiche, jede Kreuzung etc. einen solchen Typ und verbinde es mittels der bereits erwähnten Kabel. Jeder Typ hat letztendlich eine Verbindung zum Gleisbereich (Weichenantrieb, Besetztmeldung,etc.) und eine zum Bedienpult (Tasten, Ausleuchtung), sowie untereinander, woraus sich eine nicht unerhebliche Anzahl an Ein- und Ausgängen ergibt. Es gibt hierbei keine Zentrale Steuerung, die gesamte Anlage ergibt sich aus den zusammengeschalteten Typen. Ursprünglich wollte ich Kraft meiner Kenntnisse alles mittels TTL realisieren, womit ich auch begonnen hatte. Auf diese Art hatte ich die Stellwerkstechnik auf dem Papier bereits nahezu vollständig entwickelt und mittels Entwicklung von Bestückungsplänen und dem Einsatz vieler Bauteile und viel Zeit erste Schaltungen erfolgreich gelötet und zur gewünschten Funktion gebracht. Bereits im Vorfeld googlete ich viel herum, um zu sehen, was es für mögliche Unterstützung gibt, heute kann ich das gar nicht mehr genau benennen. Jedenfalls stieß ich seinerzeit erstmals auf den Begriff des Mikrocontrollers, der mir bis dahin vollkommen unbekannt war. Die weitere Beschäftigung damit zeigte mir dann die Möglichkeiten auf, so dass deren Einsatz für mich eingeplant wurde. Eigentlich war vorgesehen, die gesamte Entwicklung an einem sehr kleinen Bahnhof zunächst mittels TTL zu erproben um deren Korrektheit nachzuweisen und erst später zum Mikrocontroller überzugehen. Da sich jedoch schon bald zeigte, dass der gewünschte Bauaufwand mit TTL selbst für diesen kleinen Bahnhof sowohl zeit- als auch materialintensiv ist, habe ich den Übergang zum Mikrocontroller vorgezogen. Das ganze drumherum ist ja kein Problem für mich, aber der Mikrocontroller war nun absolutes Neuland für mich, und so ging es los! Bis jetzt habe ich mir einen ATmega8 ausgesucht und einen USB-ISP-Programmer besorgt. Mit letzterem gab es direkt Probleme (ließ sich einfach nicht vom PC erkennen!), so dass ich hier zu Diamex wechselte. Die Herren waren so nett mich in Ihrem Unternehmen mit meinem Laptop zu empfangen, da ich sichergehen wollte, dass dieser mit Einsatz des entsprechenden Treibers auch funktioniert. Als nächstes habe ich mir ein maßgeschneidertes Programmier- und Prüfboard gebaut. Dieses hat Taster und LEDs in der Form und Anordnung, wie ich sie praktischerweise benötige und funktioniert ebenfalls bestens. Während dieser Phase hatte ich immer wieder Freude damit, selbst eingebaute Fehler zu entdecken... Zuletzt war da noch das Programm, ich nutze Atmel Studio 7. Inzwischen habe ich auch erfolgreich mit kleinsten Programmen experimentiert und in diesem Zuge noch einmal alle Funktionen des Boards geprüft (und weitere Fehler bei der Nutzung des Programmes abgestellt...). Jetzt bin ich endlich soweit, dass es nur noch ums Programmieren geht und wie von mir erwartet, habe ich hier die größten Schwierigkeiten! Bei Schellong bin ich noch am Lesen, ist ja nicht gerade wenig. Ebenfalls neben mir liegen habe ich das Buch AVR von Florian Schäffer. Der Einfachheit halber dachte ich mir, die Umsetzung meiner entwickelten Schaltungen, die allein auf Logik- Gattern basieren in eine C- Programmierung wäre sinnvoll, es erspart mir eine neue Entwicklung. Im Prinzip sind das umfangreich miteinander verschaltete Gatter, die sich meiner Ansicht nach nicht einfach verschachteln lassen, wie ich es im Netz gefunden habe. Erfolgreich laufen bei mir UND und ODER Verknüpfungen, wenn ich Eingänge nutze und sie direkt wieder auf einen Ausgang ausgebe. Was ich aber benötige ist, die Ausgänge von Verknüpfungen als Variable (?) intern zu speichern, welche ich dann wiederum als Eingang für ein anderes Gatter nutze bzw. auch mal auf einen Ausgang ausgeben möchte. Im Netz fand ich nur Beispiele, in denen die Variablen von vornherein einen festen Wert zugewiesen bekommen, ich möchte aber, dass diese immer den Wert haben, den die Verknüpfung gerade in Abhängigkeit ihrer Eingänge ausgibt. Was mir fehlt, wäre unter anderem folgendes: A UND B ergibt eine Variable S1 S1 ODER C-NICHT ergibt eine Variable S2 Variable S2 auf einen Ausgang ausgeben (als Statusanzeige auf dem Bedienfeld) Ich denke, für einen der sich mit C auskennt, sind das Funktionen die grunlegender wohl kaum noch sein können, und doch habe ich dazu noch nichts passendes gefunden. Ich hatte einen Versuch gemacht, mittels Verknüpfung zunächst eine Variable zu setzen, und diese mit einem weiteren Befehl auf einen Augang zu geben. Hierbei ging die LED sozusagen beim ersten mal noch an (bei entsprechender Schalterstellung der Eingänge), es ließ sich dann aber nicht mehr wiederholen. Mit meinem Versuch eine UND- und eine ODER- Verknüpfung direkt auf einen Ausgang zu schalten hatte ich Erfolg, die Wahrheitstabelle lässt sich beliebig oft durchspielen. Ich würde mich wahnsinnig freuen, wenn mir hier mit den Befehlen geholfen werden kann, da sich im Prinzip schon alles, was ich hier vorhabe, mit diesen wenigen Befehlen umsetzen lässt. Gern stelle ich dann auch mal das funktionierende Ergebnis im entsprechenden Unterforum vor! Mit freundlichen Grüßen Christian
Christian K. schrieb: > Ich hatte einen Versuch gemacht, mittels Verknüpfung zunächst eine > Variable zu setzen, und diese mit einem weiteren Befehl auf einen Augang > zu geben. Hierbei ging die LED sozusagen beim ersten mal noch an (bei > entsprechender Schalterstellung der Eingänge), es ließ sich dann aber > nicht mehr wiederholen. Hi, beim µC arbeitet man nicht so effektiv von Anfang bis Ende in einer festgelegten Ablaufsteuerung. Besser man arbeitet mit Hauptprogramm und Interruptservice-Routinen. Dabei springt das Programm nach Interruptbedingung auslösendem Ereignis an entsprechende Unterprogramme und kehrt nach deren Abarbeitung wieder zurück auf die der Unterbrechung folgende Adresse im Hauptprogramm. Die µCs haben eine Reihe von "Interrupts" zur Verfügung. Die Main-Routine wird dabei immer wieder durchlaufen, bzw. man kann den µC "schlafen legen" und mit Interrupt aufwecken. Auch kann man durch "Flagregister" Bits setzen, folgende Programmabschnitte durchlaufen lassen die Flagregister-Bits am Ende wieder löschen, so dass die Main-Routine da wieder stoppt, bis der andere Interrupt kommt, auf einen anderen Programmabschnitt springt. Etc. pp. ciao gustav
Christian K. schrieb: > bin 38 Jahre alt Uff, sicher, nicht 83 ? Modelleisenbahn ist eher für Rentner, und es mit TTL oder Gleisbildstellwerkmodulen lösen zu wollen, hat schon die Staatskasse überfordert, die Deutsche Bahn verwendet nur noch Computer mit Bildschirmen. Mich wundert, dass du glaubst, das finanziell stemmen zu können und in deinem Leben mit der Entwicklung fertig zu werden. Christian K. schrieb: > Es gibt hierbei keine Zentrale Steuerung Das kann man versuchen, distributed computing, egal ob in Hardware oder uC per Software, aber damit Fahrstrassen aufzubauen und alle Weichen auf abweisend stellen erinnert an den Platinenentflechtungsalgorithmus von Lee, das wäre in Hardware schon krass der Aufwand. (ungefähr: ein ATmega8 uC pro Knoten, Verbindung TTL seriell an alle Nachbarn mit 4-poligem Stecker: Plus, Masse, TxD, RxD, weitere I/O für Taster und LEDs auf dem Stellwerksymbol, und dann halt geschickt programmieren, ein uC bildet das Gateway zum Booster) Die Frage ist natürlich, über welche Modelleisenbahn man verfügt, analog oder digital, mit Gleisrückmeldung oder nicht, und wie man Lokomotiven vor Signalen stoppen will, durch abgeschalteten Strom oder Digital- Kommando nach Schaltgleis-Überfahren. Nur bei letzterem geht auch Langsamfahrt. Schau ich mir eine Anlage an, Märklin Digital mit vielen Rückmeldestellen, so besteht die Elektronik nur noch aus einem ESP32 an Booster an Trafo der auch L88/S88 empfängt. Bedient wird dann nur noch über das Smartphone, man draggt die Lok im Gleisbild dorthin wo sie hin soll, und der Computer berechnet Fahrstrassen, schaltet Weichen und Signale, verwaltet Blockstellen und sendet die Kommandos ans Digitalsystem. Wer will, kann das auch zeitgesteuert fahrplanmässig machen Das kostet fast nichts (Smartphone und Digitalsystem hat man, ESP32 ist billig) und ist beliebig rekonfigurierbar, da muss man nicht löten, wenn man Gleise umgestaltet. Das ist zwar kein distributed computing, hat den aber nur 2 Monate gekostet das an der schon realisierten Digitalbahn umzusetzen.
Christian K. schrieb: > Der Einfachheit halber dachte ich mir, die Umsetzung meiner entwickelten > Schaltungen, die allein auf Logik- Gattern basieren in eine C- > Programmierung wäre sinnvoll, es erspart mir eine neue Entwicklung. Das Äquivalent dazu wären wohl keine Controller, sondern programmierbare Logic (FPGA oder CPLD), allerdings arbeiten auch diese in der Regel getaktet. Bei einem Controller arbeitest du im Gegensatz zu kombinatorischer Logik immer sequenziell irgendwas ab, die Reaktion am Ausgang folgt also mit einer gewissen Verzögerung erst auf die Eingabe der Daten. Allerdings spielt das im Kontext deiner Modelleisenbahn keine Rolle, wenn die Reaktion erst ein paar Mikrosekunden später eintritt. Was du tun kannst ist, alle diese Verknüpfungen einfach der Reihe nach immer wieder abzuarbeiten.
1 | #include <stdbool.h> // für Typ "bool" |
2 | |
3 | #include <avr/io.h> |
4 | |
5 | void setup(void) |
6 | {
|
7 | // PD0: Ausgang
|
8 | DDRD = _BV(0); |
9 | // PD1, PD2, PD3: Eingang A, B, C; aktiviere Pullups
|
10 | PORTD = _BV(1) | _BV(2) | _BV(3); |
11 | }
|
12 | |
13 | bool get_a(void) |
14 | {
|
15 | bool a = PIND & _BV(1); // PD1 abfragen |
16 | return a; |
17 | }
|
18 | |
19 | bool get_b(void) |
20 | {
|
21 | bool b = PIND & _BV(2); // PD2 abfragen |
22 | return b; |
23 | }
|
24 | |
25 | bool get_c(void) |
26 | {
|
27 | bool c = PIND & _BV(3); // PD3 abfragen |
28 | return c; |
29 | }
|
30 | |
31 | void set_x(bool state) |
32 | {
|
33 | if (state) |
34 | PORTD |= _BV(0); // PD0 setzen |
35 | else
|
36 | PORTD &= ~_BV(0); // PD0 löschen |
37 | }
|
38 | |
39 | int
|
40 | main(void) |
41 | {
|
42 | setup(); |
43 | |
44 | bool s1, s2; |
45 | |
46 | for (;;) // Endlosschleife |
47 | {
|
48 | // A UND B ergibt eine Variable S1
|
49 | s1 = get_a() && get_b(); |
50 | |
51 | // S1 ODER C-NICHT ergibt eine Variable S2
|
52 | s2 = s1 || !get_c(); |
53 | |
54 | // Variable S2 auf einen Ausgang ausgeben
|
55 | set_x(s2); |
56 | }
|
57 | }
|
MaWin schrieb: > Modelleisenbahn ist eher für Rentner Ich dachte, sowas schenken Väter sich ihren Kindern?
:
Bearbeitet durch Moderator
Hallo Christian da hast du dir was vorgenommen. ist aber nicht so dramatisch. Zuerst wirst du mal C programmieren lernen müssen. Die hardware und die Software des uC kann so designed werden wie deine TTL-Logik. Bei solchen projekten habe ich immer damit angefangen eine Blackbox zu zeichnen, wo links alle Eingänge und rechts alle Ausgänge stehen, danach macht man sich Gedanken über die Abhängigkeiten. Ein uC bietet mehr Möglichkeiten als festverdrahtete Logik. Aber sow ie du in der TTL-Logik dein Handwerkszeug kennst, musst du jetzt beim uC dein neues Handwerkszeug lernen, um die Probleme zu lösen, die du dir stellst. Viel Erfolg gerhard
Hi, und bei reiner Betrachtung nach "Boolscher Algebra" wird die Angelegenheit schnell unhandlich, wenn sie eins zu eins auf einen µC übertragen wird. Aber hier bietet die Prozessorarchitektur Features, die einem das Leben erheblich erleichtern. Eine "Bool-Algebra" hat klassischerweise einen Eingang und einen Ausgang. Der µC hat dazu noch Status-Register, wo gerade bei arithmetischen Operationen noch weitere Bits gesetzt und gespeichert werden. (Atmel AVR) Wie I, T, H, S, V, N, Z, C Die dazugehörenden statusregisterbezogenen Befehle sind ein echter Bringer. Viele Programme wären überdies ohne diese Features praktisch kaum realisierbar. Aber da muss man sich erst einmal reinarbeiten. ciao gustav
Ich vermute dass du früher oder später Zustandsautomaten verwenden wirst. Dazu habe ich eine kleine Einführung geschrieben: http://stefanfrings.de/multithreading_arduino/index.html
Und verzeihe bitte WaWin. Der ist nämlich ein multidimensionales Wesen und hat manchmal Fehler in seinen Interruptroutinen. :-D mfg
Als Einstieg gibt es hier auch ein schönes Tutorial für C-Programmierung mit dem µC. https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial Insbesondere das Kapitel https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Zugriff_auf_IO-Ports über die Nutzung der I/O-Pins.
Karl B. schrieb: > Die dazugehörenden statusregisterbezogenen Befehle sind ein echter > Bringer. Umpf. Lass ihn bitte bei C, damit wird er genug zu knaubeln haben, und versuche nicht, ihm nun auch noch Assembler aufzudrängeln. Bei C passiert der ganze Flag-Kram völlig „unter der Haube“. Und bevor jetzt der C-Hasser auf den Plan kommt, wenn man obigens mit kompletter Optimierung übersetzt [einschließlich LTO], dann hätte auch ein eingefleischter Assemblerprogrammierer da seine Freude dran:
1 | 00000038 <main>: |
2 | 38: 81 e0 ldi r24, 0x01 ; 1 |
3 | 3a: 81 bb out 0x11, r24 ; 17 |
4 | 3c: 8e e0 ldi r24, 0x0E ; 14 |
5 | 3e: 82 bb out 0x12, r24 ; 18 |
6 | 40: 81 9b sbis 0x10, 1 ; 16 |
7 | 42: 04 c0 rjmp .+8 ; 0x4c |
8 | 44: 82 9b sbis 0x10, 2 ; 16 |
9 | 46: 02 c0 rjmp .+4 ; 0x4c |
10 | 48: 90 9a sbi 0x12, 0 ; 18 |
11 | 4a: fa cf rjmp .-12 ; 0x40 |
12 | 4c: 83 9b sbis 0x10, 3 ; 16 |
13 | 4e: fc cf rjmp .-8 ; 0x48 |
14 | 50: 90 98 cbi 0x12, 0 ; 18 |
15 | 52: f6 cf rjmp .-20 ; 0x40 |
Anfangs 2000 eine Ausbildung zum Industrieelektroniker.... Wie kommt es, dass ich schon in 1983 mit Mikroprozessoren gearbeitet habe ? Die Atmel AT90S Serie kam etwa 2002 raus und hatte vor Allem Ram und Flash grad schon drin, neben den ueblichen seit dem 8032 bekannten Uart, ADC und Timer. Daneben gab's auch die PIC. Alles verpennt ? Schon vor 2000 machte man logische Verknuepfungen, also OR/AND/Not-Matritzen mit GAL und schon lange nicht mehr mit Gattern, ausser vielleicht ECL oder so. Trotzdem viel Glueck
:
Bearbeitet durch User
Purzel H. schrieb: > mit GAL Nur, wenn man eine fette Energiequelle hatte. ;-) Gatter benutzt man durchaus auch heute noch, nur nicht mehr im klobigen DIL-14-Gehäuse. Es gibt mittlerweile single-gates in Hühnerfuttergröße.
:
Bearbeitet durch Moderator
Hi, Frage nach vernünftiger IDE (Programmierumgebung) kommt bestimmt. Also ich bin mit ATMEL Studio vollauf zufrieden. Und STK500 EVA Board ist zwar nicht mehr state of the art aber erleichtert die Sache schon gewaltig. Sowas in der Richtung. Mit Arduino kann man zwar schnell tolle Sachen machen, aber irgendwie werde ich damit nicht warm, es fehlt da IMHO so das Gefühl für "echtes Programmieren". Weiß nicht. Vorteil, die Hardware ist schon dabei. Die Software, die "Sketche" gibt es auch. ciao gustav
Christian: Ich hab 2018 nen Zähler aus TTL gebaut. Einfach, weil ich lernen will und Opa die Teile noch kistenweise hat. Dein Projekt kann aber ökonomisch nur mit nem Prozessor gelöst werden. Auch wenn die OM's jetzt hier ihre Nase rümpfen werden: Arbeite Dich ins Arduino-System ein! Und-- Modelleisenbahn ist ein geiles Hobby, auch wenn freaks es hier anders sehen. mfg
Jörg W. schrieb: > dann hätte auch > ein eingefleischter Assemblerprogrammierer da seine Freude dran: Na ja, die Label und die Registernamen sollte man schon im Klartext kennen, sonst wird "ReAVR" total unübersichtlich. ;-) ciao gustav
Christian, ich wünsche dir viel Spaß und Erfolg. Meiner Meinung nach ist dein Weg genau richtig, das erst an einem kleinen Bahnhof auszuprobieren, dann groß aufzuziehen. Inhaltlich kann ich mich ansonsten nur Jörg anschließen, der dich da meiner Einschätzung nach in die richtige Richtung geschubst hat, wenn du bei der "einfachen Kombinatorik" bleiben willst. Persönlich - und deshalb schreibe ich dies - würde ich das heute anders machen und die Kombinatorik einem PC überlassen, beispielsweise mit JMRI PanelPro: https://www.jmri.org/community/examples/Gallery.shtml - dann bleibt deine eigene Hardware "nur noch" als Bedienteil und Schnittstelle zum PC. MfG, Arno
Purzel H. schrieb: > Anfangs 2000 eine Ausbildung zum Industrieelektroniker.... Lesen! >> Ich heiße Christian, bin 38 Jahre alt und habe Anfang der 2000er eine >> Ausbildung zum Energieelektroniker absolviert. > > Wie kommt es, dass ich schon in 1983 mit Mikroprozessoren gearbeitet > habe ? Woher soll der TO das wissen? Nicht er machte die Lehrpläne. Auch 2003 beinhaltete die Ausbildung zum Energieelektroniker keine Mikrocontroller-Kenntnisse.
Karl B. schrieb: > Frage nach vernünftiger IDE (Programmierumgebung) kommt bestimmt. Da er bereits schrieb, dass er ein Atmel Studio 7 hat, muss diese Frage nicht kommen. ;-) ~Lolita~ schrieb: > Dein Projekt kann aber ökonomisch nur mit nem Prozessor > gelöst werden. CPLD oder FPGA würde seiner Denkweise näher kommen. ;-) > Auch wenn die OM's jetzt hier ihre Nase rümpfen werden: > Arbeite Dich ins Arduino-System ein! Für ein bisschen Boolsche Algebra braucht er das nicht, und da er sich eh schon mit Atmel Studio angefreundet hat, muss er jetzt nicht noch 'ne andere IDE benutzen. Arduino-(Clone-)Hardware könnte er natürlich trotzdem benutzen, wenn er möchte. Da er aber alles in Hardware bauen wollte, kann es gut sein, dass ihm der Aufbau eigener Hardwaremodule Spaß bereitet.
Hallo, erstmal vielen Dank für die vielen Reaktionen in so kurzer Zeit, und ich sehe da auch schon viel hilfreiches! @gustav: Danke für deinen Beitrag, in dieser Richtung und mit deinen genannten Begriffen werde ich nochmal gezielt auf die Suche gehen! Ich hatte schon erwartet, dass sich hier ggf. eine insgesamt anders geartete Vorgehenweise als sinnvoll erweisen könnte. @MaWin: Es gibt wohl 83-jährige Modelleisenbahner und sicherlich noch ältere! Tatsächlich ist es aber längst nicht so, dass es keine jüngere Generation gibt, die wird aber in jedem Fall schleichend kleiner, das stimmt wohl. Wenn man sich näher mit dem Hobby beschäftigt stellt man fest, dass es einem viel geben kann, je nachdem wie man es lebt. In meinem Fall ist es eher ein vorbildnaher Betrieb, zu dem das Sammeln zueinander passender Fahrzeuge, eine spaßige Steuerung und auch eine gelungene Landschaft gehört, aber eben kein "Teppichbahning". Es gibt Gruppen, die bauen Kleinbahnen der Altmark nach, das hat etwas sehr beruhigendes. In Königstein gibt es eine großartige Anlage, auf der nach Fahrplan der Betrieb im Elbtal nachgestellt wird. Dann wäre da noch da MiWuLa, ebenfalls eine sehr schön gestaltete Anlage, die mit viel Blingbling aber eher auf Massentauglichkeit abzielt. Zu guter Letzt gibt es natürlich noch eine große Zahl derer, die einen recht einfach Aufbau bevorzugen und nur mit ihren Zügen auf der Tischpatte oder dem Teppich im Kreis fahren. Ich will nur sagen, dass das Hobby sehr vielseitig ist und je nach Anspruch eine ganze Menge Herausforderungen mit sich bringt und Kreativität verlangt, die weit über einen pauschalen 83- jährigen Opi hinausgehen. Jedenfalls die Kosten beim Vorbild: Erfunden wurde es ja gerade aus finanziellen Gründen, eben um die antiquierte Technik aus der Kaiserzeit mittels Relaistechnik abzulösen. Klar ist heute wiederum die Elektronik der günstigste Weg. Aber mir geht es anders als der großen Bahn ja nicht um einen rationellen Betrieb, um möglichst große Vorstandsboni herauszuholen, sondern darum, dass mir die Benutzung eines handfesten Stellpults mehr Spaß macht als ein Smartphone. Wenn es nach wirtschaftlichem Nutzen ginge, müsste die Modelleisenbahn weg, denn sie ist ein reines finanzielles Grab ohne Aussicht, einmal Gewinn einzuspielen. Klar könnte ich das Stellwerk auch über ein Computerprogramm umsetzen, aber ist es nicht auch der Spaß eines Mikrocontroller- Nutzers, etwas auf eine ganz bestimmte Art umzusetzen, unabhängig davon, ob es nachher auch einen sinnvollen Nutzen erfüllt? So geht es mir jedenfalls mit der Stellwerkstechnik. Das bringt mich auch zu Kosten und Aufwand: Beim guten alten Relais- Stellwerk hat man es gelöst wie von mir geschrieben: Eine festgelegte Schaltung pro "Teil". Innerhalb dieser Schaltung wird die Fahrstraßenfestlegung, Ausschluss feindlicher Fahrstraßen, abweisende Weichen etc. jeweils für den eigenen Teil vollständig erfüllt und ist vom Aufwand gar nicht einmal groß. Wie bereits erwähnt habe ich die Entwicklung mittels TTL nahezu abgeschlossen und kann den Aufwand auf ein paar A4- Blättern sehen, die ich recht groß für eine gute Übersichtlichkeit gezeichnet habe. Allerdings arbeitet diese Entwicklung nicht wie von dir vermutet mit 4 Adern zwischen den Schaltungen, sondern erheblich mehr (Datenaustausch zwischen Mikrocontrollern ist mir ja Stand jetzt noch viel ferner!). Hierbei habe ich mich ebenfalls wieder an den originalen Relais- Stellwerken orientiert, im Prinzip schicke ich also jeden einzelnen Befehl zwischen den Mikrocontrollern über einen eigenen Draht. Die Änderung von Gleisen ist hierbei gerade simpel, denn eine zusätzliche Weiche bedeutet nur: Verbindungskabel von einer Schaltung abziehen und an eine neue zusätzliche Weichenschaltung anschließen. 1-2 neue Kabel nehmen und anstecken, fertig. Nichts löten, nichts umprogrammieren, nur zusätzliche Schaltung und Kabel nehmen. Allerdings kommt das bei einer fest aufgebauten Anlage ohnehin so gut wie nie vor. Kostenmäßig sehe ich das so, dass ich jeweils einen Mikrocontroller und eine geätzte Platine benötige, das ganze insgesamt vielleicht 50x, die Kabel sind hier auch nicht der Brecher. Ein "Abrauchen" mit Stillstand auf der gesamten Anlage wird es damit schon mal nicht geben, wie man es leider auf jeder Ausstellung mindestens einmal erlebt. @Jörg: Vielen Dank für dein Programm! Ich werde es ausgiebig erproben um jede Zeile davon nachvollziehen zu können, auf den ersten Blick kann ich es schon zuordnen, was wofür zuständig ist. @Franko: Die Blackbox bleibt mir ja unter Umständen erspart, da ich ja bereits alle Zuordnungen habe. C programmieren erlernen: Da hast du einfach recht, nur mit Copy- Paste wird es nicht getan sein. Wenn ich erstmal ein paar Kleinigkeiten auf die Reihe bekomme (siehe oben, einzelne Logik- Gatter) und so langam größere Zusammenhänge entstehen, werde ich auch motiviert sein, über den kleinen Telerrand meines Projektes zu schauen. Wichtig ist mir definitiv das ganze nicht nur irgendwie zum laufen zu bringen sondern es genau zu verstehen, was ich da gemacht habe. Mit freundlichen Grüßen Christian Krebs
In meiner Schulzeit (1974) hatte ein Kollege aus der Parallelklasse genau so etwas aus TTL aufgebaut. Viele Eurokarten in Faedeltechnik in einem Vero Einschub Wenn ich mich richtig erinnere war da einiges an ungeplanten Zufallsfunktionen implementiert. Immer wenn die Lok auf schmutzigen Gleisen ordentlich Funken gemacht hatte, passierten alle moeglichen Dinge. Das Projekt wurde leider nie fertig - der Kollege wurde von einer echten Strassenbahn ueberfahren...
Christian K. schrieb: > Ein "Abrauchen" mit Stillstand auf der gesamten Anlage wird es damit > schon mal nicht geben, wie man es leider auf jeder Ausstellung > mindestens einmal erlebt. Hardwaremäßig solltest du dir sicher Gedanken um den elektrischen Schutz von Ein- und Ausgängen deiner Module machen. Falls du es nicht ohnehin schon vor hast: trau dich, SMD zu benutzen. Wird kleiner (und dadurch auch billiger) als THT, und bei den von dir angedachten Elementen (ATmega8 und sowas) ist das auch alles hobbymäßig problemlos zu löten.
Guenter H. schrieb: > Viele Eurokarten in Faedeltechnik in einem Vero Einschub Hi, 19-Zoll-Gestelle und Steckkarten-Einschübe mit Euopaplatinen findet man heute durchaus noch auch im industriellen Sektor. Wichtig ist, man entscheidet sich erst einmal auch vom Aufbau her für ein halbwegs genormten System, das auch später noch beliebig erweitert werden kann. ciao gustav
Karl B. schrieb: > 19-Zoll-Gestelle und Steckkarten-Einschübe mit Euopaplatinen findet man > heute durchaus noch auch im industriellen Sektor. Ich würde sagen, erst mal langsam mit den Pferden...der TO hat sich ein ordentliches Projekt vorgenommen, dass aus mindestens zwei Teilgebieten besteht. Die Steuerung, möglichst mit Mikroprozessor und eine "feldtaugliche" Hardware. Und damit meine ich nicht das Arduino-Board. Daraus ergibt sich zwingend, zuerst eine vernünftige Prozessorfamilie mit viel Unterstützung und Hardware zu suchen. Hier kann durchaus mit und rund um die Arduinos gearbeitet werden. Sind da erste Grundlagen erarbeitet worden, kann man weitersehen. Aus Gründen der Flexibilität würde ich dringend von "diskreten" Basteleien ala TTL-Grab absehen. Kein Mensch muß heutzutage auf ein Gehäuse im Minikühlschrankformat mit zig Steckkarten hinarbeiten! Da können noch so viele Stangen IC's in der Bastelkiste liegen :-) Gruß Rainer
Ooooch, ich liebe Großanlagen mit EGS* und fein ausgebundenen Kabelbäumen... mfg ------- *Einheitliches Gefäß System
Hallo, danke noch an alle anderen fleißigen Mitstreiter, mit soviel Resonanz hätte ich auf die Schnelle nicht gerechnet. @Purzel H.: Wie bereits erwähnt habe ich Energieelektroniker gelernt, und da kannst du mir glauben, Mikrocontroller wurden nicht behandelt. ;-) @Lolita: Neenee, keine gebundenen Kabelbäume. Ich dachte z.B. an Telefonkabel 10x2x0,6 und da Wannenstecker dran löten, aber das ist unterm Strich wieder ein gewisser Aufwand. Vor allem sind mir die Ausmaße der Wannenstecker eigentlich zu groß, gibt es da auch irgendwas kleineres? Ich schaue schon immer beruflich in die Geräte der großen Hersteller hinein was da so verbaut ist, aber tatsächlich siehts da meistens auch nur nach Conrad und Reichelt aus, denkt man gar nicht! Die Platinen kann man z.B. ätzen lassen, hier kommt dann also noch die Layout- Erstellung mittels Programm auf mich zu. Nachher dann also im Idealfall nur noch die Programme auf Mikrocontroller spielen und ein bisschen was auf die Platinen löten, so jedenfalls meine naive Vorstellung. Mit freundlichen Grüßen Christian Krebs
Christian K. schrieb: > so jedenfalls meine naive Vorstellung. Wenn Mikrocontroller (µC), dann würde ich einen "Controller Area Network" (CAN) verwenden. Da wird an der "Steuerzentrale" ein µC mit CAN eingesetzt und an allen möglichen Punkten der Eisenbahn wiederum ein µC mit Ein-/Ausgängen und CAN Bus. Die Verkabelung reduziert sich dann auf: + Versorgung - Versorgung (GND) 2x CAN Bus Drähte, CAN-H (=CAN-High) und CAN-L (=CAN-Low) Über CAN Bus gehen dann alle Informationen, kann problemlos neue Platinen mit µC dran bauen und die Eisenbahn erweitern. Das ist ein nettes schönes Projekt, macht Spass und man hat damit sehr lange eine Beschäftigung. CAN Bus bieten sehr viele µC bereits mit im Chip, von so gut wie allen Herstellern, im Auto wird CAN bereits seit Jahrzehnte verwendet und ist günstig auch für Hobby.
Markus M. schrieb: > Wenn Mikrocontroller (µC), dann würde ich einen "Controller Area > Network" (CAN) verwenden. Ja, kann man machen. Man muß aber im Auge behalten, dass am "CAN-Ende" auch was passieren soll!! Ich empfehle dem TO jetzt auf jeden Fall mal nach DCC, Open DCC und Ähnliches zu googeln. Man kann da jede Menge Anregungen finden und bei Unklarheiten auch hier fragen... Gruß Rainer
Christian K. schrieb: > Telefonkabel 10x2x0,6 und da Wannenstecker dran löten, Wenn schon, dann Flachbandkabel und crimpen. (Die Stecker kann man auch im Schraubstock crimpen.) > Vor allem sind mir die > Ausmaße der Wannenstecker eigentlich zu groß, gibt es da auch irgendwas > kleineres? Ja, schon, aber dann kaum noch was einheitliches. JST baut recht kleine Steckverbinder, und man bekommt auch Kabel fertig konfektioniert zu kaufen.
Hallo Gemeinde! Viel Zeit ist vergangen, eher weniger Wasser die Elbe herunter...lassen wir das. Ich hatte zwar bereits letztes Jahr vor, hier einen großen Schritt voranzumachen, aber seit letztem Mai hatte ich einfach zuviel um die Ohren, so dass das Hobby eben vollständig hinten anstand. Mit eurer Hilfe, vor allem dem Beipsiel von Jörg, bin ich tatsächlich weitergekommen und habe einige kleinere Aufgaben sogar zum Laufen bekommen. Ich hatte meine "aufgemalten" Logikschaltungen hinter jedem Gatter mit einer Variablen versehen und somit diese Schaltungen quasi nachgebaut. Was bei den kleineren Schaltungen noch funktionierte, ging bei der ersten größeren Schaltung trotz "0 errors" und "0 warnings" überhaupt nicht mehr. Will sagen: auf meinem Programmier- und Prüfboard passierte bei Taster- Bedienung nichts so, wie es geplant war. Die Schaltung an sich ist erprobt, es war die letzte, die ich noch als TTL realisiert und erfolgreich getestet hatte. Ich vermute, dass ich bei Bool wohl noch einiges an Regeln beachten muss, damit es wirklich hin haut, aber genau da fehlen mir ja wieder die Kenntnisse. Macht es Sinn, die hier schon etwas längere Programmierung hier einzustellen, oder hätte da jemand Interesse per PN? Würde mich sehr freuen, wenn mir jemand die klar sichtbaren Fehler mal um die Ohren haut, damit ich es beim nächsten Mal richtig mache, bzw. vielleicht auch eine Empfehlung für einen anderen Lösungsansatz bekäme.^^ Mit freundlichen Grüßen Christian Krebs
Christian K. schrieb: > Macht es Sinn, die hier schon etwas längere Programmierung hier > einzustellen Häng das Programm einfach als Datei hier an. Du kannst auch mehrere Dateien anhängen.
Beitrag #7156203 wurde von einem Moderator gelöscht.
Beitrag #7156214 wurde von einem Moderator gelöscht.
Hallo, anbei mal die mit Atmel Studio 7 erstellten Dateien, ich hoffe man bekommt sie auf. Sagt mir ruhig, welches Format davon ausreichend ist, ich muss ja hier nicht jedes mal alle rein stellen. Kurze Erklärung: Die Gatter am Anfang der Schaltung werden durch Taster angesteuert, die Ausgänge der Gatter habe ich dann als Variablen festgelegt. Mit diesen Variablen habe ich wiederum andere Gattereingänge beschaltet und letztendlich wiederum Gatterausgänge auch auf Ausgangspins gelegt. Während es bei kleineren Programmen noch wie gewünscht funktioniert, passiert hier überhaupt nicht das was es soll. Möglicherweise muss ich bei der Reihenfolge irgendetwas beachten, weil das Programm das in dieser Form gar nicht verarbeiten kann? Ich freue mich auf eure Hilfe! Mit freundlichen Grüßen Christian Krebs
Hi, du solltest erst alle Eingänge lesen, dann kombinieren und dann ausgeben. Damit beugst du Initialisierungsroblemen vor. Außerdem solltest di nicht die gatter programmieren, sondern doe boolsche Algebra. Das ist ein einzeiler und noch dazu viel übersichtlicher. Hast du die Minimalform der bool. Algebra vorliegen?
Martin schrieb: > du solltest erst alle Eingänge lesen, dann kombinieren und dann > ausgeben. Ganz genau! https://de.wikipedia.org/wiki/EVA-Prinzip
Deine bool-Variablen solltest Du jedenfalls vor der ersten Verwendung initialisieren.
Guten Morgen, vielen Dank für eure hilfreichen Antworten! Also ich werde als erstes mal die Programmierung aufräumen und mal sehen, ob ich sie zum Laufen bekomme. Den Weg, die boolsche Algebra zu programmieren werde ich ebenfalls prüfen, bis jetzt sehe ich da aber auch noch Lücken. In meiner Schaltung ist auch sequentielle Logik enthalten, hier kann ich noch nicht erkennen, dass diese sich einfach in boolscher Algebra darstellen lässt. Ebenso habe ich eine Gatter- Kombination mit drin, die ich weder im Sinne von Kombinatorik noch im Sinne von sequentiell einordnen kann. Konkret geht es darum, dass zwei Signale sich gegenseitig blockieren, je nachdem welches zuerst anliegt. Also das bloße Anliegen von Signal A geht weiter in die Schaltung, während ein anschließend auftretendes Signal B derweil blockiert wird. Liegt Signal A nicht mehr an, geht Signal B weiter in die Schaltung und würde bei einem erneuten Anliegen von Signal A wiederum dieses blockieren. Das lässt sich so ja auch nicht in einer kombinatorischen Wahrheitstabelle darstellen, gespeichert wird hier allerdings auch nichts. Aber da habe ich schon einiges an Lektüre gefunden, wo ich mal konkreter suchen kann. Mit freundlichen Grüßen Christian Krebs
Christian K. schrieb: > in eine C-Programmierung > werde als erstes mal die Programmierung aufräumen Hast du irgendeine psychische Blockade wenn du "Programm" schreiben sollst? Man schreibt ein Programm, oder man schreibt Code.
Hallo, nein, das kommt mehr aus der Gewohnheit heraus. Da programmiere ich Anlagen und wir reden immer von "Programmierung", kann ich hier aber gern fachlich richtig als Programm bezeichnen.
sw1 = get_c() && !sw11; An der Stelle hat die Variable noch keinen Sinnvollen Wert, da sie nicht initialisiert wurde. Der Compiler wird sie wahrscheinlich mit implizit mit 0 initialisieren, aber DU musst natürlich wissen, ob das so gewollt ist. Also besser mit einem sinnvollen Anfangswert vorbelegen. Ebenfalls wäre es Sinnvoll, statt Variablennamen wie "sw11" etwas sprechendere Namen zu verwenden. Das macht das Nachvollziehen des Codes wesentlich einfacher. Was mir auch noch aufgefallen ist, aber das ist jetzt am Anfang vielleicht nicht entscheidend, ist, dass Du sehr viele Funktionen definiert hast, die genau dasselbe tun, nur andere Namen haben. Du könntest z.b. statt bool set_x(bool state) { ... } bool set_y(bool state) { ... } bool set_z(bool state) { ... } usw. eine Funktion schreiben, die das Schreiben auf PortPins übernimmt: bool set_Pin(unsigned char port, unsigned char pin, bool state) { ... } Der Aufruf wäre dann z.B für PORTC, Pin 7 eine 1 schreiben: set_Pin(PORTC, 7, 1); Gruß
Oops... hab mich gerade dran erinnert, dass das Macro PORTC ja direkt das Register beschreibt. D.H. das lässt sich nicht einfach als unsigned char übergeben.. Dadurch ist es zwar nicht schwierig zu lösen, aber evtl als Anfänger jetzt erstmal nicht so wichtig.
Hallo Martin, MIstA und Klugscheißer, ich habe jetzt einmal versucht, das Programm in der Form zu verändern (Reihenfolge): -void setup(void) -bool get_a usw. -int main(void) -void set_x usw. Ohne einige "errors" wird das bislang aber noch nichts. @"Klugscheißer": damit wird mir zumindest schon der erwähnte Fehler beim Initialisieren der Variablen klar, bleibt noch die Frage, wie ich sie mit einem Anfangswert vorbelege. Die Variablen sollen im Ruhezustand alle den Zustand 0 haben, welcher sich dann erst mit der Betätigung von Tastern wie gewünscht zu ändern beginnt. Zu den Variblen- Namen: die Buchstaben sind ein kleiner Code für mich, die zahlen nur durchnummeriert. Ich habe die grafische Darstellung auf dem Papier neben mir liegen und dort auch die Variablen mit hinein geschrieben. Wenn ich hier vielleicht noch einen kleinen Schubs in die richtige Richtung bekommen könnte... Vielen Dank bis hier her schonmal für die zielführenden Antworten! Mit freundlichen Grüßen Christian Krebs
Christian K. schrieb: > Die Variablen sollen im Ruhezustand alle den Zustand 0 haben, welcher > sich dann erst mit der Betätigung von Tastern wie gewünscht zu ändern > beginnt. Tasten sauber zu entprellen und die Flanke erkennen, ist keine einfache Aufgabe. Daher sollte man erstmal diese Aufgabe getrennt lösen und nicht mit der eigentlichen Ablaufsteuerung zu einem unentwirrbaren Knäuel vermengen. Warum die Flanke erkennen? Weil man typisch nur eine einzige Reaktion habe will, sobald die Taste gedrückt wurde und nicht, solange die Taste gedrückt gehalten bleibt.
Christian K. schrieb: > Die Variablen sollen im Ruhezustand alle den Zustand 0 haben, welcher > sich dann erst mit der Betätigung von Tastern wie gewünscht zu ändern > beginnt. Hmm.. ich denke mal, das ist so einigermaßen realitätsfern. Besser wäre es mMn. wenn dein Rechnerlein beim Einschalten der ganzen Spielzeugeisenbahn zu allererst den tatsächlichen Zustand der diversen Gleise, Weichen, Schranken und was es sonst da noch gibt, erfassen würde und das als Startzustand deiner Variablen hernimmt. Ansonsten habe ich hier den Eindruck, daß die zahlreichen Beiträge seit über einem Jahr nur die jeweiligen Blickwinkel der Schreiber widerspiegelt. Der eine schreibt über Interrupt-Routinen, ein anderer über set_irgendwas Funktionen und so weiter. Das sind alles Details aus dem Controller_Programmieren, aber sie haben garnichts mit deinem Hauptproblem zu tun, nämlich dem eigentlichen Funktionskonzept. Ich stelle mir das schwieriger vor als es auf den ersten Blick aussieht. Eben weil man als menschlicher Betrachter unbewußt einiges abstrahiert und dabei Aspekte, die man gerade nicht als wichtig empfindet, aus der Betrachtung oftmals herausgelassen werden. Kurzum, Programmierung und Systementwurf und Prozeßmodellierung sind verschiedene Arbeitsfelder. Wenn du jetzt mit dem Programmieren anfängst, dann würde ich es für sinnvoll halten, wenn du zunächst dich an überschaubarere Projekte hältst. Es dauert so seine Zeit, bis man es wirklich kann - und damit meine ich nicht das Auswendiglernen irgend einer Programmiersprache, sondern das eigentliche Programmieren, was eher aus dem Finden von Lösungwegen und Systemstrukturen besteht. Also so etwa vergleichbar mit dem Unterschied zwischen Architekt und Maurer. Also lerne du erstmal das Mauern bzw. das Schreiben von funktionierenden Programmen in der Programmiersprache deiner Wahl und mit einfacheren Projekten - aber vergiß nicht, daß das nur der Anfang ist, quasi noch nicht die Kür beim Eistanz. W.S.
Christian K. schrieb: > A UND B ergibt eine Variable S1 S1 = a && b; Christian K. schrieb: > S1 ODER C-NICHT ergibt eine Variable S2 S2 = S1 || !C; Christian K. schrieb: > Bis jetzt habe ich mir einen ATmega8 ausgesucht Den ältesten und schlappsten aus der ganzen Reihe..... Aber ok, auch das Ding tuts. Christian K. schrieb: > Ich denke, für einen der sich mit C auskennt, sind das Funktionen die > grunlegender wohl kaum noch sein können, und doch habe ich dazu noch > nichts passendes gefunden. Ich kann dir nicht sagen wie du das machen solltest..... Aber ich orientiere mich bei "solchen" Problemstellungen an den Koppelplänen einer SPS(PLC). Zudem verwende ich nicht C, sondern C++. C++ mag schwieriger sein, aber dank der OOP ist die Modularisierung konsequenter durchzusetzen. Und Modularisierung scheint ja eins deiner Ziele zu sein.
Hallo Peter D. und W.S., zunächst zum Entprellen: Brauche ich nicht, tatsächlich wird durch die Betätigung von 2 Tasten etwas in Bewegung gesetzt, was sich selbst hält, sobald zwei Eingänge zeitgleich auf High sind. Aber dafür versuche ich nochmal kurz zusammenzufassen: Es gibt kein großes Programm, in dem ein Computer sämtliche Eingänge von Weichen etc. erhält und verarbeitet, und dann wiederum entsprechend die ganzen Befehle an die Weichen und Signale ausgibt. Es wird für jede Weiche, jeden Fahrstraßenbeginn und jedes Fahrstraßenende eine eigene "Gruppe" mit einem µ geben, die über Kabel miteinander verbunden sind. Diese Kabel werden gemeinsam mit den einzelnen Gruppen identisch dem realen Gleisverlauf verbunden. Eine Startgruppe, min. eine Weichengruppe und eine Zielgruppe bilden eine funktionierende Schaltung. Ein Tastendruck in einem Startteil legt auf eine Ader über alle verfügbaren (nicht bereits in einer Fahrstraße verwendeten) Weichengruppen ein High zu allen real zu erreichenden Zielteilen. Ein zweiter Tastendruck im gewünschten Zielteil schickt ein High zurück zu diesem Startteil (und zu keinem anderen). Nach dem loslassen beider Tasten geht vom Startteil kein High mehr aus, der Zielteil jedoch hält sein Signal selbsttätig aufrecht, hierfür ist kein Entprellen erforderlich, da ich dort bislang keine Fehlfunktion auf Grund fehlenden Entprellens ausfindig machen konnte. Jetzt werden die Weichen in Stellung gebracht, wofür es letztendlich über eine zweite Ader eine Rückmeldung gibt. Die Fahrstraße ist eingestellt, der Zug kann fahren. Über Gleisfreimeldungen wird die Rückmeldung gegeben, dass die Zugfahrt erfolgt ist, bis final der Zielteil sein High in ein Low verwandelt. Die einzelnen Gruppen arbeiten nur solange weiter, wie das High vom Zielteil anliegt, sobald es wegfällt, wird sofort in den Ruhezustand zurückgefallen. Somit ist auch jederzeit ein Löschen der Fahrstraße möglich, ohne das eine Zugfahrt stattfand. Jedes Bauteil soll über diese zwei Adern in beiden Richtungen funktionieren, dabei aber teilweise unterschiedliche Aufgaben erfüllen, deshalb die Unterscheidung, welches der beiden Signale zuerst anlag, bzw. welches anschließend als einziges erhalten bleibt. Kurzum: Du hast natürlich recht damit, zunächst mit kleinen Projekten zu beginnen, aber genau das mache ich ja hier mit der Entwicklung der einzelnen Gruppen, die jeweils überschaubare Funktionen haben. Also bitte macht euch keine Gedanken darum, wie das große ganze nachher funktionieren soll, das habe ich im Prinzip fertig ausgearbeitet. Was mir fehlt, sind die Kleinigkeiten, nach denen ich gerade suche wie eben die Frage, warum mein oben angehängtes Programm nicht läuft. Start- und Zielgruppe habe ich z.B. schon erfolgreich in Funktion. Mit freundlichen Grüßen Christian Krebs
Christian K. schrieb: > warum mein oben angehängtes Programm nicht läuft. Ich denke mal, da kann keiner helfen. Du hast die Modularisierung hoffnungslos übertrieben. Und Variablen und Funktionen mit 1, 2, 3, a, b, c usw. zu benamsen, macht den Ablauf für einen anderen völlig unverständlich. Variablen und Funktionen sollten immer beschreibend heißen. Auch sollten im Code niemals magische Port- und Bitnummern auftauchen. Alle IO-Pins werden in einem zentralen Header mit Namen versehen und im Code ausschließlich die Namen verwendet. Ändert sich was an der Verdrahtung, muß man das nur an einer einzigen Stelle anpassen. Entprellung und Flankenerkennung schadet nie. Drückt man z.B. länger, als eine Aktion dauert, wird sie nicht nochmal ausgeführt, sondern man muß erstmal loslassen und erneut drücken. Gerade Modelleisenbahnanlagen wachsen ständig und damit nehmen Drahtverhau und Störnebel ständig zu. Irgendwann wird einem daher die fehlende Entprellung auf die Füße fallen und sehr wehtun, d.h. wochenlange Fehlersuche bescheren. Auch altern Kontakte, d.h. sie sind nicht mehr so gut, wie fabrikneue. Ich benutze das EVA-Prinzip. Alle Eingänge werden eingelesen, dann verarbeitet und dann an die Ausgänge ausgegeben. Die Verarbeitung erfolgt ausschließlich im RAM, niemals direkt an den Pins. Damit hat man keine Sorge, daß verbotene Zwischenzustände auftreten können. Hier mal ein Auszug aus einer Steuerung:
1 | void key_scan( void ) |
2 | {
|
3 | if ( get_key_press( 1 << KEY_PLC )) |
4 | {
|
5 | if ( LED_PLC ) // PLC off |
6 | LED_PLC = 0; |
7 | else // PLC on |
8 | {
|
9 | LED_PLC = 1; |
10 | LED_HFC = 0; |
11 | }
|
12 | }
|
13 | if ( get_key_press( 1 << KEY_HFC )) |
14 | {
|
15 | if ( LED_HFC ) // HFC off |
16 | LED_HFC = 0; |
17 | else // HFC on |
18 | {
|
19 | LED_HFC = 1; |
20 | LED_PLC = 0; |
21 | LED_SHC = 0; |
22 | }
|
23 | }
|
24 | if ( get_key_press( 1 << KEY_SHC )) |
25 | {
|
26 | if ( LED_SHC ) // SHC off |
27 | LED_SHC = 0; |
28 | else // SHC on |
29 | {
|
30 | if ( ! LED_HFC && ! LED_PLC_DBM ) |
31 | LED_SHC = 1; |
32 | }
|
33 | }
|
34 | }
|
35 | |
36 | void control( void ) |
37 | {
|
38 | key_scan(); // handle key press |
39 | stc_actions(); // stc functions |
40 | plc_actions(); // plc functions |
41 | hfc_actions(); // hfc functions |
42 | calib_select(); // select ADC for calibration |
43 | adc_select(); // select ADC input channel |
44 | hfc_relays(); // hfc relay control |
45 | tlc_relays(); // tlc relay control |
46 | }
|
:
Bearbeitet durch User
Peter D. schrieb: > Alle IO-Pins werden in einem zentralen Header mit Namen versehen... Das ist ein weitaus größeres Problem als du annimmst. Portpins sind bei vielen Plattformen keine Einzeldinge, sondern sind in Ports zu mehreren Pins zusammengefaßt und können deshalb nicht einzeln angesprochen werden. Und einzelne Bits in Variablen im RAM kann man ebenfalls nicht einzeln ansprechen. Deshalb hat es zumeist so etwa folgendes Schema: 1. Variable bzw. Port laden 2. Operation durchführen 3. Ergebnis zurückschreiben Als Ausnahme fallen mir da grad die PIC von Microchip ein. Die haben direkte Unterstützung zum Ansprechen einzelner Bits im Maschinencode. Aber bei den meisten anderen Chips ist das nicht so. Ausnahmen wie z.B. Bitsetz- und Bitrücksetz-Register im jeweiligen GPIO-Core bei den Cortexen oder zusätzliche 'boolean'-Felder zu den GPIO-Cores brauchen wir hier nicht weiter zu diskutieren. Und so bleibt gerade in C nur eines übrig: Port (oder Variable) mit Namen versehen, Bit in diesem Port (oder dieser Variablen) mit Namen versehen. Man hat kein Ausdrucksmittel, um sowas wie
1 | #define MeinBit Portadresse,Bitnummer
|
tatsächlich zu definieren. Daraus ergeben sich nun 2 Probleme: 1. Darstellung des Bit: Entweder als schiere Bitnummer oder als (1<<Bitnummer). 2. Zuordnung von Port/Variable und Bit Beides muß bei allen Verwendungen des Bits im Programm richtig gemacht werden und bietet deshalb eine gute Gelegenheit für Schusselfehler. Insbesondere dann, wenn Definition und Verwendung weit auseinander liegen, bei die eben in 2 verschiedenen Dateien. Ich bin deshalb eher bei der Treiber-Version. Da hat man eine separate Quelle, die alle Beziehungen zwischen Bit und dessen physischer Ausführung erledigt. Heraus gucken da nur die Funktionen, also etwa sowas: Schranke_runter(); Lok_vorwärts(); Strecke_besetzt(); Strecke_frei(); na, und so weiter in solchem Stil. Das macht die Teile des Programms für die eigentliche Funktionalität recht gut lesbar und sperrt die Umsetzung zwischen 'Schranke runter' und dem Setzen/Löschen irgendeines Portbits in eine separate Datei, eben in einen Lowlevel-Treiber. Allerdings macht es auch die Firmware sperrig, wenn da ganze Heerscharen von Funktionen erforderlich sind. W.S.
W.S. schrieb: > Ich bin deshalb eher bei der Treiber-Version. Da hat man eine separate > Quelle, die alle Beziehungen zwischen Bit und dessen physischer > Ausführung erledigt. Heraus gucken da nur die Funktionen, also etwa > sowas: > Schranke_runter(); > Lok_vorwärts(); > Strecke_besetzt(); > Strecke_frei(); > na, und so weiter in solchem Stil. Das macht die Teile des Programms für > die eigentliche Funktionalität recht gut lesbar und sperrt die Umsetzung > zwischen 'Schranke runter' und dem Setzen/Löschen irgendeines Portbits > in eine separate Datei, eben in einen Lowlevel-Treiber. Volle Zustimmung. Abstraktion per portpins in defines ist Abstraktion für Leute die Abstraktion nicht verstanden haben. Das kann man in den Low-Level Treibern gerne machen, die Applikationslogik sollte davon aber nichts sehen. > Allerdings macht > es auch die Firmware sperrig, wenn da ganze Heerscharen von Funktionen > erforderlich sind. Es macht die Firmware erst modular und übersichtlich.
W.S. schrieb: > Allerdings macht > es auch die Firmware sperrig, wenn da ganze Heerscharen von Funktionen > erforderlich sind. Einmal definieren, nie wieder anfassen! (nur noch nutzen) Sperrig ist das nicht! Hier mal ein Beispiel aus meiner Arduino Wühlkiste! Ja, ich weiß, das schmeckt nicht jedem, treibt aber die Modularisierung auf eine "erträgliche" Spitze.
1 | /**
|
2 | * Ablaufdiagramm - Zeitdiagramm
|
3 | *
|
4 | * S1 _----------_____ Schalterstellung - Taster
|
5 | * OUT1 _-------------__ Verzoegertes abschalten - Absaugung
|
6 | * OUT2 ____-------_____ Verzoegertes einschalten - Kreissäge
|
7 | * Der Schalter S1 arbeitet invers und ist entprellt
|
8 | * Alle Zeiten in ms
|
9 | *
|
10 | */
|
11 | |
12 | #include <CombieTimer.h> |
13 | #include <CombiePin.h> |
14 | |
15 | #include <CombieTypeMangling.h> |
16 | using namespace Combie::Millis; |
17 | |
18 | using S1 = Combie::Pin::InvInputPin<2> ; // Taster zwischen Pin und GND(invertierend) |
19 | using OUT1 = Combie::Pin::OutputPin<3> ; // Absaugung |
20 | using OUT2 = Combie::Pin::OutputPin<4> ; // Kreissäge |
21 | |
22 | |
23 | Combie::Timer::EntprellTimer entprell { 20_ms}; // Schalter entprellen |
24 | Combie::Timer::RisingEdgeTimer ton {0.5_sec}; // steigende Flanke wird verzoegert |
25 | Combie::Timer::FallingEdgeTimer toff {500_ms}; // abfallende Flanke wird verzoegert |
26 | |
27 | void setup(void) |
28 | {
|
29 | S1{}.initPullup(); |
30 | OUT1{}.init(); |
31 | OUT2{}.init(); |
32 | }
|
33 | |
34 | void loop(void) |
35 | {
|
36 | bool schalter = entprell = S1{}; |
37 | OUT1{} = toff = schalter; |
38 | OUT2{} = ton = schalter; |
39 | }
|
EAF schrieb: > #include <CombieTimer.h> > #include <CombiePin.h> Was ist das für eine interessante Lib? Wie funktionieren das alles?
Einer schrieb: > Wie funktionieren das alles? Magie! Der dort verwendete Kram findet sich in dieser Zip. https://forum.arduino.cc/uploads/short-url/vdTvKr7F8mHxi2F1J2plss2IKrv.zip Prüfe und Urteile!
W.S. schrieb: > Man hat kein Ausdrucksmittel, um sowas wie#define MeinBit > Portadresse,Bitnummer > tatsächlich zu definieren. Doch. Z.B. der AVR-GCC kann das: Beitrag "Re: Port als Variable" Das sollte auch beim PIC gehen.
:
Bearbeitet durch User
Peter D. schrieb: > Doch. Hmm... Ich glaube, W.S. meint eher sowas:
1 | // https://www.mikrocontroller.net/attachment/319176/FastPin.h
|
2 | #include "FastPin.h" |
3 | |
4 | // die LED auf einem Arduino UNO Pin 13
|
5 | // physikalisch Port B Pin 5
|
6 | #define BuildInLED PINDEF(B,5)
|
7 | |
8 | void setup() |
9 | {
|
10 | setOutput(BuildInLED); |
11 | }
|
12 | |
13 | void loop() |
14 | {
|
15 | togglePin(BuildInLED); |
16 | delay(1000); |
17 | }
|
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.