## c't-Projekte - Mailinglisten

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

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

Absender: Achim Pankalla
Datum: So, 06.05.2007 18:51:18
In-reply-to: <38A4BFD9-CA32-436A-9A1E-B4E6E0652A5D@xxxxxxxxxxxxxxx>
References: <BCF016D5ED5AC34FBB655D109519ABCF083EBE@xxxxxxxxxxxxxxxxxxxx> <45ED3B46.4030400@xxxxxx> <45EF385C.3080609@xxxxxx> <A2ED0A68-A8F1-438A-B1E3-18033ED489E3@xxxxxxxxxxxxxxx> <45F135B9.5030203@xxxxxx> <45F13A91.6090904@xxxxxxxx> <D053B7F5-6BDD-4052-B45F-28FCF0EF45F8@xxxxxxxxxxxxxxx> <45F2B74F.8090706@xxxxxx> <38A4BFD9-CA32-436A-9A1E-B4E6E0652A5D@xxxxxxxxxxxxxxx>

    hallo,
    nach 12 monaten arbeit (mit größeren unterbrechungen, sprich warten)
    anbei ein weiterer patch für das aktuelle cvs. er enthält mein kode für
    die sensor kalibrierung und eeprom@pc mit den letzten änderungen.
    ausserdem einige anpassungen die herr sandmann, wegen dem in newsletter
    diskutierten typenproblemen zur verfügung gestellt hat und leider noch
    nicht eingepflegt sind.
    wer spass daran hat kann der patch ja mal ausprobieren, denn nur dafür
    ist er gedacht. das nennt man wohl snapshot im it deutsch.
    damit der linker auch für den pc eine exe erstellen kann, benötigt er
    die linker-script.lk. in der doku, steht wie sie eingebunden wird. diese
    ist aber nur für die w32 eclipse umgebung getestet. für den avr braucht
    man das linker-script nicht!
    die kalibrierung wird gleich gestartet und die sensorwerte berechnung
    über tabelle ist aktiv. in der doku steht, wie man alles bedient und sie
    auch ausschaltet. nach beenden des kalibrierens mit roter taste menue
    verlassen, um zur sensorübersicht zu kommen.

    änderungen (nur das wichtigste):
    kalibrieren
    - kalibriervorgang ist ein verhalten
    - nutzt nun auch gui.c für nutzerführung
    eeprom@pc
    - einiger hr. sandmanns kritikpunkte wurden bearbeitet
    folgendes geht auch, erforderte aber keine kodeänderungen
    - eep-datei kann als eeprom simulationsdatei verwendet werden, dafür
    bitte format von -ihex auf -binary änderen
    - auch binärer abzug des ct-bot eeprom kann genutzt werden,
    vorraussetzungen sind gleiche compiler
    - docu anpassungen
    resetzähler
    -kein übersetzungsfehler bei PC kode (fehlerkorrektur)

    gruss
        a. pankalla

    /* Default linker script, for normal executables */
    OUTPUT_FORMAT(pei-i386)
    SEARCH_DIR("/mingw/mingw32/lib"); SEARCH_DIR("/mingw/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
    ENTRY(_mainCRTStartup)
    SECTIONS
    {
      .text  __image_base__ + __section_alignment__  :
      {
        *(.init)
        *(.text)
        *(SORT(.text$*))
        *(.glue_7t)
        *(.glue_7)
       	___CTOR_LIST__ = .; __CTOR_LIST__ = . ;
    			LONG (-1);
    			*(EXCLUDE_FILE (*crtend.o) .ctors);
    			*(.ctor);
    			*(SORT(.ctors.*));
    			*crtend.o (.ctors);
    			LONG (0);
        	___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
    			LONG (-1);
    			*(EXCLUDE_FILE (*crtend.o) .dtors);
    			*(.dtor);
    			*(SORT(.dtors.*));
    			*crtend.o (.dtors);
    			LONG (0);
         *(.fini)
        /* ??? Why is .gcc_exc here?  */
         *(.gcc_exc)
        *(.gcc_except_table)
      }
      /* The Cygwin32 library uses a section to avoid copying certain data
         on fork.  This used to be named ".data".  The linker used
         to include this between __data_start__ and __data_end__, but that
         breaks building the cygwin32 dll.  Instead, we name the section
         ".data_cygwin_nocopy" and explictly include it after __data_end__. */
      .data BLOCK(__section_alignment__) :
      {
        __data_start__ = . ;
        *(.data)
        *(.data2)
        *(SORT(.data$*))
        __data_end__ = . ;
        *(.data_cygwin_nocopy)
      }
      .eeprom BLOCK(__section_alignment__) :
      {
        __eeprom_start__ = . ;
        *(.eeprom)
        *(.eeprom_cygwin_nocopy)
      } =0xff
      .rdata BLOCK(__section_alignment__) :
      {
        *(.rdata)
        *(SORT(.rdata$*))
        *(.eh_frame)
        ___RUNTIME_PSEUDO_RELOC_LIST__ = .;
        __RUNTIME_PSEUDO_RELOC_LIST__ = .;
        *(.rdata_runtime_pseudo_reloc)
        ___RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
        __RUNTIME_PSEUDO_RELOC_LIST_END__ = .;
      }
      .pdata BLOCK(__section_alignment__) :
      {
        *(.pdata)
      }
      .bss BLOCK(__section_alignment__) :
      {
        __bss_start__ = . ;
        *(.bss)
        *(COMMON)
        __bss_end__ = . ;
      }
      .edata BLOCK(__section_alignment__) :
      {
        *(.edata)
      }
      /DISCARD/ :
      {
        *(.debug$S)
        *(.debug$T)
        *(.debug$F)
        *(.drectve)
      }
      .idata BLOCK(__section_alignment__) :
      {
        /* This cannot currently be handled with grouped sections.
    	See pe.em:sort_sections.  */
        SORT(*)(.idata$2)
        SORT(*)(.idata$3)
        /* These zeroes mark the end of the import list.  */
        LONG (0); LONG (0); LONG (0); LONG (0); LONG (0);
        SORT(*)(.idata$4)
        SORT(*)(.idata$5)
        SORT(*)(.idata$6)
        SORT(*)(.idata$7)
      }
      .CRT BLOCK(__section_alignment__) :
      {
        ___crt_xc_start__ = . ;
        *(SORT(.CRT$XC*))  /* C initialization */
        ___crt_xc_end__ = . ;
        ___crt_xi_start__ = . ;
        *(SORT(.CRT$XI*))  /* C++ initialization */
        ___crt_xi_end__ = . ;
        ___crt_xl_start__ = . ;
        *(SORT(.CRT$XL*))  /* TLS callbacks */
        /* ___crt_xl_end__ is defined in the TLS Directory support code */
        ___crt_xp_start__ = . ;
        *(SORT(.CRT$XP*))  /* Pre-termination */
        ___crt_xp_end__ = . ;
        ___crt_xt_start__ = . ;
        *(SORT(.CRT$XT*))  /* Termination */
        ___crt_xt_end__ = . ;
      }
      .tls BLOCK(__section_alignment__) :
      {
        ___tls_start__ = . ;
        *(.tls)
        *(.tls$)
        *(SORT(.tls$*))
        ___tls_end__ = . ;
      }
      .endjunk BLOCK(__section_alignment__) :
      {
        /* end is deprecated, don't use it */
        PROVIDE (end = .);
        PROVIDE ( _end = .);
         __end__ = .;
      }
      .rsrc BLOCK(__section_alignment__) :
      {
        *(.rsrc)
        *(SORT(.rsrc$*))
      }
      .reloc BLOCK(__section_alignment__) :
      {
        *(.reloc)
      }
      .stab BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.stab)
      }
      .stabstr BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.stabstr)
      }
      /* DWARF debug sections.
         Symbols in the DWARF debugging sections are relative to the beginning
         of the section.  Unlike other targets that fake this by putting the
         section VMA at 0, the PE format will not allow it.  */
      /* DWARF 1.1 and DWARF 2.  */
      .debug_aranges BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_aranges)
      }
      .debug_pubnames BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_pubnames)
      }
      /* DWARF 2.  */
      .debug_info BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_info) *(.gnu.linkonce.wi.*)
      }
      .debug_abbrev BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_abbrev)
      }
      .debug_line BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_line)
      }
      .debug_frame BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_frame)
      }
      .debug_str BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_str)
      }
      .debug_loc BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_loc)
      }
      .debug_macinfo BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_macinfo)
      }
      /* SGI/MIPS DWARF 2 extensions.  */
      .debug_weaknames BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_weaknames)
      }
      .debug_funcnames BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_funcnames)
      }
      .debug_typenames BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_typenames)
      }
      .debug_varnames BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_varnames)
      }
      /* DWARF 3.  */
      .debug_ranges BLOCK(__section_alignment__) (NOLOAD) :
      {
        *(.debug_ranges)
      }
    }

    ### Eclipse Workspace Patch 1.0
    #P ct-Bot
    Index: bot-logic/bot-logik.c
    ===================================================================
    RCS file: /ctbot/ct-Bot/bot-logic/bot-logik.c,v
    retrieving revision 1.4
    diff -u -r1.4 bot-logik.c
    --- bot-logic/bot-logik.c	22 Feb 2007 18:02:10 -0000	1.4
    +++ bot-logic/bot-logik.c	6 May 2007 17:19:14 -0000
    @@ -92,6 +92,12 @@
     		insert_behaviour_to_list(&behaviour, new_behaviour(253, bot_servo_behaviour,INACTIVE));
     	#endif

    +	// Verhalten zum kalibrieren der IR-Distanzsensoren.
    +	// Besitzt eine hohe Prioritaet, damit andere Verhalten den Bot nicht bewegen!
    +	#ifdef BEHAVIOUR_CALIBRATE_DSENSORS
    +		insert_behaviour_to_list(&behaviour, new_behaviour(252, bot_calibrate_dsensors_behaviour,ACTIVE));
    +	#endif
    +
     	// Demo-Verhalten, ganz einfach, inaktiv
     	// Achtung, im Moment hat es eine hoehere Prioritaet als die Gefahrenerkenner!!!
     	#ifdef BEHAVIOUR_SIMPLE_AVAILABLE
    Index: bot-logic/behaviour_servo.c
    ===================================================================
    RCS file: /ctbot/ct-Bot/bot-logic/behaviour_servo.c,v
    retrieving revision 1.1
    diff -u -r1.1 behaviour_servo.c
    --- bot-logic/behaviour_servo.c	15 Jan 2007 11:07:33 -0000	1.1
    +++ bot-logic/behaviour_servo.c	6 May 2007 17:19:13 -0000
    @@ -44,7 +44,7 @@
      */
     void bot_servo_behaviour(Behaviour_t *data){
     	/* Servo ausschalten, falls Klappe zu oder Countdown abgelaufen */
    -	if ( (servo_pos == DOOR_CLOSE && sensDoor == 0) || (TIMER_GET_TICKCOUNT_16 - servo_time > MS_TO_TICKS(1000L)) ){
    +    if (timer_ms_passed(&servo_time, 1000)) {
     		servo_set(servo_nr, SERVO_OFF);	// Servo aus
     		servo_active &= ~servo_nr;
     		return_from_behaviour(data); 	// und Verhalten auch aus
    @@ -57,6 +57,7 @@
      * @param pos Zielposition des Servos
      */
     void bot_servo(Behaviour_t * caller, uint8 servo, uint8 pos){
    +    if (pos == DOOR_CLOSE && sensDoor == 0) return;    // Klappe ist bereits geschlossen
     	servo_active |= servo;
     	servo_set(servo, pos);	// Servo-PWM einstellen
     	servo_pos = pos;		// Zielposition merken
    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 May 2007 17:19:13 -0000
    @@ -27,12 +27,20 @@

     #include "bot-logic/bot-logik.h"

    +uint8  EEPROM ALIGNED err15=1;			/*!< Fehler bei Drehungen unter 15 Grad */
    +uint8  EEPROM ALIGNED err45=2;			/*!< Fehler bei Drehungen zwischen 15 und 45 Grad */
    +uint8  EEPROM ALIGNED err_big=4;		/*!< Fehler bei groesseren Drehungen */
    +
     #ifdef BEHAVIOUR_TURN_AVAILABLE
     #ifdef MCU
     	#include <avr/eeprom.h>
     #endif
    +#ifdef PC
    +	#include "eeprom-emu.h"
    +#endif
     #include <stdlib.h>
     #include <math.h>
    +#include "eeprom_map.h"
     #include "log.h"

     /* Parameter fuer das bot_turn_behaviour() */
    @@ -42,15 +50,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,52 +149,35 @@
     				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(&err15);
    +			e45=eeprom_read_byte(&err45);
    +			ebig=eeprom_read_byte(&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(&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(&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(&err_big,ebig);
     					}
     					break;
     			}
     			// ok, verhalten beenden
    +LOG_DEBUG(("%d/%d/%d", e15, e45, ebig));
     			speedWishLeft=BOT_SPEED_STOP;
     			speedWishRight=BOT_SPEED_STOP;
      			turnState=NORMAL_TURN;
    @@ -212,34 +194,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(&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);

    -		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(&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;
    +	}
      	switch_to_behaviour(caller, bot_turn_behaviour,OVERRIDE);
      }
     #else
    Index: motor.c
    ===================================================================
    RCS file: /ctbot/ct-Bot/motor.c,v
    retrieving revision 1.14
    diff -u -r1.14 motor.c
    --- motor.c	15 Jan 2007 11:08:37 -0000	1.14
    +++ motor.c	6 May 2007 17:19:13 -0000
    @@ -196,7 +196,7 @@
     		// Hier sitzt die eigentliche Regelung
     		#ifdef SPEED_CONTROL_AVAILABLE
     			register uint16 ticks = TIMER_GET_TICKCOUNT_16;
    -			if (ticks-old_mot_ticks > MS_TO_TICKS((uint16)SPEED_CONTROL_INTERVAL)) {
    +            if ((uint16)(ticks-old_mot_ticks) > MS_TO_TICKS((uint16)SPEED_CONTROL_INTERVAL)) {
     				speed_control();
     				old_mot_ticks = TIMER_GET_TICKCOUNT_16;
     			}
    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 May 2007 17:19:12 -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

    @@ -145,8 +152,8 @@
     		// So lange Daten lesen, bis das Packet vollstaendig ist, oder der Timeout zuschlaegt
     		while (i > 0){
     			// Wenn der Timeout ueberschritten ist
    -			if (TIMER_GET_TICKCOUNT_16-old_ticks > MS_TO_TICKS(COMMAND_TIMEOUT)){
    -				LOG_DEBUG(("Timeout beim nachlesen"));
    +            if (timer_ms_passed(&old_ticks, COMMAND_TIMEOUT)) {
    +                LOG_DEBUG("Timeout beim nachlesen");
     				return -1; //	==> Abbruch
     			}
     			//	LOG_DEBUG(("%d bytes missing",i));
    @@ -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: timer.c
    ===================================================================
    RCS file: /ctbot/ct-Bot/timer.c,v
    retrieving revision 1.6
    diff -u -r1.6 timer.c
    --- timer.c	15 Jan 2007 11:08:37 -0000	1.6
    +++ timer.c	6 May 2007 17:19:13 -0000
    @@ -107,8 +107,9 @@
     		LOCK();
     		/* TickCounter [176 us] erhoehen */
     		static uint16 last_simultime=0;
    -		if (simultime < last_simultime) last_simultime -= 10000;	// der Sim setzt simultime alle 10s zurueck auf 0
    -		tickCount += MS_TO_TICKS((float)(simultime - last_simultime));
    +        float tmp = (float)simultime - (float)last_simultime;
    +        if (tmp < 0) tmp += 10000;    // der Sim setzt simultime alle 10s zurueck auf 0
    +        tickCount += MS_TO_TICKS(tmp);
     		last_simultime = simultime;
     		UNLOCK();
     	}
    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 May 2007 17:19:12 -0000
    @@ -70,6 +70,8 @@
     //#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 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 +104,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 +128,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 May 2007 17:19:13 -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 "eeprom-emu.h"
    +	#endif
    +	#include "eeprom_map.h"
    +#endif
     #include "ui/available_screens.h"
     #include "display.h"
     #include "sensor.h"
    @@ -39,7 +48,6 @@
     // Defines einiger, haeufiger benoetigter Konstanten
     #define DEG2RAD (2*M_PI/360)

    -
     int16 sensLDRL=0;		/*!< Lichtsensor links */
     int16 sensLDRR=0;		/*!< Lichtsensor rechts */

    @@ -107,6 +115,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 +131,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(sct_left)) {
    +		sensDistL = SC_STARTDIST*10;
    +	} else if (left < eeprom_read_word(&sct_left[SC_NO_OF_STEPS])) {
    +		sensDistL = SENS_IR_INFINITE;
    +	} else {
    +		//Wert aus Kalibrierdaten bestimmen
    +		for(i=0; left < eeprom_read_word(&sct_left[i]); i++ ); //Realwert suchen
    +		sensDistL = (i * SC_STEPWIDTH + SC_STARTDIST) * 10; //in mm umrechnen
    +		//Ergebnis verfeinern
    +		if(left > (eeprom_read_word(&sct_left[i]) + eeprom_read_word(&sct_left[i-1])) / 2)
    +			sensDistL -= (SC_STEPWIDTH * 10) / 2;
    +	}
    +
    +	//Rechter Sensor
    +	if (right > eeprom_read_word(sct_right)) {
    +		sensDistR = SC_STARTDIST*10;
    +	} else if (right < eeprom_read_word(&sct_right[SC_NO_OF_STEPS])) {
    +		sensDistR = SENS_IR_INFINITE;
    +	} else {
    +		//Wert aus Kalibrierdaten bestimmen
    +		for(i=0; right < eeprom_read_word(&sct_right[i]); i++ ); //Realwert suchen
    +		sensDistR = (i * SC_STEPWIDTH + SC_STARTDIST) * 10; //in mm umrechnen
    +		//Ergebnis verfeinern
    +		if(right > (eeprom_read_word(&sct_right[i]) + eeprom_read_word(&sct_right[i-1]) / 2))
    +			sensDistR -= (SC_STEPWIDTH * 10) / 2;
    +	}
    +	return;
    +}
    +#endif

     /*! Sensor_update
     * Kuemmert sich um die Weiterverarbeitung der rohen Sensordaten
    @@ -166,9 +216,7 @@
     		sensMouseX += sensMouseDX;		/*!< Mausdelta X aufaddieren */
     	#endif

    -	register uint16 ticks = TIMER_GET_TICKCOUNT_16;
    -	if (ticks-old_pos > MS_TO_TICKS(50)){
    -		old_pos = ticks;
    +    if (timer_ms_passed(&old_pos, 50)) {
     		/* Gefahrene Boegen aus Encodern berechnen */
     		diffEncL=sensEncL-lastEncL;
     		diffEncR=sensEncR-lastEncR;
    @@ -243,9 +291,7 @@
     			#endif
     		#endif
     	}
    -	ticks = TIMER_GET_TICKCOUNT_16;
    -	if (ticks-old_speed > MS_TO_TICKS(250)){
    -		old_speed=ticks;
    +    if (timer_ms_passed(&old_speed, 250)) {
     		v_enc_left=  (((sensEncL - lastEncL1) * WHEEL_PERIMETER) / ENCODER_MARKS)*4;
     		v_enc_right= (((sensEncR - lastEncR1) * WHEEL_PERIMETER) / ENCODER_MARKS)*4;
     		v_enc_center=(v_enc_left+v_enc_right)/2;
    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 May 2007 17:19:12 -0000
    @@ -32,12 +32,15 @@
     //	#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 "eeprom-emu.h"
    +	#include "eeprom_map.h"
     	#include <pthread.h>
     	#include <unistd.h>
     	#include <stdlib.h>
    @@ -82,6 +85,11 @@
     #include "gui.h"
     #include "ui/available_screens.h"

    +//Variablen fuer Resetzaehler. Sollen immer definiert sein. Nicht mit ifdef einschliessen
    +uint8  EEPROM ALIGNED eresets=0;			/*!< Anzahl der Resets seid Rücksetzen des Zählers */
    +uint8  EEPROM ALIGNED eresetinfo[10];	/*!< Registerflags der letzten 10 Resets */
    +
    +//extern uint32 _eeprom_start__;
     /*!
      * Der Mikrocontroller und der PC-Simulator brauchen ein paar Einstellungen,
      * bevor wir loslegen koennen.
    @@ -261,7 +269,6 @@
     		int slog	=0;
     		char *from = NULL;	/*!< Speichert den per -M uebergebenen Quellnamen zwischen */

    -
     		/* Die Kommandozeilenargumente komplett verarbeiten */
     		while ((ch = getopt(argc, argv, "hsTt:M:c:l:")) != -1) {
     			switch (ch) {
    @@ -404,10 +411,10 @@
     //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(&eresets)+1;
    +    eeprom_write_byte(&eresets,resets);
         /* Lege den Grund fuer jeden Reset im EEPROM ab */
    -    eeprom_write_byte(&resetInfoEEPROM+resets,reset_flag);
    +    eeprom_write_byte((uint8 *)(eresetinfo+(resets%10)),reset_flag);
     #endif

     /* Hauptschleife des Bots */
    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 May 2007 17:19:14 -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 in cm*/
    +#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 May 2007 17:19:14 -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: include/bot-local.h
    ===================================================================
    RCS file: /ctbot/ct-Bot/include/bot-local.h,v
    retrieving revision 1.16
    diff -u -r1.16 bot-local.h
    --- include/bot-local.h	25 Jan 2007 14:14:00 -0000	1.16
    +++ include/bot-local.h	6 May 2007 17:19:14 -0000
    @@ -91,7 +91,7 @@
     #define SWEEP_STATE_CHECK			1	/*!< Zustamd: Ueberpruefe Objekt vor dem Bot. */

     /* Zustaende und Konstanten fuer das bot_solve_maze_behaviour-Verhalten */
    -#define BOT_DIAMETER				12
    +#define BOT_DIAMETER				10
     #define OPTIMAL_DISTANCE			BOT_DIAMETER*12	/* etwas mehr als Bot-Durchmesser ist ideal (vergroessert aufgrund der kennlinien der sharps) */
     #define ADJUST_DISTANCE				10
     #define IGNORE_DISTANCE				240
    Index: include/global.h
    ===================================================================
    RCS file: /ctbot/ct-Bot/include/global.h,v
    retrieving revision 1.6
    diff -u -r1.6 global.h
    --- include/global.h	8 Jun 2006 16:36:38 -0000	1.6
    +++ include/global.h	6 May 2007 17:19:14 -0000
    @@ -17,14 +17,16 @@
      *
      */

    -/*! @file 	global.h
    +/* @file 	global.h
      * @brief 	Allgemeine Definitionen
      * @author 	Benjamin Benz (bbe@xxxxxxxx)
      * @date 	20.12.05
    -*/
    -
    + */
    +
     #ifndef global_H
    -	#define global_H		/*!< Bereits definiert */
    +    #define global_H
    +    #ifndef __ASSEMBLER__
    +    #include <stdint.h>

     	#ifndef MCU
     		#ifndef PC
    @@ -33,8 +35,9 @@
     	#endif

     	#ifndef WIN32
    -		typedef unsigned char byte;                       /*!< vorzeichenlose 8-Bit-Zahl */
    -		typedef byte bool;                                /*!< True/False-Aussage */
    +//        typedef unsigned char byte;        /*!< vorzeichenlose 8-Bit-Zahl */
    +//        typedef byte bool;                /*!< True/False-Aussage */
    +        #define bool byte;                /*!< True/False-Aussage */
     	#endif

     	//#define DOXYGEN		/*!< Nur zum Generieren von Doku!!!! */
    @@ -45,23 +48,41 @@
     		#define __linux__	/*!< System Linux */
     	#endif

    -	typedef unsigned char uint8;                       /*!< vorzeichenlose 8-Bit-Zahl  */
    -	typedef unsigned int word;                         /*!< vorzeichenlose 16-Bit-Zahl  */
    -	typedef signed char int8;                          /*!< vorzeichenbehaftete 8-Bit-Zahl */
    -	typedef short int int16;                           /*!< vorzeichenbehaftete 16-Bit-Zahl  */
    -
    -	typedef unsigned long uint32;		/*!< vorzeichenlose 32-Bit-Zahl  */
    -	typedef signed long int32;			/*!< vorzeichenbehaftete 32-Bit-Zahl  */
    -
    -	#define uint16                  word				/*!< Int mit 16 Bit */
    +//    deprecated!
    +//    typedef unsigned char uint8;                       /*!< vorzeichenlose 8-Bit-Zahl  */
    +//    typedef unsigned int word;                         /*!< vorzeichenlose 16-Bit-Zahl  */
    +//    typedef signed char int8;                          /*!< vorzeichenbehaftete 8-Bit-Zahl */
    +//    typedef short int int16;                           /*!< vorzeichenbehaftete 16-Bit-Zahl  */
    +//
    +//    typedef unsigned long uint32;        /*!< vorzeichenlose 32-Bit-Zahl  */
    +//    typedef signed long int32;            /*!< vorzeichenbehaftete 32-Bit-Zahl  */
    +//
    +//    #define uint16                  word                /*!< Int mit 16 Bit */
    +
    +    #define byte    uint8_t                 /*!< vorzeichenlose 8-Bit-Zahl */
    +    #define uint8   uint8_t                 /*!< vorzeichenlose 8-Bit-Zahl */
    +    #define int8    int8_t                  /*!< vorzeichenbehaftete 8-Bit-Zahl */
    +    #define uint16  uint16_t                /*!< vorzeichenlose 16-Bit-Zahl */
    +    #define int16   int16_t                 /*!< vorzeichenbehaftete 16-Bit-Zahl */
    +    #define uint32  uint32_t                /*!< vorzeichenlose 32-Bit-Zahl */
    +    #define int32   int32_t                 /*!< vorzeichenbehaftete 32-Bit-Zahl */

    -	#define True                  1						/*!< Wahr */
    -	#define False                 0						/*!< Falsch */
    +    #define True                  1         /*!< Wahr */
    +    #define False                 0         /*!< Falsch */

    -	#define On                    1						/*!< An */
    -	#define Off                   0						/*!< Aus */
    +    #define On                    1        /*!< An */
    +    #define Off                   0        /*!< Aus */

    -//	#define PI					3.14159					/*!< Kreiszahl Pi fuer trigonometrische Berechnungen */
    +//    #define PI                    3.14159    /*!< Kreiszahl Pi fuer trigonometrische Berechnungen */
     	#define binary(var,bit) ((var >> bit)&1)
     	//#define NULL 0
    -#endif
    +
    +	#define EEPROM  __attribute__ ((section (".eeprom"))) //Attribute fuer eeprom Variablen
    +	#ifdef PC
    +		#define ALIGNED  __attribute__ ((aligned(1))) //Keine Luecken zwischen Daten beim PC
    +	#else
    +		#define ALIGNED
    +	#endif
    +
    +#endif    // __ASSEMBLER__
    +#endif    // global_H
    Index: include/srf10.h
    ===================================================================
    RCS file: /ctbot/ct-Bot/include/srf10.h,v
    retrieving revision 1.1
    diff -u -r1.1 srf10.h
    --- include/srf10.h	14 Apr 2006 19:23:24 -0000	1.1
    +++ include/srf10.h	6 May 2007 17:19:14 -0000
    @@ -80,7 +80,7 @@
      * Reichweite setzen, hat auch Einfluss auf die Messdauer
      * @param millimeters Reichweite in mm
      */
    -extern void		srf10_set_range(uint16 millimeters);
    +extern void		srf10_set_range(unsigned int millimeters);

     /*!
      * Messung ausloesen
    Index: include/timer.h
    ===================================================================
    RCS file: /ctbot/ct-Bot/include/timer.h,v
    retrieving revision 1.12
    diff -u -r1.12 timer.h
    --- include/timer.h	15 Jan 2007 11:07:33 -0000	1.12
    +++ include/timer.h	6 May 2007 17:19:14 -0000
    @@ -1,5 +1,5 @@
     /*
    - * c't-Sim - Robotersimulator fuer den c't-Bot
    + * c't-Bot
      *
      * This program is free software; you can redistribute it
      * and/or modify it under the terms of the GNU General
    @@ -17,7 +17,7 @@
      *
      */

    -/*! @file 	timer.h
    +/* @file 	timer.h
      * @brief 	Timer und Zaehler
      * @author 	Benjamin Benz (bbe@xxxxxxxx)
      * @date 	26.12.05
    @@ -27,6 +27,7 @@
     #define TIMER_H_

     #include "ct-Bot.h"
    +#include <stdint.h>

     /*!
      * Makros zur Umrechnung von Ticks in ms und zurueck
    @@ -94,6 +95,52 @@
      */
     //	#define TIMER_STEPS	(1 000 000/TIMER_2_CLOCK)
     	#define TIMER_STEPS 176
    +
    +/*!
    + * @brief                Prueft, ob seit dem letzten Aufruf mindestens ms Millisekunden vergangen sind
    + * @param old_ticks        Zeiger auf eine Variable, die einen Timestamp speichern kann
    + * @param ms            Zeit in ms, die vergangen sein muss, damit True geliefert wird
    + * @return                True oder False
    + *
    + * Die Funktion aktualisiert den Timestamp, der die alte Zeit zum Vergleich speichert, automatisch,
    + * falls ms Millisekunden vergangen sind.
    + * Man verwendet sie z.B. wie folgt:
    + * static uint32 old_time;
    + * ...
    + * if (timer_ms_passed(&old_time, 50)) {
    + *         // wird alle 50 ms ausgefuehrt //
    + * }
    + */
    +static inline uint8_t __attribute__((always_inline)) timer_ms_passed(void* old_ticks, uint32_t ms) {
    +
    +    /* 8 Bit Version */
    +    if (MS_TO_TICKS(ms) < UINT8_MAX) {
    +        register uint8_t ticks = TIMER_GET_TICKCOUNT_8;
    +        if ((uint8_t)(ticks - *(uint8*)old_ticks) > MS_TO_TICKS(ms)) {
    +            *(uint8_t*)old_ticks = ticks;
    +            return True;
    +        }
    +        return False;
    +
    +    /* 16 Bit Version */
    +    } else if (MS_TO_TICKS(ms) < UINT16_MAX) {
    +        register uint16_t ticks = TIMER_GET_TICKCOUNT_16;
    +        if ((uint16_t)(ticks - *(uint16_t*)old_ticks) > MS_TO_TICKS(ms)) {
    +            *(uint16_t*)old_ticks = ticks;
    +            return True;
    +        }
    +        return False;
    +
    +    /* 32 Bit Version */
    +    } else {
    +        register uint32_t ticks = TIMER_GET_TICKCOUNT_32;
    +        if ((uint32_t)(ticks - *(uint32_t*)old_ticks) > MS_TO_TICKS(ms)) {
    +            *(uint32_t*)old_ticks = ticks;
    +            return True;
    +        }
    +        return False;
    +    }
    +}

     /*!
      * Initialisiert Timer 2 und startet ihn
    Index: ui/available_screens.h
    ===================================================================
    RCS file: /ctbot/ct-Bot/ui/available_screens.h,v
    retrieving revision 1.1
    diff -u -r1.1 available_screens.h
    --- ui/available_screens.h	22 Feb 2007 18:02:10 -0000	1.1
    +++ ui/available_screens.h	6 May 2007 17:19:14 -0000
    @@ -28,6 +28,7 @@
     #define available_screens_H_

     #include "ct-Bot.h"
    +#include "bot-logic/available_behaviours.h"

     #ifdef DISPLAY_AVAILABLE

    @@ -42,6 +43,9 @@
     //#define RESET_INFO_DISPLAY_AVAILABLE	/*!< Zeigt Informationen ueber Resets an */
     #define RAM_DISPLAY_AVAILABLE			/*!< Ausgabe des freien RAMs */

    +#ifdef BEHAVIOUR_CALIBRATE_DSENSORS			/*!< Ausgabe des Kalibriermenues*/
    +	#define DISPLAY_CALIBRATE_AVAILABLE
    +#endif
     #ifndef SPEED_CONTROL_AVAILABLE
     	#undef DISPLAY_REGELUNG_AVAILABLE
     #endif
    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 May 2007 17:19:15 -0000
    @@ -65,6 +65,8 @@

     	#ifdef RESET_INFO_DISPLAY_AVAILABLE
     		uint8 reset_flag;
    +		uint8 resets = 0;
    +
     		/*!
     		 * @brief Zeigt Informationen ueber Resets an
     		 */
    Index: ui/gui.c
    ===================================================================
    RCS file: /ctbot/ct-Bot/ui/gui.c,v
    retrieving revision 1.1
    diff -u -r1.1 gui.c
    --- ui/gui.c	22 Feb 2007 18:02:10 -0000	1.1
    +++ ui/gui.c	6 May 2007 17:19:15 -0000
    @@ -79,6 +79,9 @@
      * Traegt die Anzeige-Funktionen in das Array ein.
      */
     void gui_init(void){
    +	#ifdef DISPLAY_CALIBRATE_AVAILABLE
    +		register_screen(&calibrate_display);
    +	#endif
     	#ifdef SENSOR_DISPLAY_AVAILABLE
     		register_screen(&sensor_display);
     	#endif
    Index: mcu/sensor-low.c
    ===================================================================
    RCS file: /ctbot/ct-Bot/mcu/sensor-low.c,v
    retrieving revision 1.12
    diff -u -r1.12 sensor-low.c
    --- mcu/sensor-low.c	15 Jan 2007 11:07:33 -0000	1.12
    +++ mcu/sensor-low.c	6 May 2007 17:19:14 -0000
    @@ -148,7 +148,7 @@
     	static int16 distRight[3];

     	register uint16 dist_ticks = TIMER_GET_TICKCOUNT_16;
    -	if (dist_ticks-old_dist > MS_TO_TICKS(100)){
    +    if ((uint16)(dist_ticks-old_dist) > MS_TO_TICKS(100)){
     		// Zeit fuer naechste Messung merken
     		old_dist=dist_ticks;

    Index: include/bot-logic/available_behaviours.h
    ===================================================================
    RCS file: /ctbot/ct-Bot/include/bot-logic/available_behaviours.h,v
    retrieving revision 1.2
    diff -u -r1.2 available_behaviours.h
    --- include/bot-logic/available_behaviours.h	15 Jan 2007 11:07:34 -0000	1.2
    +++ include/bot-logic/available_behaviours.h	6 May 2007 17:19:14 -0000
    @@ -26,6 +26,8 @@

     #define BEHAVIOUR_REMOTECALL_AVAILABLE /*!< Nehmen wir Remote-kommandos entgegen?*/

    +#define BEHAVIOUR_CALIBRATE_DSENSORS /*!< Erstellen wir die Kalibriertabellen neu?*/
    +
     /* Aufgrund einer ganzen reihe von Abhaengigkeiten sollte man beim Versuch Speicher
      * zu sparen, zuerst mal bei den Hauptverhalten ausmisten, sonst kommen die
      * Unterverhalten durch die Hintertuer wieder rein
    @@ -68,6 +70,13 @@
     	#define BEHAVIOUR_SERVO_AVAILABLE
     #endif

    +#ifndef DISPLAY_AVAILABLE
    +	#undef BEHAVIOUR_CALIBRATE_DSENSORS
    +#endif
    +
    +#ifdef BEHAVIOUR_CALIBRATE_DSENSORS
    +	#undef BEHAVIOUR_SIMPLE_AVAILABLE
    +#endif

     #include "bot-logic/behaviour_simple.h"
     #include "bot-logic/behaviour_drive_square.h"
    @@ -93,6 +102,8 @@
     #include "bot-logic/behaviour_catch_pillar.h"

     #include "bot-logic/remote_calls.h"
    +
    +#include "bot-logic/behaviour_calibrate_dsensors.h"

     #endif
     #endif /*AVAILABLE_BEHAVIOURS_H_*/
    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,40 @@
    +/*
    + * 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
    +*/
    +#include "global.h"
    +
    +#ifndef eeprom_map_H_
    +#define eeprom_map_H_
    +
    +//Speicher für die Kalibriertabellen der IR-Distanzsensoren
    +extern uint16 EEPROM ALIGNED sct_left[30];	/*!< Tabelle fuer linken Sensor */
    +extern uint16 EEPROM ALIGNED sct_right[30];	/*!< Tabelle fuer rechten Sensor */
    +//Variablen für TEST_AVAILABLE_COUNTERS. Resetkontrollroutine
    +extern uint8  EEPROM ALIGNED resets;		/*!< Anzahl der Resets seid Rücksetzen des Zählers */
    +extern uint8  EEPROM ALIGNED resetinfo[10];	/*!< Registerflags der letzten 10 Resets */
    +//bot_turn_behaviour Daten
    +extern uint8  EEPROM ALIGNED err15;			/*!< Fehler bei Drehungen unter 15 Grad */
    +extern uint8  EEPROM ALIGNED err45;			/*!< Fehler bei Drehungen zwischen 15 und 45 Grad */
    +extern uint8  EEPROM ALIGNED err_big;		/*!< Fehler bei groesseren Drehungen */
    +#endif
    Index: include/eeprom-emu.h
    ===================================================================
    RCS file: include/eeprom-emu.h
    diff -N include/eeprom-emu.h
    --- /dev/null	1 Jan 1970 00:00:00 -0000
    +++ include/eeprom-emu.h	1 Jan 1970 00:00:00 -0000
    @@ -0,0 +1,55 @@
    +/*
    + * 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-emu.h
    + * @brief 	Low-Level Routinen fuer den Zugriff auf das EEPROM des c't-Bots
    + * @author 	Achim Pankalla (achim.pankalla@xxxxxx)
    + * @date 	01.03.07
    +*/
    +#ifndef eeprom_emu_H_
    +#define eeprom_emu_H_
    +
    +#ifdef PC
    +#include <stddef.h>
    +/*!
    + * 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, uint16 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);
    +
    +/*!
    + * Kopiert ein Block aus den EEPROM oder in das EEPROM
    + * @param address Adresse im Speicher.
    + * @param address Adresse im EEPROM.
    + */
    +extern void eeprom_read_block(void *pointer_ram, const void *pointer_eeprom, size_t size);
    +extern void eeprom_write_block(const void *pointer_ram, void *pointer_eeprom, size_t size);
    +
    +#endif
    +#endif
    Index: bot-logic/behaviour_calibrate_dsensors.c
    ===================================================================
    RCS file: bot-logic/behaviour_calibrate_dsensors.c
    diff -N bot-logic/behaviour_calibrate_dsensors.c
    --- /dev/null	1 Jan 1970 00:00:00 -0000
    +++ bot-logic/behaviour_calibrate_dsensors.c	1 Jan 1970 00:00:00 -0000
    @@ -0,0 +1,167 @@
    +/*
    + * 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 	behaviour_calibrate_dsensors.c
    + * @brief 	Routinen zur Kalibrierung der IR Abstandssensoren des c't-Bots
    + * @author 	Peter Jonas (peter.jonas@xxxxxx) und Achim Pankalla (achim.pankalla@xxxxxx)
    + * @date 	19.03.07
    +*/
    +
    +#include "ct-Bot.h"
    +
    +#include <stdio.h>
    +#include "sensor.h"
    +#include "sensor_correction.h"
    +#include "delay.h"
    +#include "display.h"
    +#include "gui.h"
    +#include "rc5-codes.h"
    +#include "bot-logic/available_behaviours.h"
    +#include "eeprom_map.h"
    +
    +#ifdef MCU
    +	#include <avr/eeprom.h>
    +	#include "adc.h"
    +#else
    +	#include "eeprom-emu.h"
    +#endif
    +
    +#ifdef PC
    +	uint16 simadcL = 0; //Speicher fuer die Analogwerte vom Ct-Sim
    +	uint16 simadcR = 0;
    +#endif
    +
    +//Speicher fuer die Kalibriertabellen
    +uint16 EEPROM ALIGNED sct_left[30];		/*!< Tabelle fuer linken Sensor */
    +uint16 EEPROM ALIGNED sct_right[30];	/*!< Tabelle fuer rechten Sensor */
    +
    +extern uint16 RC5_Code;
    +
    +#ifdef BEHAVIOUR_CALIBRATE_DSENSORS
    +
    +#define SAMPLES_PER_AVG    50	/*!< Anzahl der Messungen pro Abstand, die in die Mittelwertbildung eingehen */
    +
    +/*!Nur in dieser Datei bekannte globale Variable*/
    +static uint8 actual_dist=SC_STARTDIST; //Aktueller Abstandswert von der Wand
    +static uint16 DistL = 0, DistR = 0; //Messwerte der Abstandssensoren(Visualisiert im Display)
    +static uint8 cstate = 1; //Status der Kalibrierung: Messen, Idle, Messr. kompl., Messen beendet, naechster + vorheriger Abstand.
    +
    +/*!
    + * Dieses Behaviour erstellt eine Kalibrierungstabelle mit den die Sensoren angeglichen
    + * und das Rauschen behoben wird. Dafuer werden  SAMPLES_PER_AVG Werte aufgenohmen und
    + * gemittelt.
    + * Die Tabelle der Werte wird nur genutzt, wenn SENSOR_TABLE_AVAILABLE gesetzt ist.
    + * Bitte lesen Sie die Dokumentation.
    + */
    +void bot_calibrate_dsensors_behaviour(Behaviour_t *data){
    +	static uint8 counter = 0;
    +	static uint16 tmp_DistL=0, tmp_DistR=0;
    +
    +	if(cstate){  //Wenn keine Messung stattfindet IR Kodes bearbeiten
    +		switch(RC5_Code){
    +			case RC5_CODE_0:	cstate = 3; break;
    +			case RC5_CODE_1:	cstate = 5; break;
    +			case RC5_CODE_3:	cstate = 4; break;
    +			case RC5_CODE_2:	cstate = 0, counter = 0; break;
    +		}
    +	}
    +	RC5_Code = 0;  //Wert loeschen
    +
    +	switch(cstate){
    +		case 0: //Position einmessen
    +			#ifdef MCU
    +			DistL = adc_read(0);//Analogwerte vom Ct-Bot
    +			DistR = adc_read(1);
    +			#endif
    +			#ifdef PC
    +			DistL = simadcL; //Analogwerte vom Ct-Sim
    +			DistR = simadcR;
    +			#endif
    +			tmp_DistL += DistL;
    +			tmp_DistR += DistR;
    +			#ifdef MCU
    +			delay(100); //Man soll auf den Bot-Display die Werte sehen
    +			#endif
    +			if(++counter == SAMPLES_PER_AVG){ //Anzahl der Messungen erreicht
    +				DistL=tmp_DistL/SAMPLES_PER_AVG;// Mittelwert berechnen, evt. hier besseren Algorithmus verwenden
    +				DistR=tmp_DistR/SAMPLES_PER_AVG;
    +				eeprom_write_word(&sct_left[(actual_dist-SC_STARTDIST)/SC_STEPWIDTH], DistL);
    +				eeprom_write_word(&sct_right[(actual_dist-SC_STARTDIST)/SC_STEPWIDTH], DistR);
    +				cstate = 4;  //Naechsten Distanzwert einstellen
    +				counter = 0;
    +				tmp_DistL = tmp_DistR = 0;
    +			}
    +			break;
    +		case 1: //Idle, warte auf Eingabe
    +			break;
    +		case 2: //Messung komplett
    +			break;
    +		case 3: //Kalibrieren beenden
    +			deactivateBehaviour(bot_calibrate_dsensors_behaviour);
    +			actual_dist = SC_STARTDIST;
    +			break;
    +		case 4: //Naechster Abstand
    +			if (actual_dist == SC_STARTDIST + SC_NO_OF_STEPS * SC_STEPWIDTH) {
    +				cstate = 2;
    +				break;
    +			}
    +			if (actual_dist < SC_STARTDIST + SC_NO_OF_STEPS * SC_STEPWIDTH)
    +				actual_dist += SC_STEPWIDTH;
    +			cstate = 1;
    +			break;
    +		case 5: //Vorheriger Abstand
    +			if (actual_dist > SC_STARTDIST)
    +				actual_dist -= SC_STEPWIDTH;
    +			cstate = 1;
    +			break;
    +	}
    +	return;
    +}
    +
    +
    +/*!
    + * Kalibriere IR-Distanzsensoren
    + * @param caller Der obligatorische Verhaltensdatensatz des Aufrufers
    + */
    +void bot_calibrate_dsensors(Behaviour_t * caller){
    +	switch_to_behaviour(caller,bot_calibrate_dsensors_behaviour,OVERRIDE);
    +}
    +
    +/*!
    + * Diese Funktion stellt den Grundaufbau des Kalibriermenues zur Verfuegung.
    + */
    +void calibrate_display(void){
    + 	display_cursor(1,1);
    +	display_printf("Sensorkalibrierung");
    +	display_cursor(2,1);
    +	display_printf("Setze Abstand: %2dcm", actual_dist);
    +	display_cursor(3,1);
    +	switch(cstate){
    +		case 0:	display_printf("MWert L=%4d R=%4d", DistL, DistR); break;
    +		case 1:	display_printf("EWert L=%4d R=%4d", DistL, DistR); break;
    +		case 2: display_printf("Messreihe komplett  ", DistL, DistR); break;
    +		case 3: display_printf("Messreihe beendet   ", DistL, DistR); break;
    +	}
    +	display_cursor(4,1);
    +	display_printf("<1 Mess=2 Ende=0 3>");
    +	return;
    +}
    +
    +#endif
    Index: include/bot-logic/behaviour_calibrate_dsensors.h
    ===================================================================
    RCS file: include/bot-logic/behaviour_calibrate_dsensors.h
    diff -N include/bot-logic/behaviour_calibrate_dsensors.h
    --- /dev/null	1 Jan 1970 00:00:00 -0000
    +++ include/bot-logic/behaviour_calibrate_dsensors.h	1 Jan 1970 00:00:00 -0000
    @@ -0,0 +1,40 @@
    +/*
    + * 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 	19.03.06
    +*/
    +#ifndef BEHAVIOUR_CALIBRATE_DSENSORS_H_
    +#define BEHAVIOUR_CALIBRATE_DSENSORS_H_
    +
    +#include "bot-logic/available_behaviours.h"
    +
    +#ifdef BEHAVIOUR_CALIBRATE_DSENSORS
    +	/*!
    + 	* Behaviour zum Kalibrieren der IR-Distanzsensoren.
    + 	*/
    +	extern void bot_calibrate_dsensors_behaviour(Behaviour_t *data);
    +	/*!
    + 	* GU-Interface fuer das Kalibrieren der Distanzsensoren
    + 	*/
    +	extern void calibrate_display(void);
    +#endif
    +#endif
    Index: pc/eeprom-emu_pc.c
    ===================================================================
    RCS file: pc/eeprom-emu_pc.c
    diff -N pc/eeprom-emu_pc.c
    --- /dev/null	1 Jan 1970 00:00:00 -0000
    +++ pc/eeprom-emu_pc.c	1 Jan 1970 00:00:00 -0000
    @@ -0,0 +1,186 @@
    +/*
    + * 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-emu_pc.c
    + * @brief 	Low-Level Routinen fuer den Zugriff auf das emulierte EEPROM des Sim-c't-Bots
    + * @author 	Achim Pankalla (achim.pankalla@xxxxxx)
    + * @date 	21.03.07
    +*/
    +
    +#include "ct-Bot.h"
    +
    +#ifdef PC
    +
    +#include <errno.h>
    +#include <sys/stat.h>
    +#include <fcntl.h>
    +#include <stdio.h>
    +
    +#include "log.h"
    +
    +extern long _eeprom_start__;
    +
    +#ifdef __AVR_ATmega644__
    +	#define EE_SIZE 2048
    +#else
    +	#define EE_SIZE 1024
    +#endif
    +
    +#define EEPROM_FILENAME	".\\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 leereangelegt. 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) {
    +	FILE  *fpw; 	//Dateizeiger
    +	uint16 i = 0; //Laufvariable
    +	uint8 dataline[2];	//Speicher fuer Datenausgabe
    +
    +//LOG_DEBUG(("write-addr=0x%x/%d", address, data));
    +	if(address > (size == 1 ? EE_SIZE-1 : EE_SIZE-2)) //Adresse checken
    +		return;
    +
    +	if(access(EEPROM_FILENAME, R_OK) == -1){ //Testen, ob Datei vorhanden ist.
    +		if(!(fpw = fopen(EEPROM_FILENAME, "wb+"))) //wenn nicht, dann erstellen
    +			return;
    +		for(i = 0; i < EE_SIZE; i++) //Leere EEPROM Datei erstellen
    +			fwrite("\377", 1, 1, fpw);
    +		fclose(fpw);
    +	}
    +	if(!(fpw = fopen(EEPROM_FILENAME, "r+b"))) //ansonsten Datei oeffnen
    +		return;
    +
    +	//Daten eintragen
    +	fseek(fpw, address, SEEK_SET); //Schreibzeiger setzen
    +	dataline[0] = data%256;
    +	dataline[1] = data/256;
    +	fwrite(dataline, 1, size, fpw);	//Daten schreiben);
    +
    +	fclose(fpw);
    +	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 eine leere angelegt.
    + * @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) {
    +	FILE *fpr; 	//Dateizeiger
    +	uint16 i = 0; //Laufvariable
    +	uint8 dataline[2] = {0,0};	//String fuer Datenausgabe
    +
    +	if(address > (size == 1 ? EE_SIZE-1 : EE_SIZE-2)) //Adresse checken
    +		return(0);
    +
    +	if(access(EEPROM_FILENAME, R_OK) == -1){ //Testen, ob Datei vorhanden ist.
    +		if(!(fpr = fopen(EEPROM_FILENAME, "wb+"))) //wenn nicht, dann erstellen
    +			return(0);
    +		for(i = 0; i < EE_SIZE; i++) //Leere EEPROM Datei erstellen
    +			fwrite("\377", 1, 1, fpr);
    +		fclose(fpr);
    +	}
    +	if(!(fpr = fopen(EEPROM_FILENAME, "rb"))) //ansonsten Datei oeffnen
    +		return(0);
    +
    +	//Daten eintragen
    +	fseek(fpr, address, SEEK_SET); //Lesezeiger setzen
    +	fread(dataline, 1, size, fpr);	//Daten lesen);
    +	fclose(fpr);
    +//LOG_DEBUG(("load-addr=0x%x/%d", address,(uint16)dataline[0] + (uint16)dataline[1]*256));
    +	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)((uint32)adr - (uint32)&_eeprom_start__), 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)((uint32)adr - (uint32)&_eeprom_start__), 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)((uint32)adr - (uint32)&_eeprom_start__), (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)((uint32)adr - (uint32)&_eeprom_start__), value, 2);
    +}
    +
    +/*!
    + * Liest ein Speicherblock aus dem simulierte EEPROM
    + * @param pointer_ram Adresse im Hauptspeicher
    + * @param pointer_eeprom Adresse im EEPROM
    + * @param Groeße des Block.
    + */
    +void eeprom_read_block (void *pointer_ram, const void *pointer_eeprom, size_t size) {
    +	uint32 i;
    +	uint8 *ram;
    +
    +	ram = (uint8 *)pointer_ram;
    +	for(i=0; i< size; i++){
    +		ram[i]=(uint16)load_parameter((uint16)((uint32)pointer_eeprom - (uint32)&_eeprom_start__ + i), 1);
    +	}
    +}
    +
    +/*!
    + * Schreibt ein Speicherblock in das simulierte EEPROM
    + * @param pointer_ram Adresse im Hauptspeicher
    + * @param pointer_eeprom Adresse im EEPROM
    + * @param Groeße des Block.
    + */
    +void eeprom_write_block (const void *pointer_ram, void *pointer_eeprom, size_t size) {
    +	uint32 i;
    +	uint8 *ram;
    +
    +	ram = (uint8 *)pointer_ram;
    +	for(i=0; i< size; i++){
    +		store_parameter((uint16)((uint32)pointer_eeprom - (uint32)&_eeprom_start__ + i), (uint16)ram[i] ,1);
    +	}
    +}
    +
    +#endif

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

- Referenzen:
  - [ct-bot] Kaibrierung
    - From: Carsten Giesen
  - [ct-bot] Re: Kalibrierung der Distanzsensren mittels EEPROM-Tabelle
    - From: Achim Pankalla
  - Re: [ct-bot] Re: Kalibrierung der Distanzsensren mittels EEPROM-Tabelle
    - From: Achim Pankalla
  - 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
  - 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
  - Re: [ct-bot] Re: Kalibrierung der Distanzsensren mittels EEPROM-Tabelle
    - From: Timo Sandmann

- Voriger (Datum): [ct-bot] Neue Funktionen der c't-Bot-Webseite: Wiki, Bugreporter und Umzug des Codes, Benjamin Benz
- Nächster (Datum): [ct-bot] Kalibrierung der Distanzsensren mittels EEPROM-Tabelle, Achim Pankalla
- Voriger (Thread): Re: [ct-bot] ct-Bot-Protokoll, Timo Sandmann
- Nächster (Thread): Re: [ct-bot] Kalibrierung der Distanzsensren mittels EEPROM-Tabelle, Timo Sandmann
- Indizes:
  - Datum
  - Thread