- 3D-Druck Einstieg und Tipps         
Seite 7 von 9 ErsteErste ... 56789 LetzteLetzte
Ergebnis 61 bis 70 von 89

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

  1. #61
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.693
    Anzeige

    Praxistest und DIY Projekte
    Zitat Zitat von BMA020 Data sheet, version 1.2, Rel. 30 May 2008, page 9
    Bits 5, 6 and 7 of register addresses 14h do contain critical sensor individual calibration data wich must not be changend or deleted by any means.

    In order to proberly modify addresses 14h for range and/or bandwidth selection using bits 0, 1, 2, 3 and 4, it is highly recommended to read-out the complete byte, perform bit-slicing and write back the complete byte with unchanged bits 5, 6 and 7.

    Otherwise the reported acceleration data may show incorrect results.
    Also: Byte auslesen und dezimal und binär anzeigen. Danach neue Werte setzen und Byte zurückschreiben. Zur Kontrolle eine kleine Routine, zwei Tasten aufs Steckbrett als Wahlhelfer (Auswahl der Messwerte, Routinen, Bitposition und -änderung).

    Getestet musste die richtige Funktion werden, bevor der erste Schreibvorgang gemacht wird. Dazu ist das Byte 14h im Auslieferungszustand nicht nützlich: -128/0b10000000, da musste zum Test der Ausgabe ein anderer Wert her. Jetzt läuft die Darstellung glaubhaft und prima.

    ............Bild hier  

    Auf den kurzen Code zur int-nach-bin-Wandlung bin ich fast stolz. Siehe z.B. Zeile 45 - 48.

    Code:
    // ------------------------------------------------------------------------------ -
    //      Lesen des Register 0x14, Range und Bandwidth
                                    //
            i2c_init();             //
      ret = i2c_start (I2C_BMA_W);  // Schreibbefehl auf Device-Adresse 0x70
      ret = i2c_write (0x14);       // Zu lesende Adresse für Range+Bandwidth
            i2c_stop  ();           // Stop
                                    //
      ret = i2c_start (I2C_BMA_R);  // Lesen bis zum Stop auf Device-Adresse 0x71
      brb = i2c_read  (NAK);        // brb = Byte mit Range + Bandwidth
            i2c_stop  ();           // Steuerwert Range+Bandwidth wurde gelesen
    
      brb = 86;     // <<<<<##### Diese Zuweisung NUR testweise <<<<<#####
    
                                    //
    // ------------------------------------------------------------------------------ -
    // ------------------------------------------------------------------------------ -
    //      Wert von Range und Bandwidth dezimal und binär aufs LCD schreiben
                                    //
      lcd_clrscr();                 // loesche LCDisplay; Cursor Zeile 0 Spalte 0
    //           012345678901234567890123
      lcd_puts ("Rng+Bndwth :         dez");        //
                                    //
      itoa(brb, zahlwort, 10);      //
      lcd_gotoxy(14, 0);            // Spalte 11 {0 bis 23} in Zeile 0 {0 bis 1}
      lcd_puts(zahlwort);           //      = neunte Spalte in erster Zeile
      lcd_gotoxy( 0, 1);            // Spalte  0 in Zeile 1
    //           012345678901234567890123
      lcd_puts ("Biner = - - - - - -  bin");        // = nullte Spalte in zweiter Zeile
      ae[0]         = 225;          // Umlaut a
      ae[1]         =   0;          // Stringende
      lcd_gotoxy(3, 1);             // Spalte 3 {0 bis 23} in Zeile 1 {0 bis 1}
      lcd_puts(ae);                 //      = schreibe "ä" von Binär
    //lcd_puts ("Binär = 0b bbbb bbbb bin ");       // Binär = korrekt geschrieben
                                    //
    // ------------------------------------------------------------------------------ -
    //      bsg[15] für Konvertierung nach binär und Darstellung: "0b bbbb bbbb"
                                    //
      bsg[0]        = 48;           // dez48 = ASCII 0
      bsg[1]        = 98;           // dez98 = ASCII b
      bsg[2]        = 30;           // dez30 = ASCII Space
    				//
      bsg[7]        = 30;           // dez30 = ASCII Space
                                    // Bis hierher ist es nur "Vorspann"
      for (ia = 1; ia <= 4; ia++)   // Erstes Nibble übersetzen nach Binär
      {                             //
        bsg [ia+2]   = ((IsBitSet (brb, (8-ia))) + 48);
      }                             // Ende for (ia = 1; ia <= 4; ia++)
    //      Die ersten vier Bits sind abgearbeitet
      for (ia = 5; ia <= 8; ia++)   // Übersetzen des zweiten Nibbels nach Binär
      {                             //
        bsg [ia+3]   = ((IsBitSet (brb, 8-ia)) + 48);
      }                             // Ende for (ia = 7; ia == 4; ia--)
    //      Die vier Bits des zweiten Nibbels sind abgearbeitet
    // ------------------------------------------------------------------------------ -
    // ------------------------------------------------------------------------------ -
    //      Null in das Feld des Ausgabestrings als Abschlusskennung
      bsg[12]       =  0;           // 
    //      Dekodieren ist abgeschlossen
    // ------------------------------------------------------------------------------ -
    // ------------------------------------------------------------------------------ -
    //      Binären Wert aufs LCD schreiben
    Ciao sagt der JoeamBerg

  2. #62
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    29.05.2005
    Beiträge
    1.018
    Hallo mausi_mick,

    nun finde ich auch deinen Link zu dem 3D-Spiele-Buch. Ich glaube, ich muss da mal kaufen gehen. Die Leseprobe sagt mir schon, dass ich den Matheteil abschreiben kann und der restliche Text reicht mir aus. Guter Tipp.


    Hey oberallgeier, nicht schlecht dein Binärwandler.

    Zum Bit-Anzeigen hätte ich folgendes geschrieben:
    Code:
    unit8_t offset, wanderbit;
    
    offset = 3;
    wanderbit = 0b10000000;
    for (i = 0; i < 8; i++)
    {
       bsg [offset] = ( brb & wanderbit >> i) ) ? '1' : '0';
       if i = 4 offset++;
    }
    Kannst du mir mal den Gefallen tun und das Zeug von mir mal kompilieren und die benötigten Bytes posten? (Mein PC ist leider immer noch AVR-frei. Sch... Firma)
    Ich tippe fast, dass deine Variante sparsamer ist.

    Gruß Sternthaler

    P.S.: Das mit der Geschwindigkeits- / Positionsmessung kommt mir noch schlimmer als oben angegeben vor.
    Klar hat der Wandler 10 Bit Auflösung. Aber kann man die tatsächlich nutzen wenn ich in einer (Fahrt-/Beschleunigungs)-Richtung messe? Bleiben da nicht nur 9 Bits als relevanter Messwert? Und somit nur 0.2% Genauigkeit?
    Lieber Asuro programieren als arbeiten gehen.

  3. #63
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.693
    Zitat Zitat von Sternthaler
    ... Das mit der Geschwindigkeits- / Positionsmessung kommt mir noch schlimmer als oben angegeben vor ... 9 Bits als relevanter Messwert? ...
    Da stelln ma uns mal jaaanz domm.

    Wat is denn integrierbar? Doch nur eine Funktion. Was ist eine Funktion? Das ist, kurz gefasst, doch die Zuordnung von Elementen der Definitonsmenge an eine Zielmenge mit all den bekannten Dingen: Stetigkeit, Eindeutigkeit etc. Als Definitionsmenge für den Weg, entlang dem die Beschleunigung existiert, ebenso für die Zeit, während der die Beschleunigung dauert, gelten alle Elemente des (reellen Zahlenraumes) Bild hier  . Wir haben aber nur einige wenige diskrete Zahlenwerte. Grund ist die endliche, nicht eindeutig fassbare Wandelzeit und die wählbare Auflösung mit max. 1024 Werten. Daher ist - streng genommen - die Funktion garnicht stetig integrierbar. Es liegen ja keine Werte d2x/dt² vor, sondern nur Δ2x/Δt². Genaugenommen ist die "Funktion" eben nur durch diejenigen Näherungsrechtecke "integrierbar", die durch die existierenden Punktpaare definiert sind (Herr Riemann freut sich gerade). Lauter Fallstricke, die die numerische Mathematik der Analytik in den Weg legt. Und damit kommen Sternthalers Fehler hinein.

    Zweimal aufintegriert mit solchen Fehlern gilt dann eher als Schätzung.

    Da ein Bild mehr als tausend (holprige Theorie-) Worte sagen kann, hier mal zwei Beispiele für identische Messwerte für zwei unterschiedliche Beschleunigungsverläufe . . . . . der Rest ist offensichtlich. Dabei wäre der Glitch im ersten Abschnitt sogar noch gesondert zu diskutieren. Die Rasterpunkte stellen die ausschließlich möglichen Zeit- und Beschleunigungswerte dar *ggg*.

    ............Bild hier  

    Verbessert mich, wenn ich daneben liege (bin von der heutigen Bergtour noch ziemlich ko).
    Ciao sagt der JoeamBerg

  4. #64
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    29.05.2005
    Beiträge
    1.018
    Oh, ja!
    Domm kann ich ganz viel. (Und wenn dann noch etwas Brennendes im Töpfchen dabei ist, ist der Abend gerettet.)
    Ausserdem sollte ich mal so langsam lernen mich nicht in mathematische Angelegenheiten einzumischen.

    Nee, den Riemann meinte ich aber auch nicht. Ist mir schon klar, dass ein System mit Messzyklen 'dazwischen' keine Realität hat.
    Was ich P.S.'en wollte ist meine Befürchtung, dass ich für eine positive Beschleunigung nur die 9 Bits habe und da vermute ich, dass dies die Begrenzung darstellt.

    Meine Bauch-Begründung:
    [Sternthaler-Theorem]
    - Fahrzeug steht: Nix zum Integrieren vorhanden -> Ergebnis: 0 m/s
    - Fahrzeug beschleunigt auf Maximum: Nur 9 Bits, die mir beim Rechnen zur Verfügung stehen.
    - Fahrzeug hält die Geschwindigkeit: Nun ja; Riemann und Co. berechnen weiterhin die Maximalgeschwindigkeit.

    Ich nutze also bei der Beschleunigung überhaupt nicht das 10-te Vorzeichenbit. Somit habe ich, um deine Rasterpünktchen zu erwähnen, ja auch nur die Hälfte auf der Y-Achse und somit geht wieder ein Teil der Realität 'dazwischen' verloren.
    [/Sternthaler-Theorem]

    Ansonsten kann ich jetzt nur sagen, dass du dir viel Mühe gemacht hast um bei mir ein Lichtlein anzuzünden.
    Vor allem dein "Bild hier  " gefällt mir sehr gut .

    Ach und natürlich noch etwas:
    Meine Code zum Binärrechen ziehe ich erst mal zurück.
    Dank oberallgeier sind da viele Tippfehler entdeckt worden, die das Zeug nicht wirklich nutzbringend erscheinen lassen. (Vor allem das Zählen von Klammern muss ich noch üben.)

    Gruß Sternthaler
    Lieber Asuro programieren als arbeiten gehen.

  5. #65
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.693
    Zitat Zitat von Sternthaler
    ... Sternthaler ... Beiträge: 999 (Stand 06. Nov. 2010, 19:12) ...
    Huiiii - da muss ich jetzt aufpassen, damit ich Dir zu Deinem Tausender gratulieren kann.

    Zitat Zitat von Sternthaler
    ... Meine Code zum Binärrechen ziehe ich erst mal zurück ...
    Ähhhh - und die Verschworenen dürfen den auch nicht mehr zur Kenntnis nehmen? Was solls denn mit ein paar Klammern mehr oder weniger - wos grad einen witzigen Thread gibt, über so viele Jammern in C - ich meine ein jammerThread über die Klamme.. . . . mist, jetzt hab ich den Faden verloren. Schade - Dein Code hätte mich interessiert. Weil Du ja ziemlich vorbildliches C schreibst. Aber um das Maß für verwuchselte Bechstaben zu füllen: ich hab mit meinem Code die Binärdarstellung aus der Dezimalzahl gerechnet - da ich leider keinen Binärrechen habe. Übrigens war ich über das Gelingen meines ersten I2C-Projektchens so happy, dass ich die Konsequenz aus dem Vorzeichenbit übersehen habe. Immerhin wäre dann die feinste Auflösung (Range 2g) schon 40 mm/s² - (ich muss mal sehen, ob der asuro so viel - oder mehr - schafft). Also - Sternthaler macht klug.

    @Sternthaler: Machs wie alle - nimm mich einfach nicht ernst.
    Ciao sagt der JoeamBerg

  6. #66

    Robi+BMA

    Hallo zusammen,

    ich arbeite mit dem BMA150, der ähnlich ist zum BMA020. Den Sensor habe ich mit einem Robi von Conrad(PRO BOT 12 verbunden. Die Kommunikation zwischen den beiden Komponenten habe ich über die I2C Schnittstelle realisiert und ich programmiere auf der Plattform von Conrad mit Hilfe von C-Conrol (Programmiersprache ist Compact C, ähnlich zu C).

    Eure Beiträge bzgl. dem Auslesen der Register hat mit gut geholfen. Es sollen die Beschleunigungen ausgelesen werden während mein Robi fährt.

    Über Multithreads habe ich die beiden Programme verbunden, damit die zwei Programme nahe zu parallel ablaufen.

    Der Robi fährt und ich bekomme auch Werte ausgelesen, nur ändern diese sich nur im Werteberecih von +/- 1g.
    Wie kann ich festlegen, ob ich mit 2g, 4g oder 8g arbeiten möchte? Laut BOSCH Datenblatt steht dazu das Register 14 (Bit 3 und 4) zur Verfügung.
    Aber muss ich jetzt in das Register reinschreiben?

    Hab euch mal mein Programm angefügt.


    Grüße TJ
    Code:
    //Die Beschleunigungen in x,y und z Richtung sollen mithilfe des BMA150 und dem PRO BOT128 ausgelesen werden
    
    
    void main(void)
    {
    
    
        word adresse;
        adresse=0x02;
    
        int             x_long,y_long,z_long;
        unsigned int    x_short,y_short,z_short;
        float           x,y,z;
        byte            bma_r,bma_w;
        bma_r=0x71;
        bma_w=0x70;
    
        PRO_BOT128_INIT();
        I2C_Init(I2C_100kHz);
        DRIVE_INIT();
    
          Thread_Start(1,thread1);
          Thread_Delay(10);
    
       /* Thread_Start(2,thread2);
        Thread_Delay(10);*/
    
        do
        {
            I2C_Start();
            I2C_Write(0x70);
            I2C_Write(adresse);
            I2C_Stop();
    
            I2C_Start();
            I2C_Write(0x71);
    
             x_short=I2C_Read_ACK();
             x_long=I2C_Read_ACK();
    
             x_long=(((x_long)*4)*+(x_short/64));
    
            if (x_long > 511)
            {
                x_long= (x_long - 511);
                x_long= (511 - x_long);
                x_long= (x_long*(-1));
    
                x= (x_long * 0.00390625);
            }
             else
            {
                x= (x_long * 0.00390625);
            }
    
              y_short=I2C_Read_ACK();
              y_long=I2C_Read_ACK();
    
              y_long=(((y_long)*4)+(y_short/64));
    
             if (y_long > 511)
             {
                  y_long= (y_long - 511);
                  y_long= (511 - y_long);
                  y_long= (y_long*(-1));
    
                  y= (y_long * 0.00390625);
             }
             else
             {
                  y= (y_long * 0.00390625);
             }
    
    
             z_short=I2C_Read_ACK();
             z_long=I2C_Read_NACK();
    
             z_long=(((z_long)*4)+(z_short/64));
    
             if (z_long > 511)
            {
                  z_long= (z_long - 511);
                  z_long= (511 - z_long);
                  z_long= (z_long*(-1));
    
                  z= (z_long *0.00390625);
            }
            else
            {
                  z= (z_long *0.00390625);
            }
    
            I2C_Stop();
    
            float str[4];
            str[1]=x;
            str[2]=y;
            str[3]=z;
    
            Str_Printf(str,"%1.2f",x);
            Msg_WriteChar(97);
            Msg_WriteChar(120);
            Msg_WriteChar(61);
            Msg_WriteText(str);
            Msg_WriteChar(13);
    
            Str_Printf(str,"%1.2f",y);
            Msg_WriteChar(97);
            Msg_WriteChar(121);
            Msg_WriteChar(61);
            Msg_WriteText(str);
            Msg_WriteChar(13);
    
            Str_Printf(str,"%1.2f",z);
            Msg_WriteChar(97);
            Msg_WriteChar(122);
            Msg_WriteChar(61);
            Msg_WriteText(str);
            Msg_WriteChar(13);
            Msg_WriteChar(13);
    
       }while(1);
    
    }

  7. #67
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.693

    Re: Robi+BMA

    Zitat Zitat von TJ_99
    ... Register 14 (Bit 3 und 4) ... Aber muss ich jetzt in das Register reinschreiben ...
    Genau das musst Du tun. Dazu steht im Datenblatt des BMA020 etwas mit "Important notes . . ." - und deswegen lese ich erst das Statusbyte in Register 14h aus, bevor ich ein Bit setze und das geänderte Byte zurückschreibe.
    Ciao sagt der JoeamBerg

  8. #68
    Hallo Oberallgeier,

    danke für deine Antwort. Ich kann also wieder über I2C schreiben und lesen auf das Register 14 und anschließend Daten hineinschreiben!?

    Kann das dann so aussehen?

    Gruß
    TJ
    Code:
    void thtead3(void)
    {
    
        byte data;
        word direction, range;
        direction=0;
    
        I2C_Start();
        I2C_Write(0x70);
        I2C_Write(0x14);
        I2C_Stop();
    
        I2C_Start();
        I2C_Write(0x71);
    
        data=I2C_Read_NACK();
    
        if(direction==0)
        {
            range=2;
        }
        else
        {
            range=4;
        }
    
        I2C_Write(0x14 & 0b00011000 >> 3);
        I2C_Stop();
    
    }

  9. #69

    BMA020 an I2C Bus

    Hi Leute,

    bin neu hier im Forum und habe direkt mal eine Frage zum BMA020 Beschleunigungssensor und dem I2C Bus. Ich benutze das Modul von ELV, welches ich an meinen AtMega8 angeschlossen habe. Die Messwerte gebe ich mir anschliessend über den UART aus. Anbei mal mein Code, ich benutze die I2C Lib von P. Fleury. Könntet ihr mal schauen, ob der Code so in Ordnung ist. Denn die Daten die ich ausgebe, machen mich ein wenig stutzig (3328, 3330, sowas in der Art).

    Code:
    #include "data_logger.h"
    
    #define   I2C_BMA_W   0x70
    #define   I2C_BMA_R   0x71
    
    
    int main()
    {	
    	io_init('D', 0xF0);
    	i2c_init();
    
    	char buf[16];
    	
    	set_port('D', 0b00110000);
    
    	int16_t     x, y, z; 
    	uint8_t 	ret;
    	unsigned char ACK, NAK; 
    	ACK = 1;
    	NAK = 0;
    
    	while(1)
    	{ 	
    		ret = i2c_start(I2C_BMA_W);
       		ret = i2c_write(0x02);
                    i2c_stop();
    
    		ret = i2c_start(I2C_BMA_R);
    
    		ret= i2c_read(ACK); x = (int16_t)ret;
    		ret= i2c_read(ACK); x = x | ((int16_t)ret << 8);
    		
    		ret= i2c_read(ACK); y = (int16_t)ret;
      		ret= i2c_read(ACK); y = y | ((int16_t)ret << 8);
    
    		ret= i2c_read(ACK); z = (int16_t)ret;
      		ret= i2c_read(NAK); z = z | ((int16_t)ret << 8);
    		i2c_stop();
    
    		itoa(x, buf, 10);
    		uart_send_string(buf);
    		uart_send_string("\t");	
    		itoa(y, buf, 10);
    		uart_send_string(buf);
    		uart_send_string("\t");
    		itoa(z, buf, 10);
    		uart_send_string(buf);
    		uart_send_string("\r");	
    		uart_send_string("\n");	
    		_delay_ms(100);	
    	}
    	return 0;
    }
    Der Code ist dem im Forum sehr ähnlich, lediglich erhalte ich keine plausible Ausgabe, ich erwarte: wenn der Sensor in Ruhe liegt, Werte um 0 herum.

    Vielen Dank schonmal für die Hilfe

  10. #70
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.693
    Tja, was soll ich sagen. C&P ist doch eigentlich recht einfach. Man muss aber dann auch alles rauskopieren, was der Sternthaler, der Gute, reingeschrieben hat. Dann klappts auch mit den Werten.
    Zitat Zitat von michael_1104
    ... ob der Code so in Ordnung ist ...
    Nein, ist er nicht. Schau Dir mal das Original nochmal an und vergleiche es mit Deinem Code.
    Zitat Zitat von michael_1104
    ... Der Code ist dem im Forum sehr ähnlich ...
    Er ist so ähnlich, dass ich das Original daran erkenne. Aber . . . .
    Ciao sagt der JoeamBerg

Seite 7 von 9 ErsteErste ... 56789 LetzteLetzte

Berechtigungen

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

12V Akku bauen