Hallo,
ich habe eine kleine Schaltung aufgebaut mit einem ATtiny13. Diese
Schaltung ist in 10-facher Ausfertigung vorhanden und soll über einen
Master-Controller angesprochen werden.
Da die Serielle Schnittstelle ausfällt (ich verwende den internen
RC-Oszillator der ist viel zu ungenau) suche ich eine Art um mit einer
Leitung daten vom Master zu den Slaves zu übertragen.
Bevor jemand Fragt, ich Progge in Bascom, falls jemand ein Problem damit
hat möchte er sich bitte mit Kommentaren wie "Bascom = Shit /
Anfängerschrot usw" zurückhalten.
Der Master soll nur Daten an die Slaves übertragen es gibt also nur eine
Datenrichtung ein Rückkanal ist nicht vorgesehen.
Der Timer im Tiny kann noch verwendet werden der läuft durch ist also
für andere Sachen auch noch zu verwenden (Macht Soft-PWM 4-Kanalig)
Meine Lösungsansätze gingen in Richtung Manchester-Codierung, aber
irgendwie peile ich nicht wie dies gehen soll.
Verschieden Lange Impulse als Übertragungsmedium habe ich mir auch schon
ausgedacht aber wie messe ich diese? Ich kann den Timer nicht anhalten
und eine ICP-Einheit hat der Tiny nicht. Vorschlag: Langer Impuls = Bit
ist 0, kurzer Impuls = Bit ist 1 aber wie realisieren?
Datenrate muß nicht schnell sein, 9600Baud reichen locker.
Als Alternative wenns nicht anderweitig zuverlässig geht nehme ich halt
zwei Leitungen eines ist die Clock und die Andere die Data-Line.
Die Clock wird dann an einen Interrupt-Eingang gehängt der wird auf
Steigende Flanke Programmiert und liest mir in der ISR dann den Pegel
der Data line ein. Der Rest ist dann ein wenig Bit-Shifterei.
Ich würde mir aber gerne die 2. Leitung sparen da die Leitungen zwischen
den Modulen durchaus gerne mal 1-2 meter lang werden können.
Für Vorschläge bin ich Dankbar.
Alexey
@ Alexey (Gast)
>Verschieden Lange Impulse als Übertragungsmedium habe ich mir auch schon>ausgedacht aber wie messe ich diese? Ich kann den Timer nicht anhalten>und eine ICP-Einheit hat der Tiny nicht. Vorschlag: Langer Impuls = Bit>ist 0, kurzer Impuls = Bit ist 1 aber wie realisieren?
Genau so.
>Datenrate muß nicht schnell sein, 9600Baud reichen locker.
Einfach. Kann man über den exteren Interrupt machen.
Interrupt steigende Flanke = Bitanfang
-> Timer auslesen und speichern
-> Interrupt auf fallende Flanke ändern
Interrupt fallende Flanke = Bitende
-> Timer auslesen und vergleichen, Bitdauer ermitteln und dekodieren
-> Interrupt auf steigende Flanke ändern
MFG
Falk
Das was du beschreibst ist ein 1-wire Schnittstelle, die braucht aber
auch eine genaue Zeit.
Warum soll es denn kein Uart sein?
du könntest ja auch eine online Kalibrierung machen.
Master sendet immer z.B. 0xAA
und die Slaves Trimmen ihren Oszi bis sie das 0xAA empfangen.
Beim ersten Lesen denke ich, dass die Zeit nur so genau sein muss, dass
man auch im Worstcase-Fall (Sender maximale Abweichung nach oben -
Empfaenger maximale Abweichung nach unten) lange und kurze Impulse
sicher unterscheiden kann. DAS sollte problemlos hinzubekommen sein.
Gast2
Kalibrierung ist der Schluessel, wie schon erwaehnt. Es ist voellig
unwichtig wie genau die Oszillatoren sind, solange sie ueber Zeit und
Temperatur aehnliche Drifts haben lassen sie sich sehr gut Kalibrieren.
Der Master haelt den Kommunikationspin dazu eine vordefinierte Zeit,
sagen wir mal 1000 Zyklen auf low, dann 1000 Zyklen auf high, die Slaves
messen und der eine stellt fest, es waren 1050 seiner Zyklen, der andere
stellt fest es waren nur 940 Zyklen, jetzt kannst die errechnen wie
schnell die Oszillatoren relativ zueinander laufen und ploetzlich ist
der UART eine ganz tolle und einfach Alternative. Die Frage bleibt
natuerlich ob der kleine Speicherbereich des Tiny dazu ausreicht.
In meiner frueheren Abteilung haben wir zuverlaessige Kommunikation
ueber UART zum PC erzeugt mit Kalibrierung obwohl der Oszillator 20-30%
vom Sollwert abweichen konnte.
Viel Spass dabei, Robert
hallo Alexey
immer 2 Bit Übertragen, kurz und dann daten.
Also z.B. 100us high 10us low 100us high 10us low-> Datenbit 0
100us high 10us low 200us high 10us low-> Datenbit 1
Dadurch das immer mitgeteilt wird was 0 was 1 ist ist es bei
denn empfängern egal ob sie in dieser Zeit bis 10 oder 635 zählen,
sie werten die daten immer nur relativ aus.
gruß hans
Warum denn so kompliziert?
Wenn, wie Alexey schreibt, eine zwei-Leiter Übertragung möglich ist,
dann macht man das so. Die zusätzliche Clock-Leitung tut nicht weh und
dadurch ist die Übertragung absolut sicher, ohne Trimmung der
Oszillatoren.
Ganz ehrlich:
So eine Hampelei, um die paar Cent für einen Quarz zu sparen, macht
eigentlich erst Sinn bei Stückzahlen jenseits von 1000.
Sollte das dein Ziel sein, wäre professionelle Hilfe angesagt, aber die
kostet auch.....
Alexey wrote:
> Verschieden Lange Impulse als Übertragungsmedium habe ich mir auch schon> ausgedacht aber wie messe ich diese? Ich kann den Timer nicht anhalten> und eine ICP-Einheit hat der Tiny nicht. Vorschlag: Langer Impuls = Bit> ist 0, kurzer Impuls = Bit ist 1 aber wie realisieren?
Ja, so macht man das.
Es kann auch sinnvoll sein, noch ein Startbit zu definieren.
Z.B.:
0-Bit = 10*T
1-Bit = 20*T
Startbit = 40*T
Du nimmst nen Pin-Change-Interrupt und liest darin den Timer aus und
bildest die Differenz zum Wert der vorherigen Flanke.
Und dann einfach vergleichen:
5..15 = 0-Bit
16..29 = 1-Bit
30..60 = Startbit
Da Du ja immer bei jedem Bit neu synchronisierst, brauchst Du auch nicht
die hohe Genauigkeit, wie bei der UART (synchronisiert erst nach 10
Bits).
Peter
Bensch wrote:
> So eine Hampelei, um die paar Cent für einen Quarz zu sparen, macht> eigentlich erst Sinn bei Stückzahlen jenseits von 1000.
Erstens ist das keine Hampelei und zweitens ist es schon ein
Unterschied, ob ich alle 6 oder nur 4 IOs benutzen kann, weil 2 durch
den Quarz belegt sind.
Peter
@Bensch,
lies das Datenblatt des Tiny13 der Anschluss eines Quarzes ist
unmöglich. Allerhöchstens ein Quarzoszillator wäre möglich aber die sind
teuer, groß und ich habe keinen da.
Außerdem geht das wie man sieht auch. Was ich machen will oder nicht
überlasse bitte mir, ja?
@Peter Danneger,
Das ist in etwa so etwas was ich vorgehabt hätte nur für was brauche ich
das Startbit? Ist dieses dazu gedacht die Module zu Synchronisieren? Den
Sinn des Startbits verstehe ich nicht so ganz vielleicht kannst du mir
einen Tip geben.
Meine Ansatz war bis jetzt folgender:
Ich sende ein Datenpaket bestehend aus folgenden Parametern:
AAA - BBB - CCC - DDD - EEE - FFF
AAA = Adresse des Moduls das Angesprochen werden soll
B-C-D-E-F = Nutzdaten die dem Modul mitgeteilt werden sollen.
jeder Datenblock besteht aus einem Byte, insgesamt werden dann also pro
Datenpaket 6 Bytes für ein Modul verschickt.
Wenn die Software im Tiny13 Daten erkennt werden diese komplett
eingelesen.
Das Erste Byte wird geprüft ob der Wert der Moduladresse entspricht.
Ist dies nicht der Fall werden alle Daten verworfen.
Wenn der Empfangene Wert gleich der Moduladresse ist werden die
Nutzdaten im Programm weiter verarbeitet.
Ich hoffe daß ich meinen Ansatz damit offen gelegt habe. :)
Du könntest noch ein weiteres Byte anhängen, in das du eine Prüfsumme
schreibst - so verhinderst du, dass hin und wieder durch Störungen
falsche Daten übertragen werden. Für die Prüfsumme einfach alle
vorherigen Bytes ver-XOR-en und als letztes Byte anhängen. Der
Rechenaufwand ist relativ gering. Wenn du noch Platz in den Tiny13 hast,
dann würde ich dir das auf jeden Fall empfehlen.
Ein Startbyte sollte schon sein. Könnte ja sein, dass ein Tiny13 ein
Byte aus irgendwelchen Gründen nicht oder nur teilweise empfängt. Woher
soll er dann wissen, wann neue Daten gesendet werden? So kann er immer
prüfen, ob das erste Byte auch wirklich den definierten Startbytewert
hat. Ist das nicht der Fall, dann weiß der Tiny13, dass er nicht
mitgekommen ist und nun wieder auf den Anfang des neuen Protokolls
warten muss.
@ Igor Metwet
Danke für die Infos, nun leuchtet mir ein warum ein startbyte sinn
macht. :)
Dann werde ich mal beginnen das Programm zu schreiben.
Alexey :)
Hallo ich schon wieder,
ich glaube das mit dem Interrupt war ein Schuss ins Knie.
Nach meinem Verständniss des Datenblattes auf (ich glaube auf Seite 45)
wird nach dem aktivieren des Externen Interrupts dieser von ALLEN Pins
ausgelöst auch von denen die als Ausgang geschaltet sind. Da ich ja ne
PWM laufen habe dürfte der Controller nur noch mit der Interruptroutine
externer Interrupts beschäftigt sein.
Ich will nur an einem Pin das der Controller auf eine Steigende Flanke
reagiert. Ist dies möglich mit dem Tiny13? Wenn nicht muß ich mir
bezüglich der Datenübertragung was anderes Überlegen.
Alexey
Ich noch mal,
Habe das Problem glaube ich gelöst, wenn ich die Register PCMSK des
Tiny13 vor Hand befummle dann gehts :) Steht auch so in der FAQ auf der
MCSelec Seite unter Support. Da habe ich das gefunden. Morgen werde ich
mal einen Prototypen Programmieren und das ganze "in Hardware"
austesten.
Alexey :))