Hallo,
ich arbeite schon etwas länger mit den AVR Controllern (Mega 8/32 usw)
und programmiere diese in Bascom. Inzwischen kann ich Bascom recht gut,
auch weil ich mir letztens ein Fachbuch gekauft habe.
Jetz möchte ich mich so langsam an das Vernetzen der AVRs wagen. (Für
Hausbus etc)
Schade nur, dass im Fachbuch kein Wort darüber verloren wird, wie man
mehrere AVRs verbindet. Nur 2 AVR über RS232 bzw. UART zu verbinden ist
ja schnuckelig einfach. Nur eben nicht das, was man für ein Netzwerk mit
sagen wir mal 20 AVRs geeignet ist.
Ein wenig Googeln und es kommen verschiedene Methoden zum Einsatz.
Funk über RFM12 Module. Scheint aufwändig zu sein und wird dann nur in
einem Raum funktionieren. Über mehrer Stockwerke mit Beton sicher nicht.
Fällt also flach.
RS485 - Billige und wenige Komponenten. Dafür aber keine Zentrale
Sternverteilung möglich, da alle Controller an einem Strang sein müssen.
Protokoll muss selber definiert werden
CAN - Protokoll schon vorhanden, anscheinend Sternverteilung möglich,
bischen mehr und teurere Komponenten als RS485.
Problem. Ich suche mich schon seit Stunden "dumm und deppert" obwohl ich
eigentlich schlauer werden will.
Über CAN findet man relativ wenig mit Bascom.
RS485, da sieht es schon etwas besser aus aber Code und Protokoll,
Buskollisionen usw. Alles nicht so einfach zu verstehn und da hilft es
mir nicht, wenn einer ein Projekt damit gemacht hat, mir den Quellcode
gibt und ich dann den RS485 Code aus dem 5000 Zeilen Programm rausfinden
soll, welches zudem nicht kommentiert ist.
Ich sucher eher nach einem kurzen und knappen Code, der nur die RS485
Routine samt Protokoll enthält. Möglichst kommentiert, warum jetz dieser
und jener Befehl verwendet wird.
Sagen wir mal so als einfaches Anfängerprojekt. Ein Master und 2 Slaves.
Jeweils Atmega 8 oder was auch immer. Max485 Controller an jeden AVR und
schon kann es losgehen.
Den ersten AVR beschalten wir mit ein, zwei Tastern und einem LCD. Den
ersten Slave ebenfalls mit einem Taster und einer Led und an den zweiten
Slave ein LM335 Temperatursensor.
Dann soll der Master nach Tastendruck z.B. an Slave 1 Senden "Schalte
Led ein". Druck auf Taster 2 sendet an Slave 2 "Gib mir Temperatur",
dann Sendet Slave 2 die Temperatur an den Master. Jetzt soll der Master
auch noch prüfen ob an Slave 1 der Taster gedrückt ist.
In diesem Beispiel wäre so ziemlich alles wichtige zum Verständnis mit
Rs485 oder einer anderen Technik drin. Zustand abfragen und einem
Controller Anweisungen geben. Nur so etwas habe ich im Netz nicht
gefunden.
Also wenn sich damit jemand auskennt, könnte er so einen Code (In
Bascom) erstellen inkl. Schaltplan? Ich denke damit wäre nicht nur ich
glücklich.
Hi
Du schreibst, das du bereits mit AVR's unter Bascom gearbeitet hast und
wünscht dir, das dir jemand einen Code sowie die Schaltpläne liefert...
Mir riecht das stark nach:
"Kann mir mal jemand meine Arbeit machen ?"
Ok, gehen wir mal davon aus, du sprichst die Wahrheit und eine RS 232
Verbindung zwischen 2 Controllern ist für dich kein Problem. Dann denk
doch mal nach, wie du mehrere Controller ganz einfach vernetzen kannst.
Du betrachtest die RxD und TxD- Leitungen einfach als Ring. Nun
schleifst du deine µC's alle in diesen Ring. Also, von TxD geht's auf
RxD, bis alle Controller verbunden sind. Nun definierst du ein
Protokoll.
Z.B. Quelle, Ziel, Daten
Quelle ist der sendende µC, Ziel der angesprochen werden soll. Nun
sendest du z.B con Controller "0", von mir aus der Basiscontroller, an
den µC mit Nr.6
Das Telegramm erreicht zuerst den µC 2. Der stellt fest "is nix für mich
und schickt es wieder raus. Der Nächste ist vielleicht µC mit Nummer 7.
Auch der schleift das Telegramm einfach durch. Irgendwann erhält µC Nr.6
das Telegramm, bearbeitet die Daten und gibt Rückmeldung an die Quelle.
Nschteil ist eine rel. lange Laufzeit, da ein solches Ringtelegramm ja
immer erst empfangen und ausgewertet werden muß. Trotzdem ist diese Art
vorzugehen bei nicht zeitkritischen Anwendungen gar nicht so schlecht,
da auch die Verkabelung sich in Grenzen hält. Auch müssen die Controller
nicht der Reihe nach in der Kette stehen, sondern es reicht, wenn jeder
µC eine Nr. besitzt. Diese kann Bspw. im EEProm liegen. Die Empfangs-
und Senderoutinen sind alle gleich zu halten. Das erspart auch
Programmierarbeit. Du siehst, nicht alles steht in Büchern, manches darf
man sich ruhig auch mal ausdenken.
Obwohl, solch eine Vorgehensart ist nix neues....
Gruß oldmax
Ich will nicht das mir jemand die Arbeit macht. Ich will ja lernen. Oder
habe ich geschrieben "Entwickelt mir mal jemand einen kompletten Hausbus
(ca. 20 Controller) mit folgenen Funktionionen..."
Ich habe um ein Beispiel gebeten wie so etwas funktioniert, anhand von
einem Master und 2 Slaves die einfache Dinge austauschen. Und wenn ich
das dann verstanden habe, kann ich es ja SELBER auf mein geplantes
Controllernetzwerk bzw Hausbus umsetzen.
Dein beschriebenes "Protokoll" ist irgendwie auch nicht das richtige.
Wenn der Befehl erst durch 20 Controller durchgejagt werden muss um dann
nach einer halben Ewigkeit am Zielcontroller zu sein (geschweige denn,
dass die anderen Controller hier den kompletten Datenstrom auswerten
müssen und dann weitersenden und so Rechenleitung verschenkt wird), dann
nenne ich das nicht sehr optimal.
Und ein RS485 Netz wird sicher nicht mit Print, Input usw. richtig gut
funktionieren. (Was ich sonst immer bei RS232 verwendet habe)
Deswegen ja die Frage, ob da nicht jemand ein kleines Tutorial schreiben
könnte. Damit man sowas von Grund auf vertehen kann und wie es richtig
funktioniert.
Florian schrieb:> Dein beschriebenes "Protokoll" ist irgendwie auch nicht das richtige.> Wenn der Befehl erst durch 20 Controller durchgejagt werden muss um dann> nach einer halben Ewigkeit am Zielcontroller zu sein (geschweige denn,> dass die anderen Controller hier den kompletten Datenstrom auswerten> müssen und dann weitersenden und so Rechenleitung verschenkt wird), dann> nenne ich das nicht sehr optimal.
Dann denk dir halt was anderes aus.
Erlaubt ist was gefällt.
> Und ein RS485 Netz wird sicher nicht mit Print, Input usw. richtig gut> funktionieren. (Was ich sonst immer bei RS232 verwendet habe)
Öhm.
Wenn du derartige Dinge machst, kannst du dir die simplen
Standardfunktionen höchst wahrscheinlich alle abschminken. Da musst du
dann selber rann, anstatt alles einer vorgefertigten Print Funktion zu
überlassen.
Hallo.
Also RS485 ist ansich relativ einfach.
Du kannst den Print-Befehl dafür auch benutzen.
UM ein RS485-Netzwerk aufzubauen, brauchst du Buscontroller wie zum
Beispiel den MAX485.
AN den wird die Betriebsspannung angeschlossen, zwei adern für den Bus
und RxD, TxD und Richtungswahl. Danach ist nur der Unterschied, dass dui
bevor du etwas sendest den 'Richtungswahl' PIn auf high ziehen musst und
das wars auch schon.
Um dies am anderen Controller zu empfangen, empfehle ich dir den
Interrupt.
AVRs haben einen hardware empfangspuffer den du dann abfragen kannst.
UDR ist das register.
Das ist doch mal eine Antwort.
Von den "Vollprofis" bekommt man immer nur: Denk dirs selber aus wir
machen hier garnix. Und Bascom ist fürn Schrott lern C. So interpretier
ich zumindest die beiden ersten Antworten und das ist nicht wirklich
hilfreich.
Und wenn es eben halt nicht mit Print usw. funktioniert, dann erklärts
mir doch bitte wie es denn sonst geht. Wenn ihr mir nur sagt: Ne so
funktionierts nicht, dann weiß ich zwar dass es so nciht funktioniert
aber nicht wie es denn sonst funktioniert.
Zurück zum Thema:
Also ich brauch schonmal Buscontroller. Gut wie der angeschlossen wird
weiß ich jetzt auch. Im Datenblatt konnte ich dann auch sehen wie
mehrere angeschlossen werden an einem Bus inkl. einer Terminierung.
Hardwareseite also geklärt. Softwareseitig bin ich immernoch auf dem
Holzpfad.
Ich habe viel gelesen und bin noch mehr verwirrt. Von Protokollen ist
die rede, Buskolissionen, Checksummen usw. Und da bräuchte ich eben ein
gut kommentiertes Beispiel, wie so ein Protokoll aussieht und in Bascom
umgesetzt ist.
Hi
>Ich habe viel gelesen und bin noch mehr verwirrt. Von Protokollen ist>die rede, Buskolissionen, Checksummen usw. Und da bräuchte ich eben ein>gut kommentiertes Beispiel, wie so ein Protokoll aussieht und in Bascom>umgesetzt ist.
Wenn du nur einen Master hast geht das ganze relativ einfach. AVRs mit
einer Hardware-Uart besitzen einen 'Multi-processor Communication Mode'.
Der ist genau dafür gemacht. Allerdings weiß ich nicht, ob der von
BASCOM direkt unterstützt wird. Aber man kann ja die Register auch
direkt ansprechen. Also auchkeine Hürde. Lies das mal im Datenblatt
nach.
MfG Spess
Hi
>Dein beschriebenes "Protokoll" ist irgendwie auch nicht das richtige.>Wenn der Befehl erst durch 20 Controller durchgejagt werden muss um dann>nach einer halben Ewigkeit am Zielcontroller zu sein (geschweige denn,>dass die anderen Controller hier den kompletten Datenstrom auswerten>müssen und dann weitersenden und so Rechenleitung verschenkt wird), dann>nenne ich das nicht sehr optimal.
Abgesehen von weiteren Inhalten deiner Antwort will ich mal nur auf
diesen Teil Bezug nehmen. Bevor du hier Lautstark dein "Nicht Wissen"
verkündest, nur mal ein Beispiel, was Zeit betrifft.
1. Ein solcher Aufbau ist Leitungstechnisch völlig einfach zu
realisieren. Du brauchst noch nicht einmal unbedingt einen RS232-
Umsetzer.
2. Wennn du das erste gesendete zeichen für die Zieladresse nimmst,
braucht auch nur 1 Zeichen ausgewertet werden, ob das Telegramm für den
empfangenen Controller relevant ist.
3. Zeit. Wenn du mit einer Baudrate von 19600 sendest, und 10 Bit pro
Information hast (Datenbits, Stoppbits) sind immerhin bei Ziel+
Quelle+8Byte Nutzdaten 1960 Byte pro Sekunde beim 1. Controller. Wenn du
20 ansprichst und der letzte bekommt die Info, dann braucht die Info
grob 1/80 Sekunden. Selbst wenn du nur 1 Zehntel Sekunde Reaktionszeit
hättest, ich wüßte nicht, was im Haus eine höhere Real-Time-Anforderung
braucht. Manchmal sind Tipps nicht gleich zu verwerfen. Es gibt andere,
schnellere Verfahren. Sicher. Aber sind diese Hardwaremäßig auch so
einfach realisierbar ? Die Software und die Auswerteroutinen dürften
sich gar nicht so sehr unterscheiden.
>Das ist doch mal eine Antwort.>Von den "Vollprofis" bekommt man immer nur: Denk dirs selber aus wir>machen hier garnix. Und Bascom ist fürn Schrott lern C. So interpretier>ich zumindest die beiden ersten Antworten und das ist nicht wirklich>hilfreich.
Dennoch, du sprichst davon, Erfahrungen mit der Kommunikation in Basic
von Controller zu Controller zu haben. Da war diese Info gar nicht die
eines hochnäsigen "Experten" und keiner hat auch nur ansatzweise über
Basic gelästert. Wenn du dir da selber Minderwertigkeitsgefühle hinein
interpretieren willst, bitte. Da ich aber nicht in Basic schreibe (ich
kann es nicht !) kann ich nur auf Prinzipien verweisen.
Ein Telegramm, um in jedem Zimmer alle Temperaturen bspw. im Haus
abzufragen könnte wie folgt aufgebaut sein:
Ziel = 255 = alle Controller
oder Ziel =7 = Controller 7
Quelle = eigene ID
8 Byte Nutzdaten = 5 Raumtemperaturen + 2 Statusbytes Eingang + 1
Statusbyte Ausgang
Das Ganze empfängst du per Interrupt und packst es in einen Ringpuffer.
Dann wertest du das erste Byte aus und erkennst
Selbst bearbeiten oder
selbst bearbeiten und weiterreichen oder
nur weiterreichen
Ich kann dir sagen, das ich schätze, es ist in Basic vielleicht
einfacher umzusetzen als in Assembler. Wenn ich in meinem Haus so etwas
vorhätte, dann würden mir die einfachen Verkabelungen sehr
entgegenkommen und ich bin jederzeit in der Lage, einen Controller
irgendwo einzuschleifen. Die Nummern müssen nämlich nicht in der Reihe
liegen, sondern es können überall "freie" Nummern zwischengeschaltet
werden.
Wo bitteschön ist bei diesem Prinzip das Agrument "völliger Quatsch"
oder mit deinen Worten "suboptimal" angebracht ?
Gruß oldmax
@oldmax
Schönes Konzept, weil einfach und übersichtlich. Wenn der jeweilige
Master den von ihm erzeugten Ist-Buszustand wieder einliest und mit dem
Soll-Buszustand vergleicht, lassen sich auch Störungsroutinen einfach
realisieren.
Jaaa ... RS485 hat schon n paar Stolpersteine eingebaut und es kommt
auch stark auf die Komplexität der Aufgabe an wie es realisiert werden
kann.
Zunächst mal kannst Du die Bascomfunktionen wie Print und Input
verwenden. Über Config Print kannst Du auch die Richtungsumschaltung des
485-Bausteins aktivieren, dann kannst DU einfach per Print die Daten
raus senden.
Daraus kannst Du Dir dann n einfaches Protokoll mit Texten und Zahlen,
also Strings zimmern ... der Nachteil, die Auswertung ist mitunter
haarig und geht auf die Reechenleistung weil Strings ausgewertet werden
müssen, zum Anderen wird bei Print dann der µC im Programmablauf dort
gestoppt bis alle Zeichen übertragen sind. Eine solche Message könnte
z.B. so aussehen:
20,1,a,1023 ... 20 = Empfänger, 1 = Sender, a= Parameter A, 1024 =
Parameterwert
Der Empfänger muss dann den String mindestens bis zum ersten ","
einlesen um zu sehen ob er gemeint ist ... bei Empfang per Input muss er
sogar den ganzen String empfangen bis zum CR-LF am Ende.
Derweil hängt das Programm im Input fest.
Bei einfachen Anwendungen kann das sogar schon reichen, kritischer wirds
wenn da noch andere Funktionen vom µC ausgeführt werden sollen. Dann
geht man hin und lässt diesen per Interrupt empfangen und reiht die
Daten hintereinander auf in einem String oder Array. Der Interrupt heißt
dann URXC und wird bei jedem empfangenen Zeichen ausgelöst.
So hat man den Programmstillstand im Input schonmal umschifft ... aber
der µC muss halt auch wissen wann ein Paket komplett empfangen wurde.
Dafür gibt es im Prinzip zwei Techniken. Entweder Dein Paket hat eine
festgelegte Länge, die entweder bei jedem Paket mit übertragen wird oder
Du sagst, wenn x Millisekunden nix übertragen wurde ist das Paket
komplett und wertest dann aus. Letzteres kann z.B. mit einem Timer
realisiert werden, der bei einem URXC Interrupt zurückgesetzt wird und
bei Überlauf eben n Flag setzt.
Beim Senden per Print hast Du ja wie gesagt das Problem, dass während
der Ausführung das Programm im Print stehen bleibt bis alles übertragen
ist. Auch hier gibt es eine Methode um das zu verhindern, den
UTXC-Interrupt. Er funktioniert wie der Empfangsinterrupt nur in die
andere Richtung, wird ausgelöst wenn ein Zeichen gesendet ist. Man geht
dann einfach hin, schreibt seine zu sendende Message in ein Array oder
String, scchickt das erste Zeichen auf das UDR-Register und los gehts.
Ist das Zeichen raus, wird der Interrupt ausgelöst, man schiebt das
nächste Zeichen ins UDR usw. bis eben die ganze Message raus ist, dann
stoppt man, indem man einfach kein Zeichen sendet.
Wenn man mehrere Slaves am Bus hat kann es dann irgendwann schon eng
werden mit dem Timing, die Baudrate hängt stark von der Bustopologie und
den Kabeln ab, sodass hier Grenzen gesetzt sind. Dann wird es u.U.
notwendig ein kürzeres Protokoll zu verwenden, die Bytes sinnvoller zu
nutzen. Das erste Beispiel war 11 Byte lang, man könnte es aber auch
anders formulieren:
&H14 &H01 &H41 &Hff &Hff ... das sind dann noch 5 Bytes, also nur
weniger als die Hälfte der Daten mit dem gleichen Inhalt und schneller
zu verarbeiten, da keine Stringauswertung vorgenommen werden muss.
Dann haben wir ja noch Störungen immer und überall um uns herum, die
eben auch abgefangen werden sollten. In der Übertragung macht man es
meist so, dass am Ende der Message ne Prüfsumme angehängt wird, CRC8
CRC16 etc.. Schau mal in die Bascomhilfe rein, da sind die erwähnt.
Die Protokollauswertung kann dann so gemacht werden:
erstes Byte empfange, bin ich als Slave gemeint? Ja, dann empfange
weiter bis alles da ist, dann rechne die Prüfsumme nach, stimmt die mit
der übertragenen überein, ok, führe aus und gib OK zurück.
Wenn nicht ok, schick dem Sender ein "wie bitte?" zurück, damit der
nochmal den Befehl sendet.
Störungen / Kollisionen können auch u.U. schon bei dem Empfang der Bytes
festgestellt werden indem man den Frame-Error abfragt. Das ist ein Flag,
den der µC setzt wenn die Bits nicht ins Format z.B. 8n1 passen ... auch
dann sollte der µC ein "wie bitte" zurück senden an den Master.
Auch beim Master kann es Probleme geben ... wird das Datenpaket so
verstümmelt, dass kein Slave sich angesprochen fühlt so sollte er seine
Anfrage irgendwann wiederholen oder bei 2-3-maliger Wiederholung eben
weiter machen im Text ...
Du siehst schon, das kann man in die Abstraktion treiben bist zum
erbrechen ... kommt halt drauf an was Du brauchst.
ps: @oldmax
Das von Dir beschriebene Verfahren unterscheidet sich vom Protokoll her
garnicht von einem RS485 und reicht auch in den meisten Fällen aus ...
ich sehe nur einen Knackpunkt.
Fällt einer der Slaves in der Kette ... warum auch immer ... aus, ist
ggf. der ganze Strang, minimum aber bis zu dem Slave tot.
Ist schon weniger günstig wenn evtl. die Rolladensteuerung die Grätsche
macht und dafür dann Lichttaster und Raumtemperatur auch weg sind.
Wer mit RS485 und Bascom ein Bus-System aufbauen möchte,
dem sei mal empfohlen, sich mit "Modbus" vertraut zu machen
Das ist kein neuartiges Bussystem sondern ein recht komfortables
Protokoll auf der Basis von RS485.
Die LIB in Bascom ist leider nur für Modbus-Master tauglich,
aber man kann damit wenigstens die Checksumme generieren
Komisch, alle reden bei dem Thema nur von Protokollen und den logischen
Schichten.
Das hat doch mir rs 485/422 erst mal nix zu tun.
Hier sind die elektrischen Eigenschaften erst mal wichtig und
differenzieren.
Somit ist RS484/422 erst mal kein Protokoll sondern definiert in der ISO
Schicht die untersten Ebenen, hier Differenzspannungschnittstelle.
Ich empfehle an dieser Stelle mal die viel gescholtene Elektor.
Hier werkelt seit ca. 1 1/2 Jahren jemand ( ein ganzes Team
mittlerweile von durchaus bekannten Fachleuten) an einem freien
Hausbusprotokoll auf Basis RS485.
Das ist ausgereift, sehr durchdacht, einfach und basiert auch auf Bascom
Routinen mit Beispielen etc.. Die Programmierung erfolgt aber auch in C
oder in beliebig anderen Sprachen.
Auch Hostanwendungen und Testprogramme unter Windows existieren.
Back to the roots