## c't-Projekte - Mailinglisten

[Voriger (Datum)] [Nächster (Datum)] [Voriger (Thread)] [Nächster (Thread)]
[Nach Datum][Nach Thread]

### [ct-bot] Re: Kalibrierung der Distanzsensren mittels EEPROM-Tabelle

Absender: Achim Pankalla
Datum: Di, 06.03.2007 10:58:46
In-reply-to: <BCF016D5ED5AC34FBB655D109519ABCF083EBE@xxxxxxxxxxxxxxxxxxxx>
References: <BCF016D5ED5AC34FBB655D109519ABCF083EBE@xxxxxxxxxxxxxxxxxxxx>

    hallo freunde des ct-bot,

`fast ein jahr ist es her, da machte sich begeisterung über die idee von` `hr. jonas breit, die distanzsensoren über eine tabelle im eeprom zu` `kalibrieren. der erste patch wurde hier veröffentlicht. so soll nun auch` `sein abschluss hier sein platz finden... ;-)` `hier ist nun meine finale version (ich habe mich damals bereit gefunden` `sie patch-fähig zu machen) davon.`

    neues gegenüber versionen vom juli 06 und september 06:

`- kode wurde ordentlich aufgeräumt und ist nun weniger geworden. (sowohl` `in bezug auf dateien als auch kodezeilen)`

    - weniger vorhandene datei werden im cvs geändert
    - der bot code für den laufenden betrieb wurde kleiner

`- die fkt. die das eeprom in der pc-version simuliert heisst jetzt` `eeprom_read/write_byte/word, wie beim winavr`

    - fehlerkorrektur im kode gegenüber juli 06
    - neu eingeführte src (seid feb07 release 13) wird berücksichtigt.

`- dateinamen wurden geändert, damit weitere sensorkalibrierungen ergänzt` `werden können.`

    - handling vereinfacht, docu aktualisiert

    hier nochmals die vorteile des patches.
    - über tabellen im eeprom liefern die dist sensoren stabile werte.
    - beide sensoren sind nun angeglichen liefern gleiche wert

`- eeprom ist nun auch im sim vorhanden, eeprom kann vom bot im sim` `benutzt werden`

    - alle fkt. die das eeprom benutzen sind schon agepasst.
    - src kode wird übersichtlicher fuer eeprom kein #ifdef PC mehr notwendig
    - fehler bei reset-counter fkt. werden korregiert

    hier die nachteile oder besser einschränkungen

`- eingeschränkte auslösung der distanzwerte (bei mir 10mm auflösung noch` `super ruhig)`

    - eeprom benutzung muss über eeprom_map.h erfolgen
    - man muss die docu in documente-ordner lesen ;-)

`leider geht der eigentliche kalibriervorgang nicht mehr im neuen ct-sim` `(ct-bot zu langsam meldung, wahrscheinlich muss da ein lebenszeichen vom` `bot kommen, doch das kalibrieren erfolgt ja vor der endlosschleife). die` `nutzung der kalibrierungstabelle geht jedoch einwandfrei. meine bot hat` `mit meinen eepromwerten mehrer parcours gemeistert. nun könnte ja jemand` `wieder schwankende sensor-werte einbauen. mein patch ist ja nicht mehr` `mit den neuen sim kompatible, vielleicht erbarmt sich ja jemand. :-)`

`und nicht zu vergessen: dank nochmal an P.Jonas für seine idee und ich` `begeisterter kalibrierer ;-)`

    viel spass mit dem tool
    achim pankalla

    ### Eclipse Workspace Patch 1.0
    #P ct-Bot
    Index: include/sensor_correction.h
    ===================================================================
    RCS file: /ctbot/ct-Bot/include/sensor_correction.h,v
    retrieving revision 1.5
    diff -u -r1.5 sensor_correction.h
    --- include/sensor_correction.h	6 Nov 2006 12:32:12 -0000	1.5
    +++ include/sensor_correction.h	6 Mar 2007 10:05:13 -0000
    @@ -35,5 +35,10 @@
     #define SENS_IR_MAX_DIST	750		/*!< Obergrenze des Erfassungsbereichs */
     #define SENS_IR_INFINITE	999		/*!< Kennzeichnung fuer "kein Objekt im Erfassungsbereich" */

    +/* Parameter fuer IR-Sensorkalibrierung */
    +#define SC_STARTDIST      	8       /*!< Startdistanz der Kalibrierung in cm*/
    +#define SC_STEPWIDTH	    4		/*!< Abstand der einzelnen Messwerte*/
    +#define SC_NO_OF_STEPS     20       /*!< Anzahl der weitere Werte, ausser dem Startwert max. 24*/
    +extern uint16 simDistL, simDistR;   /*!< Sichert die Analogen Werte der Abstandssensoren des ct-Sim*/

     #endif /*SENSOR_CORRECTION_H_*/
    Index: include/gui.h
    ===================================================================
    RCS file: /ctbot/ct-Bot/include/gui.h,v
    retrieving revision 1.1
    diff -u -r1.1 gui.h
    --- include/gui.h	22 Feb 2007 18:02:10 -0000	1.1
    +++ include/gui.h	6 Mar 2007 10:05:13 -0000
    @@ -57,6 +57,7 @@

     #ifdef RESET_INFO_DISPLAY_AVAILABLE
     	extern uint8 reset_flag;	 /*<! Nimmt den Status von MCU(C)SR bevor dieses Register auf 0x00 gesetzt wird */
    +	extern uint8 resets;         /*<! Hilfsvariable fuers Reset zaehlen*/
     	/*!
     	 * @brief	Zeigt Informationen ueber den Reset an
     	 */
    Index: Changelog.txt
    ===================================================================
    RCS file: /ctbot/ct-Bot/Changelog.txt,v
    retrieving revision 1.141
    diff -u -r1.141 Changelog.txt
    --- Changelog.txt	5 Mar 2007 12:32:03 -0000	1.141
    +++ Changelog.txt	6 Mar 2007 10:05:10 -0000
    @@ -1,5 +1,14 @@
     CHANGELOG fuer c't-Bot
     ======================
    +2007-03-06 Peter Jonas [peter.jonas@xxxxxx] & Achim Pankalla [achim.pankalla@xxxxxx]
    +		   (Peter Jonas)
    +		   Menuegefuehrte Kalibrierung der Distanzsensoren über EEPROM-Tabelle entwickelt.
    +		   (Achim Pankalla)
    +		   Kleine Optimierungen. Anpassung des Kodes an die Koderichtlinien. Damit der Kode
    +		   auch im ct-Sim funktioniert, werden die Zugriffe auf das EEPROM des realen bot
    +		   durch zugriff auf eine Datei simuliert. Diese ist kann auch für den bot benutzt
    +		   werden oder von diesem runtergeladen werden. Anpassung vorhandener EEPRPM-Zugriffe.
    +
     2007-03-05 Timo Sandmann [mail@xxxxxxxxxxxxxxx]: Bugfix fuer Remote-Display (falsche Cursorposition, falls nicht vor jedem display_printf() ein display_cursor() efolgte)

     2007-03-05 Timo Sandmann [mail@xxxxxxxxxxxxxxx]: Bugfix im RC5-Code (Toggle-Bit wurde versehentlich komplett ignoriert bei der neuen GUI)
    Index: command.c
    ===================================================================
    RCS file: /ctbot/ct-Bot/command.c,v
    retrieving revision 1.23
    diff -u -r1.23 command.c
    --- command.c	5 Mar 2007 12:06:25 -0000	1.23
    +++ command.c	6 Mar 2007 10:05:11 -0000
    @@ -53,6 +53,10 @@
     	#include <pthread.h>
     #endif

    +#ifdef SENSOR_TABLE_AVAILABLE
    +	#include "sensor_correction.h"
    +#endif
    +
     #ifdef MCU
     	#ifdef NEW_AVR_LIB
     		#include <util/delay.h>
    @@ -73,6 +77,9 @@
     	// Auf dword alignment bestehen, wird fuer MacOS X benoetigt
     	pthread_mutex_t     command_mutex __attribute__ ((aligned (4)))
     		= PTHREAD_MUTEX_INITIALIZER;
    +	// Wird fuer die weitergabe der simulierten Analogwerte der Abstandssenoren benötigt
    +	extern uint16 simadcL;
    +	extern uint16 simadcR;
     #endif

    @@ -403,7 +410,7 @@
     		// Einige Kommandos ergeben nur fuer simulierte Bots Sinn
     		#ifdef PC
     			case CMD_SENS_IR:
    -				sensor_abstand(received_command.data_l,received_command.data_r);
    +				sensor_abstand(simadcL = received_command.data_l,simadcR = received_command.data_r);
     				break;
     			case CMD_SENS_ENC:
     				sensEncL+=received_command.data_l;
    Index: ct-Bot.h
    ===================================================================
    RCS file: /ctbot/ct-Bot/ct-Bot.h,v
    retrieving revision 1.38
    diff -u -r1.38 ct-Bot.h
    --- ct-Bot.h	22 Feb 2007 18:02:10 -0000	1.38
    +++ ct-Bot.h	6 Mar 2007 10:05:12 -0000
    @@ -67,9 +67,12 @@
     //#define TEST_AVAILABLE_ANALOG		/*!< Sollen die LEDs die analoge Sensorwerte anzeigen */
     #define TEST_AVAILABLE_DIGITAL		/*!< Sollen die LEDs die digitale Sensorwerte anzeigen */
     //#define TEST_AVAILABLE_MOTOR		/*!< Sollen die Motoren ein wenig drehen */
    -//#define TEST_AVAILABLE_COUNTER 	/*!< Gibt einen Endlos-Counter auf Screen 3 aus und aktiviert Screen 3 */
    +#define TEST_AVAILABLE_COUNTER 	/*!< Gibt einen Endlos-Counter auf Screen 3 aus und aktiviert Screen 3 */
     //#define DOXYGEN		/*!< Nur zum Erzeugen der Doku, wenn dieser schalter an ist, jammert der gcc!!! */

    +//#define CALIBRATE_DIST_SENSOR  	/*!< Aktivieren des Kalibrierungsprogramm fuer die Erstellung der SENSOR_TABLE*/
    +//#define SENSOR_TABLE_AVAILABLE 	/*!< EEPROM-Tabelle verwenden, um die Sensoren zu kalibrieren */
    +
     #define BEHAVIOUR_AVAILABLE /*!< Nur wenn dieser Parameter gesetzt ist, exisitiert das Verhaltenssystem */

     //#define MAP_AVAILABLE /*!< Aktiviere die Kartographie */
    @@ -102,12 +105,17 @@
     #ifndef DISPLAY_AVAILABLE
     	#undef WELCOME_AVAILABLE
     	#undef DISPLAY_REMOTE_AVAILABLE
    +	#undef CALIBRATE_DIST_SENSOR
     #endif

     #ifndef IR_AVAILABLE
     	#undef RC5_AVAILABLE
     #endif

    +#ifndef RC5_AVAILABLE
    +	#undef CALIBRATE_DIST_SENSOR
    +#endif
    +
     #ifndef MAUS_AVAILABLE
     	#undef MEASURE_MOUSE_AVAILABLE
     	#undef MEASURE_COUPLED_AVAILABLE
    @@ -121,6 +129,8 @@
     		#undef TWI_AVAILABLE
     		#undef SPEED_CONTROL_AVAILABLE // Deaktiviere die Motorregelung
     		#undef MMC_AVAILABLE
    +		#undef TEST_AVAILABLE_COUNTER
    +		#undef CALIBRATE_DIST_SENSOR
     	#endif

     	#define COMMAND_AVAILABLE		/*!< High-Level Communication */
    Index: sensor.c
    ===================================================================
    RCS file: /ctbot/ct-Bot/sensor.c,v
    retrieving revision 1.29
    diff -u -r1.29 sensor.c
    --- sensor.c	22 Feb 2007 18:02:10 -0000	1.29
    +++ sensor.c	6 Mar 2007 10:05:12 -0000
    @@ -28,6 +28,15 @@
     #include "bot-local.h"
     #include "math.h"
     #include "sensor_correction.h"
    +#ifdef SENSOR_TABLE_AVAILABLE
    +	#ifdef MCU
    +		#include <avr/eeprom.h>
    +	#endif
    +	#ifdef PC
    +		#include "parameter-low.h"
    +	#endif
    +	#include "eeprom_map.h"
    +#endif
     #include "ui/available_screens.h"
     #include "display.h"
     #include "sensor.h"
    @@ -107,6 +116,7 @@
      * @param left Linker Rohwert [0-1023]
      * @param right Rechter Rohwert [0-1023]
      */
    +#ifndef SENSOR_TABLE_AVAILABLE
     void sensor_abstand(uint16 left, uint16 right){
     	if (left  == SENSDISTOFFSETLEFT)  // Vermeidet Div/0
     		left++;
    @@ -122,6 +132,47 @@
     	if (sensDistR > SENS_IR_MAX_DIST || sensDistR<=0)
     		sensDistR=SENS_IR_INFINITE;
     }
    +#endif
    +
    +#ifdef SENSOR_TABLE_AVAILABLE
    +/*!
    + * Funktion benutzt die Kalibrierungstabelle im EEPROM dazu die Werte der Abstandssensoren
    + * zu stabilisieren.
    + */
    +void sensor_abstand(uint16 left, uint16 right){
    +	uint16 i; //Laufvariablen fuer Werteindizierung
    +
    +	//Linke Sensor
    +	//Grenzwerte behandeln
    +	if (left > eeprom_read_word((uint16 *)SCT_LEFT)) {
    +		sensDistL = SC_STARTDIST*10;
    +	} else if (left < eeprom_read_word((uint16 *)(SCT_LEFT + SC_NO_OF_STEPS*2))) {
    +		sensDistL = SENS_IR_INFINITE;
    +	} else {
    +		//Wert aus Kalibrierdaten bestimmen
    +		for(i=0; left < eeprom_read_word((uint16 *)(SCT_LEFT + i*2)); i++ ); //Realwert suchen
    +		sensDistL = (i * SC_STEPWIDTH + SC_STARTDIST) * 10; //in mm umrechnen
    +		//Ergebnis verfeinern
    +		if(left > (eeprom_read_word((uint16 *)(SCT_LEFT + i*2)) + eeprom_read_word((uint16 *)(SCT_LEFT + (i-1)*2))) / 2)
    +			sensDistL -= (SC_STEPWIDTH * 10) / 2;
    +	}
    +
    +	//Rechter Sensor
    +	if (right > eeprom_read_word((uint16 *)SCT_RIGHT)) {
    +		sensDistR = SC_STARTDIST*10;
    +	} else if (right < eeprom_read_word((uint16 *)(SCT_RIGHT + SC_NO_OF_STEPS*2))) {
    +		sensDistR = SENS_IR_INFINITE;
    +	} else {
    +		//Wert aus Kalibrierdaten bestimmen
    +		for(i=0; right < eeprom_read_word((uint16 *)(SCT_RIGHT + i*2)); i++ ); //Realwert suchen
    +		sensDistR = (i * SC_STEPWIDTH + SC_STARTDIST) * 10; //in mm umrechnen
    +		//Ergebnis verfeinern
    +		if(right > (eeprom_read_word((uint16 *)(SCT_RIGHT + i*2)) + eeprom_read_word((uint16 *)(SCT_RIGHT + (i-1)*2))) / 2)
    +			sensDistR -= (SC_STEPWIDTH * 10) / 2;
    +	}
    +	return;
    +}
    +#endif

     /*! Sensor_update
     * Kuemmert sich um die Weiterverarbeitung der rohen Sensordaten
    Index: ct-Bot.c
    ===================================================================
    RCS file: /ctbot/ct-Bot/ct-Bot.c,v
    retrieving revision 1.43
    diff -u -r1.43 ct-Bot.c
    --- ct-Bot.c	22 Feb 2007 18:02:10 -0000	1.43
    +++ ct-Bot.c	6 Mar 2007 10:05:11 -0000
    @@ -32,12 +32,14 @@
     //	#include <avr/signal.h>
     	#include <avr/wdt.h>
     	#include "bot-2-pc.h"
    +	#include <avr/eeprom.h>
     #endif

     #ifdef PC
     	#include "bot-2-sim.h"
     	#include "tcp.h"
     	#include "tcp-server.h"
    +	#include "parameter-low.h"
     	#include <pthread.h>
     	#include <unistd.h>
     	#include <stdlib.h>
    @@ -64,6 +66,7 @@
     #include "timer.h"
     #include "sensor.h"
     #include "log.h"
    +#include "eeprom_map.h"

     #include "motor.h"
     #include "sensor-low.h"
    @@ -81,6 +84,9 @@
     #include "mmc-vm.h"
     #include "gui.h"
     #include "ui/available_screens.h"
    +#ifdef CALIBRATE_DIST_SENSOR
    +	#include "calibrate_sensors.h"
    +#endif

     /*!
      * Der Mikrocontroller und der PC-Simulator brauchen ein paar Einstellungen,
    @@ -404,11 +410,14 @@
     //TODO: what's that?!?
     #ifdef TEST_AVAILABLE_COUNTER
     //	display_screen=2;
    - 	resets=eeprom_read_byte(&resetsEEPROM)+1;
    -    eeprom_write_byte(&resetsEEPROM,resets);
    + 	resets=eeprom_read_byte((uint8 *)RESETS)+1;
    +    eeprom_write_byte((uint8 *)RESETS,resets);
         /* Lege den Grund fuer jeden Reset im EEPROM ab */
    -    eeprom_write_byte(&resetInfoEEPROM+resets,reset_flag);
    +    eeprom_write_byte((uint8 *)(RESETINFO+(resets%10)),reset_flag);
     #endif
    +#ifdef CALIBRATE_DIST_SENSOR
    +	calibrate_distsensor();
    +#endif

     /* Hauptschleife des Bots */
     for(;;){
    Index: bot-logic/behaviour_turn.c
    ===================================================================
    RCS file: /ctbot/ct-Bot/bot-logic/behaviour_turn.c,v
    retrieving revision 1.2
    diff -u -r1.2 behaviour_turn.c
    --- bot-logic/behaviour_turn.c	22 Feb 2007 01:41:16 -0000	1.2
    +++ bot-logic/behaviour_turn.c	6 Mar 2007 10:05:13 -0000
    @@ -31,9 +31,13 @@
     #ifdef MCU
     	#include <avr/eeprom.h>
     #endif
    +#ifdef PC
    +	#include "parameter-low.h"
    +#endif
     #include <stdlib.h>
     #include <math.h>
     #include "log.h"
    +#include "eeprom_map.h"

     /* Parameter fuer das bot_turn_behaviour() */
     #ifndef MEASURE_MOUSE_AVAILABLE
    @@ -42,15 +46,6 @@
     #else
     int8 angle_correct=0;			/*!< Drehabschnitt 0=0-15Grad, 1=16-45 Grad, 2= >45 Grad */
     int16 to_turn;					/*!< Wieviel Grad sind noch zu drehen? */
    -	#ifdef MCU
    -		uint8 __attribute__ ((section (".eeprom"))) err15=1;					/*!< Fehler bei Drehungen unter 15 Grad */
    -		uint8 __attribute__ ((section (".eeprom"))) err45=2;					/*!< Fehler bei Drehungen zwischen 15 und 45 Grad */
    -		uint8 __attribute__ ((section (".eeprom"))) err_big=4;				/*!< Fehler bei groesseren Drehungen */
    -	#else
    -		uint8 err15=0;
    -		uint8 err45=0;
    -		uint8 err_big=0;
    -	#endif
     #endif
     int8 turn_direction;			/*!< Richtung der Drehung */

    @@ -150,48 +145,30 @@
     				speedWishRight=BOT_SPEED_STOP;
     				break;
      			}
    -			#ifdef MCU
    -				e15=eeprom_read_byte(&err15);
    -				e45=eeprom_read_byte(&err45);
    -				ebig=eeprom_read_byte(&err_big);
    -			#else
    -				e15=err15;
    -				e45=err45;
    -				ebig=err_big;
    -			#endif
    +			e15=eeprom_read_byte((uint8 *)ERR15);
    +			e45=eeprom_read_byte((uint8 *)ERR45);
    +			ebig=eeprom_read_byte((uint8 *)ERR_BIG);

     			// Neue Abweichung mit alter vergleichen und ggfs neu bestimmen
     			switch(angle_correct) {
     				case 0:
     					if (abs(to_turn+e15) > 1){
     						e15 = (uint8)(-to_turn + e15) / 2;
    -						#ifdef MCU
    -							eeprom_write_byte(&err15,e15);
    -						#else
    -							err15=e15;
    -						#endif
    +						eeprom_write_byte((uint8 *)ERR15,e15);
     					}
     					break;

     				case 1:
     					if (abs(to_turn+e45) > 1){
     						e45 = (uint8)(-to_turn + e45) / 2;
    -						#ifdef MCU
    -							eeprom_write_byte(&err45,e45);
    -						#else
    -							err45=e45;
    -						#endif
    +		 				eeprom_write_byte((uint8 *)ERR45,e45);
     					}
     					break;

     				case 2:
     					if (abs(to_turn+ebig) > 1){
     						ebig = (uint8)(-to_turn + ebig) / 2;
    -						#ifdef MCU
    -							eeprom_write_byte(&err_big,ebig);
    -						#else
    -							err_big=ebig;
    -						#endif
    +						eeprom_write_byte((uint8 *)ERR_BIG,ebig);
     					}
     					break;
     			}
    @@ -212,34 +189,21 @@
      	if(degrees < 0) turn_direction = -1;
      	else turn_direction = 1;
     	to_turn=abs(degrees);
    -	#ifdef MCU
    -		/* Fehlerwerte initialisieren, falls noch nicht geschehen */
    -		if (eeprom_read_byte(&err15) == 255) eeprom_write_byte(&err15,1);
    -		if (eeprom_read_byte(&err45) == 255) eeprom_write_byte(&err45,2);
    -		if (eeprom_read_byte(&err_big) == 255) eeprom_write_byte(&err_big,4);
    +	/* Fehlerwerte initialisieren, falls noch nicht geschehen */
    +	if (eeprom_read_byte((uint8 *)ERR15) == 255) eeprom_write_byte((uint8 *)ERR15,1);
    +	if (eeprom_read_byte((uint8 *)ERR45) == 255) eeprom_write_byte((uint8 *)ERR45,2);
    +	if (eeprom_read_byte((uint8 *)ERR_BIG) == 255) eeprom_write_byte((uint8 *)ERR_BIG,4);

    -		if (to_turn>45) {
    -			to_turn-=eeprom_read_byte(&err_big);
    -			angle_correct=2;
    -		} else if (to_turn<=45 && to_turn>15) {
    -			to_turn-=eeprom_read_byte(&err45);
    -			angle_correct=1;
    -		} else {
    -			to_turn-=eeprom_read_byte(&err15);
    -			angle_correct=0;
    -		}
    -	#else
    -		if (to_turn>45) {
    -			to_turn-=err_big;
    -			angle_correct=2;
    -		} else if (to_turn<=45 && to_turn>15) {
    -			to_turn-=err45;
    -			angle_correct=1;
    -		} else {
    -			to_turn-=err15;
    -			angle_correct=0;
    -		}
    -	#endif
    +	if (to_turn>45) {
    +		to_turn-=eeprom_read_byte((uint8 *)ERR_BIG);
    +		angle_correct=2;
    +	} else if (to_turn<=45 && to_turn>15) {
    +		to_turn-=eeprom_read_byte((uint8 *)ERR45);
    +		angle_correct=1;
    +	} else {
    +		to_turn-=eeprom_read_byte((uint8 *)ERR15);
    +		angle_correct=0;
    +	}
      	switch_to_behaviour(caller, bot_turn_behaviour,OVERRIDE);
      }
     #else
    Index: ui/misc.c
    ===================================================================
    RCS file: /ctbot/ct-Bot/ui/misc.c,v
    retrieving revision 1.1
    diff -u -r1.1 misc.c
    --- ui/misc.c	22 Feb 2007 18:02:10 -0000	1.1
    +++ ui/misc.c	6 Mar 2007 10:05:13 -0000
    @@ -65,6 +65,8 @@

     	#ifdef RESET_INFO_DISPLAY_AVAILABLE
     		uint8 reset_flag;
    +		uint8 resets = 0;
    +
     		/*!
     		 * @brief Zeigt Informationen ueber Resets an
     		 */
    Index: Documentation/parameter-low.html
    ===================================================================
    RCS file: Documentation/parameter-low.html
    diff -N Documentation/parameter-low.html
    --- /dev/null	1 Jan 1970 00:00:00 -0000
    +++ Documentation/parameter-low.html	1 Jan 1970 00:00:00 -0000
    @@ -0,0 +1,141 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    +<HTML>
    +<HEAD>
    +	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252">
    +	<TITLE></TITLE>
    +	<META NAME="GENERATOR" CONTENT="OpenOffice.org 2.1  (Win32)">
    +	<META NAME="AUTHOR" CONTENT="Achim Pankalla">
    +	<META NAME="CREATED" CONTENT="20060528;19455600">
    +	<META NAME="CHANGEDBY" CONTENT="Achim Pankalla">
    +	<META NAME="CHANGED" CONTENT="20070303;19541418">
    +	<STYLE>
    +	<!--
    +		@page { size: 21cm 29.7cm; margin: 2cm }
    +		P { margin-bottom: 0.21cm }
    +	-->
    +	</STYLE>
    +</HEAD>
    +<BODY LANG="de-DE" DIR="LTR">
    +<P ALIGN=CENTER STYLE="margin-bottom: 0cm"><B>Parameterspeicherung</B></P>
    +<P STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P STYLE="margin-bottom: 0cm"><FONT SIZE=3><B>Author: </B></FONT>
    +</P>
    +<P STYLE="margin-bottom: 0cm"><FONT SIZE=3>Achim Pankalla
    +(achim.pankalla@xxxxxx)</FONT></P>
    +<P STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P STYLE="margin-bottom: 0cm"><B>Beschreibung:</B></P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">Die Funktionen der
    +Parameterspeicherung wurden von mir erstellt, um den Zugriff auf die
    +Hardware des Prozessors zu abstrahieren.
    +</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">Parameter sind nach
    +dieser Definition Daten, die man auch nach dem Abschalten des ct-bots
    +noch benoetigt. Natuerlich legt man solche Daten im EEPROM des
    +Prozessors ab und da setzen die Funktionen an. Sie sorgen dafuer das
    +diese Moeglichkeit auch im Simulator zur Verfuegung steht. Der
    +Programmierer kann damit sowohl im Ct-Sim als auch im realen ct-bot
    +mit den selben Aufrufen seine Daten sichern.</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">Damit auch der
    +Austausch dieser Daten einfach von statten gehen kann, werden die
    +EEPROM Daten beim ct-sim in eine BIN-Datei abgelegt. Diese kann mit
    +den gaengigen Programmiersoftware auf den Prozessor uebertragen
    +werden. Andererseits koennen vom Prozessor abgezogenen Daten auch
    +EEPROM fuer den ct-sim benutzt werden, wenn sie im BIN Format von der
    +Programmiersoftware gesichert werden.</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">Der Zugriff auf das
    +simulierte EEPROM erfolgt &uuml;ber die gleichen Funktion wie beim
    +boot-Code (eeprom_read/write_byte/word). Ein #ifdef PC oder MCU ist
    +nicht notwendig.
    +</P>
    +<P STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal"><B><FONT SIZE=4 STYLE="font-size: 15pt"><FONT COLOR="#ff0000">Achtung!!</FONT></FONT></B><BR>Die
    +Reservierung von Speicher im EEPROM darf nur durch die eeprom_map.h
    +erfolgen. Eine Definition einer EEPROM-Variable mit Hilfe von
    +<I>__attribute__ ((section (&quot;.eeprom&quot;))) </I>darf nicht
    +erfolgen, dies wuerde zu Doppelnutzungen von Speicherbereichen
    +f&uuml;hren, mit unberechenbaren Auswirkungen.</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">Ein zweiter Punkt,
    +den man beachten sollte ist die Zeigerarithmetik von C. Alle
    +eeprom-Funktionen erwarten, wie beim avr-Compiler Pointer auf uint8
    +oder uint16 als Adressparameter. Damit auch alles sicher klappt
    +sollten bei berechneten Adressen wie folgt vorgegangen
    +werden.<BR>eeprom_read_word((uint16 *)<B> </B><SPAN STYLE="font-weight: medium">(SCT_LEFT
    ++ i*2))</SPAN></P>
    +<P STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal"><B>EEPROM-Datei
    +fuer Simulation:</B></P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">Die Datei, die das
    +simulierte EEPROM darstellt, wird in <I>parameter-low_pc.c</I> mit
    +dem DEFINE EEPROM_FILENAME festgelegt. Bei der Vergabe des Namens,
    +ist zu folgendes zu beachten:</P>
    +<P STYLE="margin-bottom: 0cm"><I>Pfad</I></P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">Der Pfad, der den
    +eigentlichen Dateinamen vorangestellt werden kann, muss existieren.
    +Es werden von den Funktionen keine neuen Verzeichnisse angelegt.
    +Stimmt die Pfadangabe nicht, so werden keine Daten abgelegt. Ist die
    +Datei selbst nicht vorhanden, so wird eine Neue angelegt.</P>
    +<P STYLE="margin-bottom: 0cm"><I>Backslash</I></P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">Das \ in der
    +Pfadangabe muss immer gedoppelt werden (\\), da der Compiler das
    +Backslash als Einleitung fuer ein Sonderzeichen sieht.
    +</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">Suffix</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">Die Datei muss
    +nicht unbedingt mit <I>.bin</I> enden. Dies erleichtert jedoch die
    +Arbeit, wenn zum Beispiel PonyProg schon als Standartprogramm fuer
    +diesen Dateityp eingestellt ist.</P>
    +<P STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">Existiert keine
    +Datei mit den angegebenen Namen, so wird beim Schreibzugriff eine
    +solche angelegt. Beim Lesen von Daten, wird bei einer nicht
    +existenten Datei Null zurueckgegeben.</P>
    +<P STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal"><B>Memory MAP</B></P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">Damit alle Routinen
    +des ct-bot problemlos miteinander harmonieren koennen und keine
    +Probleme mit verschieden Konfigurationen auftreten, sollte jeder
    +Programmierer der diese Funktionen nutzen moechte seinen Bedarf
    +EEPROM-Speicher in die Memory-Map als DEFINE eintragen. Diese
    +Konstanten beginnen mit EEP_... und enden mit ..._START und ...STOP.
    +Dadurch soll eine versehentliche Doppelnutzung verhindert werden. Ein
    +erklaerender Kommentar sollte auch dort stehen.</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">In der zweite
    +Sektion sollte man ein DEFINE eintragen mit der Adresse f&uuml;r den
    +Zugriff auf die Speicherzelle im EEPROM. Dadurch wird er Kode
    +uebersichtlicher.</P>
    +<P STYLE="margin-bottom: 0cm; font-style: normal">Die Memory MAP
    +befindet sich in <I>eeprom_map.h</I>.</P>
    +<P STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P STYLE="margin-bottom: 0cm"><B>Funktionen:</B></P>
    +<P STYLE="margin-bottom: 0cm"><B>Nur in parameter-low_pc.c sichtbare
    +Funktionen</B></P>
    +<P STYLE="margin-bottom: 0cm">store_parameter() - Speichern von
    +Informationen im simulierten EEPROM</P>
    +<P STYLE="margin-bottom: 0cm">load_parameter() - Laden von
    +Informationen aus dem simulierten EEPROM</P>
    +<P STYLE="margin-bottom: 0cm"><B>Zugriffsfunktionen f&uuml;r den PC
    +(Identisch zu denen von WinAVR)</B></P>
    +<P STYLE="margin-bottom: 0cm">eeprom_read_byte()</P>
    +<P STYLE="margin-bottom: 0cm">eeprom_write_byte()</P>
    +<P STYLE="margin-bottom: 0cm">eeprom_read_word()</P>
    +<P STYLE="margin-bottom: 0cm">eeprom_write_word()</P>
    +<P STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P STYLE="margin-bottom: 0cm"><FONT SIZE=3><B>Dateien:</B></FONT></P>
    +<P STYLE="margin-bottom: 0cm"><FONT SIZE=3>parameter-low.h Include
    +Dateinamen mit Funktionsparameter</FONT></P>
    +<P STYLE="margin-bottom: 0cm"><FONT SIZE=3>parameter-low_pc.c
    +Funktionen fuer den ct-Sim</FONT></P>
    +<P STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +</BODY>
    +</HTML>
    Index: include/eeprom_map.h
    ===================================================================
    RCS file: include/eeprom_map.h
    diff -N include/eeprom_map.h
    --- /dev/null	1 Jan 1970 00:00:00 -0000
    +++ include/eeprom_map.h	1 Jan 1970 00:00:00 -0000
    @@ -0,0 +1,50 @@
    +/*
    + *  * c't-Sim - Robotersimulator fuer den c't-Bot
    + *
    + * This program is free software; you can redistribute it
    + * and/or modify it under the terms of the GNU General
    + * Public License as published by the Free Software
    + * Foundation; either version 2 of the License, or (at your
    + * option) any later version.
    + * This program is distributed in the hope that it will be
    + * useful, but WITHOUT ANY WARRANTY; without even the implied
    + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
    + * PURPOSE. See the GNU General Public License for more details.
    + * You should have received a copy of the GNU General Public
    + * License along with this program; if not, write to the Free
    + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
    + * MA 02111-1307, USA.
    + *
    + */
    +
    +/*! @file 	eeprom_map.h
    + * @brief 	Speicherbelgegung des EEPROM Bereiches vom ct-bot Prozessor
    + * @author 	Achim Pankalla (achim.pankalla@xxxxxx)
    + * @date 	01.03.07
    +*/
    +#ifndef eeprom_map_H_
    +#define eeprom_map_H_
    +
    +/******************************************************************************
    +* EEPROM Memory map zur Uebersicht welche Adressbereiche bereits genutzt werden
    +* Adressbereiche durch START und END eingrenzen.
    +******************************************************************************/
    +#define EEP_DIST_CTABLE_START 	0x0000 //Distanzsensor-Kalibrierung
    +#define EEP_DIST_CTABLE_END   	0x0063
    +#define EEP_BOT_TURN_START		0x0064 //Bot-Tuern Parameter
    +#define EEP_BOT_TURN_END		0x0066
    +#define EEP_RESET_COUNT_START	0x0067 //Resetprotokoll der letzten 10
    +#define EEP_RESET_COUNT_STOP	0x0071
    +
    +/******************************************************************************
    + * EEPROM Adressen für den vereinfachten Zugriff
    + *****************************************************************************/
    +#define SCT_LEFT	0x0000 //Start der Sensor Kalibrierungstabelle links
    +#define SCT_RIGHT	0x0032 //Start der Sensor Kalibrierungstabelle rechts
    +#define ERR15		0x0064  //bot_turn Variablen
    +#define ERR45		0x0065
    +#define ERR_BIG		0x0066
    +#define RESETS		0x0067  //Resetzaehler
    +#define RESETINFO	0x0068  //Start der letzten 10 Resetgruende
    +
    +#endif
    Index: include/parameter-low.h
    ===================================================================
    RCS file: include/parameter-low.h
    diff -N include/parameter-low.h
    --- /dev/null	1 Jan 1970 00:00:00 -0000
    +++ include/parameter-low.h	1 Jan 1970 00:00:00 -0000
    @@ -0,0 +1,46 @@
    +/*
    + * c't-Sim - Robotersimulator fuer den c't-Bot
    + *
    + * This program is free software; you can redistribute it
    + * and/or modify it under the terms of the GNU General
    + * Public License as published by the Free Software
    + * Foundation; either version 2 of the License, or (at your
    + * option) any later version.
    + * This program is distributed in the hope that it will be
    + * useful, but WITHOUT ANY WARRANTY; without even the implied
    + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
    + * PURPOSE. See the GNU General Public License for more details.
    + * You should have received a copy of the GNU General Public
    + * License along with this program; if not, write to the Free
    + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
    + * MA 02111-1307, USA.
    + *
    + */
    +
    +/*! @file 	parameter-low.h
    + * @brief 	Low-Level Routinen fuer den Zugriff auf das EEPROM des c't-Bots
    + * @author 	Achim Pankalla (achim.pankalla@xxxxxx)
    + * @date 	13.05.06
    +*/
    +#ifndef parameter_low_H_
    +#define parameter_low_H_
    +
    +#ifdef PC
    +/*!
    + * Speichern Daten im EEPROM.
    + * @param address Adresse im EEPROM zwischen 0 und 1023.
    + * @param data Variable mit den abzulegenen Daten.
    + */
    +extern void eeprom_write_byte(uint8  *adr, uint8 value);
    +extern void eeprom_write_word(uint16 *adr, uint8 value);
    +
    +/*!
    + * Laden Daten aus dem EEPROM.
    + * @param address Adresse im EEPROM zwischen 0 und 1023.
    + * @return Wert der Speicheraddresse im EEPROM
    + */
    +extern uint8  eeprom_read_byte(uint8  *adr);
    +extern uint16 eeprom_read_word(uint16 *adr);
    +
    +#endif
    +#endif
    Index: Documentation/sensor_eprom_doc.htm
    ===================================================================
    RCS file: Documentation/sensor_eprom_doc.htm
    diff -N Documentation/sensor_eprom_doc.htm
    --- /dev/null	1 Jan 1970 00:00:00 -0000
    +++ Documentation/sensor_eprom_doc.htm	1 Jan 1970 00:00:00 -0000
    @@ -0,0 +1,163 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    +<HTML>
    +<HEAD>
    +	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252">
    +	<TITLE></TITLE>
    +	<META NAME="GENERATOR" CONTENT="OpenOffice.org 2.1  (Win32)">
    +	<META NAME="CREATED" CONTENT="20060508;19143406">
    +	<META NAME="CHANGEDBY" CONTENT="Achim Pankalla">
    +	<META NAME="CHANGED" CONTENT="20070303;16390884">
    +	<STYLE>
    +	<!--
    +		@page { size: 21cm 29.7cm }
    +		H2.western { font-family: "Albany", sans-serif; font-size: 14pt; font-style: italic }
    +		H2.cjk { font-family: "HG Mincho Light J"; font-size: 14pt; font-style: italic }
    +		H2.ctl { font-family: "Arial Unicode MS"; font-size: 14pt; font-style: italic }
    +	-->
    +	</STYLE>
    +</HEAD>
    +<BODY LANG="de-DE" DIR="LTR">
    +<H2 CLASS="western">Sensorkalibrierung mittels EEPROM-Tabelle</H2>
    +<P STYLE="margin-bottom: 0cm">Version 0.6 (03-Maer-2007)<BR><BR>Peter
    +Jonas (peter.jonas@xxxxxx)
    +</P>
    +<P STYLE="margin-bottom: 0cm">Achim Pankalla (achim.pankalla@xxxxxx)</P>
    +<HR>
    +<P ALIGN=CENTER><U><B>Einleitung</B></U></P>
    +<P ALIGN=LEFT>Mit diesem Patch kann mittels einer EEPROM-Tabelle die
    +Kalibrierung der Distanzsensoren durchgefuehrt werden. Dies gilt auch
    +fuer den ct-Sim. Der Vorteil dieses Verfahrens sind. <BR>1) Ruhigere
    +Messwerte.<BR>2) Beide Sensoren liefern bei gleichen Distanzen
    +identische Werte.<BR>3) Die Messwerte liegen fest, dh. Man kann ohne
    +Probleme im Kode bestimmte Abstaende abfragen. <BR><BR><BR>
    +</P>
    +<P ALIGN=CENTER><U><B>Einstellungen im Quellkode</B></U></P>
    +<P ALIGN=LEFT>Die Kalibrierung wird ueber mehrere <I>#defines</I> in
    +der Datei <I>ctbot.h</I> und <I>sensor_correction.h</I> gesteuert:
    +</P>
    +<P ALIGN=CENTER><BR><FONT COLOR="#ff0000">#define
    +CALIBRATE_DIST_SENSOR</FONT></P>
    +<P ALIGN=LEFT>Wenn diese Zeile aktiviert ist, geht der Roboter in den
    +Kalibrierungsmodus. Diese Einstellung ist nur einmal notwendig, um
    +die Kalibrierung der Sensoren durchzufuehren. Im spaeteren normalen
    +Roboterbetrieb ist diese Zeile zu deaktivieren.
    +</P>
    +<P ALIGN=CENTER><BR><FONT COLOR="#ff0000">#define
    +<FONT FACE="Times New Roman, serif">SENSOR_TABLE_AVAILABLE</FONT></FONT><BR><BR><BR>
    +</P>
    +<P ALIGN=LEFT>Wenn diese Zeile aktiviert ist, wird im normalen
    +Roboterbetrieb eine im EEPROM abgelegte Tabelle fuer die
    +Linearisierung der Distanzsensoren benutzt. Wenn diese Zeile
    +deaktiviert ist, wird die urspruengliche Linearisierung der Sensoren
    +ueber die einfache Hyperbelfunktion durchgefuehrt.
    +</P>
    +<P ALIGN=CENTER STYLE="margin-bottom: 0cm"><FONT COLOR="#ff0000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><B>#define</B>
    +SAMPLES_PER_AVG</FONT></FONT></FONT></P>
    +<P ALIGN=LEFT STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P ALIGN=LEFT STYLE="margin-bottom: 0cm"><FONT COLOR="#000000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>Anzahl
    +der Messungen pro Abstand, die zur Mittelwertberechung genutzt
    +werden.</FONT></FONT></FONT></P>
    +<P ALIGN=CENTER STYLE="margin-bottom: 0cm"><FONT COLOR="#ff0000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><B>#define</B>
    +<FONT FACE="Courier New, monospace">SC_STARTDIST</FONT></FONT></FONT></FONT></P>
    +<P ALIGN=CENTER STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P ALIGN=LEFT STYLE="margin-bottom: 0cm"><FONT COLOR="#000000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>Abstand
    +in Zentimeter, bei dem die Messreihe beginnt. Dieser Wert muss dort
    +liegen, wo die Sensoren ihre hoechsten Werte liefern und dann den Bot
    +noch ein kleines Stuck weiter. Acht Zentimeter hat sich als guter
    +Wert erwiesen. </FONT></FONT></FONT>
    +</P>
    +<P ALIGN=CENTER STYLE="margin-bottom: 0cm"><FONT COLOR="#ff0000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><B>#define</B>
    +<FONT FACE="Courier New, monospace">SC_STEPWIDTH</FONT></FONT></FONT></FONT></P>
    +<P ALIGN=CENTER STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P ALIGN=LEFT STYLE="margin-bottom: 0cm"><FONT COLOR="#000000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>Abstand
    +zwischen den Messpunkten. Mit der aktuellen Auswertungsfunktion wird
    +dieser Wert halbiert und man erhaelt so die Genauigkeit der
    +ermittelten Werte. Bei mir hat sich der Wert 4 als gut erwiesen. Der
    +Bot kann dann auf 20mm die Werte aufl&ouml;sen und diese sind auch
    +sehr stabil. Der Wert entspricht natuerlich Zentimeter. Man sollte
    +aber auf eine Gesamtdistanz von mindestens 80cm kommen. Notfalls den
    +folgenden Wert erhoehen.</FONT></FONT></FONT></P>
    +<P ALIGN=CENTER STYLE="margin-bottom: 0cm"><FONT COLOR="#ff0000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3><B>#define</B>
    +<FONT FACE="Courier New, monospace">SC_NO_OF_STEPS</FONT></FONT></FONT></FONT></P>
    +<P ALIGN=CENTER STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P ALIGN=LEFT STYLE="margin-bottom: 0cm"><FONT COLOR="#000000"><FONT FACE="Times New Roman, serif"><FONT SIZE=3>Dieser
    +Wert legt fest, wie viele Messungen gemacht werden. Man sollte nicht
    +uber eine Gesamtdistanz von ca. 80cm kommen, da die Sensoren mehr
    +nicht hergeben und Werte zu dicht beieinander liegen. Der Wert gibt
    +die Anzahl der Messungen ohne Startwert an, dh. Fuer insgesamt 16
    +Messungen, muss man hier 15 eintragen. Es nur ein <U>Maximum von 24</U>
    +zulaessig.</FONT></FONT></FONT></P>
    +<P ALIGN=LEFT STYLE="margin-bottom: 0cm"><BR>
    +</P>
    +<P ALIGN=CENTER><U><B>Kalibrierung</B></U></P>
    +<P ALIGN=LEFT><BR>Im Kalibriermodus sieht man auf dem Display
    +zunaechst ein Menue. Man wird aufgefordert, den Roboter auf eine
    +bestimmte Distanz in cm zur Wand zu stellen. Wenn man das gemacht
    +hat, drueckt man die Taste &quot;2&quot; auf der Fernbedienung. (Kann
    +beim erstenmal zweimal notwendig sein.) Es wird nun aus den folgenden
    +vorgegebenen Zahl von Me&szlig;werten pro Sensor ein Mittelwert
    +gebildet. Dieser Wert wird dann in den beiden Tabellen (links und
    +rechts getrennt) im EEPROM abgelegt. Danach wird man aufgefordert,
    +eine neue Distanz einzustellen und der Vorgang beginnt von vorn.
    +<BR><BR>Nach SC_NO_OF_STEPS Messungen ist die Kalibrierung
    +abgeschlossen. Die Sensorwerte fuer die SC_NO_OF_STEPS Abstaende sind
    +nun im EEPROM. (Meldung in Zeile drei des Displays) Man kann aber mit
    +den Tasten &bdquo;1&ldquo; (zurueck) und &bdquo;3&ldquo; (vor)
    +nochmal zu einzelnen Werten gehen und diese nochmal wiederholen,
    +solang der letzte Wert nicht schon gemessen wurde.<BR>Mit der Taste
    +&quot;0&quot; kommt man in den normalen Roboterbetrieb zurueck und
    +kann die Kalibrierung gleich testen (SENSOR_TABLE_AVAILABLE muss
    +dafuer definiert sein). Dies ist auch bei nicht vollstaendiger
    +Kalibrierung moeglich aber nicht sinnvoll, wenn man die
    +EEPROM-Tabelle fuer die Sensoren nutzen moechte. Zu beachten ist, das
    +die Normale Belegung der Zahlentasten nicht gegeben ist, da diese
    +fuer Kalibrierung genutzt wurden.</P>
    +<P ALIGN=LEFT>Waehrend des Kalibrierungsvorgangs, zeigt die dritte
    +Zeile des Displays immer die aktuellen Messwerte an (waehrend des
    +Kalibrierungsvorgangs, MWert) oder das gemittelte Ergebnis an
    +(EWert). Die Anzahl der Messungen pro Entfernung legt uebrings das
    +<I>#define <FONT COLOR="#000000"><FONT SIZE=2><FONT FACE="Courier New, monospace">SAMPLES_PER_AVG</FONT></FONT></FONT></I><FONT COLOR="#000000">
    +<FONT FACE="Times New Roman, serif">fest, dies befindet sich in
    +<I>calibrate_sensors.c.</I></FONT></FONT><BR>Wenn die Sensoren im
    +Normalbetrieb Distanzen messen, die au&szlig;erhalb des eingestellten
    +Distanzbereiches der EEPROM-Tabelle liegen, wird der Werte aus der
    +Konstanten <FONT SIZE=2><FONT FACE="Courier New, monospace"><FONT COLOR="#000000">SENS_IR_INFINITE</FONT></FONT></FONT>
    +ausgegeben. <BR><BR>Im EEPROM werden fuer den Distanzbereich
    +SC_NO_OF_STEPS Messwerte pro Sensor gespeichert. Da die Sensoren
    +jedoch auch Werte fuer Distanzen zwischen den gemessenen Distanzen
    +ausgeben, wird im laufenden Betrieb des Roboters zwischen den
    +Stuetzwerten interpoliert, um fuer jeden Sensorwert einen mm-Wert
    +liefern zu koennen. <BR><BR>Beim Flashen mu&szlig; man aufpassen,
    +dass die Tabelle im EEPROM nicht ueberschrieben wird, deshalb sollte
    +man sie unmittelbar nach der Kalibrierung zunaechst sichern. Bei
    +PonyProg zb. Mit der Funktion <I>Command-&gt;Read Data</I> und diese
    +dann auch auf der Platte sichern. <BR>Um spaeter ein Programmupdate
    +zu flashen, liest man die Programm-Hexdatei mit &quot;Open Program
    +(Flash) File ...&quot; ein und flasht es dann mit &quot;Write Program
    +(Flash)&quot; und dann muss man die EEPROM-Datei wieder neu
    +aufspielen, da diese durch das Flashen des Programms geloescht
    +werden<BR>Speichert man den EEPROM-Bereich im BIN-Format, kann diese
    +Datei direkt auch fuer den ct-Sim nutzen.</P>
    +<P ALIGN=CENTER><B>Nutzung der Kalibrierdaten</B></P>
    +<P ALIGN=LEFT>Hat man das Define <I>SENSOR_TABLE_AVAILABLE</I> in
    +ctbot.h gesetzt, so werden die Daten in der Funktion <I>sensor_abstand</I>
    +in <I>sensor.c</I> genutzt, um aus den aktuellen Messwerten der
    +Abstandssensoren moeglichst genaue und ruhige Abstaende zu bestimmen.
    +Dafuer wird beim ct-bot nochmal die Genauigkeit der Werte durch eine
    +Mittlung ueber mehrere Werte erhoeht.<BR>Beim Simulator ist die
    +Nutzung der Kalibrierdaten auch moeglich. In dem man die
    +EEPROM-Simulation benutzt und die Werte vom realen Bot in einer Datei
    +im BIN-Format ablegt und diese ins entsprechende Verzeichnis ablegt.
    +(Siehe auch Docu fuer parameter-low).</P>
    +<P ALIGN=CENTER><FONT COLOR="#ff0000"><I><U><B>ACHTUNG!</B></U></I></FONT></P>
    +<P ALIGN=LEFT>Fuer die Nutzung der Kalibrierung ist es wichtig, das
    +die Konstanten (DEFINEs) immer die Werte haben, die auch bei der
    +Aufnahme der Daten aktuell waren. Die neue Version der
    +Kalibrierfunktion (Docu-Version ab 0.5) ist nicht kompatible mit
    +BIN-Dateien vorheriger Versionen.</P>
    +</BODY>
    +</HTML>
    Index: include/calibrate_sensors.h
    ===================================================================
    RCS file: include/calibrate_sensors.h
    diff -N include/calibrate_sensors.h
    --- /dev/null	1 Jan 1970 00:00:00 -0000
    +++ include/calibrate_sensors.h	1 Jan 1970 00:00:00 -0000
    @@ -0,0 +1,36 @@
    +/*
    + * c't-Sim - Robotersimulator fuer den c't-Bot
    + *
    + * This program is free software; you can redistribute it
    + * and/or modify it under the terms of the GNU General
    + * Public License as published by the Free Software
    + * Foundation; either version 2 of the License, or (at your
    + * option) any later version.
    + * This program is distributed in the hope that it will be
    + * useful, but WITHOUT ANY WARRANTY; without even the implied
    + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
    + * PURPOSE. See the GNU General Public License for more details.
    + * You should have received a copy of the GNU General Public
    + * License along with this program; if not, write to the Free
    + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
    + * MA 02111-1307, USA.
    + *
    + */
    +
    +/*! @file 	calibrate_sensors.h
    + * @brief 	Routinen fuer die Kalibrierung der Sensoren des c't-Bots
    + * @author 	Achim Pankalla (achim.pankalla@xxxxxx)
    + * @date 	01.09.06
    +*/
    +#ifndef CALIBRATE_SENSORS_H_
    +#define CALIBRATE_SENSORS_H_
    +
    +#ifdef CALIBRATE_DIST_SENSOR
    + 	/*!
    + 	 * Erstellt das Menue des Kalibrierungsprogramm auf dem Display und fragt die
    +	 * Fernbedienung ab.
    +	 */
    +	extern void calibrate_distsensor(void);
    +#endif
    +
    +#endif
    Index: calibrate_sensors.c
    ===================================================================
    RCS file: calibrate_sensors.c
    diff -N calibrate_sensors.c
    --- /dev/null	1 Jan 1970 00:00:00 -0000
    +++ calibrate_sensors.c	1 Jan 1970 00:00:00 -0000
    @@ -0,0 +1,172 @@
    +/*
    + * c't-Sim - Robotersimulator fuer den c't-Bot
    + *
    + * This program is free software; you can redistribute it
    + * and/or modify it under the terms of the GNU General
    + * Public License as published by the Free Software
    + * Foundation; either version 2 of the License, or (at your
    + * option) any later version.
    + * This program is distributed in the hope that it will be
    + * useful, but WITHOUT ANY WARRANTY; without even the implied
    + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
    + * PURPOSE. See the GNU General Public License for more details.
    + * You should have received a copy of the GNU General Public
    + * License along with this program; if not, write to the Free
    + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
    + * MA 02111-1307, USA.
    + *
    + */
    +
    +/*! @file 	calibrate_sensors.c
    + * @brief 	Routinen zur Kalibrierung der Sensoren des c't-Bots
    + * @author 	Peter Jonas (peter.jonas@xxxxxx) und Achim Pankalla (achim.pankalla@xxxxxx)
    + * @date 	01.03.07
    +*/
    +
    +#include "ct-Bot.h"
    +
    +#include <stdio.h>
    +#include "sensor.h"
    +#include "sensor_correction.h"
    +#include "delay.h"
    +#include "display.h"
    +#include "rc5.h"
    +#include "rc5-codes.h"
    +#include "eeprom_map.h"
    +#include "parameter-low.h"
    +
    +#ifdef MCU
    +	#include <avr/eeprom.h>
    +	#include "adc.h"
    +#endif
    +
    +#ifdef PC
    +	uint16 simadcL = 0; //Speicher fuer die Analogwerte vom Ct-Sim
    +	uint16 simadcR = 0;
    +#endif
    +
    +extern uint16 RC5_Code;
    +
    +#ifdef CALIBRATE_DIST_SENSOR
    +
    +#define SAMPLES_PER_AVG    50		/*!< Anzahl der Messungen pro Abstand, die in die Mittelwertbildung eingehen */
    +
    +static uint8 actual_dist=SC_STARTDIST; /*!Nur in dieser Datei bekannte globale Variable*/
    +
    +/*!
    + * Zeigt das Ende des Kalibriervorgangs an und setzt Abbruchwert der Hauptschleife.
    + * @param mode Mode ist 1 bei vollstaendiger Kalibrierung und 0 bei Abbruch.
    + */
    +void calibrate_is_finish(uint8 mode){
    +	display_cursor(2,1);
    +	if(mode){
    +		display_printf("Messreihe komplett  ");
    +	}
    +	else {
    +		display_printf("Messreihe beendet   ");
    +		actual_dist = 0;
    +	}
    +	return;
    +}
    +/*!
    + * Aendert die Distanzwert abhaengig von par und zeigt den neuen Wert auf den Display an.
    + * @param par Bei par=3 wird die Distanz um DISTANCE_STEP erhoeht bei par=1 wird sie um
    + * DISTANCE_STEP vermindert.
    + */
    +
    +void calibrate_chng_dist(uint16 par) {
    +	switch(par) { //Distanzwert par Abhaengig veraendern.
    +		case RC5_CODE_1:
    +			if (actual_dist > SC_STARTDIST)
    +       			actual_dist -= SC_STEPWIDTH;
    +       		break;
    +       	case RC5_CODE_3:
    +			if (actual_dist == SC_STARTDIST + SC_NO_OF_STEPS * SC_STEPWIDTH) {
    +				calibrate_is_finish(1);
    +				return;
    +			}
    +			if (actual_dist < SC_STARTDIST + SC_NO_OF_STEPS * SC_STEPWIDTH)
    +       			actual_dist += SC_STEPWIDTH;
    +       		break;
    +	}
    +	display_cursor(2,1); //Ausgabe aktualisieren
    +	display_printf("Setze Abstand: %2dcm",actual_dist);
    +	return;
    +}
    +
    +/*!
    + * Kalibriert die Abstandssensoren ueber einen Mittelwert von einer bestimmten Anzahl von
    + * Messungen und schreibt den aktuellen Wert in eine Tabelle ins EEPROM.
    + * Waehrend der Messung werden die aktuellen Werte angezeigt, danach der gemittelte Wert.
    + */
    +void calibrate_act_value(void) {
    +	uint16 tmp_DistL,tmp_DistR, i;
    +	uint16 act_DistL, act_DistR; //Aktuelle Messwerte
    +
    +	for (i=0,tmp_DistL=0,tmp_DistR=0;i<SAMPLES_PER_AVG;i++) {	//Den Mittelwert aus einer Anzahl von Werten bilden
    +#ifdef MCU
    + 		act_DistL = adc_read(0);//Analogwerte vom Ct-Bot
    +		act_DistR = adc_read(1);
    +#endif
    +#ifdef PC
    +		act_DistL = simadcL; //Analogwerte vom Ct-Sim
    +		act_DistR = simadcR;
    +#endif
    +		display_cursor(3,1);
    +		display_printf("MWert L=%4d, R=%4d",act_DistL, act_DistR);	// Einzelmessung anzeigen
    +		tmp_DistL += act_DistL;
    +		tmp_DistR += act_DistR;
    +		delay(100);
    +	}
    +	tmp_DistL=tmp_DistL/SAMPLES_PER_AVG;// Mittelwert berechnen, evt. hier besseren Algorithmus verwenden
    +	tmp_DistR=tmp_DistR/SAMPLES_PER_AVG;
    +
    +	display_cursor(3,1);
    +	display_printf("EWert L=%4d, R=%4d",tmp_DistL, tmp_DistR);	// Mittelwert anzeigen
    +
    +	eeprom_write_word((uint16 *)(SCT_LEFT  +((actual_dist-SC_STARTDIST)/SC_STEPWIDTH) * 2), tmp_DistL);
    +	eeprom_write_word((uint16 *)(SCT_RIGHT +((actual_dist-SC_STARTDIST)/SC_STEPWIDTH) * 2), tmp_DistR);
    +
    +	calibrate_chng_dist(3); //Naechsten Distanzwert einstellen
    +	return;
    +}
    +
    +/*!
    + * Erstellt das Menue des Kalibrierungsprogramm auf dem Display und fragt die
    + * Fernbedienung ab.
    + */
    +void calibrate_distsensor(void){
    +//	display_screen=3;    //Start Bildschirm erstellen
    +	display_clear();
    +	delay(200); //Sonst fehlt Teil der Ausgabe auf Bot
    + 	display_cursor(1,1);
    +	display_printf("Sensorkalibrierung");
    +	display_cursor(2,1);
    +	display_printf("Setze Abstand: %2dcm", SC_STARTDIST);
    +	display_cursor(3,1);
    +	display_printf("EWert L=---- R=----");
    +	display_cursor(4,1);
    +	display_printf("<1 Mess=2 Ende=0 3>");
    +
    + 	do {                // Wiederhole den Vorgang bis er beendet oder abgebrochen wird.
    + 		delay(200);     // Bisschen einbremsen, damit PC nicht so eingebremst wird.
    +		rc5_control();	// Abfrage der IR-Fernbedienung
    +		switch(RC5_Code){
    +			case RC5_CODE_0:	calibrate_is_finish(0); break;
    +			case RC5_CODE_1:
    +			case RC5_CODE_3:	calibrate_chng_dist(RC5_Code); break;
    +			case RC5_CODE_2:	calibrate_act_value(); break;
    +			default: 			break;
    +		}
    +		RC5_Code = 0;  //Wert loeschen
    + 	}
    +	while(actual_dist);
    +	delay(5000); //Damit man das Ende noch sehen kann :-)
    +	actual_dist = SC_STARTDIST; //Alles auf Ursprungswerte setzen
    +// 	display_screen=0;    //Start Bildschirm erstellen
    +
    +	return;
    +}
    +
    +
    +#endif
    Index: pc/parameter-low_pc.c
    ===================================================================
    RCS file: pc/parameter-low_pc.c
    diff -N pc/parameter-low_pc.c
    --- /dev/null	1 Jan 1970 00:00:00 -0000
    +++ pc/parameter-low_pc.c	1 Jan 1970 00:00:00 -0000
    @@ -0,0 +1,139 @@
    +/*
    + * c't-Sim - Robotersimulator fuer den c't-Bot
    + *
    + * This program is free software; you can redistribute it
    + * and/or modify it under the terms of the GNU General
    + * Public License as published by the Free Software
    + * Foundation; either version 2 of the License, or (at your
    + * option) any later version.
    + * This program is distributed in the hope that it will be
    + * useful, but WITHOUT ANY WARRANTY; without even the implied
    + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
    + * PURPOSE. See the GNU General Public License for more details.
    + * You should have received a copy of the GNU General Public
    + * License along with this program; if not, write to the Free
    + * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
    + * MA 02111-1307, USA.
    + *
    + */
    +
    +/*! @file 	parameter-low_pc.c
    + * @brief 	Low-Level Routinen fuer den Zugriff auf das simulierte EEPROM des Sim-c't-Bots
    + * @author 	Achim Pankalla (achim.pankalla@xxxxxx)
    + * @date 	24.06.06
    +*/
    +
    +#include "ct-Bot.h"
    +
    +#ifdef PC
    +
    +#include <errno.h>
    +#include <io.h>
    +#include <sys/stat.h>
    +#include <fcntl.h>
    +#include <stdio.h>
    +
    +#define EEPROM_FILENAME	"e:\\temp\\eeprom.bin" 	/*<! Name und Pfad der EEPROM Datei. Verzeichnis muss existieren. Backslash doppeln!*/
    +
    +/*!
    + * Traegt die uebergebenen Daten in das simulierte EEPROM ein. Dieses simulierte EEPROM
    + * besteht aus einer Datei. Ist sie nicht vorhanden, so wird eine angelegt. Sie ist im Binaer
    + * Format und kann direkt mit zB. PonyProg in den realen Bot eingespielt werden.
    + * Es koennen Bytes (uint8 size = 1) und Integer (uint16 size = 2) uebergeben werden.
    + * @param address Adresse im EEPROM zwischen 0 und 1023.
    + * @param data Daten die abgelegt werden sollen.
    + * @param size Groesse der Daten in Byte.
    + */
    +static void store_parameter(uint16 address, uint16 data, uint8 size) {
    +	int16 fh = 0; 	//Dateizeiger
    +	uint16 i = 0; //Laufvariable
    +	uint8 dataline[2];	//Speicher fuer Datenausgabe
    +
    +	if(address < 0 || address > (size == 1 ? 1023 : 1022)) //Adresse checken
    +		return;
    +
    +	if(access(EEPROM_FILENAME, R_OK) == -1){ //Testen, ob Datei vorhanden ist.
    +		if((fh = open(EEPROM_FILENAME, O_BINARY|O_CREAT|O_RDWR, S_IWRITE|S_IREAD)) == -1) //wenn nicht, dann erstellen
    +			return;
    +		for(i = 0; i < 1024; i++) //Leere EEPROM Datei erstellen
    +			write(fh, "\377", 1);
    +		close(fh);
    +	}
    +	if((fh = open(EEPROM_FILENAME, O_BINARY|O_WRONLY)) == -1) //ansonsten Datei oeffnen
    +		return;
    +
    +	//Daten eintragen
    +	lseek(fh, address, SEEK_SET); //Schreibzeiger setzen
    +	dataline[0] = data%256;
    +	dataline[1] = data/256;
    +	write(fh, dataline, size);	//Daten schreiben);
    +
    +	close(fh);
    +	return;
    +}
    +
    +/*!
    + * Liest die gewuenschten Daten aus eine simulierten EEPROM. Dieses simulierte EEPROM
    + * besteht aus der Datei eeprom.bin. Ist die Datei nicht vorhanden, so wird 0x00 zurueck-
    + * gegeben
    + * @param address Adresse im EEPROM zwischen 0 und 1023.
    + * @param size Groesse der Daten in Byte.
    + * @return Aus dem EEPROM gelesener Wert.
    + */
    +static uint16 load_parameter(uint16 address, uint8 size) {
    +	int16 fh = 0; 	//Dateizeiger
    +	uint8 dataline[2] = {0,0};	//String fuer Datenausgabe
    +
    +	if(address < 0 || address > (size == 1 ? 1023 : 1022)) //Adresse checken
    +		return(0);
    +
    +	if(access(EEPROM_FILENAME, R_OK) == -1){ //Testen, ob Datei vorhanden ist.
    +		return(0);
    +	}
    +	if((fh = open(EEPROM_FILENAME, O_BINARY|O_RDONLY)) == -1) //ansonsten Datei oeffnen
    +		return(0);
    +
    +	//Daten eintragen
    +	lseek(fh, address, SEEK_SET); //Lesezeiger setzen
    +	read(fh, dataline, size);	//Daten schreiben);
    +	close(fh);
    +	return((uint16)dataline[0] + (uint16)dataline[1]*256);
    +}
    +
    +/*!
    + * Liest ein Byte aus den simulierten EEPROM
    + * @param address Adresse im EEPROM
    + * @return Aus dem EEPROM gelesener Wert.
    + */
    +uint8 eeprom_read_byte(uint8 *adr) {
    +	return((uint8)load_parameter((uint16)adr, 1));
    +}
    +
    +/*!
    + * Liest ein Word aus den simulierten EEPROM
    + * @param address Adresse im EEPROM
    + * @return Aus dem EEPROM gelesener Wert.
    + */
    +uint16 eeprom_read_word(uint16 *adr) {
    +	return(load_parameter((uint16)adr, 2));
    +}
    +
    +/*!
    + * Schreibt ein Byte in das simulierte EEPROM
    + * @param address Adresse im EEPROM
    + * @param Zu schreibender Wert.
    + */
    +void eeprom_write_byte(uint8 *adr, uint8 value) {
    +	store_parameter((uint16)adr, (uint16)value, 1);
    +}
    +
    +/*!
    + * Schreibt ein Word in das simulierte EEPROM
    + * @param address Adresse im EEPROM
    + * @param Zu schreibender Wert.
    + */
    +void eeprom_write_word(uint16 *adr, uint16 value) {
    +	store_parameter((uint16)adr, value, 2);
    +}
    +
    +#endif

- Antworten:
  - Re: [ct-bot] Re: Kalibrierung der Distanzsensren mittels EEPROM-Tabelle
    - From: Benjamin Benz
  - Re: [ct-bot] Re: Kalibrierung der Distanzsensren mittels EEPROM-Tabelle
    - From: Timo Sandmann
  - Re: [ct-bot] Re: Kalibrierung der Distanzsensren mittels EEPROM-Tabelle
    - From: Achim Pankalla

- Referenzen:
  - [ct-bot] Kaibrierung
    - From: Carsten Giesen

- Voriger (Datum): [ct-bot] CVS-Update: c't-Sim, Benjamin Benz
- Nächster (Datum): Re: [ct-bot] Re: Kalibrierung der Distanzsensren mittels EEPROM-Tabelle, Benjamin Benz
- Voriger (Thread): Re: [ct-bot] Kaibrierung, Randolf
- Nächster (Thread): Re: [ct-bot] Re: Kalibrierung der Distanzsensren mittels EEPROM-Tabelle, Benjamin Benz
- Indizes:
  - Datum
  - Thread