- LiFePO4 Speicher Test         
Seite 9 von 9 ErsteErste ... 789
Ergebnis 81 bis 89 von 89

Thema: 3-Achs Beschleunigungssensor - sensationell günstig !

  1. #81
    Erfahrener Benutzer Begeisterter Techniker Avatar von H.A.R.R.Y.
    Registriert seit
    15.09.2005
    Beiträge
    306
    Anzeige

    Powerstation Test
    Hallo damfino,

    Dein Code ist wohl nur ein Ausschnitt. Auf welche Geschwindigkeit ist der I²C eingestellt? Habe eben etwas über die max. Geschwindigkeit und Kabellänge am Sensor gelesen. Solltest 100kHz auf SCL nicht überschreiten. Leider finde ich auf die schnelle das Datenblatt des Sensors nicht (bei ELV ist jedenfalls kein direkter Download ode sowas zu sehen). Ohne Datenblatt kann ich aber die Sequenz nicht nachprüfen...

    H.A.R.R.Y.
    a) Es gibt keine dummen Fragen, nur dumme Antworten
    b) Fehler macht man um aus ihnen zu lernen
    c) Jeder IO-Port kennt drei mögliche Zustände: Input, Output, Kaputt

  2. #82
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    12.07.2006
    Ort
    Puchheim
    Alter
    77
    Beiträge
    455
    Hallo Kekse,

    war lange nicht im Forum und hab Deine Frage erst heute gesehen.
    Hab mir das mit der Linearisierung relativ einfach gemacht und das eigentlich
    nur auf +-255 normiert.
    Wenn der Maximalmesswert bei 90° z.B. bei 280 lag und der Minimalwert z.B. bei -230, hab ich das auf +-255 umgerechnet und dazwischen dann eine Gerade gelegt (bei 0,5% Linearität eigentlich erlaubt).


    Dafür hab ich bei meinem Exemplar folgende Parameter benutzt:

    double const rad_to_grad = 57.29577951;
    double const maxm = 256.00;
    // Konstanten zur Eichung der acc-Kennlinie (von Exemplar zu Exemplar unterschiedlich)
    double const x_norm = 1.080169; // x : 267 ... - 207 = 474 512/474 = 1.108169;
    double const y_norm = 1.028112; // y : 227 ... - 271 = 498 512/498 = 1.102811;
    double const z_norm = 1.015873; // z : 259 ... - 245 = 504 512/504 = 1.105873;
    double const x_null = -32.405; // x : (267 - 32.405) * x_norm = 256;
    double const y_null = 22.619; // y : (227 + 22.619) * y_norm = 256;
    double const z_null = -7.11; // z : (259 - 7.11) * z_norm = 256;


    Gruss mausi_mick

  3. #83
    Erfahrener Benutzer Begeisterter Techniker Avatar von H.A.R.R.Y.
    Registriert seit
    15.09.2005
    Beiträge
    306
    Hallo damfino,

    bins nochmal - nachdem ich jetzt das Datenblatt vom Sensor habe, sehe ich einen möglichen Fehler in Deinem Code. Um zu lesen sendest Du ein WR-Befehl (0x70) mit Registeradresse 2. Danach eine RESTART-Sequenz. Im Gegensatz zu den diversen I²C-EEPROMs, die diese Sequenz kennen, kann der Sensor sie offenbar nicht! Im Datenblatt ist ganz eindeutig eine STOP-Sequenz und dann eine neue START-Sequenz, diesmal mit Lesebefehl (0x71), zu sehen. Keine RESTART-Sequenz! [Page 35, Figure 16]

    Versuch mal dein Programm entsprechend zu ändern und bitte berichte über Erfolg oder Mißerfolg.

    H.A.R.R.Y.
    a) Es gibt keine dummen Fragen, nur dumme Antworten
    b) Fehler macht man um aus ihnen zu lernen
    c) Jeder IO-Port kennt drei mögliche Zustände: Input, Output, Kaputt

  4. #84
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    06.08.2008
    Ort
    Graz
    Beiträge
    521
    Hi,
    das hatte ich auch schon probiert als ich hier die Codebeispiele durchging.
    Code vom letzten Versuch gestern (im AVR Studio ists schön formatiert aber hier??):
    Code:
    i2c_start(0x70);   	
    	   		
    			i2c_write(2);		 	
    			i2c_stop(); _delay_ms(1);	
    		  	i2c_start(0x70+I2C_READ);      	      
    		   	xl = i2c_readAck();   
    		   	xm = i2c_readAck();
    			yl = i2c_readAck();   
    		   	ym = i2c_readAck();
    			zl = i2c_readAck();   
    		   	zm = i2c_readNak();
    
    			i2c_stop();_delay_ms(1);
    Ich habe auch kurze Delays eingebaut falls stop-start zu schnell hintereinander kommt, hat nichts geändert. Im Datenblatt steht vom Sensor eine maximale Busgeschwindigkeit von 3.4Mhz, aber keine Ahnung wie schnell die Pegelwandler von der ELV Platine arbeiten. Der I2C Bus ist auf 100khz eingestellt.
    Bei dem obigen Beispiel erhalten ich für alle Bytes den Wert 113, dh hex71.

    LG!
    alles über meinen Rasenmäherroboter (wer Tippfehler findet darf sie gedanklich ausbessern, nur für besonders kreative Fehler behalte ich mir ein Copyright vor.)

  5. #85
    Erfahrener Benutzer Begeisterter Techniker Avatar von H.A.R.R.Y.
    Registriert seit
    15.09.2005
    Beiträge
    306
    Das sieht immerhin schon mal so aus wie im Datenblatt dargestellt.

    Mich irritiert aber Dein Rücklesewert von 0x71. Das ist ziemlich genau das was Du abschickst, als ob der USI noch gar nichts empfangen hätte. Oder der Sensor einfach nur ein Echo sendet.

    Funktioniert genau dieses i2c_readAck() & Co mit dem Balancer oder Kompaß?

    Als Referenz würde ich spätestens jetzt einen PCF8574 an den Bus anhängen, 4 LEDs zur Ausgabe und 4 Jumper, Taster, Schalter, Drahtbrücken oder was auch immer zur Eingabe dran. Wenn die Lib den sauber ansteuern kann, dann ist sie wohl auch grundsätzlich I²C-konform.
    a) Es gibt keine dummen Fragen, nur dumme Antworten
    b) Fehler macht man um aus ihnen zu lernen
    c) Jeder IO-Port kennt drei mögliche Zustände: Input, Output, Kaputt

  6. #86
    Hab den gleichen Sensor von ELV ich hab ihn versucht mit dem I2C/USB Adapter auch von ELV auszulesen da kommt aber nur Müll raus welchen Bustakt solt ich einstellen bzw wie habt ihr das Makro abgeändert ?

  7. #87
    Neuer Benutzer Öfters hier
    Registriert seit
    18.03.2011
    Beiträge
    6
    Hallo.

    Erstmal wollte ich mich bedanken, da ich mit hilfe euer Codes erstmal einigermaßen verstanden habe wie der Sensor anzusprechen ist. Leider ist es mir nach einer Woche noch nicht gelungen die Kommunikation zwischen meinem TI 28016, welcher auf nem Olimex Development Board sitzt, und dem BMA020 auf die Beine zu stellen.
    Meine µC-Kenntnis sind eher rudimentär und mit dem TI arbeite ich erst seit 3 Wochen. Deshalb habe ich versucht ein fertiges Snippet anzupassen, geschrieben von Brad Griffis 2008.
    Das ist dabei rausgekommen:
    Code:
    //I2C test 
    
    #include "DSP280x_Device.h"     // DSP280x Headerfile Include File
    #include "DSP280x_Examples.h"   // DSP280x Examples Include File
    
    // Prototype statements for functions found within this file.
    void   I2CA_Init(void);
    Uint16 I2C_Write(Uint16 slvaddr, int data, Uint16 length);
    Uint16 I2C_Read(Uint16 slvaddr, Uint16* data, Uint16 length);
    
    Uint16 Values[6];
    
    void main(void)
    {
       InitSysCtrl();	// Step 1. Initialize System Control:
       InitI2CGpio();	// Step 2. Initalize GPIO only for I2C functionality
       I2CA_Init();		// Step 4. Initialize all the Device Peripherals
    
       for(;;)		// Application loop
       {   
    	I2C_Write(0x70,0x02,2);
       	I2C_Read(0x71,Values,6);
       }   // end of for(;;)
    }   // end of main
    
    
    void I2CA_Init(void)
    {
    //   I2caRegs.I2CSAR = 0x38;		// Slave address - EEPROM control code
       I2caRegs.I2CPSC.all = 6;		// Prescaler - need 7-12 Mhz on module clk for 60MHz CPU
       I2caRegs.I2CCLKL = 4200;		// NOTE: must be non zero
       I2caRegs.I2CCLKH = 4200;		// NOTE: must be non zero
       I2caRegs.I2CIER.all = 0x3E;		// Enable SCD,XRDY,RRDY,ARDY,NACK interrupts
    //   I2caRegs.I2CMDR.all = 0x0020;	// Take I2C out of reset, Stop I2C when suspended
    //   I2caRegs.I2CFFTX.all = 0x6000;	// Enable FIFO mode and TXFIFO
    //   I2caRegs.I2CFFRX.all = 0x2040;	// Enable RXFIFO, clear RXFFINT,
       return;
    }
    
    Uint16 I2C_Write(Uint16 slvaddr, int data, Uint16 length)
    {
       Uint16 i;
       while (( I2caRegs.I2CSTR.bit.BB==1 ));	//bus busy?
       if (I2caRegs.I2CSTR.bit.BB == 1)
       {
          return I2C_BUS_BUSY_ERROR;
       }
    	I2caRegs.I2CMDR.all = 0;	//disable I2C during config
    	I2caRegs.I2CCNT = length;	//number of bytes to be send
    	I2caRegs.I2CSAR = slvaddr;	//setup receiver addr
    //	Mode settings
    	I2caRegs.I2CMDR.bit.IRS=1;	//I2C module enable							
    	I2caRegs.I2CMDR.bit.STT=1;	//If master -> start condition generated
    	I2caRegs.I2CMDR.bit.STP=1;	//If master -> stop condition generated if data counter=0
    	I2caRegs.I2CMDR.bit.TRX=1;	//Transmitter mode
    	I2caRegs.I2CMDR.bit.MST=1;	//Master mode
    	I2caRegs.I2CMDR.bit.FREE=1;	//I2C module runs free
    	I2caRegs.I2CMDR.bit.RM=1;	
    	
    	/* Transmission*/
    	for(i=0;i<length;i++)
    	{
    		while(!(I2caRegs.I2CSTR.bit.XRDY|I2caRegs.I2CSTR.bit.ARDY));	//wait for xdry flag before transmit data or ardy if NACK appears
    		if (I2caRegs.I2CSTR.bit.NACK==1)				//if NACK appears -> SCL=low, STP=0
    		{
    			I2caRegs.I2CMDR.all=0;					//reset I2C -> SCL not held low
    		}
    		I2caRegs.I2CDXR = data;
    	}
    }
    
    Uint16 I2C_Read(Uint16 slvaddr, Uint16* data, Uint16 length)
    {
    	Uint16 i;
    	while (( I2caRegs.I2CSTR.bit.BB==1 ));		//bus busy?
       if (I2caRegs.I2CSTR.bit.BB == 1)
       {
          return I2C_BUS_BUSY_ERROR;
       }
    	I2caRegs.I2CMDR.all = 0;			//disable I2C during config
    	I2caRegs.I2CCNT = length;			//number of bytes to be send
    	I2caRegs.I2CSAR = slvaddr;			//setup receiver addr
    //	Mode settings
    	I2caRegs.I2CMDR.bit.IRS=1;			//I2C module enable							
    	I2caRegs.I2CMDR.bit.STT=1;			//If master -> start condition generated
    	I2caRegs.I2CMDR.bit.STP=1;			//If master -> stop condition generated if data counter = 0
    	I2caRegs.I2CMDR.bit.MST=1;			//Master mode
    	I2caRegs.I2CMDR.bit.FREE=1; 			//I2C module runs free
    	I2caRegs.I2CMDR.bit.NACKMOD=1;
    
    	/* Reception */
    	for(i=0;i<length;i++)
    	{
    		while(!(I2caRegs.I2CSTR.bit.XRDY|I2caRegs.I2CSTR.bit.ARDY));	//wait for xdry flag before transmit data or ardy if NACK appears
    		if (I2caRegs.I2CSTR.bit.NACK==1)				//if NACK appears -> SCL=low, STP=0
    		{
    			I2caRegs.I2CMDR.all=0;					//reset I2C -> SCL not held low
    		}
    		while(I2caRegs.I2CSTR.bit.RRDY==1);
    		data[i] = I2caRegs.I2CDRR ;
    	}
    }
    
    //EOF
    Das Ergebnis hab ich mir mit nem Oszi angeschaut: Nach dem ersten Senden wird SDI auf low gezogen und SCK bleibt high. Wenn ich die
    Code:
    while (( I2caRegs.I2CSTR.bit.BB==1 ));
    in der Schreib- bzw. Lesefunktion auskommentiere kann ich folgendes Bild sehen:

    http://img24.imageshack.us/img24/7899/bild0027h.jpg

    Meiner laienhaften Meinung nach wird keine Stop Condition erzeugt, weshalb BB immer 1 ist.

    Ein Versuch eine I2C-Minimalversion für diese Sache zu schreiben sah so aus:
    Code:
    //I2C test 
    
    
    #include "DSP280x_Device.h"     // DSP280x Headerfile Include File
    #include "DSP280x_Examples.h"   // DSP280x Examples Include File
    
    // Prototype statements for functions found within this file.
    void   I2CA_Init(void);
    
    Uint16 Values[6],i;
    
    
    void main(void)
    {
       InitSysCtrl();			// Step 1. Initialize System Control:
       InitI2CGpio();			// Step 2. Initalize GPIO only for I2C functionality
       I2CA_Init();				// Step 4. Initialize all the Device Peripherals:
    
    
       for(;;)					// Application loop
       {
       		      //---> Write instruction <--- //
          I2caRegs.I2CMDR.bit.STT = 1;
          I2caRegs.I2CSAR = 0x70;				//Write addr
          I2caRegs.I2CCNT = 3;				//3bytes=2bytes addr + 1 byte instr
          I2caRegs.I2CDXR = 0x02;				//instr
          I2caRegs.I2CMDR.bit.STP = 1; 
    //      I2caRegs.I2CMDR.all = 0x2620;		//Send data to setup EEPROM address
    
          
          //---> Read values <--- //
          I2caRegs.I2CMDR.bit.STT = 1;
          I2caRegs.I2CSAR = 0x71;				//Read addr
          I2caRegs.I2CCNT = 1;				//6bytes=2bytes per coordinate
          Values[0] = I2caRegs.I2CDRR;
          /*for(i=0;i<6;i++)
          {
          	Values[i] = I2caRegs.I2CDRR;
          }*/
          I2caRegs.I2CMDR.all = 0x2C20;			//Send restart as master receiver
       	  I2caRegs.I2CMDR.bit.STP = 1;					
       }   // end of for(;;)
    }   // end of main
    
    
    void I2CA_Init(void)
    {
    //   I2caRegs.I2CSAR = 0x38;			// Slave address - EEPROM control code
       I2caRegs.I2CPSC.all = 6;			// Prescaler - need 7-12 Mhz on module clk for 60MHz CPU
       I2caRegs.I2CCLKL = 4200;			// NOTE: must be non zero
       I2caRegs.I2CCLKH = 4200;			// NOTE: must be non zero
       I2caRegs.I2CIER.all = 0x24;		// Enable SCD & ARDY interrupts
       I2caRegs.I2CMDR.all = 0x0020;	// Take I2C out of reset, Stop I2C when suspended
       I2caRegs.I2CFFTX.all = 0x6000;	// Enable FIFO mode and TXFIFO
       I2caRegs.I2CFFRX.all = 0x2040;	// Enable RXFIFO, clear RXFFINT,
       return;
    }
    
    //EOF
    Führte aber leider auch nicht zum Ergebnis.

    Falls es relevant ist ich nutze das Code Composer Studio V4.
    Falls jemand hier Erfahrungen mit TI DSPs oder Vorschläge jeglicher Art zu meinen beiden Code-Versuchen hat wäre ich sehr dankbar.

    Grüße
    Stephan

  8. #88
    Neuer Benutzer Öfters hier
    Registriert seit
    18.03.2011
    Beiträge
    6
    hallo,

    habs jetzt hinbekommen und falls mal jemand den BMA020 mit TI C2000 DSPs nutzen will poste ich mal meinen, durchaus verbesserungswürdigen, Code, welcher hier bereits gepostete Codeschnipsel enthält.

    Code:
    //I2C test 
    
    #include "DSP280x_Device.h"     // DSP280x Headerfile Include File
    #include "DSP280x_Examples.h"   // DSP280x Examples Include File
    
    // Prototype statements for functions found within this file.
    void   I2CA_Init(void);
    
    int Values[6]={0,0,0,0,0,0};
    Uint16 instr=0x02;
    int i,dx=0,dy=0,dz=0;
    double D2G,gx=0,gy=0,gz=0;
    
    void main(void)
    {
       InitSysCtrl();			// Step 1. Initialize System Control:
       InitI2CGpio();			// Step 2. Initalize GPIO only for I2C functionality
       I2CA_Init();				// Step 4. Initialize all the Device Peripherals
       
       D2G=0.00390625;			// 4g/1024
       
       for(;;)					// Application loop
       	{  
       		I2caRegs.I2CSAR = 0x38; 		//Set slave address
       		I2caRegs.I2CCNT = 1; 			//Set count to 1 Byte for instr 0x02
       		I2caRegs.I2CDXR = 0x02;			//Send instr
       		I2caRegs.I2CMDR.bit.TRX = 1; 		//Set to Transmit mode
       		I2caRegs.I2CMDR.bit.MST = 1; 		//Set to Master mode
       		I2caRegs.I2CMDR.bit.FREE = 1;		//Run in FREE mode
       		I2caRegs.I2CMDR.bit.STP = 1; 		//Stop when internal counter becomes 0
       		I2caRegs.I2CMDR.bit.STT = 1; 		//Send the start bit, transmission will follow
    				
        
       		while(I2caRegs.I2CSTR.bit.XRDY == 0){}; 	//Do nothing till data is shifted out
       		I2caRegs.I2CCNT = 6;				//read 6 bytes from sensor
       		I2caRegs.I2CMDR.bit.TRX = 0; 			//Set to Recieve mode
       		I2caRegs.I2CMDR.bit.MST = 1; 			//Set to Master mode
       		I2caRegs.I2CMDR.bit.FREE = 1;			//Run in FREE mode
       		I2caRegs.I2CMDR.bit.STP = 1; 			//Stop when internal counter becomes 0
       		I2caRegs.I2CMDR.bit.STT = 1; 			//Repeated start, Reception will follow
       		for(i = 0; i < 6; i++)
       			{
       				while(I2caRegs.I2CSTR.bit.RRDY == 0){}; //I2CDRR not ready to read?
       				Values[i] = I2caRegs.I2CDRR;
       			}
       		DELAY_US(100);				//wait for new data provided
       		dx=Values[0];				//dataadaptation by malthy & Sternthaler
       		dx=(dx|((Values[1]<<8))>>6);
       		gx=dx*D2G;
       		dy=Values[2];
       		dy=(dx|((Values[3]<<8))>>6);
       		gy=dy*D2G;
    		dz=Values[4];
       		dz=(dx|((Values[5]<<8))>>6);
       		gz=dz*D2G;
       		   	   		 	   
       }   // end of for(;;)
    }   // end of main
    
    
    void I2CA_Init(void)
    {
       I2caRegs.I2CSAR = 0x38;		// Slave address - EEPROM control code
       I2caRegs.I2CPSC.all = 6;		// Prescaler - need 7-12 Mhz on module clk for 60MHz CPU
       I2caRegs.I2CCLKL = 42;		// NOTE: must be non zero
       I2caRegs.I2CCLKH = 21;		// NOTE: must be non zero
       I2caRegs.I2CIER.all = 0x3E;		// Enable SCD,XRDY,RRDY,ARDY,NACK interrupts
       I2caRegs.I2CMDR.bit.IRS = 1;      // Take I2C out of reset, Stop I2C when suspended
       I2caRegs.I2CFFTX.all = 0x0000;	// Enable FIFO mode and TXFIFO
       I2caRegs.I2CFFRX.all = 0x0000;	// Enable RXFIFO, clear RXFFINT,
       return;
    }
    
    //EOF
    An der Stelle nochmals danke an die "Code-Sponsoren".

    Das einzige was mich im Betrieb stört ist, dass die Ergebnisse nicht konstant bleiben selbst wenn ich den Sensor fest einspanne. Dabei treten manchmal Sprünge von bis zu 0.5g auf, was für meine anschließende Aufgabe tötlich sein wird. Hat schon mal jemand in dem Zusammenhang mit den Filtern rumgespielt ?

  9. #89
    Neuer Benutzer Öfters hier
    Registriert seit
    18.03.2011
    Beiträge
    6
    Hallo,

    ich weiß nicht ob dass hier noch relevant ist, aber falls nochmal jemand auf schwankende Werte kommt kann ich empfehlen die Einstellung des im Sensor befindlichen Tiefpasses zu checken. Bei mir war die Einstellung für "bandwidth" (14h,bits 2-0) nämlich auf 750Hz, abweichend von der Standardbelegung mit 25Hz. Dadurch hatte ich bei einem Wertebereich von +/-256 einen Fehler von ca. +/-10. Mit 25Hz komm ich auf +/-2 und bin für meine Anwendung ausreichend schnell.

    In dem Sinne fröhliches Beschleunigen

Seite 9 von 9 ErsteErste ... 789

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests