-         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 16

Thema: Wie kann ich mit i2c-Sensoren für Nibo2 kommunizieren?

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    02.02.2020
    Ort
    Harz
    Alter
    70
    Beiträge
    8

    Wie kann ich mit i2c-Sensoren für Nibo2 kommunizieren?

    Anzeige

    Hallo zusammen,

    ich bin hier neu im Forum, weil ich dringend eure Hilfe benötige!!!

    Ich besitze einen Nibo2-Roboter (ja, den gibt es immer noch!) und habe schon recht viel mit ihm angestellt und durch ihn gelernt.
    Jetzt wage ich den nächsten Schritt:
    Ich kaufte mir einen GY-271 DA5883 Kompassmodul - 3-Achse Magnetometer Sensor und baute diesen in meinen Nibo2 ein.
    So weit, so gut. Doch es gelingt mir beim besten Willen nicht, mit diesem über das i2c-Protokoll zu kommunizieren.
    Mir stehen aus der Nibo2-Bibliothek die folgenden Befehle zur Verfügung:

    i2cmaster.h-Dateireferenz

    Routinen zur Kommunikation ueber den I2C Bus.
    #include <stdint.h>

    Makrodefinitionen
    #define I2C_TX(ADDR) ((ADDR)<<1)

    #define I2C_RX(ADDR) (((ADDR)<<1)+1)

    Aufzählungen
    enum { I2C_BUSY, I2C_IDLE, I2C_SUCCESS, I2C_ERROR =0x10 }

    Funktionen
    void i2c_init (void)

    uint8_t i2c_start_transmission (void)

    uint8_t i2c_status (void)

    uint8_t i2c_wait_transmission (void)

    Variablen
    volatile uint8_t i2c_size

    uint8_t i2c_buf [I2C_BUF_SIZE]

    volatile uint8_t i2c_last_TWSR

    volatile uint8_t i2c_pos


    Daher meine Bitte: Wer kann mir mit einem konkreten Code-Beispiel helfen, mittels I2C die Daten aus dem Sensor in den Roboter zu bekommen?

    Vielen Dank schon im Voraus!
    Gruß
    Klaus

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    4.964
    hallo!
    ich würde den Nibo2 in der Arduino-IDE programmieren, da hast du sehr viele praktische Libs zur Verfügung mit einfacher Ansteuerung (ebenfalls in C/C++):
    https://www.roboter.cc/index.php?opt...2333&Itemid=20

    wenn du diese verwendest und Fragen hast, stell ggf. nochmal die Frage neu hier im Arduino-Unterforum!
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    02.02.2020
    Ort
    Harz
    Alter
    70
    Beiträge
    8
    Hallo HaWe,
    vielen Dank für deine schnelle Antwort.
    Ich habe bisher immer das AVRStudio4 verwendet und komme gut klar damit.
    Wenn ich nun weiter mit der Arduino-IDE programmiere, muss ich ja wohl alle meine Codes wieder neu erstellen, oder?!?
    Ich will doch den Gyro-Sensor in ein bestehendes Projekt einbinden.
    Gibt es nicht die Möglichkeit, die i2c-Routinen, die die Nibo2-Bibliothek mir bietet, zu nutzen?
    Gruß
    Klaus

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    32
    Beiträge
    4.883
    Wenn du auf die Arduino IDE umsteigst, musst du die Programme neu schreiben oder zumindest anpassen. Ich weiß nicht ob man C Programme importieren kann.

    Die Library kenne ich nicht, aber du könntest versuchen auf eine andere I2C Library umsteigen. Eine häufig verwendete Library ist die von Peter Fleury.
    die "i2cmaster" Library von hier http://www.peterfleury.epizy.com/avr-software.html#libs

    Wichtig ist das du Pullup Widerstände zwischen VCC (+5V) und SCL bzw VCC und SDA hast. Entweder du nimmst externe Widerstände oder schaltest die internen Pullup Widerstände ein.
    Ohne Widerstände funktioniert der Bus nicht.

    Zusätzlich ist noch der Ablauf wichtig.
    Die Unterscheidung zwischen Lesen und Schreiben wird mit dem niederwertigsten Bit bei der Adresse angegeben. Eine "0" bedeutet das du schreiben willst, eine "1" bedeutet lesen.
    https://www.roboter-bausatz.de/media...asheet-1-0.pdf
    Wenn das dieses IC ist hast du die I2C Grundadresse "0D" => 0001101
    Somit hast du als Schreibadresse 00011010 => 1A
    und die Leseadresse 00011011 => 1B
    Hier der Ablauf in Pseudocode.

    Beim Schreiben:
    Code:
    I2C Start
    I2C Schreibadresse
    I2C Register (im Datenblatt des ICs nachschauen)
    I2C Daten (Daten die du ins Register schreiben willst, z.B. Einstellungen)
    I2C Stopp
    Beim Lesen:
    Code:
    I2C Start
    I2C Schreibadresse
    I2C Register (Register aus dem du lesen willst)
    I2C Start  (bzw repeated start)
    I2C Leseadresse
    Daten in Variable lesen mit ACK => wenn weitere Daten gelesen werden sollen, Registeradresse wird automatisch um 1 erhöht
    Daten in Variable lesen mit NACK => wenn keine weiteren Daten gelesen werden sollen
    I2C Stopp
    Du hast oben Makrodefinitionen angegeben (aus der Headerdatei). Dort steht z.B. "#define I2C_TX(ADDR) ((ADDR)<<1)".
    In diesem Fall müsstest du bei "ADDR" die "0D" angeben und nicht "1A" bzw "1B", weil dieses Makro das Linksschieben übernimmt.

    MfG Hannes

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    02.02.2020
    Ort
    Harz
    Alter
    70
    Beiträge
    8
    Hallo Hannes,
    toll, dass du dich um mein Problem bemühst! Danke.
    Ja, das istder IC, den ich gekauft habe, und auch von diesem Shop.
    Das mit dem Links-Schieben wusste ich nicht. Bin eben ein Neuling auf diesem Gebiet.
    Ich habe folgenden Beispielsketch für Arduino Kompassmodul GY-282 HMC5983 gefunden:

    #include <Wire.h> //I2C Arduino Library
    #define addr 0x1E //I2C Address for The HMC5883
    void setup(){
    Serial.begin(9600);
    Wire.begin();
    Wire.beginTransmission(addr); //start talking
    Wire.write(0x02); // Set the Register
    Wire.write(0x00); // Tell the HMC5883 to Continuously Measure
    Wire.endTransmission();
    }
    void loop()
    {
    int x,y,z; //triple axis data
    //Tell the HMC what regist to begin writing data into
    Wire.beginTransmission(addr);
    Wire.write(0x03); //start with register 3.
    Wire.endTransmission();
    //Read the data.. 2 bytes for each axis.. 6 total bytes
    Wire.requestFrom(addr, 6);
    if(6<=Wire.available()){
    x = Wire.read()<<8; //MSB x
    x |= Wire.read(); //LSB x
    z = Wire.read()<<8; //MSB z
    z |= Wire.read(); //LSB z
    y = Wire.read()<<8; //MSB y
    y |= Wire.read(); //LSB y
    }
    // Show Values
    Serial.print("X Value: ");
    Serial.println(x);
    Serial.print("Y Value: ");
    Serial.println(y);
    Serial.print("Z Value: ");
    Serial.println(z);
    Serial.println();
    delay(500);
    }


    Könnte man diesen Code nicht so umschreiben,
    dass er mit den Befehlen der Nibo2-Bibliothek (wie im 1. Post beschrieben)
    ausführbar ist?!?
    Würdest du mir dabei bitte auch behilflich sein?
    Gruß
    Klaus

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    32
    Beiträge
    4.883
    Das ist ein Code der für die Arduino IDE, der ist so nicht kompatibel mit dem AVR Studio.
    Dort wird die "wire.h" verwendet, die ist Teil der Arduino IDE.

    Der Code, den du gepostet hast, liest die Werte der 3 Achsen aus und sendet es mittels UART an die USB Schnittstelle (über UART/USB Wandler).
    Die Adresse ist auch eine andere, warum weiß ich aber nicht.

    Die Nibo Library kenne ich überhaupt nicht. Die Lib die ich gepostet habe habe ich zu Testzwecken schon verwendet, habe aber noch nicht viel gemacht.

    Ich würde die von mir gepostete Library herunterladen und diese verwenden. Die ist relativ leicht zu bedienen.

    Wenn du Code postest, bitte in Code Tags posten. Entweder unter "Erweitert" und dann das #-Symbol oder du schreibst den Code zwischen [ code] und [ /code] (du musst die Leerzeichen entfernen).

    Beim Code selbst kann ich dir aber helfen, programmiere zwar mittlerweile mit dem aktuellen AVR Studio, habe aber mit der Version 4 angefangen.

    MfG Hannes

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    02.02.2020
    Ort
    Harz
    Alter
    70
    Beiträge
    8
    Hallo Hannes,
    zum letzten Mal heute Abend:
    Habe die Library von Peter Fleury heruntergeladen und entpackt.
    Doch wohin nun mit den einzelnen Dateien? Habe in die Anleitung geschaut,
    aber das sieht ja nun wieder ganz anders aus als in der Nibo-Bibliothek oder bei Arduino.
    Da werde ich mir wohl oder übel noch die letzten Haare raufen müssen...
    Aber ich will das Ganze auf meine alten Tage unbedingt noch lernen,
    dann kann ich mein Wissen auch noch an meinen Enkel weitergeben,
    der genau wie ich roboterbesessen ist.
    Gruß
    Klaus

  8. #8
    Erfahrener Benutzer Robotik Einstein Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    32
    Beiträge
    4.883
    Du benötigst nur 2 Dateien, einmal die "i2cmaster.h" und die "twimaster.c".

    Diese beiden Dateien würde ich in den Projektordner kopieren (in der die C-Datei mit der "main" liegt).

    Wenn du dann das Projekt öffnest gibt es im Projektbaum (der Abschnitt mit den Ordnern "Source Files", "Header Files",...) den Ordner mit den verwendeten Source Files, dort musst du die C-Datei hinzufügen. Rechte Maustaste auf den Ordner "Source Files" und dann "Add existing Source File(s)". Jetzt wählst du die "twimaster.c" aus.
    In dem Ordner muss jetzt die C-Datei mit der "main" sein und die "twimaster.c" (eventuell noch mehrere C-Dateien).

    Anschließend musst du noch die Headerdatei integrieren. Es gibt 2 verschiedene Arten Headerdateien zu integrieren.
    1) die Datei wird in den Symbolen < und > geschrieben (z.B. #include <avr\interrupt.h>) => die Dateien sind in einem Ordner die dem AVR Studio bekannt sind, wie die Standartmäßigen Headerdateien.
    2) die Datei wird zwischen 2 "-Symbolen geschrieben (z.B. #include "i2cmaster.h") => die Dateien liegen im Projektordner

    Wenn du das Projekt dann übersetzt sollte unter "External Dependencies" die Headerdatei (in dem Fall die i2cmaster.h) zu finden sein.

    Wenn du soweit bist kannst du die einzelnen Funktionen der Library nutzen.
    Am Programmanfang musst du 1x den TWI initialisieren (damit die Bitrate richtig eingestellt ist). Hier würde ich auch die Einstellung für das IC machen.
    In der Loop kannst du dann die Werte auslesen.

    Ich hoffe das hilft dir weiter.

    MfG Hannes

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    02.02.2020
    Ort
    Harz
    Alter
    70
    Beiträge
    8
    Hallo Hannes,
    auf ein Neues!!!
    Ich habe deine Hinweise beachtet und die beiden Dateien eingebunden. Dann habe ich mein kleines Projekt geschrieben. Es wurde fehlerfrei compiliert. Allerdings liest der Nibo2 nicht die Werte des Gyros.
    Ich dachte mir, vielleicht liegt es daran, dass die vorher vorhandenen i2c-Routinen für den eingebauten Abstandsmesser nds3 nicht mehr vorhanden sind. Habe also folglich die alten i2c-Dateien wieder eingebunden (wie es vorher war) und die neuen i2c-Dateien namenlich angepasst (i2c__master.h und die Routine i2c__init), damit nichts kollidiert.
    Es wird fehlerfrei compiliert, aber in der Textausgabe zum Schluss kommt nichts an. Wenn ich den Zugriff auf den Sensor auskommentiere (siehe Code), dann wird die Textausgabe (stellvertretend mit x=5, y=6, z=7) geschrieben.
    Nun bin ich mit meinem Latein wieder mal am Ende und bitte dich um Hilfe.

    Code:
    /*  Nibo2-Programm Test_Gyro_I2C, erstellt von Klaus Beutel  im Februar 2020                        */ 
    /********************** Bibliotheken einbinden ******************************************************/
    #include <math.h>
    #include <stdio.h>								// Standardein- und -ausgabefunktionen
    #include <avr/interrupt.h>						// Interrupts ermöglichen
    #include <stdlib.h>								// notwendig u.a. für die abs-Funktion
    #include <nibo/niboconfig.h>					// Konfiguration der Nibo-Bibliothek
    #include <nibo/display.h>               		// Ansprechen eines Displays
    #include <nibo/gfx.h>							// Ansteuerung eines LC-Grafik-Displays                
    #include <nibo/spi.h>							// Kommunikation über SPI.
    #include <nibo/copro.h>							// Ansprechen des Coprozessors
    #include <nibo/delay.h>							// Warteschleifen
    #include <nibo/iodefs.h>						// Zuordnung der physikalischen Pins zu symbolischen Namen
    #include <nibo/bot.h>							// allgemeine Funktionen des Roboters
    #include "i2c__master.h"						// Kommunikation ueber den I2C Bus
    #include <nibo/pwm.h>							// Erzeugung der PWM-Signale und der Systemzeit.
    #include <nibo/leds.h>							// Ansteuerung der LEDs
    #include <nibo/i2cmaster.h>						// Kommunikation ueber den I2C Bus
    #include <nibo/nds3.h>							// Kommunikation mit dem NDS3 Modul
    
    /************************* Konstante definieren *****************************************************/
    #define gyroaddr 0x0D							// i2c-Adresse für HMC5883
    
    /************************* Globale Variable definieren **********************************************/
    char text[22] = "                     ";		// Text-Ausgabe-Buffer
    uint16_t x,y,z; 								// triple axis data
    
    /************************* Hauptprogramm ************************************************************/
    int main()
    {
    /********************** Initialisierung *************************************************************/   
      	sei(); 										// Interrupts global erlauben
      	bot_init(); 								// Controller reseten
      	leds_init(); 								// LEDs initialisieren
      	pwm_init(); 								// PWM-Kanäle initialisieren
      	display_init(2); 							// Display initialisieren
      	spi_init(); 								// SPI initialisieren 	
    	gfx_init(); 								// Graphikdisplay initialisieren
    	i2c_init();									// i2c-Bus initialisieren
    	nds3_init();
    	i2c__init();
    
    /********************* Lokale Variable definieren ***************************************************/
    	
    /****************************************************************************************************/
      	nds3_move(82);								// nds3 auf Null-Position
        leds_set_displaylight(1024); 				// Display-Hintergrundsbeleuchtung einschalten
      	gfx_set_proportional(0); 					// Schrift auf normal setzen
    	gfx_move(0, 50);
    	gfx_print_text("S3: Start");
    
      	while (PIND&(1<<4)) 						// warten auf Betätigung von S3 zum Starten
    	{
        	delay(250); 							// alle grünen LEDs blinken
        	PORTC=0xFF;
        	delay(250);
        	PORTC=0x00;
      	}
    
      	gfx_fill(0x00); 							// Display leeren
    	gfx_move(0, 0);
    	gfx_print_text("      x    y    z");
     
    /*	i2c_start(gyroaddr+I2C_WRITE);       		// set device address and write mode
    	i2c_write(0x09);                       		// write address = 9
        i2c_write(0x1D);                       		// Define OSR = 512, Full Scale Range = 8 Gauss, ODR = 200Hz, set continuous measurement mode)
        i2c_write(0x0A);                       		// write address = 10
        i2c_write(0x40); 							// The I2C data pointer will automatically roll, 6.Bit = 1 setzen
    	i2c_write(0x0B);                       		// write address = 11
        i2c_write(0x01); 							// Define Set/Reset period
    	i2c_stop();                            		// set stop conditon = release bus
    */
      	while (1) 									// Hauptschleife
    	{
    /*		i2c_start_wait(gyroaddr+I2C_WRITE);     // set device address and write mode
            i2c_write(0x00);                        // write address = 0
            i2c_rep_start(gyroaddr+I2C_READ);       // set device address and read mode
            x = i2c_readAck()<<8;                   // read one byte from address 0	MSB  x 
            x |= i2c_readAck();                    	//  "    "    "    "     "    1	LSB  x 
            y = i2c_readAck()<<8;                   //  "    "    "    "     "    2	MSB  y
            y |= i2c_readAck();                    	//  "    "    "    "     "    3	LSB  y
    		z = i2c_readAck()<<8;                   //  "    "    "    "     "    4	MSB  z
            z |= i2c_readNak();                    	//  "    "    "    "     "    5	LSB  z
            i2c_stop();                            	// set stop condition = release bus
    */		x=5;
    		y=6;
    		z=7;
    		gfx_move(0, 10);
    		sprintf(text,"->  %04d %04d %04d", x, y, z);
    		gfx_print_text(text);
    
      	}
      	return 0;
    }
    Gruß
    Klaus

    P.S.: Die Adressen habe ich aus dem Datenblatt des IC entnommen. Vielleicht liegt ja da der Fehler?!?

  10. #10
    Erfahrener Benutzer Robotik Einstein Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    32
    Beiträge
    4.883
    Man sollte nur eine Lib verwenden und nicht 2 oder noch mehr. Es könnte sein das sich die beiden Libs beeinflussen. Z.B. Lib 1 stellt in der Init die I2C Frequenz auf 100kHz und Lib 2 stellt es dann auf 400kHz.

    Das Problem ist das ich nicht herausgefunden habe welche Adresse das NDS3 hat. Dadurch benötigst du die originale I2C Lib.

    Das Problem das du aber mit dem Sensor hast ist ein anderes, du hast die falsche Adresse.

    Die Grundadresse ist die 0D, das ist aber nicht Bit 0-Bit 6 sondern Bit 1-Bit 7.

    Du musst die Adresse zuerst um 1 nach links schieben und dann 0 oder 1 an Bit 0 hinzufügen (vergleiche es mit der Makrofunktion im 1ten Post). Das geht entweder mit einer Addition oder einer Oder Verknüpfung. Achte auf die Adresse die ich im Post 4 geschrieben habe.
    Ich empfehle dir die Rechnung mit dem Windowsrechner zu prüfen, dort gibt es einen Punkt "Programmierer".

    Was mir auch noch aufgefallen ist, die Bytes sind verdreht.
    Im Arduinocode und auch in deinem steht im 1ten Byte das MSB und im 2ten Byte das LSB, laut Datenblatt ist aber im 1ten Byte das LSB und im 2ten Byte das MSB.
    Um das kann man sich aber dann später kümmern, wichtig ist aber das du erst einmal Daten bekommst.

    MfG Hannes

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Suche Microcontroller welcher mit Android kommunizieren kann
    Von Mr.P. im Forum PC-, Pocket PC, Tablet PC, Smartphone oder Notebook
    Antworten: 10
    Letzter Beitrag: 04.10.2012, 11:13
  2. Antworten: 3
    Letzter Beitrag: 17.12.2010, 22:03
  3. Wie kann Mega8 mit ProfiLab Expert kommunizieren?
    Von mikro-VIIV im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 15.12.2007, 14:54
  4. Welche Sensoren kann ich dafür verwenden?
    Von blue_man im Forum Sensoren / Sensorik
    Antworten: 12
    Letzter Beitrag: 20.05.2005, 18:53
  5. Sensoren kommunizieren miteinander
    Von Andreas im Forum Neuigkeiten / Technik-News / Nachrichten / Aktuelles
    Antworten: 0
    Letzter Beitrag: 30.04.2004, 23:51

Stichworte

Berechtigungen

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