So, hab nun nochmal die i2c-Signale am Logik-Analyser aufgezeichnet für drei Fälle. Für alle drei Fälle ist die Startsequenz auf dem I2C Bus identisch, siehe Datei i2c_first_start.png. Nun die 3 Fälle:
1. ohne FOR-Schleife US-Sensoren einzeln abgefragt und Messung neu gestartet: das ist die Referenz, alles läuft wie es soll, siehe Dateien i2c_first_meas.png und i2c_second_start.png.
2. mit FOR-Schleife von i=0 bis i=2 alle US-Sensoren abgefragt, er versucht noch den 2. Sensor zu lesen, aber die Schleife wird nicht weiter ausgeführt, siehe Datei i2c_first_meas_error.png.
3. wie Fall 2, bloß noch einen Marker eingefügt nach der LCD Ausgabe, bei dem der Wert von i auf den I2C Bus ausgegeben wird. Dies ist bei i=0 auch der Fall, aber i=1 wird nicht mehr ausgegeben, d.h. die Schleife wird gar nicht bis dort ausgeführt, siehe Datei i2c_first_meas_error_marker.png.
Der Code (mit jeweils auskommentierten Sequenzen) ist ebenfalls beigefügt: allrounder.c
Bitte schaut nochmal drauf und gebt mir Tipps, was der Fehler sein könnte mit der Ausführung der FOR-Schleife. Eigentlich sehe ich im Moment nur die Erklärung, dass bei i=1 die Abfrage des 2. US Sensors mit busy[1]=... dazu führt, dass dieser noch als busy angesehen wird (dies ist auch bei allen folgenden Abfragen der Fall [Ausführung der großen while Schleife] und die Sensoren werden nie mehr neu gestartet mit einer Messung). Aber warum? Denn im Fall 1 ohne FOR Schleife ist er ja nicht busy.
Hier der Code für Fall 1 (ohne FOR-Schleife, wird fehlerfrei abgearbeitet):
Code:
busy_US[0] = i2c_start(US_left + I2C_READ);
// address I2C device ultrasonic sensor with read access
if (busy_US[0] == 0)
{
distance[0] = i2c_readNak(); // read one byte
i2c_stop(); // release I2C bus
utoa(distance[0], buffer, 10);
// move cursor to position on line 0
lcd_gotoxy(10,0);
// put string to display (line 0)
lcd_puts(buffer);
lcd_puts(" ");
}
else
{
i2c_stop(); // release I2C bus
}
busy_US[1] = i2c_start(US_front + I2C_READ);
// address I2C device ultrasonic sensor with read access
if (busy_US[1] == 0)
{
distance[1] = i2c_readNak(); // read one byte
i2c_stop(); // release I2C bus
utoa(distance[1], buffer, 10);
// move cursor to position on line 0
lcd_gotoxy(14,0);
// put string to display (line 0)
lcd_puts(buffer);
lcd_puts(" ");
}
else
{
i2c_stop(); // release I2C bus
}
busy_US[2] = i2c_start(US_right + I2C_READ);
// address I2C device ultrasonic sensor with read access
if (busy_US[2] == 0)
{
distance[2] = i2c_readNak(); // read one byte
i2c_stop(); // release I2C bus
utoa(distance[2], buffer, 10);
// move cursor to position on line 0
lcd_gotoxy(18,0);
// put string to display (line 0)
lcd_puts(buffer);
lcd_puts(" ");
i2c_start(US_general + I2C_WRITE);
// address I2C device ultrasonic sensor with write access
i2c_write(Start_US); //start new ultrasonic measurement
i2c_stop(); // release I2C bus
}
else
{
i2c_stop(); // release I2C bus
}
Hier der Code für Fall 2 & 3 (mit FOR-Schleife, bricht bei i=1 ab):
Code:
// select display
lcd_select(0);
for ( i = 0 ; i < 3 ; i++ )
{
// check if ultrasonic sensor is busy
busy_US[i] = i2c_start(US_left + (2*i) + I2C_READ);
// address I2C device ultrasonic sensor with read access
if (busy_US[i] == 0)
{
distance[i] = i2c_readNak(); // read one byte
i2c_stop(); // release I2C bus
utoa(distance[i], buffer, 10);
// move cursor to position on line 0
lcd_gotoxy(10+(4*i),0);
// put string to display (line 0)
lcd_puts(buffer);
lcd_puts(" ");
//marker: put out i on I2C bus
i2c_start(i);
i2c_stop();
if (i==2)
{
i2c_start(US_general + I2C_WRITE);
// address I2C device ultrasonic sensor with write access
i2c_write(Start_US); //start new ultrasonic measurement
i2c_stop(); // release I2C bus
}
}
else
{
i2c_stop(); // release I2C bus
}
}
Danke und Gruß, Dirk.
Lesezeichen