PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Kompassmodul mit USART-Schnittstelle auswerten



MarkusH
24.09.2004, 20:35
Hallo an alle!
Ich hab ein Kompassmodul namens 2XCM-I von Kaot-dar. Das hat laut Datenblatt ne USART-Schnittstelle. Wenn ich die zwei pins TX und RX direkt an die serielle Schnittstelle an pin 2&3 anschließe kommt nur müll raus. Wenn ich es statt dessen über den MAX232 ähnlichen Baustein des STK500 von Atmel anschließe alledings auch. Wenn ich ihn über das STK500 anschließe kann man aber beobachten das sich die Kryptischen Zeichen je nach position des Kompass verändern. Hab aber schon alle Terminal-Typen ausprobiert, da kommt nie was halbwegs sinnvolles raus nur so ein "°""°"" Müll.
Mach ich da grundsätzlich was falsch?
Ich muss dazu sagen das ich relativ neu auf dem Gebiet bin.
Danke schonmal im Voraus.

Gruß, Markus

Joerg
24.09.2004, 21:10
Hallo Markus,


Wenn ich die zwei pins TX und RX direkt an die serielle Schnittstelle an pin 2&3 anschließe kommt nur müll raus.
TX vom Modul muss an RX des Controllers und umgekehrt.
Um Befehle zu übertragen (Parametrierung, Umschaltung), braucht man noch einen weiteren Ausgang am Controller, den man mit CS des Moduls verbindet.


Wenn ich es statt dessen über den MAX232 ähnlichen Baustein des STK500 von Atmel anschließe alledings auch.
HALT!!! Damit zerstörst du das Modul, falls du die Sendeleitung des Treibers mit dem Modul verbindest!!!


Mach ich da grundsätzlich was falsch?

Hört sich evtl. nach ner falschen Baudrate an (9600,8,N,1).

HTH und Viele Größe
Jörg

MarkusH
24.09.2004, 21:19
Danke für die schnelle Antwort.
Also der Rs232-Controller geht noch (ich hab noch nen Atmega8 den ich dran anschließen kann). Baudrate ist auch richtig (9600,8,N,1) wie es in der beschreibung des Moduls steht. Das Modul hat tatsächlich einen CS-Pin. Da der aber in der Beschreibung nie erwähnt wird, hab ich ihn nicht angeschlossen. Was muss ich damit jetzt verbinden?

Gruß, Markus

Joerg
24.09.2004, 22:23
Hallo Markus,


Also der Rs232-Controller geht noch (ich hab noch nen Atmega8 den ich dran anschließen kann).

naja, das Modul war ja in Gefahr, nicht der Treiber.


Das Modul hat tatsächlich einen CS-Pin. Da der aber in der Beschreibung nie erwähnt wird, hab ich ihn nicht angeschlossen. Was muss ich damit jetzt verbinden?

Also das CS-Pin (taucht übrigens in der Beschreibung in fast allen Diagrammen auf) wird gebraucht, wenn man einen Befehl an das Modul schicken möchte. Z.B. um die Betriebsart umzuschalten (->Temperatur oder ->Sleep) oder um die Kalibrierung zu starten.
Du verbindest ds CS-Pin am besten mit einem freien Ausgang am Mega8.

Nochmal zur Verdrahtung, Pin7 (TX) vom Modul muss an Pin2 (RX) des Mega8 und Pin8 (RX) vom Modul muss an Pin3 (TX) des Mega8. Gleichzeitig darf nichts anderes (auch kein RS-232-Treiber) am Pin2 des Mega8 angeschlossen sein.

Nach dem Einschalten geht das Modul normalerweise in den Kompass-Mode und sendet kontinuierlich die Messwerte.
Wenn jetzt etwas verkrüppeltes empfangen wird, liegt das u.U. neben einer falschen Baudrateneinstellung auch an einer falschen Fuse-Setting (interner 1MHz-Takt statt externer Takt). Vielleicht auch mal den Empfang im Mega8 mit einer anderen Quelle testen.

HTH und Viele Grüße
Jörg

MarkusH
25.09.2004, 10:57
Vielleicht hab ich mich falsch ausgedrückt, ich will das Modul vorerst ohne Atmega8 an den Com-Port anschließen. Nur zum kucken was da überhaupt rauskommt. Weil ich ja noch nicht weiß wie ich es mit dem Atmega ansprechen soll. Den Atmega hab ich nur erwähnt um zu sagen das wenn ich den an die RX/TX Pins des Schnittstellenmoduls des STK500 anschließe was sinnvolles rauskommt. Und wenn ich das Kompassmodul ansschließe eben nicht. Wenn irgend ein Modul einen USART-Ausgang hat, bedeutet das dann das ich es direkt an die schnittstelle anschleißen kann oder das ich da noch nen "Treiber" dazwischen schalten muss? Der CS-Pin hat wenn er nicht angeschlossen ist immer 5V, den brauch ich ja aber vorerst nicht wenn ich nur empfangen will wenn ich das richtig verstanden hab. In der Anleitung steht das Signale nur gesendet werden wenn der CS-Pin HIGH ist. Das ist ja der fall und es kommt ja auch irgendwas undefinierbares raus.

Joerg
25.09.2004, 11:22
Hallo Markus,


Vielleicht hab ich mich falsch ausgedrückt, ich will das Modul vorerst ohne Atmega8 an den Com-Port anschließen.

In der Tat, dann brauchst du natürlich den Pegelwandler. Am PC kommen an der Schnittstelle -12V/+12V raus. Habe ja schon mehrfach betont, dass das nicht mit dem Kompass-Modul verbunden werden darf.
Der Pegelwandler macht aus den -12V -> +5V und aus den +12V -> 0V das heißt er invertiert das ganze zusätzlich noch.


Wenn irgend ein Modul einen USART-Ausgang hat, bedeutet das dann das ich es direkt an die schnittstelle anschleißen kann oder das ich da noch nen "Treiber" dazwischen schalten muss?

USART sagt erst mal überhaupt nichts über den Pegel aus. USART ist halt ein Schnittstellenbaustein, der asynchrone und synchrone serielle Übertragung beherrscht.
Generell gilt. An Mikrocontrollern kommt an der seriellen Schnittstelle zumeist nur TTL-Pegel raus (5V/0V). Das darf man ohne weitere Maßnahmen nicht direkt mit dem PC verbinden. Dazu gibt es dann Pegelwandler, z.B. den verbreiteten MAX232 oder Äquivalente.


Der CS-Pin hat wenn er nicht angeschlossen ist immer 5V, den brauch ich ja aber vorerst nicht wenn ich nur empfangen will wenn ich das richtig verstanden hab. In der Anleitung steht das Signale nur gesendet werden wenn der CS-Pin HIGH ist. Das ist ja der fall und es kommt ja auch irgendwas undefinierbares raus.

Der CS hat einen internen Pull-Up.
Wenn du dir die Ausgaben des Moduls mit einem Terminal angucken willst (Hyperterm) kommt tatsächlich etwas undefinierbares heraus, da das Modul keine ASCII sondern Binärwerte sendet.

Das heißt, es war schon eigentlich alles OK, nur ich habe nicht verstanden, was du eigentlich ausdrücken wolltest. Die Sache mit dem Mega8 (Pin2 und 3) machte die Verwirrung perfekt.

Ich rate dir, die Werte jetzt mit einem Mega8 einzulesen und den Wert entsprechend der Doku Seite 9 zu berechnen.
Dann wird alles gut ;)

HTH und Viele Grüße
Jörg

MarkusH
25.09.2004, 11:45
Also gut, ich hatte es also richtig angeschlossen, nur das Hyperterminal die Signale nicht unterpretieren kann. Gibt es ein anderes Terminal-Programm das das kann? Ich glaube nämlich das ich mit der Berechnung im Atmega anhand des Handbuchs vorerst gnadenlos überfordert bin O:)
Da brauch ich ja noch den Timer des Atmegas dafür so wie das aussieht. Mit dem hab ich mich bis jetzt noch garnicht auseinander gesetzt. Außerdem müsst ich ja dann zwei UART's an den Atmega anschließen, einen zum Kopass und einen zum PC. Das wollt ich eben anfangs vermeiden und mich langsam vorarbeiten weil es mir sonst zu viele Fehlerquellen auf einmal gibt. So wie das aussieht hast du das wohl schonmal gemacht. Hast du da vielleicht noch irgendwelche Code-Schnipsel? Wär echt toll weil ich mit Google fast nix zu dem Thema finde. Ich arbeite bisher mit Bascom weil ich Basic ganz gut kann und mir das AVR-Studio mit Assemblersprache zu umständlich war. Danke für deine Hilfe. Gruß, Markus

Joerg
25.09.2004, 15:18
Hi Markus,


Also gut, ich hatte es also richtig angeschlossen, nur das Hyperterminal die Signale nicht unterpretieren kann. Gibt es ein anderes Terminal-Programm das das kann?

Nein. Du kannst dir natürlich mit Delphi oder VB o.ä. schnell ein Programm schreiben, was das macht. Ist aber dann kein Terminal mehr.


Ich glaube nämlich das ich mit der Berechnung im Atmega anhand des Handbuchs vorerst gnadenlos überfordert bin

warum, du liest alle 0,5s eine Sequenz ein. Da kommen 4 byte. LSB, MSB, checksum und CR (0x13). Aus LSB und MSB berechnest du den Kompasswert wie folgt:
x = MSB * 256 + LSB
Wenn du möchtest, kannst du mit der Prüfsumme noch überprüfen, ob ein Übertragungsfehler aufgetreten ist:
Dazu werden 0xff, das MSB und das LSB XOR verknüpft. Das Ergebnis muss mit der Checksum übereinstimmen.


Da brauch ich ja noch den Timer des Atmegas dafür so wie das aussieht. Mit dem hab ich mich bis jetzt noch garnicht auseinander gesetzt.

Nein, da braucht man keine Timer. Zum Ausprobieren wartest du halt, bis Daten über die serielle Schnittstelle kommen. Die werden nach obiger Formel ausgewertet und der Kompasswert irgendwie zur Anzeige gebracht.


Außerdem müsst ich ja dann zwei UART's an den Atmega anschließen, einen zum Kopass und einen zum PC.

????

HTH und Viele Grüße
Jörg

MarkusH
26.09.2004, 17:49
So, ich hab mal ein wenig in der Bascom-Hilfe rumgekramt und hab was gefunden wie man von einem USART was einliest:

$crystal = 3686400
$baud = 9600
Ddrd = 0
Portd = 0
Dim Var As String * 10

Serin Var , 0 , D , 4 , 9600 , 0 , 8 , 1
'Serin Variable, Länge(unwichtig weil die variable string ist), portnummer, Baudrate, flussteuerung, datenbits, stoppbits
Wait 1
Print "var"

Wenn ich den code laufen lasse hängt er bei der serin zeile und weigert sich weiter zu machen. Ich hab so das gefühl das der auf diese 13H-Endmarkierung wartet und diese aber nicht erkennt weil ich die crysatl-variable falsch gesetzt hab. Kann das sein? Wenn ich die Crystalvariable aber veränder kommt auf der siellen konsole zum pc nu blädsinn raus. In der bascom hilfe steht das auf ein return(13H) gewartet wird wenn ein string als variable verwendet wird.

Gruß, Markus

MarkusH
26.09.2004, 17:51
Hoppla, die beschreibung von Serin war in falscher reihenfolge,
SERIN var , bytes , port , pin, baud , parity , dbits , sbits

Joerg
26.09.2004, 22:20
Hallo Markus,

hier kann ich momentan nicht weiterhelfen, da ich von BASCOM, wie schon mehrfach geschrieben, keine Ahnung habe :(.

Da aber BASCOM hier sehr stark verbreitet ist, müsste es doch jemanden geben, der helfen kann.

Nur soviel, ich würde die Werte nicht in einen String einlesen. Du willst ja anschließend mit den einzelnen Bytes rechnen, ein String dürfte dafür aber denkbar ungeeignet sein.

Viele Grüße
Jörg

MarkusH
27.09.2004, 07:50
Schade, ich werde die Frage mal unter "Bascom Programmierung" posten. Trozdem mal vielen dank für deine hilfe. Jetzt weis ich wenigstens wo ich anfangen soll.

Gruß, Markus

Joerg
27.09.2004, 09:45
Hallo Markus,

habe mir mal die Hilfe zu BASCOM vorgenommen:


Port The name of the port to use. This must be a letter like A for portA.
Pin The pin number you want to use of the port. This must be in the range from 0-7.

Demnach liest du in deinem Programmbeispiel von D4 (Pin6) ein. Weiter oben war aber die Rede von Pin2 (RXD).

Allerdings fällt mir bei der Literatur der Hilfe auf, dass BASCOM die Hardwareroutinen des Mega8 wohl gar nicht nutzt. Deshalb kann man auch jeden beliebigen Pin für die Funktion angeben.

Zurück zu deinem Programm. Wenn der Wert in einen String eingelesen ist und anschließend mit Print ausgegeben wird, wird mit Sicherheit wegen des Binärformats irgendwelcher Müll ausgegeben (siehe Terminal).

Besser ist doch, gleich in Variable einzulesen mit denen man auch was anfangen kann.


$regfile = "m8def.dat"

$crystal = 3686400
$baud = 9600
Ddrd = 0
Portd = 0

Dim Heading As Word
Dim H_low As Byte
Dim H_high As Byte
Dim Check As Byte

Dim Strtemp As String * 10

Do

Serin Strtemp , 0 , D , 0 , 9600 , 0 , 8 , 1 ' wartet auf CR (synch)

Serin H_low , 1 , D , 0 , 9600 , 0 , 8 , 1
Serin H_high , 1 , D , 0 , 9600 , 0 , 8 , 1
Serin Check , 1 , D , 0 , 9600 , 0 , 8 , 1

Heading = H_high * 256
Heading = Heading + H_low

Print "Kompass: " ; Heading

Loop

Allerdings darf die Ausgabe mit Print nicht an das Kompassmodul geschickt werden, sondern muss zum PC (Terminal). Achso, der Code oben ist nicht getestet sondern einfach so aufgeschrieben. Vielleicht kann ja jemand mit BASCOM-Erfahrung da mal draufgucken. Was erreicht werden soll steht ein paar Postings weiter oben.

Viele Grüße
Jörg

MarkusH
28.09.2004, 11:17
Hey, super, vielen dank, das werd ich mal ausprobiern. Der pin ist schon richtig glaub ich, die serielle konsole zum pc ist auf portD0 und 1. Das ist bei bascom anscheinend standardmässig so wenn man einfach nur print "irgendwas" schreibt. Und jetzt versuch ich eben noch zusätzlich an nem anderen pin was einzulesen.

MarkusH
28.09.2004, 17:00
Funktioniert nicht :-s
Wenn ich irgendwas in einen string einlese bleibt er generell hängen. Vermutlich weil er das CR nicht lesen kann. Wenn ich was in byte einlese kommt immer null raus. Ich hab jetzt von dem Sandard USART-Port (also D0 und D1) die TX leitung mit dem PC verbunden und die RX mit dem Kompas. So krig ich wenigstens was rein weils ja an anderen ports mal garnicht funktioniert. Die einzigste möglichkeit überhaupt was vom kompas zu empfangen ist mit dem Waitkey()-befehl aber der wartet natürlich nur auf ASCII-Zeichen und gibt die dann auch so weiter. Ds heißt es sieht genau so aus als wenn ich den kompas direkt anschließe. Hast du den gleichen Kompas oder hast du jetzt extra wegen meinem problem die anleitung durchgelesen??? Falls du den gleichen hast, wie hast du das gemacht?

Joerg
28.09.2004, 17:43
Hallo Markus,

zu dem seriellen Problem in BASCOM kann ich dir leider nicht weiterhelfen. Das Programm oben entstand quasi im "Blindflug", durch Vergleich von deinem Programm und den bei BASCOM mitgelieferten Beispielen.
Es ist, wie weiter oben geschrieben, nicht getestet.

Allerdings verstehe ich auch nicht, wenn fast jeder redet, dass er in BASCOM programmiert und wie toll das System ist, dass keiner ne Lösung beitragen kann.

Eine andere Geschichte ist der Kompass, hierzu kann ich dir durchaus Tips geben, die jedoch momentan dein Problem nicht lösen. Ich kanns blöderweise auch nicht mehr nachvollziehen, da alle 2XCXM-I, selbst meine stille Reserve, ausverkauft sind.


Hast du den gleichen Kompas oder hast du jetzt extra wegen meinem problem die anleitung durchgelesen???

Ja genau, allerdings die von BASCOM.

Viele Grüße
Jörg

MarkusH
28.09.2004, 18:01
Kann es denn sein das die $crystal variable falsch ist? Oder kommt es nur auf die $baud variable an? Irgendwie stehen die doch in abhängigkeit zueinander oder? wenn ich was anderes nehme als 3686400 kommt immer nur schrott raus. Vielleicht braucht der Kompass ja nen anderen wert wie die verbindung zum pc.

Joerg
28.09.2004, 18:45
Hallo Markus,

$crystal ist die Angabe der Taktfrequenz des Mega8, 3,6864MHz ist eine gebräuchliche Größe, bei der die Baudraten 100%ig exakt sind. Ich gehe mal davon aus, dass du einen entsprechenden Quarz im System hast.


Vielleicht braucht der Kompass ja nen anderen wert wie die verbindung zum pc.

Nein, sofern die korrekte Baudrate ($baud = 9600) eingestellt ist.

Viele Grüße
Jörg

MarkusH
29.09.2004, 19:34
Ich habs jetzt geschafft indem ich mit "Variable = Waitkey()" auf die 19 warte, was ja 13H entspricht. Dann lese ich die nächsten 3 byte auch mit Waitkey ein. da kommt dann je nach dem wie man den kompass dreht folgendes raus:
140,130,241 oder 122,130,7. Aber laut der anleitung müsst ich ja die 130 jetzt mal 256 nehmen... da kommen dann ja so große zahlen raus das man die nicht vernünftig umrechnen kann. Kann es sein das ich an der falschen stelle anfange mit einlesen? Oder ist das erste bit von dem gesendeten byte vielleicht ein start-bit das nicht mitgerechnet wird? Wenn ich bei jeder zahl die reinkommt das erste bit weglasse (also 128 abziehe) dann komm ich auf ein endergebniss das wenigstens zwischen 0 und 360 liegt. allerdings kommen erst jedes dritte mal werte die man dafür verwenden kann. Kann ich irgendwie sicher gehen das er das byte tatsächlich von anfang an einliest und nicht irgendwo in der mitte beginnt und noch die hälfte vom nächsten dazu nimmt?

MarkusH
29.09.2004, 20:02
Hmm... ich glaub das mit dem 128 abziehen funktioniert nur in ganz wenigen fällen... ich hab mal 5 bytes nacheinander eingelesen: 19+97+130+28+19+97

Wenn das irgendwie bitmässig versetzt wäre dann würden da nicht so viele 19er kommen. und vor allem wären dann wohl nicht genau 3 bytes dazwischen kommen, trozdem kann ich mit den bytes dazwischen nix anfangen weil sie viel zu gross und zu komisch sind. Das ist total verwirrend, ich glaub ich dreh voll am rad.

sonic
30.09.2004, 07:26
Hi Markus,

ohne das Problem und das Modul zu kennen, würde ich dir empfehlen die UART interruptgesteuert abzurufen.
Und zwar so lange bis der CR (Carriage Return) ankommt, also 0x13.

Oben stand ja das Format in dem das Modul sendet.

"du liest alle 0,5s eine Sequenz ein. Da kommen 4 byte. LSB, MSB, checksum und CR (0x13). Aus LSB und MSB berechnest du den Kompasswert wie folgt:
x = MSB * 256 + LSB"

Für den interruptgesteuerten Empfang schau mal hier http://www.rowalt.de/mc/avr/avrboard/04/avrb04.htm vorbei.

Du könntest es so machen das du, wie in dem Link beschrieben, ein Array aus 4 Byte solange auffüllst bis das 4. Byte den Wert 0x13 hat.
Aus dem 1. und 2. Byte berechnest du dann deine Werte.
Also x = MSB * 256 + LSB.
MSB ist übrigens das "Höherwertige Byte" und LSB das "niederwertige Byte" deiner gesuchten Zahl. Auf englisch "Most" und "Least significant Byte".

x ist dann eine 16Bit Zahl, also max. 65535, wie z.B. Integer. Ich denke aber das man das dann nochmal umrechnen muss. Vielleicht x * 0,00549, aber ohne Gewähr...

Das 3. Bit ist die Prüfsumme, sofern du die nicht brauchst kannst du die über Board werfen.

Zusammengefasst:

4 Byte einlesen, das 4. Bit mus 0x13 sein.
Wenn das erfüllt ist x = 2. Byte * 256 + 1. Byte, danach eventuell umrechnen.
3. Bit ist die Prüfsumme und vorerst nicht benötigt, 4. Bit dient als Trennzeichen der Sequenz, wird zum berechnen nicht benötigt.

Gruß, Sonic

sonic
30.09.2004, 07:46
...wäre dann würden da nicht so viele 19er kommen. und vor allem wären dann wohl nicht genau 3 bytes dazwischen kommen, trozdem kann ich mit den bytes dazwischen nix anfangen weil sie viel zu gross und zu komisch sind. Das ist total verwirrend, ich glaub ich dreh voll am rad.

Wieso funktioniert doch ;-)

Was ist 0x13 im Dezimalsystem? 19, genau das ist das Trennzeichen zwischen den gesendeten Bytes...also einlesen bis du 0x13(19) empfängst, die nächsten 2 Bytes speichern, das 3. verwerfen (checksum),
das 4. müsste wieder 0x13 sein und stöst die Aktion von vorne an ;-)

Gruß, Sonic

MarkusH
30.09.2004, 18:58
WOW! Der link ist super! Da lernt man richtig was im gegensatz zu den anderen avr-seiten. Wenn ich das so mache wies dort beschrieben ist funktionierts! Mit eben dieser riesigen Integer-Zahl bin ich nicht klar gekommen weil ich dachte wenn ich das richtig mache muss da was zwischen 0 und 360 rauskommen. Wenn ich sie aber mit 0,00549 malnehme kommt was brauchbares raus. Wie kommst du darauf das man das nochmal umrechnen muss und wie kommst du die blöde zahl??? Also nochmal ein riesiges DANKE an euch beide! Wenn man sowas noch nie gemacht hat, hat mans ohne hilfe echt schwer...

sonic
30.09.2004, 19:18
WOW! Der link ist super! Da lernt man richtig was im gegensatz zu den anderen avr-seiten. Wenn ich das so mache wies dort beschrieben ist funktionierts! Mit eben dieser riesigen Integer-Zahl bin ich nicht klar gekommen weil ich dachte wenn ich das richtig mache muss da was zwischen 0 und 360 rauskommen. Wenn ich sie aber mit 0,00549 malnehme kommt was brauchbares raus. Wie kommst du darauf das man das nochmal umrechnen muss und wie kommst du die blöde zahl??? Also nochmal ein riesiges DANKE an euch beide! Wenn man sowas noch nie gemacht hat, hat mans ohne hilfe echt schwer...

Danke, danke, leider funktionierts bei mir nicht so wie es in der Seite beschrieben ist O:) aber das liegt wahrscheinlich an meiner Hardware ,-(

Zu deinen Fragen, aus bestimmten Gründen werden Binärzahlen manchmal in 2 Teilen übertragen, eben einmal MSB und einmal LSB.
Zusammensetzen tut man die eben wieder mit der genannten Formel.

Und da 2 Byte insgesamt 16 Bit sind wird insgesamt eine 16Bit Zahl in 2 8Bit Wörtern übertragen.

Mit 16 Bit kannst du bis 65535 zählen. Ich hab angenommen das der Kompass den kompletten Zahlenraum der 16Bit ausschöpft.
Daraus wiederum folgt 360° / 65535 = 0,00549.....

Die 360° werden dann also in 65535 Schritte unterteilt (allerdings ist das eine extrem unrealistische Genauigkeit, müsste aber im Datenblatt was drüber stehen, das sind immerhin 5/1000el Gradschritte ,-)

Gruß, Sonic

MarkusH
01.10.2004, 09:16
Hi, also eine Frage hab ich noch. Muss man das ding Kalibrieren? Braucht man die Kalibration blos um permanente Störquellen auszuschließen? Muss man den nach jedem einschalten kalibrieren oder nur ein einziges mal???

Joerg
05.10.2004, 09:43
Hallo Markus,

sorry, war ne Weile nicht hier, die Kalibrierung ist nur notwendig, wenn permanente Magnetfelder in unmittelbarer Nähe (Dauermagnete von Motoren o.ä.) ausgeglichen werden sollen.
Der Wert bleibt im internen E2PROM gespeichert.

Viele Grüße
Jörg