-         

Ergebnis 1 bis 6 von 6

Thema: I²C Bus --- Frage zu meinem Programm

  1. #1
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    26.11.2006
    Ort
    Hamburg
    Alter
    25
    Beiträge
    384

    I²C Bus --- Frage zu meinem Programm

    Anzeige

    SMARTPHONES & TABLETS-bis zu 77% RABATT-Kostenlose Lieferung-Aktuell | Cool | Unentbehrlich
    Guten Abend,

    Ich habe nun mal angefangen mich mit dem I²C Bus auseinander zu setzen und stosse glich am anfang auf Probleme. Das Erweiterungs board M32 soll wenn ich klatsche oder irgendein anderes Geräusch wahrgenommen wird in das read regist 5 den Wert 1 schreiben und wenn kein geräusch da ist den wert null. Der Master soll wenn er den Wert 1 aus dem Register lesen kann die Funktion CACS ausführen (die soll Licht hinterherfahren und dabei nirgendwo gegenfahren). Wenn er den Wert 0 empfängt stehen bleiben. Er bleibt aber die ganze zeit stehen. Wenn ich klatsche führt der Slave aber das kleine Lauflicht aus, daher vermute ich das er auch die Daten schreibt. Ich denke das mein Problem beim Master Programm liegt und ich was beim Daten lesen falsch mache. Nur was?. Hier mal das Program für den Master:

    Code:
    #include "RP6RobotBaseLib.h"
    #include "RP6I2CmasterTWI.h" 
    #define RECHTS adcLSR
    #define LINKS  adcLSL
    
    void CACS (unsigned int warten)
    {
    	
    		if (getBumperLeft())
    		{
    			move(60,BWD,100,1);
    			rotate(60,RIGHT,45,1);
    			moveAtSpeed(80,80);
    		}
    		else if (getBumperRight())
    		{	
    			move(60,BWD,100,1);
    			rotate(60,LEFT,45,1);
    			moveAtSpeed(80,80);
    		}
    		else if(getBumperLeft()&&getBumperRight())
    		{
    			move(60,BWD,100,1);
    			rotate(60,LEFT,90,1);
    			moveAtSpeed(80,80);
    		}
    		
    		else
    		{
    			if (obstacle_left)
    			{
    				changeDirection(FWD);
    				moveAtSpeed(80,30);
    				setLEDs(0b010000);
    			}
    		
    			else if (obstacle_right)
    			{
    				changeDirection(FWD);
    				moveAtSpeed(30,80);
    				setLEDs(0b000010);
    				
    			}
    		
    
    		
    			
    			else if(obstacle_right&&obstacle_left)
    			{
    				changeDirection(BWD);
    				moveAtSpeed(60,60);
    				setLEDs(0b110110);
    			}
    		
    			else 
    			{
    				changeDirection(FWD);
    				if (LINKS>RECHTS)
    				{
    					moveAtSpeed(50,80);
    					setLEDs(0b001000);
    				}
    				else if (RECHTS>LINKS)
    				{
    					moveAtSpeed(80,50);
    					setLEDs(0b000001);
    				}
    				
    				else
    				{
    					moveAtSpeed(100,100);
    					setLEDs(0b100010);
    				}
    			
    			}
    			mSleep(warten);
    		}
    }
    	
    
    		
    	
    	
    
    int main(void)
    {
    	unsigned int data;
    	initRobotBase();
    	I2CTWI_initMaster(100);
    	powerON();
    	setACSPwrMed();
    	moveAtSpeed(100,100);
    	setLEDs(0b001001);
    	
    	
    	
    	while(1)
    	{
    	
    	
    	I2CTWI_transmitByte(10,5);
    	data=I2CTWI_readByte(5);
    	
    	if (data==1)
    	{
    		CACS(40);
    	}
    	
    	else
    	{
    		stop();
    	}
    	
    		task_ACS();
    		task_motionControl();
    		task_ADC();
    	}
    		
    
    	return 0; 
    }
    und das Programm für den Slave:

    Code:
    #include "RP6I2CslaveTWI.h"
    #include "RP6ControlLib.h" 		
    
    void start_sound (void)
    {
    	sound(200,10,10);
    	sound(175,10,10);
    	sound(215,10,10);
    	sound(135,50,40);
    	sound(225,20,25);
    	sound(205,50,50);
    	sound(135,120,120);
    	sound(95,50,10);
    	sound(145,40,10);
    	sound(200,30,15);
    	sound(175,30,20);
    	sound(135,50,25);
    }
    
    void lauf_licht (void)
    {
    	setLEDs(0b0001);
    	mSleep(50);
    	setLEDs(0b0010);
    	mSleep(50);
    	setLEDs(0b0100);
    	mSleep(50);
    	setLEDs(0b1000);
    	mSleep(50);
    }
    	
    
    
    uint16_t main(void)
    {	
    	uint16_t oldton=0;
    	initRP6Control();
    	I2CTWI_initSlave(10);
    	start_sound();
    	
    	dischargePeakDetector();
    
    
    
    	while(1) 
    	{
    		uint16_t tmp = getMicrophonePeak();
    		
    		
    		if (tmp>5)
    		
    		{
    			if(tmp > oldton)
    			{
    				lauf_licht();
    			
    				tmp=oldton;
    				if (!I2CTWI_readBusy)
    				{
    					I2CTWI_readRegisters[5]=1;
    				}
    			
    			}
    			
    			
    		}
    		
    		else
    		{
    			setLEDs(0b0000);
    			I2CTWI_readRegisters[5]=0;
    		}
    		
    	
    	
    	}
    	return 0;
    }

    Danke schonmal im vorraus
    mfg
    Erik

  2. #2
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    26.11.2006
    Ort
    Hamburg
    Alter
    25
    Beiträge
    384
    Hmm es scheint mir als hätte noch niemand Erfahrungen mit dem I²C Bus gemacht. Oder ist blos die Frage unverständlich? Naja dann werd ich die Erfahrung wohl selbst machen müssen.

    mfg
    Erik

  3. #3
    Erfahrener Benutzer Roboter Genie Avatar von SlyD
    Registriert seit
    27.11.2003
    Ort
    Paderborn
    Alter
    32
    Beiträge
    1.514
    Hallo Erik,

    Du musst auf dem Slave die Abfrage "if (!I2CTWI_readBusy) " eher als Schleife realisieren, die wartet bis keine Lesezugriffe mehr erfolgen. Sonst kannst Du hier nicht sicher sein, das der Wert überhaupt jemals geschrieben wird.

    Also in der Art:
    - Frage ab ob das Mikrofon etwas detektiert hat.
    - WENN es etwas detektiert hat, setze ein Flag und warte solange bis schreibzugriff möglich ist.

    Das gilt auch für den umgekehrten Fall, also wenn das Register auf 0 gesetzt werden soll.

    Und vor allen Dingen wird bei Deinem Slave Code das Register fast sofort wieder auf 0 gesetzt - denn der Peak wird nur einmal kurz detektiert.
    Du musst also zusätzlich den Code so auslegen, dass der Slave den Wert zurücksetzt sobald der Master das entsprechende Register gelesen hat.

    Schau Dir hierzu auch mal das Beispielprogramm "RP6Base_I2CSlave" an - ist zwar für den Controller auf dem Mainboard, ist vom Prinzip her aber ähnlich. Da wird genau das gemacht (Interrupt flag zurücksetzen usw.)

    MfG,
    SlyD

  4. #4
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    26.11.2006
    Ort
    Hamburg
    Alter
    25
    Beiträge
    384
    Ok danke erstmal für die Antwort. Ich werd es probieren sobald ich zeit hab.

    mfg
    Erik

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    10.08.2007
    Beiträge
    47
    Mir scheint auch die generelle Programmlogik nicht zielfuehrend zu sein ...
    Ich weiss nicht, ob SlyD das auch meinte.

    Das Klatschen ist ein kurzer Augenblick. Die meiste Zeit ist Stille. D.h. zunaechst steht der Roby. Beim Klatschen "faehrt" er los (zumindest koennte dieser Zustand fuer einen minimalen Zeitraum eingenommen werden). Gleich darauf ist aber wieder Stille und der RP6 soll sofort stehen bleiben...

    Vielleicht solltest Du nach dem Programmstart (suche das Licht) eine gewisse Zeit verstreichen lassen, in der der RP6 "nur" diesem Programm folgt. Das wird angehalten/unterbrochen bei einem zweiten Klatschen oder nach einem Timeout. Nur so als Idee ...

    HTH
    Kay

  6. #6
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    26.11.2006
    Ort
    Hamburg
    Alter
    25
    Beiträge
    384
    Hmm ich verstehe, ich werde das dann wohl in einer Schleife ausführen.

    mfg
    Erik

Berechtigungen

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