Guten Tag.
Ich habe eine Frage zu einem Softwareproblem. Ich habe vor, eine kleine
variable Steuerung zu bauen. Es gibt ein Master und mehrere verschiedene
Slaves. Die Initialisierung ist soweit fertig. Beim Einschalten senden
die Slaves hintereinander ihre Adresse (entspricht Position) und ihre
Modul_ID. Die Modul_ID ist z.B. 0x13 16bit Digital In oder 0x82 16bit
Digital Out.
Der Master füllt bei diesem Durchlauf ein Array "char module[255]". Die
Adresse vom Slave ist der Index und der Inhalt die Modul_ID.
Jetzt will ich der Einfachheit und Variabilität wegen die Module wie
folgt ansprechen:
1
unsignedintbuffer;
2
buffer=Read_16bit_DI(1);// Lese die 16bit-Eingänge des ersten Moduls Typ 0x13
3
Copy_16bit_DO(2,buffer);// Kopiere buffer nach Ausgänge des zweiten Moduls Typ 0x82
Die Zahlen als Übergabewert soll das dementsprechende Modul ansprechen.
Aber das soll immer passieren, egal ob das erste Modul vom Typ 0x13 die
Adresse 5 oder 50 hat.
Da habe ich mir 2 Lösungen überlegt, wobei mich beides irgendwie nicht
zufrieden stellt ;)
1. Die Software durchläuft das Array "module" jedesmal und zählt bei
übereintreffender Modul_ID hoch, bis das gewünschte Modul gefunden
wurde. Ist also das erste 16bit DI-Modul gesucht, zählt er den Index vom
Array hoch. Hat er das erste gefunden, weiß er, welchen Index es hat,
was der Adresse entspricht.
2. Nach dem Initialisieren erstellt der Master pro Modul_ID noch ein
Array, wo er in Element 0 die Adresse des ersten Moduls vom
entsprechenden Typ ist. Element 1 wäre die Adresse vom zweiten usw.
Das Problem bei Nummer 1 ist, dass er bei jedem Ansprechen von irgend
einem Modul das Array durchlaufen muss. Das kostet jedesmal wieder Zeit
und ich finde das irgendwie unschön.
Das Problem bei Nummer 2 ist, dass er für knapp 50 verschiedene Module
ein Array machen muss, dass aber auch 255 Elemente haben muss, denn es
können ja auch 255 Module des selben Typs angeschlossen werden. Das
bedeutet aber auch, dass die meisten Arrays frei bleiben oder nur ein
oder zwei Einträge haben. In C kann man meines wissens auch kein Array
erstellen, dessen Elemente-Anzahl bei der Definition über eine Variable
bestimmt wird. Sonst könnte man vor dem Erstellen der Arrays pro
Modul_ID zählen, ob und wieviele es davon gibt und bräuchte seinen
Speicher nicht mit leeren Array-Elementen zu zumüllen. Denn 256 Byte *
50 sind 12800 Byte. Das ist viel zu viel und unnötig, da ich ja nur 256
davon brauche.
Gibt es eine bessere Lösung, die mir entgangen ist? Wie würdet ihr
soetwas machen?
programmierer schrieb:> In C kann man meines wissens auch kein Array> erstellen, dessen Elemente-Anzahl bei der Definition über eine Variable> bestimmt wird.
Mach dich mal schlau über malloc und free.
Hallo,
ich hatte mal so was ähnliches vor. Ist leider aus Zeitmangel
untergegangen. Ich hätte das mit einer einfach oder mehrfach verketteten
Liste und mit Alloziierung gemacht.
Ich hätte die Liste dann zunächst nach der ModulID "vertikal" und dann
die einzelnen Module mit der selben ID "horizontal" geordnet.
Ich versuchs mal grafisch dar zu stellen:
ModulID 1 - Adresse 0x00 - Adresse 0x01 - etc
|
ModulID 2 - Adresse 0x05 - Adresse 0x50 - etc
|
ModulID 3 - usw.
|
etc.
Vieleicht ist das ne Idee...
programmierer schrieb:> 1. Die Software durchläuft das Array "module" jedesmal und zählt bei> übereintreffender Modul_ID hoch, bis das gewünschte Modul gefunden> wurde. Ist also das erste 16bit DI-Modul gesucht, zählt er den Index vom> Array hoch. Hat er das erste gefunden, weiß er, welchen Index es hat,> was der Adresse entspricht.
Stichwort: Binäre Suche evt. auch Hashtabelle
Problem 2 verstehe ich nicht so ganz. Du hast irgendeine maximale Zahl
der Module? Und verschiedene Module haben unterschiedliche
Datenstrukturen? Entweder musst du das Array auf dein Maximum
dimensionieren oder mit dynamischer Speicherverwaltung arbeiten. Um
Module verschiedener Art (verschiedene Datenstrukturen) in wahlweise in
dem selben Speicherberecih zu verwalten könntest Du ein Kennzeichenbyte
am Anfang deiner Struktur der Modulbeschreibung machen und die
unterschiedliche Daten über eine Union definieren.
Ich programmiere mit dem mikroC PRO. Da kennt er die funktion malloc
nicht. Kann man da einfach die normale stdlib einbinden? Kann der
Compiler das trotzdem für einen µC verständlich machen, wenn man eine
Funktion benutzt, die Standardmäßig nicht beim Compiler dabei ist?
quadral schrieb:> Vieleicht ist das ne Idee...
Das ist ja ansich das Gleiche, was ich machen will. Nur da muss man auch
wissen, welche und wieviele Module es gibt.
U.R. Schmitt schrieb:> Problem 2 verstehe ich nicht so ganz.
Das Problem da ist, dass es funktionieren muss, ob ich von einem der 50
verschiedenen Arten von Modulen 100 Stück habe, oder aber zwei von jeder
Art von Modul. Bei dem ersten Fall ist ein Array recht voll, alle
anderen leer und im zweiten Fall sind alle Arrays nur mit 2 Einträgen
belegt. Egal bei welche Kombination habe ich maximal 255 Byte der 12800
Byte belegt. Und mein µC hat "nur" 4kB RAM.
Ein Anderer Gedanke, der mir gekommen ist:
Ich habe 50 char-Variable, eine für jeden Modul-Typ. Zusätzlich habe ich
ein zweites Array mit 255 Elementen. Jetzt könnte man nach der
Initialisierung das Array durchsuchen. Ich sage mal alle Arrays, die ich
vorher geplant hatte, kann man in ein einziges machen, da es ja
insgesammt nie mehr als 256 Module werden können. Die Modul_IDs, da ja
für die autmatisierte Suche gebraucht werden, kann man ja als Konstante
in den Programmspeicher schreiben. Somit brauche ich 50*Char und
2*256*Char -> 562 Byte. Damit kann ich leben. Durch die Variablen kann
man den "Start-Index" festlegen, wo ein bestimmter Typ von Modul
anfängt. Ist die Variable 0, gibt es kein Modul von dem Typ.
Code zur Verdeutlichung, wie ich das meine (nur mit 3 statt 50
Modul-Typen):
1
charmodulpos[256]={0x01,0x03,0x05,0x02,0x04,0x06}
2
charmodul_0x13=1,modul_0x82=4,modul_0x12=0;
3
// Wird nach Initialisierung automatisch erstellt bzw. gefüllt
4
// Adresse 01, 03, 05 ist vom Modul Typ 0x13
5
// Adresse 02, 04, 06 ist vom Modul Typ 0x82
6
// Kein Modul vom Typ 0x12 angeschlossen
7
8
charRead_8bit_DI(charposition){
9
chartemp,adresse;
10
if(modul_0x12>=1&&position>=1){
11
temp=(modul_0x12+position)-2;
12
}
13
adresse=modulpos[temp];
14
//....
15
}
16
unsignedintRead_16bit_DI(charposition){
17
chartemp,adresse;
18
if(modul_0x13>=1&&position>=1){
19
temp=(modul_0x13+position)-2;
20
}
21
adresse=modulpos[temp];
22
//....
23
}
24
voidCopy_16bit_DO(charposition,chartemp_buffer){
25
chartemp,adresse;
26
if(modul_0x82>=1&&position>=1){
27
temp=(modul_0x82+position)-2;
28
}
29
adresse=modulpos[temp];
30
//....
31
}
oder
1
charmodulpos[256]={0x01,0x02,0x03,0x04,0x05,0x06}
2
charmodul_0x13=1,modul_0x82=5,modul_0x55=0;
3
// Wird nach Initialisierung automatisch erstellt bzw. gefüllt
> 1. Die Software durchläuft das Array "module" jedesmal und zählt bei> übereintreffender Modul_ID hoch, bis das gewünschte Modul gefunden> wurde. Ist also das erste 16bit DI-Modul gesucht, zählt er den Index vom> Array hoch. Hat er das erste gefunden, weiß er, welchen Index es hat,> was der Adresse entspricht.>> Das Problem bei Nummer 1 ist, dass er bei jedem Ansprechen von irgend> einem Modul das Array durchlaufen muss. Das kostet jedesmal wieder Zeit> und ich finde das irgendwie unschön.>
Methode 1 ist so einfach, dass sie wahrscheinlich ziemlich schnell
fehlerfrei umzusetzen ist. Wie wirkt sich der erhöhte Zeitbedarf bei
Deiner Anwendung in der Praxis aus? YAGNI und KISS, optimieren kann man,
wenn die Sache läuft und sich als zu langsam erweist. Ich würde nicht
versuchen, im Vorfeld Probleme zu lösen, die noch gar keine sind.
Tom K. schrieb:> Wie wirkt sich der erhöhte Zeitbedarf bei> Deiner Anwendung in der Praxis aus? YAGNI und KISS,> optimieren kann man, wenn die Sache läuft und sich> als zu langsam erweist.
Ganz genau.
@programmierer:
Geh noch mal einen Schritt zurück. Frag nicht "wie kann ich dies und das
programmiertechnisch lösen?", sondern guck dir noch mal das Gesamtbild
an und erklär, was genau die Aufgabe ist.
Ich bezweifle nämlich, dass diese eierlegende Wollmilchsau im konkreten
Anwendungsfall notwendig ist. Was ändert sich denn von Mal zu Mal, dass
da bei jedem Programmstart alles gescannt und dynamisch zusammengesetzt
werden muss?
programmierer schrieb:> quadral schrieb:>> Vieleicht ist das ne Idee...>> Das ist ja ansich das Gleiche, was ich machen will. Nur da muss man auch> wissen, welche und wieviele Module es gibt.
Quatsch. Die Module melden sich doch bei deinem Master an. Ob du jetzt
Speicher alloziierst und das Objekt in die entsprechende Liste einhängst
oder dein Array durchläufst mach keinen Unterschied. Nur das du halt bei
der dynamischen Speicherverwaltung nicht so viel Speicher "verballerst"
wie bei deinem Array.
Mein entgültiges Ziel ist, dass ich eine Steuerung habe, in die ich (am
besten) über SD-Karte mein Programm "einlegen" kann. Das Programm soll
aber so aufgebaut sein, dass es egal ist, an welches Stelle welches
Modul ist. Somit kann ich, wenn ein 16bit Digital In Modul voll ist, ich
aber noch einen Input benötige, einfach ein zweites Modul hinten dran
hängen oder dazwischen, wo auch immer. Denn angesprochen wird es mit
Read_16bit_DI(2); und da soll es egal sein, an welcher Stelle -> welche
Adresse es hat. Jedes Modul mit fester Adresse zu programmieren und
vorher gucken, welche Adresse man schon gewählt hat ist meiner Meinung
nach doof, deshalb soll das alles beim Einschalten geregelt werden.
Keine Konfiguration mehr, welches Modul an welcher Stelle ist, wie z.b.
bei Step7. Das wird am Anfang automatisch gemacht. Am Master ist dann
ein kleines Display, wo man u.A. eine Auflistung hat, welches Modul wo
ist und bei einem Klick darauf, kann man die Aktuellen Zustände der
Ein-/Ausgänge sehen.
Als Beispiel: Ich habe an meinem Digital Output-Modul eine Lampe hängen,
die über zwei Taster eingeschaltet bzw ausgeschaltet werden. Wenn ich
jetzt einen 3. Taster dazu haben will, der das gleiche Licht anmachen
soll, ich aber keinen Eingang mehr frei habe, schnapp ich mir mein
Digital-Iinput-Modul und steck es hinten dran. Editiere im Programm eine
Zeile oder vielleicht auch zwei und fertig ist es.
Jedes Modul eines Typs hat das gleiche Programm, d.H. ich brauch nur die
Karte rausnehmen, die Zeile mit der Abfrage ändern und wieder
reinstecken.
Das Initialisieren kostet pro Modul 1ms -> bei Vollauslastung (wobei ich
erstmal keine 255 Module anhängen werde ;) ) wären dass 255ms, plus das
erstellen des Arrays, sollte die Initialisierung keine halbe Sekunde
dauern. Das sollte ja wohl gehen.
quadral schrieb:> Quatsch. Die Module melden sich doch bei deinem Master an. Ob du jetzt> Speicher alloziierst und das Objekt in die entsprechende Liste einhängst> oder dein Array durchläufst mach keinen Unterschied. Nur das du halt bei> der dynamischen Speicherverwaltung nicht so viel Speicher "verballerst"> wie bei deinem Array.
ja, ich hab mich da glaube ich falsch ausgedrückt. Ich meine, dass ich,
bevor ich eine Liste oder Tabelle oder Array erstelle, wissen muss,
wieviele Module ich von welchem Typ habe. Das weiß ich aber erst
hinterher, denn man kann ja kein global-gültiges Array (Liste/Tabelle)
mit vorher gezählter Anzahl an Elementen erstellen. Ich muss das ja in C
programmieren und der Compiler weiß ja noch nicht, wieviel von was wo
rein kommt. Also muss er ja erstmal alle Speicherregister reservieren.
Deswegen ja auch die DYNAMISCHE Speicherverwaltung.
Kleines Beispiel:
Das Modul 0 mit der ModulID 0x23 meldet sich bei deinem Master an. Du
erstellst ein neues Objekt, das für dieses Modul steht.
Jetzt übermittelt dir das Modul seine Adresse oder der Master weißt dem
Modul eine Adresse zu (Einmal schreibste ja, das die Module sich mit
ihrer Adresse anmelden und später dann, das eine feste Adressierung doof
wäre.)
Jetzt meldet sich Modul 1 mit der ModulID 0x44 an. Du erstellst wieder
ein Objekt und hängst dieses in die Liste ein, da es ja bis jetzt noch
kein Modul mit dieser ID gegeben hat. Es wird quasi vertikal eingehängt
(s.o)
Nun meldet sich Modul 2 an, das die selbe ID hat wie Modul 0. Da die ID
bereits bekannt ist, hängst du das Modul 2 "horizontal" hinter Modul 0
in die Liste ein.
usw.
Der Vorteil daran ist, dass die Module bereits nach ID und Adresse
geordnet sind, was dann später einen schnelleren Zugriff ermöglichen
kann.
> Deswegen ja auch die DYNAMISCHE Speicherverwaltung.
Die ist bei Controllern eher blöd.
Denn was soll er tun, wenn der Spiecher zu Ende ist ?
Man muß so oder so von vorneherein für genug Speicher sorgen.
Dann kann man ihn auch gleich statisch belegen.
Auch die Frage, ob ich ein Array nun linear durchsuche,
ob ich überhaupt ein Array nach Nummern habe oder doch
nur einfach hintereinander alle empfangenen IDs speichere,
ist letztlich egal:
Hab ich die Zeit, kann ich mir den Aufwand z.B. einer doppelten
Datenstruktur sparen, manchmal muß ich mir den Speicherplatz
sogar sparen und nehme lieber ein langsameres Programm in Kauf.
Es gibt also keine Patentlösung, es ist immer eine Abwägung
der Anforderungen, trade space for speed, und der Knappheit
(wenn weder Speicher noch Zeit knapp sind, kann ich beliebigen
Unsinn programmieren, sogar dynamische Speicherverwaltung...)
Es gibt nur einen Tip: Keep it simple !
quadral schrieb:> Einmal schreibste ja, das die Module sich mit> ihrer Adresse anmelden und später dann, das eine feste Adressierung doof> wäre.)
Der Slave / Das Modul schickt seine Adresse und seine ModulID zum
Master. Mit fester Adressierung meine ich, dass ein Slave eine fest
einprogrammierte Adresse hat. Das ist aber nicht so.
quadral schrieb:> Kleines Beispiel:....
Achso, jetzt verstehe ich, wie du das meinst. Allerdings wüsste ich auf
anhieb nicht, wie ich das Programmieren könnte. Das "anhängen" ist ja
quasi das, was schön wäre, denn dann müsste ich nicht von vornherein
definieren, wieviel Spalten oder Zeilen ich habe.
MaWin schrieb:> Es gibt also keine Patentlösung, es ist immer eine Abwägung> der Anforderungen, trade space for speed, und der Knappheit> (wenn weder Speicher noch Zeit knapp sind, kann ich beliebigen> Unsinn programmieren, sogar dynamische Speicherverwaltung...)>> Es gibt nur einen Tip: Keep it simple !
Ich werde mal gucken. Ich denke entweder jedesmal durchgucken, oder so
wie ich es in meinem vorletzten Post gemacht erklärt habe.
Tja. Die Auslastung des Speichers ist letztendlich von der Anzahl der
möglichen Module abhängig. Wenn du dir nun einen Baugruppenträger
vorstellst, der sowieso nur 12 Einschübe tragen kann, brauchst du auch
nur Speicherplatz für 12 Einschübe. Von welchem Typ der Einschub nun
ist, ist egal, da durch die dynamische Verwaltung eh alle Objekte gleich
sind.
Das macht dann letztendlich mehr Sinn, als ein Array mit der Größe
Anzahl der Module * Anzahl der Typen zu erstellen, wie er es im ersten
Post unter 2. vorhatte.
Im Fall 1. gebe ich dir bezüglich des Speicherplatzes natürlich recht.
Allerdings kann der Zugriff über eine Liste dann schneller sein ;-).
Wenn du beispielsweise alle Digital-In Module nacheinander Abfragen
möchtest, kannst du ja die letzte Liste auf die Erste verweisen lassen.
Du musste dann nur einmal die ID suchen.
Oder wenn er nur ein DI-Modul und auch nur ein DO-Modul hat, die auch
noch von ihren ID's her direkt hintereinander in der Liste liegen,
müsste er, um auf ein Eingangssignal mit einem Ausgangssignal zu
reagieren einfach nur den Pointer, der auf die ID verweist in- oder
dekrementieren und hätte das DO-Modul.
Es ist einfach mehr Ordnung drinne.
Gut dafür ist der Aufwand beim Schreiben dann größer. Die ganzen Pointer
erstmal zurechtbiegen etc. Nervt...
MaWin schrieb:> Es gibt nur einen Tip: Keep it simple !
Wonach der Ansatz hier allerdings garnicht aussieht.
Es muß erstmal einen triftigen Grund geben, warum ich mir die erheblich
höhere Komplexität einer Vernetzung mehrerer MCs überhaupt aufhalsen
will.
Z.B. daß lange Leitungen bestehen und ich Drähte sparen will. Allerdings
bringt es dann nichts, wenn ein Modul nur 16 Ausgänge hat. In der Regel
brauche ich von allem etwas (analog/digital In/Out), um eine
Funktionseinheit anzusteuern. Daher sollten die Module frei
konfigurierbar sein.
Brauche ich aber nur zusätzliche IO-Pins, dann nehme ich einfache
Logik-ICs (74HC595/165) und kaskadiere sie.
Peter
quadral schrieb:> Tja. Die Auslastung des Speichers ist letztendlich von der Anzahl der> möglichen Module abhängig. Wenn du dir nun einen Baugruppenträger> vorstellst, der sowieso nur 12 Einschübe tragen kann, brauchst du auch> nur Speicherplatz für 12 Einschübe. Von welchem Typ der Einschub nun> ist, ist egal, da durch die dynamische Verwaltung eh alle Objekte gleich> sind.
Ja schon, aber man könnte ja auch mit einem Verbindungskabel 2 Schienen
verbinden, a la SPS, oder noch mehr. Ich hab mir einfach gedacht, mit
8bit Adressen kann man 255 Module ansprechen, also programmiere ich auch
gleich so, dass es mit 255 Modulen geht.
quadral schrieb:> Das macht dann letztendlich mehr Sinn, als ein Array mit der Größe> Anzahl der Module * Anzahl der Typen zu erstellen, wie er es im ersten> Post unter 2. vorhatte.
Deswegen hab ich den Gedanken ja auch verworfen.
Peter Dannegger schrieb:> Allerdings> bringt es dann nichts, wenn ein Modul nur 16 Ausgänge hat. In der Regel> brauche ich von allem etwas (analog/digital In/Out), um eine> Funktionseinheit anzusteuern. Daher sollten die Module frei> konfigurierbar sein.>> Brauche ich aber nur zusätzliche IO-Pins, dann nehme ich einfache> Logik-ICs (74HC595/165) und kaskadiere sie.
Ich hab ja auch mehrere Module geplant, verschiedene, gemischte usw. Die
beiden hab ich nur rausgesucht, weil ich daran meine Frage erklären
wollte. Z.b. hab ich neben "normalen" Analog-In/Out Modulen auch ein
Modul geplant, an dem gewisse Temperatursensoren angeschlossen werden
und gleich im Modul in Kelvin oder Celsius umgerechnet werden. Spart dem
Master / dem Programm auch wieder Arbeit.
Ich habe bei dem 16bit Digital-In/Out auch gedacht, die Anschlussklemmen
neben und (schräg) übereinander zu machen. Also 4 nebeneinander und in
Stufen quasi 4 übereinander. Bei einem Raster von 5.08mm sind das ~20mm
Breite, also kommt man mit einem 25-30mm breiten Modul locker hin und
kann soviele wie man braucht anstecken. Warum sollte ich ein Modul
haben, mit dem ich zwar 32 oder auch 64 Eingänge habe, ich aber nur 15
brauche. Ob Digital oder Analog, ist ja erstmal egal. Dann nehme ich
lieber 4 16kanälige Module, wenn ich 64 brauche, statt nur 64kanälige
Module zu haben und wenn ich 10 oder 15 brauche, Platz und "Geld" zu
verschwenden.
programmierer schrieb:> einfach ein zweites Modul hinten dran> hängen oder dazwischen, wo auch immer. Denn angesprochen wird es mit> Read_16bit_DI(2); und da soll es egal sein, an welcher Stelle -> welche> Adresse es hat.
Wieso kriegt das die Nummer 2? Wovon hängt das ab? Und wenn du alles
aus- und wieder einschaltest - bleibt die Zuordnung dieselbe? Warum ist
das so?
programmierer schrieb:> Jedes Modul mit fester Adresse zu programmieren und> vorher gucken, welche Adresse man schon gewählt hat ist meiner Meinung> nach doof, deshalb soll das alles beim Einschalten geregelt werden.
OK, die Module kommen also alle doof auf die Welt und müssen sich erst
mal vom Master eine Adresse holen. Aber woher weiß der denn, welches der
30 Module, die gerade eine Adresse wollen, dasjenige ist, welches das
Licht im Keller schaltet? Oder das Licht im Erdgeschoss?
Irgendwie schnall ich das System noch nicht.
Das erste Modul sendet an den Master die Adresse 1 und seine ModulID.
Die ModulID ist fest drinne, muss ja auch, weil das Programm auch davon
abhängig ist, was es kann etc.
Wenn der gesendet hat, weiß jedes andere Modul, dass ein Modul schon
gesendet hat und zählen einen Zähler hoch. Dann schickt das zweite Modul
die Adresse 2, zusammen mit seiner ModulID.
Es ist ansich ein Paralleler Bus, nur eine Leitung ist seriell, sodass
jeder weiß, wann er dran ist zu senden. Die Leitung ist nur für die
Initialisierung nötig, danach quasi tot.
Ansich bräuchte man die Adresse nicht mitsenden, da der Master ja auch
hochzählen kann. Nur hab ich ein Protokoll, das immer 4 Byte schickt.
Adresse, Befehl, Data1, Data2. Data1 ist dann die Adresse und Data2 die
ModulID.
Auf dieses Problem bin ich damals auch gestoßen.
Die Antwort ist Simple: Daisy Chain.
Der Einschub der direkt neben dem Master hockt, ist demnach in der Daisy
Chain der Erste, der eine Adresse bekommt. Ist er angemeldet und hat
eine Adresse, ist der Nachbar dran. Die Anmeldung wird dann von Einschub
zu Einschub weitergereicht.
Später kann man sich dann überlegen, ob man die serielle Adressierung
per Flüsterpost weiterreicht oder eine eigene Leiterbahn dafür nutzt.
Gut, es fallen dann pro µC bis zu 3 Eingänge weg, aber dafür braucht man
dann eben nicht so viele Bahnen aufem Bus. In diesem Fall hier dann
255... Muss man sich halt überlegen.
Die IO-Reihenfolge kann man dann ja ganz einfach festlegen. Der mit der
niedrigsten Adresse unter den Digital-Out-Modulen schaltet dann das
Licht im Keller ein usw...
Ich will das so machen:
Die Schaltung startet/bekommt Strom und die µCs auf dem Master und auf
den Modulen sind im Init-Modus. Die Slaves warten auf ein High-Signal an
der Init-Leitung. Wenn der Master geprüft hat, ob an seinem Test-Eingang
ein Highsignal ist, dann setzt er die Init-Leitung auf high. Das erste
Modul bekommt das mit und sendet seine Adresse + Modul_ID über den
Parallelbus zum Master. Das dauert ca 0,5ms. Der Kasten "1ms" ist eine
1-Millisekunden-Einschaltverzögerung. Also kommt das Highsignal vorne
rein, wartet die Schaltung 1ms (in der Zwischenzeit sendet das Modul)
und setzt dann die Init-Leitung zum nächsten Modul auf High. Sollte ein
Modul an seinem Test-Eingang kein High-Signal haben, sendet er eine
End-Bedingung, weil es das letzte Modul ist.
Man kann natürlich auch das Init-Signal per µC weiterreichen, doch was
ist, wenn er sich aufgehangen hat oder ausgefallen/defekt ist. Dann ist
ab dem Modul alles tot. Ich brauche die Test-Leitung, damit der letzte
Slave eine Endbedingung schicken kann. Sollte aber das letzte Modul
einen defekten µC haben wird es doof^^ Dann muss ich im Master die
gesammte Initialisierung stoppen (ich meine Zeit messen, nicht anhalten)
und nach 300ms oder so einfach beenden. Nur das ist worst-case. Im
Normalfall muss man ja nicht die volle Zeit warten, wenn nur 3 oder 4
Module angeschlossen sind.
Ich weiß, dass im Blockdiagramm Sachen fehlen, wie z.B.
GND,5V,ParallelBus sind nicht am µC angeschlossen.