- SF800 Solar Speicher Tutorial         
Seite 5 von 7 ErsteErste ... 34567 LetzteLetzte
Ergebnis 41 bis 50 von 64

Thema: Anschluss von Infrarotsensoren

  1. #41
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    62
    Beiträge
    5.799
    Blog-Einträge
    8
    Anzeige

    E-Bike
    Hallo

    Ich war mal so frei und habe den Code nach meinen Gewohnheiten formatiert:
    Code:
    void infrarotkollission(void)
    {
       DDRC &=~ (1<<PC3); // PC3 als Eingang infrarotempfänger
    
       if(ir_erweiterung == 0)
       {
          if (!(PINC & (1<<PC3)))
          {
             writeString_P("Infrarotempfang ein\n");
             writeStringLCD("ir_counter=:");
             writeString("ir_counter=:");
             writeInteger(ir_counter,DEC);
             writeIntegerLCD(ir_counter, DEC);
             writeChar('\n');
    
             ir_ende = false;
             ir_counter++; // infrarot empfangen
          }
       }
    
       if (ir_counter == 50)
       {
          ir_hindernis = true;
          ir_erweiterung = 1;
       }
    
       if (ir_ende)
       {
          ir_counter = 0;
          ir_erweiterung = 0;
          ir_hindernis = false;
       }
    }
    Code:
    // IR-Radar von proevofreak                                              26.2.2010
    
    
    // von radbruch formatierter Code
    
    #include "RP6ControlLib.h"
    #include "RP6ControlServoLib.h"
    #include "RP6I2CmasterTWI.h"
    #include "RP6Control_I2CMasterLib.h"
    
    // Servo 1 => PC2
    // Servo 2 => PC3
    // Servo 3 => PC4
    // Servo 4 => PC5
    // Servo 5 => PC6
    
    uint8_t move_state = 0; // Wenn nichts anderes zugewiesen ist, ist move_state =0
    
    void RP6_Bewegung(void)
    {
       if (ir_hindernis)
       {
          if (!(ir_ende))
          {
             stopStopwatch3(); // stopwatch3 anhalten wenn ir erkannt wird und damit servobewegung anhalten
             writeString_P("ir ende gleich false\n");
          }
    
          switch(move_state)
          {
             case 0:
                if (getStopwatch3() <1000 || getStopwatch3() >6000)
                {
                   rotate(50,RIGHT,90,NON_BLOCKING); // um 90 grad rotieren
                   move_state= 1; // move_state den wert 1 zuweisen
                }
             break;
    
             case 1:
                if(isMovementComplete())
                {
                   ir_ende= true; // ir_ende=true, wenn bewegung abgeschlossen
                   startStopwatch3(); // stopwatch3 starten => servo wieder drehen
                   writeString_P("ir ende gleich true\n");
                }
             break;
          }
       }
    }
    
    void servoansteuerung(void)
    {
       if (getStopwatch3() <1000)
       {
          servo3_position = 0;
          writeString_P("LEFT Touch\n");
       }
    
       if (getStopwatch3() >1000 && getStopwatch3() <2000)
       {
          servo3_position = 20;
          writeString_P("servo position 40\n");
       }
    
       if (getStopwatch3() >2000 && getStopwatch3() <3000)
       {
          servo3_position = 90;
       }
    
       if (getStopwatch3() >3000 && getStopwatch3() <4000)
       {
          servo3_position = RIGHT_TOUCH;
          writeString_P("Servo Right touch\n");
       }
    
       if (getStopwatch3() >4000 && getStopwatch3() <5000)
       {
          servo3_position = 90;
       }
    
       if (getStopwatch3() >5000 && getStopwatch3() <6000)
       {
          servo3_position = 20;
       }
    
       if (getStopwatch3() >6000 && getStopwatch3() <7000)
       {
          servo3_position = 0;
          writeString_P("LEFT Touch\n");
       }
    
       if (getStopwatch3() >7000)
       {
          setStopwatch3(0);
          writeString_P("stopwatch3 auf 0 zurück\n");
       }
    }
    
    int main(void)
    {
       initRP6Control();
       I2CTWI_initMaster(100);
       initSERVO(SERVO3);
       startStopwatch3();
    
       while(true)
       {
          servoansteuerung();
          task_SERVO();
          infrarotkollission();
          RP6_Bewegung();
       }
       return 0;
    }
    (Weder kompiliert noch überprüft oder getestet)

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  2. #42
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.01.2008
    Ort
    Allgäu
    Alter
    37
    Beiträge
    220
    Zitat Zitat von radbruch
    Hallo

    Ich war mal so frei und habe den Code nach meinen Gewohnheiten formatiert:
    ist ja nett, dass du meinen code sauber umformatierst (jetzt weiß ich glaube ich auch was man unter sauberer formatierung versteht) aber leider löst das auch nicht mein bestehendes problem.
    mein eigentliches problem liegt ja nicht in der unübersichtlichen programmierung, sondern vielmehr daran, dass in case1 isMovementComplete() nie true wird, obwohl der rp6 korrekt rotiert.

    wenn mir da jemand weiterhelfen würde und mir sagen würde was ich anders programmieren muss, wäre ich richtig dankbar.

    mfg andi

  3. #43
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    40
    Beiträge
    1.516
    Du rufst nirgendwo task_RP6System(); auf.
    Jedenfalls sehe ichs nicht...

    Das MUSS unbedingt in die Endlosschleife in der Main rein!

    MfG,
    SlyD

  4. #44
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.01.2008
    Ort
    Allgäu
    Alter
    37
    Beiträge
    220
    Zitat Zitat von SlyD
    Du rufst nirgendwo task_RP6System(); auf.
    Jedenfalls sehe ichs nicht...

    Das MUSS unbedingt in die Endlosschleife in der Main rein!

    MfG,
    SlyD
    bist du dir sicher? ich verwende für mein programm ja die M32 und nicht die Base.
    also in den beispielprogrammen der M32 (z.b. in RP6Control_06_I2CMaster) rotiert der RP6 auch, ohne dass task_RP6System(); aufgerufen wird.

    mfg

  5. #45
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    40
    Beiträge
    1.516
    Ach sorry - hab ich nicht drauf geachtet.
    Ändert aber prinzipiell nix dran das ein ähnlicher Aufruf fehlt

    Hier musst Du halt

    task_checkINT0();
    task_I2CTWI();

    aufrufen - wie soll der Controller auf dem Erweiterungsmodul sonst mitbekommen das der andere Controller auf dem Mainboard seinen Status geändert hat (also mit rotieren fertig ist)?
    Das muss ja über den I2C Bus übertragen werden - das regelt die task_I2CTWI... und die andere Funktion wird gebraucht um zu prüfen ob der Controller auf dem Mainboard die Interrupt Leitung gesetzt hat (also neue Daten vorhanden sind).

    Du musst auch noch die entsprechenden Handler setzen damit die Funktion checkRP6Status aus der RP6Control Master Lib aufgerufen wird und die Register aktualisiert.

    Schau Dir die M32 Beispielprogramme nochmal an da wird das genau beschrieben!

    MfG,
    SlyD

  6. #46
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.01.2008
    Ort
    Allgäu
    Alter
    37
    Beiträge
    220
    oh danke, ja daran könnte es liegen. hab nur bisher gedacht, dass da schon alles passt, weil ich schon mal die M32 als Master mit gleichzeitiger fahrfunktion (allerdings damals mit moveAtSpeed()) verwendet habe, und damals nichts weiter aufgerufen habe und trotzdem alles funktioniert hat.

    aber gut dass du jetzt darauf hingewiesen hast, dann werd ich jetzt die ganze I2C funktionen und Beispielprogramme erst mal nochmal gründlich anschauen und dann in meinem programm ergänzen.

    danke nochmal

  7. #47
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.01.2008
    Ort
    Allgäu
    Alter
    37
    Beiträge
    220
    so, nach wirklich stundenlangem durcharbeiten der I²C lib, der beispielprogramme mit I²C und dem durchlesen der anleitung der base und der M32 habe ich mein programm jetzt nochmal abgeändert:

    Code:
     // Uncommented Version of RP6ControlServo.c
    
    #include "RP6ControlLib.h"
    #include "RP6ControlServoLib.h"
    #include "RP6I2CmasterTWI.h"
    #include "RP6Control_I2CMasterLib.h"
    
    
    
    
    
    uint8_t move_state = 0; // Wenn nicht anders zugewiesen,move_state=0
    
    
    
    void motionControlStateChanged(void)
    {	if (ir_hindernis)
    	{
    		if (!(ir_ende))
    		{stopStopwatch3();		//stopwatch3 anhalten wenn ir erkannt wird und damit servobewegung anhalten
    		writeString_P("stopStopwatch3\n");}	
    
    
    	
    	
    
    			switch(move_state)
    	
    				{case 0:
    					if (getStopwatch3() <1000 || getStopwatch3() >6000)
    					{rotate(50,RIGHT,90,NON_BLOCKING); //um 90 grad rotieren wenn hindernis erkennt wird und stopwatch3 <1000 oder >6000 ist
    					move_state= 1;	// move_state den wert 1 zuweisen
    					}
    					break;
    	
    	
    					case 1:
    					if(isMovementComplete())
    					{ir_ende= true; 		//ir_ende=true, wenn bewegung abgeschlossen
    					startStopwatch3();		//stopwatch3 wieder starten und servo wieder starten
    					writeString_P("stopwatch3 starten\n");
    					}
    					break;
    					
    				}
    	
    
    			
    			
    	}
    
    }
    	
    
    	
    	
    	
    	
    
    
    
    
    
    void servoansteuerung(void)
    {if (getStopwatch3() <1000)
    	{servo3_position = 0;
    	writeString_P("LEFT Touch\n");}
    
    
    if (getStopwatch3() >1000 && getStopwatch3() <2000)
    	{servo3_position = 20;
    	writeString_P("servo position 40\n");}
    	
    if (getStopwatch3() >2000 && getStopwatch3() <3000)
    	{servo3_position = 90;}
    
    if (getStopwatch3() >3000 && getStopwatch3() <4000)
    		{servo3_position = RIGHT_TOUCH;
    		writeString_P("Servo Right touch\n");}
    		
    if (getStopwatch3() >4000 && getStopwatch3() <5000)
    	{servo3_position = 90;}
    	
    if (getStopwatch3() >5000 && getStopwatch3() <6000)
    	{servo3_position = 20;}
    		
    if (getStopwatch3() >6000 && getStopwatch3() <7000)
    	{servo3_position = 0;
    	writeString_P("LEFT Touch\n");}
    	
    if (getStopwatch3() >7000)
    	{
    	setStopwatch3(0);
    	writeString_P("stopwatch3 auf 0 zurück\n");}
    	
    }
    
    
    
    
    
    void I2C_requestedDataReady(uint8_t dataRequestID)
    {
    	checkRP6Status(dataRequestID);
    }
    
    
    
    
    
    void I2C_transmissionError(uint8_t errorState)
    {
    	writeString_P("\nI2C ERROR - TWI STATE: 0x");
    	writeInteger(errorState, HEX);
    	writeChar('\n');
    }
    
    	
    
    	
    int main(void)
    { 
       initRP6Control();
       
       
       I2CTWI_initMaster(100);  
       
    	I2CTWI_setRequestedDataReadyHandler(I2C_requestedDataReady);
    	
    	I2CTWI_setTransmissionErrorHandler(I2C_transmissionError);
    	
    	
    	I2CTWI_transmit3Bytes(I2C_RP6_BASE_ADR, 0, CMD_ROTATE, true);
    	
     MOTIONCONTROL_setStateChangedHandler(motionControlStateChanged);
    
     initSERVO(SERVO3); 
    startStopwatch3(); 
       
       while(true) 
       {
    servoansteuerung();
        task_SERVO();
     
    	  infrarotkollission();
    	  
    	task_checkINT0();
            task_I2CTWI();
       }
       return 0;
    }
    jetzt ist es so, dass das programm zwar fehlerfrei kompiliert wird, wenn ich es aber laufen lasse, springt es sofort nach dem start wieder in den standby- modus (hoffe die bezeichnung ist so richtig) und im terminal erscheint folgende meldung:
    Code:
    [READY]
    LEFT Touch
    
    I2C ERROR - TWI STATE: 0x20
    LEFT Touch
    LEFT Touch
    LEFT Touch
    LEFT Touch
    LEFT Touch
    LEFT Touâ
    [RP6BOOT]
    offensichtlich ist im programm noch irgendetwas in verbindung mit I²C falsch.
    grundsätzlich kann ich nicht behaupten, dass ich die I²C lib bzw. funktionen trotz gründlichem durcharbeitens wirklich 100%ig verstanden habe, da sie doch aus sehr vielen verschiedenen teilen bestehen.
    um so mehr bin ich auf eure hilfe hier angewiesen.

    mfg andi

  8. #48
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.01.2008
    Ort
    Allgäu
    Alter
    37
    Beiträge
    220
    kann mir denn wirklich niemand sagen was noch fehlt bzw. falsch ist?

    mfg andi

  9. #49
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.01.2008
    Ort
    Allgäu
    Alter
    37
    Beiträge
    220
    so, jetzt hab ich threads zu diesem thema und die beispielprogramme untersucht, so dass ich mein programm jetzt nach dem vorbild de RP6Control_09_Move beispielprogramm abgeändert habe:

    Code:
     
    #include "RP6ControlLib.h"
    #include "RP6ControlServoLib.h"
    #include "RP6I2CmasterTWI.h"
    #include "RP6Control_I2CMasterLib.h"
    
    
    
    
    
    uint8_t move_state = 0; // Wenn nichts anderes zugewiesen ist, ist move_state =0
    
    
    
    void motionControlStateChanged(void) 
    {	if (ir_hindernis)
    	{
    		if (!(ir_ende))
    		{stopStopwatch3();		//stopwatch3 anhalten wenn ir erkannt wird und damit servobewegung anhalten
    		writeString_P("stopStopwatch3\n");}	
    
    
    	
    	
    
    			switch(move_state)
    	
    				{case 0:
    					if (getStopwatch3() <1000 || getStopwatch3() >6000)
    					{rotate(50,RIGHT,90,NON_BLOCKING); //um 90 grad rotieren wenn hindernis erkennt wird und stopwatch3 <1000 oder >6000 ist
    					move_state= 1;	// move_state den wert 1 zuweisen
    					}
    					break;
    	
    	
    					case 1:
    					if(isMovementComplete())
    					{ir_ende= true; 		//ir_ende=true, wenn bewegung abgeschlossen
    					startStopwatch3();		//stopwatch3 wieder starten und servo wieder starten
    					writeString_P("stopwatch3 starten\n");
    					}
    					break;
    					
    				}
    	
    
    			
    			
    	}
    
    }
    	
    
    	
    	
    	
    	
    
    
    
    
    
    void servoansteuerung(void)
    {if (getStopwatch3() <1000)
    	{servo3_position = 0;
    	writeString_P("LEFT Touch\n");}
    
    
    if (getStopwatch3() >1000 && getStopwatch3() <2000)
    	{servo3_position = 20;
    	writeString_P("servo position 40\n");}
    	
    if (getStopwatch3() >2000 && getStopwatch3() <3000)
    	{servo3_position = 90;}
    
    if (getStopwatch3() >3000 && getStopwatch3() <4000)
    		{servo3_position = RIGHT_TOUCH;
    		writeString_P("Servo Right touch\n");}
    		
    if (getStopwatch3() >4000 && getStopwatch3() <5000)
    	{servo3_position = 90;}
    	
    if (getStopwatch3() >5000 && getStopwatch3() <6000)
    	{servo3_position = 20;}
    		
    if (getStopwatch3() >6000 && getStopwatch3() <7000)
    	{servo3_position = 0;
    	writeString_P("LEFT Touch\n");}
    	
    if (getStopwatch3() >7000)
    	{
    	setStopwatch3(0);
    	writeString_P("stopwatch3 auf 0 zurück\n");}
    	
    }
    
    
    void watchDogRequest(void)
    {
    	static uint8_t heartbeat2 = false;
    	if(heartbeat2)
    	{
    		clearPosLCD(0, 14, 1);
    		heartbeat2 = false;
    	}
    	else
    	{
    		setCursorPosLCD(0, 14);
    		writeStringLCD_P("#"); 
    		heartbeat2 = true;
    	}
    }
    
    
    
    void I2C_requestedDataReady(uint8_t dataRequestID)
    {
    	checkRP6Status(dataRequestID);
    }
    
    
    
    
    
    void I2C_transmissionError(uint8_t errorState)
    {
    	writeString_P("\nI2C ERROR - TWI STATE: 0x");
    	writeInteger(errorState, HEX);
    	writeChar('\n');
    	
    }
    
    	
    
    	
    int main(void)
    { 
       initRP6Control();
       
       WDT_setRequestHandler(watchDogRequest); 
       
       I2CTWI_initMaster(100);  
       
    	I2CTWI_setRequestedDataReadyHandler(I2C_requestedDataReady);
    	
    	I2CTWI_setTransmissionErrorHandler(I2C_transmissionError);
    	
    	I2CTWI_transmit3Bytes(I2C_RP6_BASE_ADR, 0, CMD_SET_ACS_POWER, ACS_PWR_MED);
    	I2CTWI_transmit3Bytes(I2C_RP6_BASE_ADR, 0, CMD_SET_WDT, true);
    	I2CTWI_transmit3Bytes(I2C_RP6_BASE_ADR, 0, CMD_SET_WDT_RQ, true);
    
     initSERVO(SERVO3); 
    startStopwatch3(); 
       
       while(true) 
       {
    servoansteuerung();
        task_SERVO();
    
    	  infrarotkollission();
    	
    	task_checkINT0();
            task_I2CTWI();
       }
       return 0;
    }
    das ergebnis ist aber leider immer noch das selbe wie vorher. der das programm läuft nur einen sekundenbruchteil und der mikrocontroller springt dann in den standby modus zurück.

    im terminal erscheint diese meldung:

    Code:
    I2C ERROR - TWI STATE: 0x20
    
    I2C ERROR - TWI STATE: 0x20
    LEFT Touch
    
    I2C ERROR - TWI STATE: 0x20
    LEFT Touch
    LEFT Touch
    LEFT Touch
    LEFT Touch
    LEFT Touch
    LEFT Touc
    ich kann mir vorstellen, dass ich vielleicht dem ein oder anderen in diesem forum mit meinem problem auf die nerven gehe, aber da ich die ganzen I²C funktionen noch überhaupt nicht kapiere und mittlerweile mit allen möglichen programmschnipsel aus beispielprogrammen erfolglos hantiert habe, bin ich halt auf eure hilfe angewiesen.

    danke schon mal im voraus für eure mühen mir zu helfen.

    mfg andi

  10. #50
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    40
    Beiträge
    1.516
    deaktivier erstmal den Watchdog und Request (WDT und WDT_RQ auf false!).

    Dann zusätzlich brauchst Du eine Pause von mind. 500ms am Anfang des Programms direkt nach der initialisierung da eine kleine Pause auch in dem Base Programm drin ist vorher reagiert das nicht daher auch wahrscheinlich die 0x20 Fehler am Anfang.

    Für den Rest hab ich nun aber leider keine Zeit - sorry

    MfG,
    SlyD

Seite 5 von 7 ErsteErste ... 34567 LetzteLetzte

Berechtigungen

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

fchao-Sinus-Wechselrichter AliExpress