Forum: Mikrocontroller und Digitale Elektronik Wie programmiere ich das am besten.


von programmierer (Gast)


Lesenswert?

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
unsigned int buffer;
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?

von Skua (Gast)


Lesenswert?

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.

von quadral (Gast)


Lesenswert?

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...

von U.R. Schmitt (Gast)


Lesenswert?

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.

von programmierer (Gast)


Lesenswert?

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
char modulpos[256] = {0x01, 0x03, 0x05, 0x02, 0x04, 0x06}
2
char modul_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
char Read_8bit_DI(char position){
9
    char temp, adresse;
10
    if(modul_0x12 >= 1 && position >= 1){
11
        temp = (modul_0x12 + position) - 2;
12
    }
13
    adresse = modulpos[temp];
14
    //....
15
}
16
unsigned int Read_16bit_DI(char position){
17
    char temp, adresse;
18
    if(modul_0x13 >= 1 && position >= 1){
19
        temp = (modul_0x13 + position) - 2;
20
    }
21
    adresse = modulpos[temp];
22
    //....
23
}
24
void Copy_16bit_DO(char position, char temp_buffer){
25
    char temp, adresse;
26
    if(modul_0x82 >= 1 && position >= 1){
27
        temp = (modul_0x82 + position) - 2;
28
    }
29
    adresse = modulpos[temp];
30
    //....
31
}

oder
1
char modulpos[256] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}
2
char modul_0x13 = 1, modul_0x82 = 5, modul_0x55 = 0;
3
// Wird nach Initialisierung automatisch erstellt bzw. gefüllt
4
// Adresse 01, 02, 03, 04 ist vom Modul Typ 0x13
5
// Adresse 05, 06 ist vom Modul Typ 0x82
6
// Kein Modul vom Typ 0x12 angeschlossen
7
8
char Read_8bit_DI(char position){
9
    char temp, adresse;
10
    if(modul_0x12 >= 1 && position >= 1){
11
        temp = (modul_0x12 + position) - 2;
12
    }
13
    adresse = modulpos[temp];
14
    //....
15
}
16
unsigned int Read_16bit_DI(char position){
17
    char temp, adresse;
18
    if(modul_0x13 >= 1 && position >= 1){
19
        temp = (modul_0x13 + position) - 2;
20
    }
21
    adresse = modulpos[temp];
22
    //....
23
}
24
void Copy_16bit_DO(char position, char temp_buffer){
25
    char temp, adresse;
26
    if(modul_0x82 >= 1 && position >= 1){
27
        temp = (modul_0x82 + position) - 2;
28
    }
29
    adresse = modulpos[temp];
30
    //....
31
}

von Tom K. (ez81)


Lesenswert?

> 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.

von willibald (Gast)


Lesenswert?

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?

von quadral (Gast)


Lesenswert?

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.

von programmierer (Gast)


Lesenswert?

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.

von programmierer (Gast)


Lesenswert?

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.

von quadral (Gast)


Lesenswert?

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.

von MaWin (Gast)


Lesenswert?

> 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 !

von programmierer (Gast)


Lesenswert?

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.

von quadral (Gast)


Lesenswert?

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...

von Peter D. (peda)


Lesenswert?

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

von programmierer (Gast)


Lesenswert?

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.

von willibald (Gast)


Lesenswert?

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.

von programmierer (Gast)


Lesenswert?

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.

von quadral (Gast)


Lesenswert?

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.

von quadral (Gast)


Lesenswert?

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...

von programmierer (Gast)


Angehängte Dateien:

Lesenswert?

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.

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
Noch kein Account? Hier anmelden.