Hallo, ich möchte das Gyroscope (L3G4200D - ich besitze das Breakout board von Pololu) gerne auslesen und die Daten dann auf einem Display ausgeben. Ich nutze einen ATMEGA16 und programmiere in C / C++. Verbinden möchte ich den Sensor per SPI. Leider gelingt es mir nicht geeignete Tutorials oder Einsteigertipps hierzu zufinden. Auf der Pololu-Seite gibt es nur Arduino-Language Sample-Code. Arduino-Language möchte ich aber nicht nutzen auch wenn diese c-ähnlich oder was auch immer ist. Meine konkrete Frage ist also wie ich programmiertechnisch auf die verschiedenen Register des Sensors zugreifen kann bzw. diese auslese und in Variablen abspeicher. Simpelster Beispielcode in c wäre Klasse oder irgendwelche Hinweise wie ich mich darüber schlau lesen kann. EDIT: Die grundsätzliche Kommunikation per SPI ist mir bekannt und hat auch schon mit einem anderen µC funktioniert, allerdings will ich nun ja verschiedene Register des Sensors auslesen bzw verändern, nur weiß ich nicht wie das funtioniert. Anhang meiner bisherigen SPI-Kommunikation siehe SPI.c
Funktioniert Die Kommunikation mit dem Sensor vielleicht so, dass ich wenn ich das Ctrl_Reg1 auslesen will, dafür folgendes vom Master senden muss: 1 0 100000 Read | no incre. | Ctrl_Reg1 Daraufhin sendet mir der Sensor das Register und ich kann es aus dem SPDR auslesen? Ich kenne mich mit SPI leider noch so gutt wie garnicht aus und möchte meinen Sensor nicht gleich mit dem ersten "Befehl" zerstören. Ich wäre sehr dankbar für eine Reaktion!
Gast
#2936435
Florian K. schrieb: > Ich kenne mich mit SPI leider noch so gutt wie garnicht aus Also darfst du dich SELBST einarbeiten. Dauer: keine 15 Minuten. Im Datenblatt des Atmega ist ALLES piekfein beschrieben. Florian K. schrieb: > möchte > meinen Sensor nicht gleich mit dem ersten "Befehl" zerstören Also wenn du es schaffst, irrtümlich durch einen "falschen" Befehl den Sensor zu schrotten, dann kommst du in den "Hall of Flame" und ich kaufe dir einen neuen Sensor :-) Jetzt aber im Ernst: nur Mut! Programmieren, testen, debuggen... so wie es auch die Großen machen.
Das ist recht einfach. Ich habe noch Code für den L3G4200D auf der Platte liegen (geschrieben für einen Atmega64 mit soft SPI). Den müsst ich aber erstmal raussuchen.
@Dennis: Danke für deine Motivation, leider schaffe ich es dennoch nicht alleine aus den Datenblättern heraus schlau zu werden, ich möchte auch garnicht eine fertige Lösung für eine konkrete Aufgabenstellung, mir würde schon reichen das WHO_AM_I Register auszulesen und in einer Variable abzuspeichern. Mein Versuch sieht so aus und gibt mir leider nur 255 zurück, was dann wohl für 0b11111111 steht und nicht meinem WHO_AM_I Register entspräche! :(
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
@Jo: Ja ich bin sehr an Code interessiert :)
Kann mir nicht vielleicht jemand weiterhelfen? Wie gesagt mir reichen wirklich nur die nötigen Zeilen um das WHO_AM_I Register auf meinem AVR zu empfangen und abzuspeichern.
Hallo Florian, ich habe mal hier meine BASCOM-Dateien angehäng. Was ich allerdings benutzt habe war das MinIMU-9 von Pololu an ein PollinBoard mit ATmega88 drauf. Anschlüsse waren angelötet mit 10kOhm Pullup-Widerständen gegen +5V. Auf dem Board sind 3-Achsen Gyro L3G4200D und 3-Achsen Kompass / Beschleunigungssensor LSM303DLM. Sollte mal für ein Mikrokopter sein, habe aber schon länger aus Zeitmangel nichts mehr damit gemacht. Ich hoffe du kannst was damit anfangen auch wenn es nur BASIC ist. Und für alle anderen MitLeser: -> Bitte verzeiht mein schlechten Programmierstil! (Aber es hat funktioniert!!) Holger
@Holger: Vielen Dank für deinen Beitrag, leider suche ich C-Code und SPI als Kommunikation. Leider kann ich daher mit deinen Dateien nicht viel anfangen. Ich verzweifele bald :/
@ Florian, sorry habs gestern vergessen. Wenn du dich noch bis heute Abend gedulden kannst - hab die Daten leider nicht auf meinem Arbeitsrechner. Werde den Code heute abend posten - versprochen ;)
doppelt
So jetzt aber. Die Datei einfach einbinden und dann in der Main folgendes aufrufen um die Sensorwerte auszulesen:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
Vielen Dank schon einmal ich werde es mir sofort anschauen! :) Was genau bedeutet diese Zeile Code?
1 | |
Florian K. schrieb: > Vielen Dank schon einmal ich werde es mir sofort anschauen! :) > Was genau bedeutet diese Zeile Code? >
1 | |
2 | |
Ich schau mir das Bit Nummer 7 in der Variablen Byte an und setze demgemäß meinen Ausgangspin auf 1 oder 0 je nachdem ob das Bit 1 ist oder 0 ist. Das Ganze wird 8 mal durchgeführt bis das ganze Byze rausgesendet wurde. Der Code ist deshalb etwas lang geraten. Prinzipiell kann man den ganzen Spaß auch in einer For-Schleife machen, dann spart man sich eine Menge Zeilen. PS: Deine Ausgangspins musst du natürlich noch entsprechend an dein Design anpassen. Das vergaß ich oben zu erwähnen.
Ok ich hab es verstanden, ich nahm naiver weise an, das der AVR am SPI-BUS zumindest die Chip-Select Leitung selbst steuert und ich direkt eine 8-BIT Zahl senden kann. Naja aber vielen vielen dank! Du hast mir damit sehr geholfen, heute habe ich keinen Kopf mehr das anzupassen aber ich werde morgen versuchen die Register auszulesen und teile dann nochmal mein Ergebnis mit :) Genau danach habe ich nun Zwei Tage gesucht :D
> Ok ich hab es verstanden, ich nahm naiver weise an, das der AVR am > SPI-BUS zumindest die Chip-Select Leitung selbst steuert und ich direkt > eine 8-BIT Zahl senden kann. Zur Harware SPI des AVR kann ich nichts sagen. Der Code von oben ist Soft-SPI - d.h an allen Portpins verwendbar. Auf jeden Fall viel Erfolg.
OK das erklärt vermutlich so einiges :/ Dann bin ich weiterhin auf der Suche nach Hilfe!
Gast
#2938484
Florian K. schrieb: > SPI-BUS zumindest die Chip-Select Leitung selbst steuert und ich direkt > eine 8-BIT Zahl senden kann. Wieso sollte er das tun? Wäre doch vollkommen sinnlos.
Gast
#2938490
Aber erzähl doch mal welche Stelle im Datenblatt des Atmega16 dir Probleme bereitet?
Florian K. schrieb: > OK das erklärt vermutlich so einiges :/ > > Dann bin ich weiterhin auf der Suche nach Hilfe! Bist du denn auf die Hardware SPI angewiesen? Die brauchst du doch nur, wenn du zeitkritische Anwendungen machst.
@Eumel: Ich meine überall zu lesen das folgende Zeilen ausreichen um ein Byte auzulesen:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
Wobei addr zum Beispiel = 0b10001111 ist um das Register WHO_AM_I auszulesen. Und als Rückgabewert dann 0b11010011 ausgeben sollte Ich erhalte allerdings immer als Rückgabewert 255. @ Jo: Ja ich möchte wirklich gerne den SPI-BUS verwenden!
Gast
#2938943
Stichwort: Dumybyte senden.
Gast
#2939031
Um es nochmal etwas deutlicher zu sagen. Du hast nocht nicht ganz
verstanden wie SPI funktioniert. Deine Funktion ReadByteSPI sendet ein
Byte an deinen Sensor und wartet, dass der Controller mit Senden fertig
ist. Allerdings musst du danach noch ein Byte nachschieben. Dein Sensor
verhält sich nämlich so wie jeder SPI slave. Die machen NICHTS von
alleine.
Also: du schickst 0b10001111 an den Sensor. Der weiß jetzt: "Aha, er
will mein WHO_AM_I Register auslesen" Der Sensor legt dann das
entsprechende Byte in sein Schieberegister. Allerdings kommt das da von
alleine nicht raus, der Master muss es rausschieben. Also sendest du
noch ein Dummybyte hinter. Der Wert dieses Bytes ist EGAL, es dient nur
dazu die von dir gewollten Daten aus dem Sensor rauszuschieben.
Richtig wäre also:
char ReadByteSPI(char addr)
{
SPDR = addr; //Load byte to Data register
while(!(SPSR & (1<<SPIF))); // Wait for transmission complete
SPDR = addr; //Load byte to Data register, wir jetzt als Dummybyte
benutzt!!!!!
while(!(SPSR & (1<<SPIF))); // Wait for transmission complete
addr=SPDR;
return addr;
}
das sollte funktionieren.
Gast
#2939032
Ach mist, vielleicht zwischendurch noch cs toggeln. Schau mal ins Datenblatt deines Sensors.
Vielen Vielen Dank!!!!! Nun klappt es endlich! Damit zauberst du mir doch glatt ein lächeln aufs Gesicht. Also wie gesagt vielen Dank!!! :D
Gast
#2939140
Schön, dass es klappt. Wichtig ist auch, dass du verstanden hast wieso! Schau dir z.b. das hier: http://www.uni-koblenz.de/~physik/informatik/MCU/SPI.pdf nochmals an.
Holger E. schrieb: > Hallo Florian, > ich habe mal hier meine BASCOM-Dateien angehäng. > .... > > Ich hoffe du kannst was damit anfangen auch wenn es nur BASIC ist. > > Und für alle anderen MitLeser: > -> Bitte verzeiht mein schlechten Programmierstil! > (Aber es hat funktioniert!!) > > Holger Holger, genau dieses Beisp. für den minIMU-9 mit BASCOM hab ich gesucht! Es funktioniert wunderbar! DANKE!!!!! Gruß Hans
Gast
#3169586
Hi, ich bin auch grad daran, den L3G4200D auszulesen. Mache das aber über I2C... Hab alles korrekt angeschlossen und die Kommunikation gelingt auch. Also Das WhoAmI bekomm ich korrekt zurück. Wenn ich aber nun die 3 Achsen auslesen möchte, erhalte ich nicht die erwarteten Wert zurück. Hier zunächst mal der Code:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
Als Ergenis bekomme ich dann: X: -5 Y: -104 Z: 31 T: 17 X: -25 Y: -101 Z: 63 T: 17 X: 5 Y: -110 Z: 31 T: 17 X: 5 Y: -78 Z: 31 T: 17 X: -37 Y: -141 Z: 15 T: 17 X: -15 Y: -53 Z: 42 T: 17 X: -20 Y: -77 Z: 43 T: 17 X: -14 Y: -82 Z: 41 T: 17 X: 28 Y: -60 Z: 21 T: 16 X: -20 Y: -83 Z: 50 T: 17 X: 10 Y: -95 Z: 31 T: 17 Wie man sieht schwanken die Achsen ziemlich stark, was nicht sein kann, da der Sensor nur auf dem Tisch liegt. Die Temperatur ist zwar relativ stabil, jedoch viel zu niedrig... Hat hierzu jemand eine Idee, was das Problem sein könnte? In der Konfig ein Register vergessen oder ähnliches?
Gast
#3170322
Hallo nochmal, wie ich mittlerweile herausgefunden habe ist der Temperatursensor nicht für die Umgebungstemperatur, sondern für die IC-Temperatur gedacht. Die Achsenwerte scheinen doch zu stimmen, da der Gyro die Werte in °/s ausgibt. Und wenn der Sensor nur liegt, bleiben die Werte natürlich gleich, bis auf die üblichen Schwankungen.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.