Grüße, ich habe gestern mein neues Spielzeug, einen 12Bit-Absolutwertgeber für eine Synchronmaschine) von Hengstler (AD36) bekommen und versuche dieses nun auszuwerten. Für die Ansteuerung der SSI-Schnittstelle schicke ich ein Taktbündel raus und empfange die Daten (13Bit) in Gray Code. Dies wurde von mir mittels Oszi überprüft und funktioniert wunderbar. Zumindest empfange ich Daten, welche sich nur ändern, wenn ich den Winkel verändere. Nun versuche ich den "Gray-Code" in Bin/Dez zu wandeln. Hierfür verwende ich folgende Funktion: SSIAusgabeBin = (SSIAusgabeGray>>1) ^ (SSIAusgabeGray>>2) ^ (SSIAusgabeGray>>3) ^ (SSIAusgabeGray>>4) ^ (SSIAusgabeGray>>5) ^ (SSIAusgabeGray>>6) ^ (SSIAusgabeGray>>7) ^ (SSIAusgabeGray>>8) ^ (SSIAusgabeGray>>9) ^ (SSIAusgabeGray>>10) ^ (SSIAusgabeGray>>11) ^ (SSIAusgabeGray>>12); Ich weiß, meine Variablen sind nicht gerade die kürzesten, aber zumindest sind sie leicht nachzuvollziehen ;)! Jetzt zu meinem Problem! Die ausgegebenen Werte passen nicht wirklich zu den Winkeln. Hier eine kleine Übersicht. Winkel Wert 0° 0 90° 2000 180° (hier wird das Maximum von 4095 erreicht mit anschließenden Sprung auf den korregten Wert von 2000) 270° 3000 360° 0 Das heißt im Bereich von 0 - 180° steigt der Wert um den Faktor 2 an, erreicht bei 180° sein Maximum, fallt anschließend auf den korrekten Wert von 2000 und verhält sich im Bereich von 180 - 360° wieder korrekt. Habt für sowas schonmal erlebt? Für weitere Infos findet ihr unter dem folgenden Link das Datenblatt und im Anhang einen Auszug des Quellcodes. http://www.drehgeber-onlineshop.de/downloads/ad36.pdf
Irrtum, im Bereich von 180 - 360° habe ich auch mehrere Sprünge. Das heißt dieser Bereich funktioniert auch nicht wirklich. Könnte meine Umrechnung von Gray nach Bin/Dez fehlerhaft sein? Ich vermute mal ja!
So, ich habe soeben meine Gray zu Bin Wandlung überprüft und diese scheint i. O. zu sein. Das Problem muss also am Absolutwertgeber liegen. Kennt sich jemand mit dem Typen (AD36 von Hengstler) aus?
Danke für eure rege Beteiligung ^^! Habe den AD36 jetzt selbst zum Laufen gebracht und ich muss sagen, es war meine eigene Schuld. Ich habe den Geber auf das selbe Potential wie den µC gelegt und das war der Fehler.
Hi Leute! Wollte kein neues Thema aufmachen, deshalb hier: Ich will einen Absolutwertgeber MAB25 12HS (Winkelgeber in 12Bit, Datenblatt hier http://www.wobit.com.pl/download/pdf/przetworniki/MAB25.pdf) mit einem ATmega32 auslesen und weiß nicht so recht, wie ich den seriellen Datenstrom empfangen kann. Zuerst hatte ich fälschlicherweise angenommen, dass es sich um eine SPI Kommunikation handelt. Laut Datenblatt sind 3 Pins nötig: -Eine Select Leitung, standardmäßig auf HIGH -Takt -Data Out Ich habe übrigens das Pollin Eval Board, also ist ein 16 MHz Quarz verbaut. Für ein Bisschen Hilfe wäre ich dankbar!
@ Benedict (Gast) > MAB25_Timing.JPG Auch wenn es hier nicht kritisch ist. Screenshots generiert und postet man als PNG. Warum da so ist, steht im Artikel Bildformate. >Zuerst hatte ich fälschlicherweise angenommen, dass es sich um eine SPI >Kommunikation handelt. Laut Datenblatt sind 3 Pins nötig: >-Eine Select Leitung, standardmäßig auf HIGH >-Takt >-Data Out Klingt stark nach SPI. Wird man sicher auch damit lesen können. Allerdings sind 18 Bit recht exotisch. Aber wenn die Logik nicht vollkommen vergurkt ist, kann man die mit 3x8 Bit auslesen. >Für ein Bisschen Hilfe wäre ich dankbar! Siehe SPI und AVR-Tutorial: Schieberegister MFG Falk
Hallo und danke für die Antwort! Okay, also du hättest auch erstmal SPI vermutet. Ich hatte schonmal ein Bisschen Code für SPI zusammengeschrieben, allerdings ohne Daten vom Sensor zu bekommen. Der Code war aber garantiert noch fehlerbehaftet. Dann werde ich jetzt erstmal ein Bisschen weiter in die Richtung schauen. Wie könnte man denn bei SPI die ersten acht Bit wegschreiben, bevor sie von den folgenden überschrieben werden?
@ Benedict (Gast) >Wie könnte man denn bei SPI die ersten acht Bit wegschreiben, bevor sie >von den folgenden überschrieben werden? Ganz einfach. In einer beliebigen Variable. Lies erstmal was über SPI und denk drüber nach, ehe du wieder nachfragst. Denn SPI ist sehr einfach. Und das kleine 1x1 muss man sich selber erarbeiten. MFG Falk
Also. Habe mir heute mehr über SPI durchgelesen. Die Frage von oben bleibt aber. Laut des Timing Diagramms übergibt er den Messwert bei fallender Flanke von CS (also ist dies !SS). Die Bits werden zur steigenden Flanke des Clock-Signals übergeben. Allerdings steht im Datenblatt nichts davon, dass irgendwann das SPI Interrupt Flag SPIF gesetzt wird, welches die Übertragung abschließt. Im Atmel Datenblatt steht auch folgendes: "After eight clock pulses the transmission is completed. In both the master and the slave device the SPI interrupt flag (SPIF) is set and the received byte is transferred to the receive buffer." Dementsprechend weiß ich immernoch nicht, wie es nach den ersten acht Bit weitergeht. Wenn überhaupt, setzt der Absolutwertgeber das Interrupt Flag nach seinen 18 gesendeten Bits. Dafür ist aber das SPDR Datenregister zu klein...
@Benedict (Gast) >Laut des Timing Diagramms übergibt er den Messwert bei fallender Flanke >von CS (also ist dies !SS). ja. >Allerdings steht im Datenblatt nichts davon, dass irgendwann das SPI >Interrupt Flag SPIF gesetzt wird, welches die Übertragung abschließt. Aber sicher. >Dementsprechend weiß ich immernoch nicht, wie es nach den ersten acht >Bit weitergeht. Die Daten aus dem Puffer des SPI auslesen (SPDR) und in eine normale Variable schreiben. Dann das Ganze nochmal für die nächsten 8 Bits. Und dann noch mal. > Wenn überhaupt, setzt der Absolutwertgeber das Interrupt >Flag nach seinen 18 gesendeten Bits. Der Geber setzt gar keine Interruptbits. Der klingelt einfach seine Daten raus. > Dafür ist aber das SPDR Datenregister zu klein... So ein Pech aber auch! Musst du dir wohl einen anderen AVR kaufen. Oder einfach mehrmals die Bits lesen. SPI ist syncron, sprich mit einem Takt. Da kann man zwischendurch kurze Pausen machen. MFG Falk
Falk Brunner schrieb: > So ein Pech aber auch! Musst du dir wohl einen anderen AVR kaufen. Soweit wird's dann wohl nicht kommen müssen :) Falk Brunner schrieb: > SPI ist syncron, sprich mit einem Takt. > Da kann man zwischendurch kurze Pausen machen. Meinst du, dass ich nach acht bit die Clock manuell ausschalten soll, um diese Daten wegzuschreiben? Oder kann ich das auch in einer Schleife machen, wo beispielsweise auf das SPIF Flag gewartet wird? Was ich bis jetzt gesehen habe, war sowas, wie loop_until_bit_is_set(SPSR, SPIF); Wenn dieses Flag dann irgendwann gesetzt werden würde, könnte ich ja einfach den Wert der SPSR Registers mit SPIF vergleichen und gleichzeitig nach einem Count bis 8 immer die Daten aus SPDR in eine 18 Bit Variable schreiben.
@ Benedict (Gast) >> SPI ist syncron, sprich mit einem Takt. >> Da kann man zwischendurch kurze Pausen machen. >Meinst du, dass ich nach acht bit die Clock manuell ausschalten soll, um >diese Daten wegzuschreiben? Wegschreiben. Was für ein Wort!?! Speichern, kopieren. Ausserdem muss du keinen Takt anhalten, geht so auch gar nicht. Und ich wiederhole mich. Lies was über SPI und lass es dir durch denn Kopf gehen. Denn das SPI Modul erzeugt erstmal nur 8 Takte für 8 Bits. Dann ist erstmal Pause. Erst wenn deine CPU sagt, sie hätte gern noch mal 8 Bits, generiert das SPI 8 neue Takte. Also nix mit anhalten. > Oder kann ich das auch in einer Schleife >machen, wo beispielsweise auf das SPIF Flag gewartet wird? Ja, so macht man das. >Was ich bis jetzt gesehen habe, war sowas, wie >loop_until_bit_is_set(SPSR, SPIF); Das ist ein altes Makro aus den Kindertagen des AVR-GCC. Würde ich heute nicht mehr nehmen. Die allgemeine Schreibweise
1 | while (!(SPSR & (1<<SPIF))); |
Ist allgemein und "besser" lesbar. Und der AVR-GCC macht schon sinnvollenm Assemblecode draus. >Wenn dieses Flag dann irgendwann gesetzt werden würde, könnte ich ja >einfach den Wert der SPSR Registers mit SPIF vergleichen und Das macht die Schleife oben, das Bit SPIF prüfen. >gleichzeitig nach einem Count bis 8 immer die Daten aus SPDR in eine 18 >Bit Variable schreiben. Wozu Count bis 8? Du hast 18 Datenbits, das ist etwas mher als zwei Bytes, also eher 3 Bytes. Die kann man in ein Array aus drei Bytes schreiben oder in eine 32 Bit Variable. 18 Bit Variablen gibt es in C nicht. MFG Falk P S Das Ganze geht in etwa so.
1 | SPDR = 0; // Dummywert, Übertragung starten |
2 | while (!(SPSR & (1<<SPIF))); |
3 | data[0] = SPDR; |
4 | |
5 | SPDR = 0; // Dummywert, Übertragung starten |
6 | while (!(SPSR & (1<<SPIF))); |
7 | data[1] = SPDR; |
8 | |
9 | SPDR = 0; // Dummywert, Übertragung starten |
10 | while (!(SPSR & (1<<SPIF))); |
11 | data[2] = SPDR; |
Super! Vielen Dank für deine geduldige Hilfe, jetzt habe ich alles verstanden! Genau, dieses Schleifenkonstrukt meinte ich, hatte es aber nicht mehr gefunden. Ja klar, 18 Bit ist in der Tat etwas krumm, aber so in etwa, wie deine Array Lösung hatte ich mir das auch vorgestellt! Nochmals dankschön. Werde dann nochmal posten, wenn ich das hier mal lauffähig habe.
Hi Benedict, hab eine Beschreibung (englisch) mit Beispielcode gefunden, die die Problemstellung mit dem SSI auslesen über Mikrocontroller ganz gut beschreibt : http://www.posital.sg/sg/products/POSITAL/AbsoluteEncoders_Context/AbsoluteEncoders_Context_Technology_SSI_AppNote.pdf da sind auch die Grundlagen des SSI Protokolls erklärt. Gruß Ulf
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.