|
 |
 |
 |
|
|
c't Projekte - c't-Bot und c't-Sim -
Mailinglisten
[Voriger (Datum)]
[Nächster (Datum)]
[Voriger (Thread)]
[Nächster (Thread)]
[Nach Datum][Nach Thread]
Absender: Harald Härtl
Datum: Sa, 18.03.2006 18:41:49
In-reply-to:
<200603171353.38977.tevers@xxxxxxxxxxxxx>
References:
<9612803660.20060317112342@xxxxxxxxxxxxxxxxx> <8614128726.20060317114547@xxxxxxxxxxxxxxxxx> <441A94E3.6060709@xxxxxxxxxxxx> <200603171353.38977.tevers@xxxxxxxxxxxxx>
Hallo Torsten Evers,
Die Messwerte schwanken zwar immer noch über die letzten zwei Stellen
gleicher Effekt bei mir. Ich habe einen Patch geschrieben (-> Anhang),
der für alle analogen Sensoren einen gleitenden Mittelwert berechnet,
wobei der Glättungsfaktor für jeden Sensor einzeln einstellbar ist.
Jetzt ist bei mir einigermaßen Ruhe auf der Anzeige.
Grüße,
Harald
Index: include/sensor_correction.h
===================================================================
RCS file: /ctbot/ct-Bot/include/sensor_correction.h,v
retrieving revision 1.1
diff -u -r1.1 sensor_correction.h
--- include/sensor_correction.h 4 Mar 2006 14:54:23 -0000 1.1
+++ include/sensor_correction.h 18 Mar 2006 18:29:56 -0000
@@ -25,8 +25,8 @@
#ifndef SENSOR_CORRECTION_H_
#define SENSOR_CORRECTION_H_
-#define SENSDISTSLOPE 65330 /*!< Steigung der Sensorkennlinie */
-#define SENSDISTOFFSET -3 /*!< Offset der Sensorkennlinie */
+#define SENSDISTSLOPE 5084 /*!< Steigung der Sensorkennlinie */
+#define SENSDISTOFFSET 43 /*!< Offset der Sensorkennlinie */
#endif /*SENSOR_CORRECTION_H_*/
Index: mcu/sensor-low.c
===================================================================
RCS file: /ctbot/ct-Bot/mcu/sensor-low.c,v
retrieving revision 1.4
diff -u -r1.4 sensor-low.c
--- mcu/sensor-low.c 4 Mar 2006 14:54:23 -0000 1.4
+++ mcu/sensor-low.c 18 Mar 2006 18:29:57 -0000
@@ -105,6 +105,32 @@
timer_2_init();
}
+/*!
+ * Berechnung eines fliessenden Mittelwerts
+ * @param actValue Aktuell vom Sensor erfasster Wert
+ * @param sensor Nummer des Sensors (#defines aus ADC-Pins)
+ * @return Geglaetteter Messwert des Sensors
+ */
+ int16 smooth (int16 actValue, uint8 sensor) {
+
+ static long oldValue[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+ static int8 strength[8] = {3, 3, 2, 2, 3, 3, 1, 1};
+ // DIST LINE LDR BORDER
+
+ /* Bitshiften statt multiplizieren/dividieren sollte Rechenzeit sparen. */
+ /* Formel: wert = (alt * (2^strength - 1) + neu) / 2^strength */
+ /* stength = 0: Keine Glaettung */
+ /* stength = 1: Mittelwert: (alt + neu)/2 */
+ /* stength = 2: Neuer Wert geht zu einem Viertel ein */
+ /* stength = 3: Neuer Wert geht zu einem Achtel ein */
+
+ oldValue[sensor] = ((oldValue[sensor] << strength[sensor]) - oldValue[sensor] + actValue) >> strength[sensor];
+
+ return (int16)oldValue[sensor];
+ }
+
+
+
/*!
* Konvertiert einen Sensorwert vom analogen Abstandssensor in mm
* Da die Sensoren eine nichtlineare Kennlinie haben,
@@ -114,8 +140,15 @@
* @return Distanz in mm
*/
int16 sensor_abstand(int16 sensor_data){
- // TODO reale Kennlinie beachten!!!!
- return SENSDISTSLOPE / (sensor_data - SENSDISTOFFSET);
+ // SENSDISTSLOPE sprengt bei Millimeterauflösung den Wertebereich
+ // eines int16. Also Zentimeter und in der Berechnung mal 10.
+ // Eine Messgenauigkeit im Millimeterbereich ist sowieso nicht gegeben.
+ static const int16 max = (SENSDISTSLOPE + 99 * SENSDISTOFFSET) / 99;
+
+ if (sensor_data > max)
+ return 10 * (SENSDISTSLOPE / (sensor_data - SENSDISTOFFSET));
+ else
+ return 999; // Ein Meter und mehr kann sowieso nicht mehr vernuenftig gemessen werden
// return 1023-sensor_data;
}
@@ -142,23 +175,23 @@
sensMouseX += sensMouseDX;
// ---------- analoge Sensoren -------------------
- sensLDRL = adc_read(SENS_LDR_L);
- sensLDRR = adc_read(SENS_LDR_R);
+ sensLDRL = smooth (adc_read(SENS_LDR_L), SENS_LDR_L);
+ sensLDRR = smooth (adc_read(SENS_LDR_R), SENS_LDR_R);
- sensBorderL = adc_read(SENS_KANTE_L);
- sensBorderR = adc_read(SENS_KANTE_R);
+ sensBorderL = smooth (adc_read(SENS_KANTE_L), SENS_KANTE_L);
+ sensBorderR = smooth (adc_read(SENS_KANTE_R), SENS_KANTE_R);
ENA_off(ENA_KANTLED);
- sensLineL = adc_read(SENS_M_L);
- sensLineR = adc_read(SENS_M_R);
+ sensLineL = smooth (adc_read(SENS_M_L), SENS_M_L);
+ sensLineR = smooth (adc_read(SENS_M_R), SENS_M_R);
ENA_off(ENA_MAUS);
//Aktualisiere Distanz-Sensoren
// Die Distanzsensoren sind im Normalfall an, da sie 50 ms zum booten brauchen
// sensDistL= adc_read(SENS_ABST_L);
// sensDistR= adc_read(SENS_ABST_R);
- sensDistL= sensor_abstand(adc_read(SENS_ABST_L));
- sensDistR= sensor_abstand(adc_read(SENS_ABST_R));
+ sensDistL= smooth (sensor_abstand(adc_read(SENS_ABST_L)), SENS_ABST_L);
+ sensDistR= smooth (sensor_abstand(adc_read(SENS_ABST_R)), SENS_ABST_R);
// ------- digitale Sensoren ------------------
sensDoor = (SENS_DOOR_PINR >> SENS_DOOR) & 0x01;
|
|
|