- LiTime Speicher und Akkus         
Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 25

Thema: I2C Verständnisprobleme

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    07.07.2010
    Alter
    34
    Beiträge
    228

    I2C Verständnisprobleme

    Anzeige

    Praxistest und DIY Projekte
    Guten Abend,

    hänge nun schon ein paar Tage an einem Problem fest und weiß nicht mehr weiter.
    Nichtmal die Sufu und die damit gefundenen Threads konnten mir weiterhelfen

    Hier mal mein Code:

    M32
    Code:
    #include "RP6ControlLib.h"
    #include "RP6I2CmasterTWI.h"
    
    uint8_t data[2];
    
    void I2C_transmissionError(uint8_t errorState) 
    { 
       writeString_P("I2C ERROR -->TWI STATE IS: 0x"); 
       writeInteger(errorState, HEX);
       writeChar('\n');
    }
    
    int main(void){
    	initRP6Control();
    	initLCD();
    	I2CTWI_initMaster(100);
    	I2CTWI_setTransmissionErrorHandler(I2C_transmissionError);
    	while(1){
    		clearLCD();
    		I2CTWI_transmitByte(10,0);
                    writeString_P("transmit....");               //reine Testausgabe wo die Funktion hängen bleibt
    		data[0] = I2CTWI_readByte(10);
                    writeString_P("read....");                    //reine Testausgabe wo die Funktion hängen bleibt
    		writeIntegerLCD(data[0],DEC);
    	}
    	return 0;
    }
    Base
    Code:
    #include "RP6RobotBaseLib.h"
    #include "RP6I2CslaveTWI.h"
    
    int main(void){
    	initRobotBase();
    	I2CTWI_initSlave(10);
    	int8_t data = 1;
    	while(1){
    		if(I2CTWI_writeRegisters[0] && !I2CTWI_writeBusy){
    			I2CTWI_readRegisters[0] = data;
    			data++;
    		}
    	}
    }
    Die Master Funktion läuft leider nur bis nach "I2CTWI_transmitByte" danach gehts nicht weiter.

    Dabei will ich eigentlich erstmal nur einen festen Wert (data) übertragen. Erst wollte ich den Wert eines Lichtsensors übertragen, da dies aber scheiterte wollte ich erstmal mit was anderem (in meinen Augen leichteren) beginnen.

    Hoffe mir kann jmd helfen.

    MfG

    Ezalo
    Welches sind die drei Feinde eines Programmierers?

    Sonnenlicht, Sauerstoff und das unerträgliche Gebrüll der Vögel

  2. #2
    Erfahrener Benutzer Roboter-Spezialist Avatar von RolfD
    Registriert seit
    07.02.2011
    Beiträge
    414
    Hallo,
    in der M32 Seite fehlt dir der Aufruf von task_I2CTWI(); in der While Loop.
    Das löst das Problem jedoch nicht komplett, da für ein Befehl das task_I2CTWI(); ggf. mehrfach aufgerufen werden muss.
    Orientiere dich im Schleifenaufbau mehr an den beigelegten Masterprogrammen für die M32. Und berücksichtige, das die I2CTWI
    Funktionen ggf. asyncron arbeiten. Das Datum wird also ggf. nicht 100% genau dann verschickt wenn du es erwartest sondern
    erst beim Aufruf von task_I2CTWI(); Zum Verständniß, die TWI Befehle bestücken eigentlich nur die Vars mit Daten, die eigentliche Ausführung stößt task_I2CTWI(); an. Zumindest bei einigen TWI Befehlen mit Leseoperationen.

    LG Rolf
    Geändert von RolfD (01.04.2011 um 00:50 Uhr)
    Sind Sie auch ambivalent?

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    @Ezalo:
    In diesem Thread:
    https://www.roboternetz.de/community...-RP6-I2C/page2
    ... sind ein paar Beispiele für eine einfache Datenübertragung.
    Gruß
    Dirk

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    07.07.2010
    Alter
    34
    Beiträge
    228
    In dem von dir genannten Beispiel geht es doch aber um die Datenübertragung von Master zu Slave. Ich möchte ja aber mit dem Master die Daten vom Slave lesen
    Welches sind die drei Feinde eines Programmierers?

    Sonnenlicht, Sauerstoff und das unerträgliche Gebrüll der Vögel

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    10.09.2010
    Beiträge
    74
    Hallo!
    Ich habe leider keinen anderen Beitrag gefunden, also versuche ich es hier. Ich habe seit letzter Woche ein RP6 Control M32. Ich habe mir alle Beispiel Programme angeschaut. Jetzt möchte ich aber genau wissen, wie ich den Austausch über den I²C Bus mache.
    Ich habe herausgefunden, dass folgende Aufrufe auf jedem Fall zu machen sind: (laut Beispiel 06_I2CMaster.c)
    #include "RP6I2CmasterTWI.h"

    I2CTWI_initMaster(100);
    I2CTWI_setTransmissionErrorHandler(I2C_transmissio nError);

    So, mein erstes Problem ist, wie kann ich dem Roboter auf einfache Weise "sagen", dass er auf dem Base die LED 1 anschalten soll.
    Ich habe mal im Programm geschaut und festgestellt, dass in der Zeile
    I2CTWI_transmit3Bytes(I2C_RP6_BASE_ADR, 0, 3, counter); die LEDs angesprochen werden.

    ich hoffe ihr könnt mein Problem verstehen.
    Ich danke schonmal für die Hilfe

    Gruß RP6fahrer

    PS: vielleicht ibt es irgendwo eine zusammenfassende Befehlsliste für den I²C des RP6

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.803
    @RP6fahrer,

    das Problem ist, dass du einerseits die I2C-Befehle des RP6 kennen must (die stehen aber in der Anleitung gut beschrieben!), andererseits must du auf der Control M32 DIE Befehle senden, die das RP6Base_I2CSlave Programm kennt.

    Wenn du dich damit nicht beschäftigen willst, gibt es eine gute Möglichkeit:
    Du bindest in deine M32-Programme auch noch die RP6Control_I2CMasterLib (du findest sie z.B. im Beispiel Example_10_Move2) ein. In dieser Lib hat SlyD fast alle Befehle, die es auf der Base (z.B. zur LED-Ansteuerung) gibt, für die M32 zur Verfügung gestellt. Da gibt es also z.B. die Funktion updateStatusLEDs() und setRP6LEDs() (anstelle von setLEDs der Base!). Die kannst du genau so benutzen, wie auf der Base (siehe Anleitung zur Base!). Wenn du dir die Funktionen in der RP6Control_I2CMasterLib ansiehst, kannst du lernen, wie du auch ohne diese Lib mit reinen I2C-Makrobefehlen z.B. LEDs schalten kannst.
    Gruß
    Dirk

  7. #7
    Erfahrener Benutzer Roboter-Spezialist Avatar von RolfD
    Registriert seit
    07.02.2011
    Beiträge
    414
    @rp6fahrer
    Eine "Befehlsübersicht" findet sich in den .h files zu den Libs, eine funktionelle Erklärung in den Handbüchern zur Base und M32 sowie im Quellcode der gut dokumentierten Libs, Detailfragen beantwoten z.B. die Datenblätter und Fragen zu allgemeinen Zusammenhängen wie I2C das RN-Wiki. Dirk hat es auch schon angeschnitten.
    Was Dir leider niemand abnehmen kann, ist dich da durch zu graben um es zu verstehen damit du es ausbauen kannst. Ich hab mir den Programmteil nicht angesehen aber da Du ja schon rausgefunden hast, das die M32 der Base offensichtlich sagen kann das LEDs geschaltet werden, musst Du ja nur noch den passenden Wert counter für das Bit LED1 raus kriegen oder? Ein Blick in eine Zahlenconversionstabelle oder bissel Hirnakrobatik sollte Auskunft geben, welches LED-Bit zu welchem counter-wert führt. In dem Fall mit LED1 wohl 0 für aus und 1 für an... für weitere LEDs werden die Bits logisch verknüpft. Alles weitere steht bei Dirk. Man kann jetzt natürlich auch die von Dirk angesprochene RP6Control_I2CMasterLib nutzen und sich bissel Schreiberei sparen aber man sollte das Prinzip verstanden haben.
    LG Rolf
    Geändert von RolfD (20.04.2011 um 11:54 Uhr)
    Sind Sie auch ambivalent?

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    10.09.2010
    Beiträge
    74
    Danke für eure Antworten. Die LEDs habe ich nun unter Kontrolle. Eine Frage habe ich allerdings noch dazu: I2CTWI_transmit3Bytes(I2C_RP6_BASE_ADR, 0, 3, counter) Das erste in der Klammer ist ja die Adresse, aber was bedeutet das 2. (0) und 3.(3)? Also wenn ich die 3 ändere, dann kann ich die LEDs nicht mehr steuern. Wo kann man herausfinden, was ich eintragen muss( also bei 2. und 3.) um jetzt z.B. die Motoren zu steuern.
    Bin auch schon drüber, die RP6Control_I2CMasterLib durchzuarbeiten.
    Werde es noch ein bisschen studieren.
    Habe auch schon ein Programm geschrieben mit dieser Library.
    Es ist ein ganz einfaches Programm zum Lesen von 2 ADCs
    Hier ein Auszug aus dem Code
    void task_ADClesen(void)
    {
    writeString_P("\nADC1: ");
    writeIntegerLength(adc1, DEC, 3);
    setRP6LEDs(0b001001);
    writeString_P("\nADC0 : ");
    mSleep(500);
    writeIntegerLength(adc0, DEC, 3);
    setRP6LEDs(0b110110);
    mSleep(500);
    }
    Das Problem ist, dass er mir bei dem adc 0 und adc1 immer 000 anzeigt. Obwohl dort (auf dem Base) zwei Lichtsensoren angeschlossen sind. Wisst ihr warum er mir nicht den Wert der Lichtsensoren anzeigt? Allerdings der Befehl setRP6LEDs funktioniert.

    Ich danke nochmal, dass ihr mir helft. Bei mir dauerts halt leider etwas länger, bis ich es komplett verstanden habe.

    MfG RP6fahrer
    Geändert von RP6fahrer (20.04.2011 um 12:42 Uhr)

  9. #9
    Erfahrener Benutzer Roboter-Spezialist Avatar von RolfD
    Registriert seit
    07.02.2011
    Beiträge
    414
    Es ist doch egal wie lang es dauert so lange Du erreichst was Du vor hast.

    Zum Befehl bzw. Parameter von I2CTWI_transmit3Bytes, er hat 4 Werte, erster ist die Zieladresse des I2C Gerätes. Betrachten wir das Ziel (RP6Base_I2CSlave.c) etwas genauer. Das was da übertragen wird ist schreibend eine Befehlssequenz die der Slave entschlüsseln muss und lesend ein Register.
    Schaut man im Slave bei

    // Command Registers - these can be written by the Master.
    // The other registers (read registers) can NOT be written to. The only way to
    // communicate with the Robot is via specific commands.
    // Of course you can also add more registers if you like...

    und

    // Command processor:
    // Commands:

    nach, findet man das.

    #define CMD_SETLEDS 3

    Die 3 sagt also dem Slave das dies ein Befehl zum setzen von LEDs ist, da was anderes zu setzen macht nur Sinn wenn die restlichen Parameter passen. Siehe auch void task_commandProcessor(void). Der Wert counter sagt welche LEDs, vergleichbar mit setLEDs.

    Übrigends ist das sehr unschön programmiert, besser und lesbarer wäre:
    I2CTWI_transmit3Bytes(I2C_RP6_BASE_ADR, 0, CMD_SETLEDS, counter);
    Denn ändert man aus irgendwelchen Gründen den Define Wert, fliegt einem unnötiger Weise die halbe Software um die Ohren.

    Liest man jedoch Werte aus (statt bisher schreibend vom Master aus gesehen), so muss man anders vorgehen. Dazu liest man Register aus, der Slave trägt die Werte dort ein. Welche Register, das sagen die Defines:

    #define I2C_REG_ADC_ADC0_L 23
    #define I2C_REG_ADC_ADC0_H 24
    #define I2C_REG_ADC_ADC1_L 25
    #define I2C_REG_ADC_ADC1_H 26

    Grundsätzlich ist es nun so, das es einen bzw. 2 Zeiger gibt, der die Leseposition in den Registern anzeigt. Dieser wird pro gelesenem Byte erhöht. Beim schreiben ist es ebenso. Dieser Pointer wird normal durch den 2. Parameter in I2CTWI_transmit3Bytes gesetzt. 0 setzt also den Zeiger auf den Anfang, 5 würde ihn auf die 5 Stelle setzen so das als nächstes das 6.te byte gelesen wird. Das Verfahren entspricht auch grundsätzlich dem Lesen und Schreiben von eeproms nur das dort weit mehr Speicherzellen ansprechbar und adressierbar sind. Nachdem das gelesene low/high byte im Master wieder richtig zusammen gesetzt wurde, hat man einen Wert. Bekommt man keinen, hat man z.B. den Zeiger nicht richtig gesetzt, überlesen oder sonst was ist schief gegangen...

    Ich hoffe das erklärt grob wie der Slave arbeitet bzw. was da wie und in welche Richtung übertragen wird. Durch entsprechende Änderungen kommst du auch an die Motorsteuerung. Dann noch eine Anmerkung, das I2C arbeitet mit diesen Libs nicht unbedingt stabil, es kann daher schon mal vorkommen das die ADCs keine Werte liefern, das muss aber nicht unbedingt ein Fehler in deinem Programm sein. Bevor man die Werte aus dem I2C nutzt, sollte man sie ggf. auf Plausibilität prüfen und nicht blind in Funktionen einspeisen. Das führt nur dazu, das man sich beim debuggen nen Wolf sucht.

    Wenn Du verstehen willst wie Master und Slave zusammen arbeiten, wirst Du auch in beiden Programmteilen die Abläufe studieren müssen. Die emulierten Registersets sind der Schlüssel dazwischen. Müsste aber auch so aus dem Handbuch ersichtlich sein.
    LG Rolf
    Geändert von RolfD (20.04.2011 um 16:15 Uhr)
    Sind Sie auch ambivalent?

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    10.09.2010
    Beiträge
    74
    Okay, also nochmal zum ersten Teil. wenn ich z.B. I2CTWI_transmit3Bytes(I2C_RP6_BASE_ADR, 0, 1, 1) kann ich dann die PowerON LED anschalten..

    Bzw. zum Empfangen mit
    I2CTWI_transmitByte(I2C_RP6_BASE_ADR, 23); Es beginnt also ab Register 23
    I2CTWI_readBytes(I2C_RP6_BASE_ADR,RP6data, 1); wird ADC0_L gelesen
    Aber welche Funktion hat RP6data? Es ist ja nur eine Definition, also theoretisch könnte ich dort auch RP6adc dort hinschreiben.
    Und wie kann ich diesen Wert anzeigen lassen? Weil da sehe ich noch nicht so durch.
    Ich hoffe, ich liege einigermaßen richtig.
    Oder wenn ich die RP6Control_I2CMasterLib eingefügt habe, müsste doch trotzdem über adc0 / adc1 die Werte der ADCs angezeigt werden.

Seite 1 von 3 123 LetzteLetzte

Ähnliche Themen

  1. Verständnisprobleme -> Drehmomentrechner
    Von selan im Forum Motoren
    Antworten: 9
    Letzter Beitrag: 13.11.2006, 15:25
  2. Verständnisprobleme über die Funktionsweise eines Interrupts
    Von electrofux im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 31.10.2006, 17:14
  3. Syntax - Verständnisprobleme
    Von R2D3212 im Forum C - Programmierung (GCC u.a.)
    Antworten: 8
    Letzter Beitrag: 05.07.2006, 02:41
  4. Serielle Verständnisprobleme
    Von steffenvogel im Forum Software, Algorithmen und KI
    Antworten: 6
    Letzter Beitrag: 09.04.2006, 14:23
  5. Antworten: 17
    Letzter Beitrag: 01.01.2006, 18:33

Berechtigungen

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

LiFePO4 Speicher Test