Hallo,
ich versuche mit einem Arduino Uno einen Winkelsensor auszulesen. Der
Sensor ist von Infineon (TLE5012B)
http://www.infineon.com/dgdl/Infineon-Angle_Sensor_TLE5012B-UM-v01_00-en.pdf?fileId=5546d46146d18cb40146ec2eeae4633b
In Arduino gibt es schon eine libary die SPI.h heist und die ich dafür
auch benutze. Mein Problem ist jetzt, dass der Chip nur ein Data Pin hat
und nicht MISO/MOSI getrennt hat. Ich habe hier im Forum schon einen
Beitrag gefunden(Beitrag "SPI mit bidirektionale Datenverbindung"). Leider
klappt es mit dem 4k7 Widerstand auch nicht.
Des Weiteren bin ich mir über den Commandbefehl zum lesen nicht ganz
sicher, ob es der Richtige ist?
Oder liegt es an meinen Einstellungen von SPI?
hier mein Code:
1
#include<SPI.h>
2
3
intangleValue_command=0x4010;// Register command für Anglevalue read
Ich habe mir gerade mal das Datenblatt von dem Sensor angesehen und wie
man die SSC Schnittstelle per SPI bedient steht da doch drin -> Seite
34.
Was bei Dir oben noch fehlt ist, den MOSI Pin auf Eingang umzuschalten.
Mal davon abgesehen, dass die Datentypen durcheinander sind in dem
Gewurschtel da oben, aus dem angleValue_command mit 16 Bit wird mal eben
read_command mit 8 Bit.
Da müsstest Du schon die beiden Bytes von angleValue_command
nacheinander schicken, dann MOSI auf Eingang umschalten und dann noch
zwei Transfers machen, damit die Antwort vom Sensor gelesen werden kann.
/*-----------------Antwort vom Slave----------------------*/
45
data1=SPI.transfer(0);
46
47
// Für den Fall wenn der Sensor einen 16 Bit Wert zurücksendet ...
48
data1<<=8;
49
data1|=SPI.transfer(0);
50
51
/* 16Bit Data 2 empfangen */
52
data2=SPI.transfer(0);// Antwort vom Slave
53
54
// Für den Fall wenn der Sensor einen 16 Bit Wert zurücksendet ...
55
data2<<=8;
56
data2|=SPI.transfer(0);
57
58
/* 16Bit safety empfangen */
59
safety=SPI.transfer(0);// Antwort vom Slave
60
61
// Für den Fall wenn der Sensor einen 16 Bit Wert zurücksendet ...
62
safety<<=8;
63
safety|=SPI.transfer(0);
64
intmiso=data1;
65
digitalWrite(ss,HIGH);// Chipselect auf high
66
returnmiso;
67
}
Das Problem was ich noch habe ist, dass ich die Miso und Mosi Leitung
nicht direkt anschließen kann. Die MOSI Leitung geht dabei erst noch
über einen 4k7 Ohm Widerstand, wie in dem anderen Beitrag schon gezeigt
wurde.
Wennn ich den 4k7 Widerstand weg lasse ist kein Datenempfang möglich.
Auch durch hochohmig schalten der MOSI Leitung beim Datenempfang.
Ich habe den TLE5012B vor ca. 4 Jahren mal an einem FPGA am laufen
gehabt, so ca. mit 2,5 MHz auf der SCK.
Dabei bin ich auch mal ueber die "schlappe" Flanke des Chips gestolpert,
kann mit PAD_DRV in irgeneinem Register konfiguriert werden. Ich musste
dann den Sample Zeitpunkt im FPGA noch 'nach hinten schieben', weil die
Daten vom TLE eben elendig spaet nach der SCK-Flanke gekommen sind. Ok,
ich hatte die SSC auch noch ueber LVDS-Treiber angebunden, das macht's
nochmal langsamer (Latenz)...
Nicht, dass du da ins gleiche Problem reinrennst... Evtl. mal die SPI
deutlich langsamer takten (ca. 1MHz fuer Versuche)
Also zumindest nach Datenblatt vom Mega328 ist die Datenrichtung für
MOSI im SPI Master-Mode "User Defined".
Der Widerstand sollte also nicht notwendig sein, oder könnte
sicherheitshalber zumindest kleiner ausfallen.
Aber was die Arduino-IDE aus "pinMode(MOSI, INPUT);" macht ist die
Frage, das muss ja nicht unbedingt zum gewünschten Ergebnis führen. :-)
Und wie sieht überhaupt der Schaltplan zu dem Sensor aus, also wie der
wirklich benutzt wird, und nicht sowas wie "nach Seite 5 im Datenblatt"?
@berndl:
Danke für den Tipp. Ich werde mal ein wenig mit dem SCK und den
Registern rum probieren um zu sehen, ob dies eine Veränderung bringt. Du
sagst, dass du schon einmal mit dem Chip zu tun hattest, wie ist denn so
Deine Bewertung im großen und ganzen von dem Chip?
@Rudolph:
Rudolph schrieb:> Aber was die Arduino-IDE aus "pinMode(MOSI, INPUT);" macht ist die> Frage, das muss ja nicht unbedingt zum gewünschten Ergebnis führen. :-)
Das habe ich mich auch schon gefragt :D. Vor allem kann es auch gut
möglich sein, dass der Befehlt gar nichts bringt, wenn in der Funktion
"SPI.transfer() evtl. der MOSI wieder auf output gesetzt wird. Da muss
ich mich mal durch die Libary wühlen.
Rudolph schrieb:> Und wie sieht überhaupt der Schaltplan zu dem Sensor aus, also wie der> wirklich benutzt wird, und nicht sowas wie "nach Seite 5 im Datenblatt"?
Momentan geht es erstmal nur darum den Chip zu test und zu gucken wie
ich die Daten ausgelesen kann. Mit anderen Worten, ich habe noch keinen
exakten Schaltplan bis auf ein paar Skizzen, aber am Ende des Tages soll
ein funktionierender Winkelsensor dabei rum kommen.
Ich habe den auch schon benutzt, allerdings mit PWM als Ausgang und dann
per Input-Capture eingelesen -> komplett anders.
Vom Ergebnis her war das schon nett, umgerechnet habe ich das auf 0,1°.
Das lief, war aber nur ein Demonstrator, Referenzmessungen um die
Abweichung zum tatsächlichen Winkel festzustellen wollte da keiner
haben. :-)
Hi,
ich brauche bei folgendem Hilfe.
Mit dem Sensor von Infenion TLE 5012B kann ich bereits den Winkel über
SPI auslesen.
Zur Info, der Sensor ist in der nähe eines Magneten angebracht. Der
Magnet sitzt an der der Welle eines Motors.
Nun möchte ich gerne das Angle Revolution Register ansprechen. Das lesen
funktioniert und es werden Inkremente hoch gezählt von 0 bis 255.
void UmlaufAusgabe(void)
{
unsigned Frame_Counter;
int Num_Revolution;
int miso_data = (spi_read(angleRevolution_command));//& 0x7FFF);
Num_Revolution = 0x00FF & miso_data;
Serial.print( "\t\t Aktueller Umlauf: ");
Serial.println(Num_Revolution);
}
Was ich aber nicht so ganz vertsehe ist, dass laut Datenblatt das
Register 9 Bit für die Umdrehungen hat. Somit habe ich folgendes
probiert und es kommt nur blödsinn raus.
Num_Revolution = 0x01FF & miso_data;
Zusätzlich habe ich das Problem, dass ein Inkerement immer hochgezählt
wird, bei 2 Umdrehungen des Motors.
Nun glaube ich, dass entweder mein auslesen falsch ist oder die
einstellungen die ich im Register benutze.
/*Auslesen des Umlaufs / Angle Revolution (Revolution = Umlauf) Register
*/
int angleRevolution_command = 0x8040;
/*Auslesen der Winkelposition*/
int angleValue_command = 0x8021; // Register command für Anglevalue read
/*Adressen und Befehle für Interface Mode2*/
int mode2_command = 0x5081; // Register command für interface
Mode2
int write_mode2 = 0x0809; //Wirte Befehl interface Mode2, Set
ANG_Range 080H, ANG_DIR: 1B, PREDICT: 0B, AUTOCAL: 01B
ich bin für jede Hilfe Dankbar.