-         

Ergebnis 1 bis 7 von 7

Thema: I2C-Kommunikation luft nicht ber lngere Zeit (Atmega644PA)

  1. #1

    I2C-Kommunikation luft nicht ber lngere Zeit (Atmega644PA)

    Anzeige

    Hallo Community!

    Ich bin schon seit lngerer Zeit hier im Forum Mitleser und habe bereits einige ntzliche Informationen erhalten, auch fr mein aktuelles Projekt (einen Quadrocopter zu bauen ). Doch nun stehe ich vor einem Problem, das mich seit Tagen verwirrt.

    Ich habe einen zentralen Controller (Atmega644PA), der den Sensor ausliest (MPU6050), alle Berechnungen durchfhrt und die Daten fr die Geschwindigkeit an die 4 Motorregler (Atmega88A) bertrgt.
    Die gesamte Kommunikation zwischen den Bauteilen luft ber I2C (mit der fleury-lib) , jedoch nur etwa 0-30sec, danach funktioniert der I2C-Part nicht mehr. Doch nun ein wenig genauer:

    Was ich bisher getestet habe:
    - Auslesen des Sensors + Berechnung (Winkel, PID (aktuell nur P)) und Ausgabe auf einem LCD Display (es werden die Werte genauso angezeigt wie sie zu einem Motorregler gesendet werden wrden) Das funktioniert wunderbar, auch beliebig lange.

    - Kommunikation mit den Reglern (Atmega88A als Slave) und Motorsteuerung. Die Regler (+Software) sind ein Nachbau der Regler von Ulrich Radig. Die Motoren fahren langsam hoch und starten wieder von vorne, das Ganze ebenfalls beliebig lange.

    Hier die main fr die Augabe aufm LCD:
    Code:
    while(1){
    	while(a!=1);		// wait until timer1 overflow (sets a=1) -> constant sample rate (500Hz)
    	a=0;
    	
    	get_gyro_data(gyro_data);      //gyro_data -> uint16_t , reads raw data from MPU6050
    	get_acc_data(acc_data);
    		
            //complementary filter + angle calculation in degrees
    	angle_calculation(acc_data,gyro_data,gyro_data_offset,&pitch,&roll);    //gyro_data_offset -> uint16_t, pitch/roll -> float
    
            pid_calculation(0,&pitch,&pid_pitch);     //pid_pitch -> int16_t
            motora+=pid_pitch;    //motora -> uint8_t
    
            i2c_send_data_to_lcd(motora);      //sends data to lcd display
         }
    Und hier fr die Motoren:
    Code:
    while(1){
    	while(a!=1);		// wait until timer1 overflow (sets a=1) -> 10Hz
    	a=0;
    	
            motora++;
            motorb++;
    	i2c_start(MOTORA+I2C_WRITE);     //MOTORA: adress of motor A
    	i2c_write(motora);
    	i2c_stop();
            i2c_start(MOTORB+I2C_WRITE);     //MOTORB: adress of motor B
    	i2c_write(motorb);
    	i2c_stop();
    }
    Da beides so sehr gut funktioniert kann ich eigentlich ein Hardware-Fehler ausschlieen. Trotzdem hier noch kurz: Pull-ups fr I2C sind 4,7k, der MPU6050 ist ber einen Pegelwandler, bestehend aus 2 Transistoren (siehe AN10441), angeschlossen. Stromversorgung ist ein 3S Lipo (mit 78S05 fr die 5V). Elkos mssten genug 1mF low-esr drauf sein). Wenn ein Schaltplan hilfreich ist, stell ich ihn auch noch rein.

    Tja nur zusammen luft es nicht wirklich. Wenn ich die berechneten Werte, statt an das Display, an die Regler schicke, dann luft es maximal 30 Sekunden, dann bricht die Kommunikation zusammen. Innerhalb dieser 30 sec stabilisiert sich aber mein quad 1achsig auf einer Holzkonstruktion (und schwingt dabei, ist aktuell ja nur ein P-Regler). Immerhin etwas

    Bei den Reglern kommt es zu einem i2c-timeout. d.h. es werden keine neuen Werte mehr vom Atmega644PA versendet und die Motoren gehen aus.
    Der Atmega644PA hngt sich aber nicht vollkommen auf. In der ISR fr den Timer1 habe ich einen Zhler eingebaut, der eine LED blinken lsst. Gehen die Motoren aus, blinkt diese weiter.
    -> d.h. die while(1) schleife hngt irgendwo nach 30sec fest.
    Dann habe ich eine Variable drin, die berprft ob sie von der while(1) schleife zurckgesetzt wurde (d.h. die schleife noch aktiv ist), wenn sie in der ISR abgefragt wird.
    Wenn sie nicht zurckgesetzt wurde dann resete ich das TWI und bertrage neue Daten an den Motor (langsames hochfahren), dann luft er wieder!

    Hier die ISR:
    Code:
    ISR(TIMER1_COMPA_vect){
    	if(b==1){				//d=1 if while(1) in main does nothing -> reset TWI + send new datas to motor 
    		TWCR &= ~((1 << TWSTO) | (1 << TWEN));
    		TWCR |= (1 << TWEN);
    		for(int b=0;b<50;b++){					//shows that I2C works again
    			i2c_start(MOTORC+I2C_WRITE);
    			i2c_write(b);
    			i2c_stop();
    			_delay_ms(100);
    		}
    	}	
    	
    	a=1;   //for while(1)
    	DDRB|=(1<<PB1);
    	if(c==250){
    		PORTB^=(1<<PB1);	//toggle green led (=ISR works)
    		c=0;
    	}
    	c++;
    }
    Der Fehler, wo es nun hngt liegt offenbar in der Funktion i2c_start(), genauer hier:
    Die LED bleibt an, der Controller hngt in dieser Schleife. Anscheinend kommt kein ACK/NACK mehr zurck. berprfen kann ich das leider nicht, meine Soundkarte als Oszi ist nicht schnell genug btw die i2c-Frequenz zu senken bringt leider nichts, im Gegensatz selbst TWBR=5; (~760kHz) funktioniert.

    Code:
    unsigned char i2c_start(unsigned char address)
    {
            //....... other code
    	PORTB|=(1<<PB3);		//red led = on
    
    	// wail until transmission completed and ACK/NACK has been received
    	while(!(TWCR & (1<<TWINT)));
    
    	PORTB&=~(1<<PB3);		//red led = off
    	//....... other code
    }

    Eine Lsung wre in der ISR TWI zu resetten und dann an den Anfang der Schleife zu springen, aber das ist, soweit ich wei, ein nogo... Ein Watchdog kommt eher nicht in Frage da ich am Anfang vom Programm ja den Gyro-Offset bestimmen muss und zudem noch andere Einstellungen vornehmen muss. Auerdem Suche ich nach einem Weg das Hngenbleiben zu vermeiden. Stndige Resets in einem Quadrocopter sind nicht das wahre

    Klicke auf die Grafik fr eine grere Ansicht

Name:	bild1.jpg
Hits:	14
Gre:	68,9 KB
ID:	28775

    motorregler.c PID.c PID.h mpu6050.c MPU6050.h i2cmaster.h main.c twimaster.c

    Vielen Dank im Voraus!

    mfg adrian

  2. #2
    Erfahrener Benutzer Robotik Visionr Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgu
    Beitrge
    7.551
    ... Kommunikation ... luft ber I2C ... nur etwa 0-30sec, danach funktioniert der I2C-Part nicht mehr. Doch nun ein wenig genauer:
    ...
    Code:
    ...
        i2c_start(MOTORA+I2C_WRITE);     //MOTORA: adress of motor A
        i2c_write(motora);
        i2c_stop();
            i2c_start(MOTORB+I2C_WRITE);     //MOTORB: adress of motor B
        i2c_write(motorb);
        i2c_stop();
    }
    Hallo Adrian,

    willkommen im Forum.

    Leider hast Du den IC-Takt in Deiner Lsung nicht genannt. Aber das ist wohl nicht so wichtig. Ich kenne hnliche Fehler die ich so lange hatte, bis ich mich mal mit dem IC-Timing beschftigt hatte. Der Code, den ich oben blau markiert hatte, scheint mir verdchtig.

    Nach dem Stop braucht das System ne Weile bis per IC wieder geschrieben -- oder gelesen -- werden kann. Wenn man das sofort angeht KANN es funktionieren, muss aber nicht. Und wenns nicht sofort klappt ,dann kann die Kommunikation hngen bleiben. Daher hatte ich bei i2c_start nach einem i2c_stop -- neee, genaugenommen jetzt immer -- eine Abfrage eingefgt, ob der Bus berhaupt bereit ist. Beispiel hier (klick).
    Code:
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    //      Lesen (read back) vom Slave   ... mit der Routine aus fleurys lib
      i2c_start_wait(SLAVE_MoCo+I2C_WRITE); // set device address and write mode
      i2c_write( laddr );           // write address = laddr, das angepeilte Byte
            i2c_stop();             //
    
      while ((i2c_rep_start(SLAVE_MoCo+I2C_READ))) {}// Slave bereit zum Lesen?
    //i2c_rep_start(SLAVE_MoCo+I2C_READ);   // set device address and read mode
      ipwm12  = i2c_readAck();      // Bytes lesen... ab laddr = 0x33/51
      soll12  = i2c_readAck();      //
      ipwm34  = i2c_readAck();      // 
      soll34  = i2c_readNak();      // letztes Byte lesen, NAK
            i2c_stop();             //
    Das Zauberwort heit bei mir "while" - und dann wartet der Befehl ab, bis der Bus frei ist. Und schon liefs (bei mir). Nun knnte ich Dir das viele Zeugs in den Herstellerschriften zum TWI/IC bzw. dessen Timing schreiben - kannst Du in den entsprechenden Schriften nachlesen. Vorschlag: probiers mit "while" - vielleicht klappts und dann kannst Du Dir vielleicht das Lesen sparen. brigens knnte man bei erfolglosem Warten noch ne Fehlermeldung einbauen. Wenn man mchte.

    Viel Erfolg.
    Ciao sagt der JoeamBerg

  3. #3
    Ja, die Frequenz habe ich vergessen (wrden aber in der datei twimaster.c stehen), sie liegt bei 400kHz. Aber wie gesagt, das Problem tritt frequenzunabhngig auf.

    Leider funktioniert dein Lsungsansatz bei mir nicht. Ich glaube auch zu wissen warum: nach i2c_stop() wird ja trotzdem im Endeffekt i2c_start() (ber den Umweg while() und i2c_rep_start() ) direkt aufgerufen und kann deswegen dort hngen. Ich habe es auch mit kurzen delays zwischen jeder i2c-Operation versucht, brachte recht wenig.

    Um mal zu sehen, wo genau das Programm stehen bleibt, habe ich jeweils vor den einzelnen Funktionen eine Led angeschalten, am Ende wieder ausgeschalten. Abwechselnd blieb es bei i2c_start() und i2c_readAck() an.
    D.h. es kann nur in folgender Schleife hngen: while(!(TWCR & (1<<TWINT))); (je nachdem was ihr fr eine lib bentzt, ich verwende die von fleury)

    Um diese zu verlassen muss TWINT == 1 sein. Deswegen habe ich in der ISR, statt wie oben das TWI zu reseten und die Motoren neu ansteuern einfach TWCR |= (1<<TWINT); eingegeben. Sozusagen die brachiale Lsung dass das Programm weiterluft. Und es scheint zu funktionieren!

    Was es allerdings genau bewirkt und welche Auswirkungen es genau hat kann ich leider nicht sagen, dazu fehlt mir das Wissen (und die Zeit mich dazu ordentlich einzulesen^^)

    Zwar eigentlich keine schne Lsung und es packt das Problem nicht an der Wurzel, aber es luft... Es sei denn ich hatte in der letzten halben Stunde einfach nur Glck und es lief auch so Sobald ich es mal lngere Zeit laufen lassen kann melde ich mich wieder!

  4. #4
    Ich hatte wohl doch nur Glck.
    Das setzten von TWCR |= (1<<TWINT); in der ISR bringt ein paar mal etwas und das Programm luft weiter (eine LED an der Stelle, wo ich TWCR |= (1<<TWINT) setze, schaltet um) aber nur fr weitere 10 Sekunden... danach bleibt das Programm wieder stehen...
    SDA und SCL sind beide High! (dauerhaft)

    Da ich mir nun beim besten Willen nicht vorstellen kann, wo das Problem nun liegt werde ich fr die Ansteuerung auf PPM o.. umsteigen.

    Es ist etwas komisch, da das ansprechen der Regler ja bereits funktioniert, ich kann nacheinander z.B. immer grere Werte bergeben, sodass der Motor hochfhrt. Nur zusammen mit dem MPU6050 nicht. Aber ich kann wiederum von diesem Sensor die Werte auf einem LCD-Display ausgeben lassen.

    Es wre natrlich weiterhin praktisch wenn jemand eine Lsung htte I2C zu resetten bzw. wenn die ISR ausgefhrt wird, die Schleife zu unterbrechen und an anderen bestimmen Stelle weiterzumachen.

    mfg

  5. #5
    Erfahrener Benutzer Robotik Visionr Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgu
    Beitrge
    7.551
    ... wenn jemand eine Lsung htte I2C zu resetten ...
    Versuch mal die Methode von Klebwax (klick hier). Habs (noch) nicht getestet - derzeit ne andere Baustelle.
    Ciao sagt der JoeamBerg

  6. #6
    Hat leider auch nicht funktioniert Mittlerweile glaube ich, dass der Sensor die ganzen Probleme macht und den Bus blockiert.
    Habe es jetzt so gelst, dass ich den Sensor mit Hardware-I2C auslese und die 4 Motorregler mit Software-I2C ansteuere (getrennte Leitungen). Funktioniert bestens!

  7. #7
    Benutzer Stammmitglied Avatar von fulltime
    Registriert seit
    08.10.2011
    Beitrge
    50
    Kein Plan ob dass hilfreich ist, aber solange ds TWINT-Bit gesetzt ist kann keine Altion auf den TWI gestartet werden. TWINT wird ja nach jeder Aktion am I2C gesetzt und anschlieend gelscht werden. Vielleicht wird es bei deinem Problem irgendwann nicht gelscht und haltet somit den TWI auf.

    Bin selbst leider kein Mikrokontroller-Guru, beschftige mich erst seit einigen Monaten intensiv damit. Wird wohl zu meinem neuen Hobby ^^

    Mfg
    fulltime

hnliche Themen

  1. LCD an PCF8574 ber I2C - 2*16 luft / 4*20 LCD nicht?
    Von stfan1409 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 6
    Letzter Beitrag: 15.04.2012, 16:06
  2. Problem: Kommunikation ber RN-PC->I2C langsam
    Von hspecht74 im Forum Bauanleitungen, Schaltungen & Software nach RoboterNetz-Standard
    Antworten: 8
    Letzter Beitrag: 08.04.2010, 13:50
  3. Kommunikation Atmega8 <-> Beagleboard ber I2C
    Von PcVirus im Forum C - Programmierung (GCC u.a.)
    Antworten: 0
    Letzter Beitrag: 23.03.2010, 14:15
  4. TWI kommunikation, Slave luft nicht
    Von hosti im Forum C - Programmierung (GCC u.a.)
    Antworten: 13
    Letzter Beitrag: 24.06.2009, 14:23
  5. Temperaturmessung ber I2C und LM75 luft nicht
    Von michaelkoemm im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 16.10.2007, 19:50

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhnge hochladen: Nein
  • Beitrge bearbeiten: Nein
  •