/****************************************************************************
 *
 * Projekt			:	Magnetfeldmessgerät
 * Dateiname		:	objSample.c
 * Autor			:	orginal MHoffmann, abgeändert für dieses Projekt Eros Schatzmayer
 * Erstellungsdatum	:	17.04.2019
 * Beschreibung		:	"Messung der Magnetfelder Dauermagnet und Spule"
 *
 *
 * Versionsgeschichte
 * 	Revision 1.0	10.06.2020
 *
 ****************************************************************************/

/****************************************************************************/
/* COMPILER Direktiven */

/****************************************************************************/
/* INCLUDE Dateien */
#include "ObjSample.h"
#include <stdio.h>
#include <stdlib.h>

/****************************************************************************/
/* KONSTANTEN */
uint16_t		gudt_eeprAdr[8] = {0x0016, 0x0021, 0x002C, 0x0037, 0x0042, 0x004D, 0x0058, 0x0063};
uint16_t		gudt_adcIdeal[8] = {279, 302, 332, 364, 551, 646, 802, 1023};

/****************************************************************************/
/* Globale Variablen */
tObjSmplIntf 	gudt_ObjSmplIntf;
//tTestParameter  gudt_TestPara;
tEEData			gudt_IntEedata;
uint16_t		gudt_hall[10];
//uint16_t		gudt_temp;

// Defaulttestparameter. koennen auch per Monitor geaendert werden
/*const tTestParameter gudt_TestParaDefault = 
{	{(int16_t)-25, (int16_t)-25},							// min 
	{(int16_t)25, (int16_t)25}, 							// max
	(uint8_t)1,												// tol
	(int16_t)0												// kal offset
};	*/	// Default Prueflimits 

// Defaulttestparameter. koennen auch per Monitor geaendert werden
/*const tTestParameter gudt_TestParaDefault =
{	{(int16_t)700, (int16_t)500},						// min
{(int16_t)800, (int16_t)600}, 							// max
};		// Default Prueflimits
*/
const tTestParameterDM gudt_TestParaDMDefault =
{	{(int16_t)700},	//min 
	{(int16_t)800}	//max					
};		// Default Prueflimits Dauermagnet

const tTestParameterCoil gudt_TestParaCoilDefault =
{	{(int16_t)500},	//min 
	{(int16_t)600},	//max					
};		// Default Prueflimits Spule

/****************************************************************************/
/* Funktionen */
static void ObjSample_Check(void);
static uint16_t ObjSample_ExtEepromGetNextWritePos(void);

void ObjSample_Init(void)
{
	//Parameter aus EEPROM laden und pruefen - ggf. wiederherstellen
	ObjSample_InitParameter();
}

int16_t ObjSample_GetHallOffset(void)
{
	uint16_t    u16_avg, tmp;						
	uint16_t	u16_offsetLast = 512;		// Zwischenspeicher zur Differenzberechnung
	uint8_t		u8_index = 0;				// Index der Schreibposition im Ringbuffer
	uint8_t		u8_offsetFlag = 0;
	uint8_t		i, j;
		
	//Richtigen ADC-Kanal auswählen
	DrvAdc_Select(ADC_U_OFFSET);

	while (u8_offsetFlag == 0)
	{
		gudt_hall[u8_index] = DrvAdc_Read();
		gudt_hall[u8_index] = ObjSample_compOffs(gudt_hall[u8_index]);
		
		// Schleife soll verlassen werden, sobald ein neues Ventil aufgesteckt wird
		if (abs(u16_offsetLast - gudt_hall[u8_index]) > 4)
		{
			u8_offsetFlag = 1;
		}
				
		u16_offsetLast = gudt_hall[u8_index];
		u8_index++;
		u8_index = u8_index % 10;
		_delay_ms(100);
	}
	
	// Array sortieren, so können Spitzenwerte, die beim Aufstecken des Ventils entstehen und den Offset beeinflussen eliminiert werden
	for (i = 1; i < 10 ; i++)
	{
		for (j = 0; j < 10 - i ; j++)
		{
			if (gudt_hall[j] > gudt_hall[j+1])
			{
				tmp = gudt_hall[j];
				gudt_hall[j] = gudt_hall[j+1];
				gudt_hall[j+1] = tmp;
			}
		}
	}
		
	//ADC anhalten
	DrvAdc_Stop();
	
	// Mittelwert berechnen
	u16_avg = (gudt_hall[1]+gudt_hall[2]+gudt_hall[3]+gudt_hall[4]+gudt_hall[5]+gudt_hall[6]+gudt_hall[7]+gudt_hall[8])/8;
	
	return u16_avg;
}

int16_t ObjSample_TempCompDM(int16_t i16_DMUnComp)
/*============================================================================
 *
 *  Funktion:		ObjSample_TempCompDM
 *  Ü-Parameter:	Unkompensierter H-Feld Wert des Dauermagneten in Gauss
 *  R-Parameter:	Temperaturkompensierter H-Feld Wert des Dauermagneten in Gauss
 *  Beschreibung:	Die Funktion erhält den bereits umgerechneten H-Feld Wert
 *					und berechnet den theoretischen Wert bei 20°C
 *
 *	Messdaten, welche zu dieser Kompansationsmethode fuehrten:
 *	Durchschnittlicher H-Feldabfall bei 4 gemessenen Kunststoffventilen bei Erwärmung von 19 auf 40°C:
 *		- Dauermagnet hat ca. 0.4% Verlust => 0.020% Verlust pro Kelvin
 *		- Elektromagnet hat ca. 5.6% Verlust => 0.267% Verlust pro Kelvin
 *==========================================================================*/
{
	int16_t i16_Temperature;
	int16_t	i16_DMComp = i16_DMUnComp;
	
	//Temperatur auslesen
	i16_Temperature = DrvRtc_GetTemp();

	// Ist die Temperatur höher als 20°C wird der Faktor zum aktuellen H-Feld Wert dazuaddiert (H-Feld bei 20°C ist grösser als gemessener Wert bei erhöhter Temp.)
	if (i16_Temperature > 20)
	{
		//Differenz bilden
		i16_Temperature = i16_Temperature - 20;
		
		//Temperaturkompensation
		i16_DMComp = i16_DMUnComp + i16_DMUnComp * i16_Temperature / 5000;
	}
	// Ist die Temperatur geringer als 20°C wird der Faktor vom aktuellen H-Feld Wert subtrahiert (H-Feld bei 20°C ist kleiner als gemessener Wert bei niedriger Temp.)
	else if (i16_Temperature < 20)
	{
		//Differenz bilden
		i16_Temperature = 20 - i16_Temperature;
		
		//Temperaturkompensation
		i16_DMComp = i16_DMUnComp - i16_DMUnComp * i16_Temperature / 5000;
	}
	
	
	return i16_DMComp;
}
int16_t ObjSample_TempCompS(int16_t i16_SUnComp)
/*============================================================================
 *
 *  Funktion:		ObjSample_TempCompDM
 *  Ü-Parameter:	Unkompensierter H-Feld Wert des Dauermagneten in Gauss
 *  R-Parameter:	Temperaturkompensierter H-Feld Wert des Dauermagneten in Gauss
 *  Beschreibung:	Die Funktion erhält den bereits umgerechneten H-Feld Wert
 *					und berechnet den theoretischen Wert bei 20°C
 *
 *	Messdaten, welche zu dieser Kompansationsmethode fuehrten:
 *	Durchschnittlicher H-Feldabfall bei 4 gemessenen Kunststoffventilen bei Erwärmung von 19 auf 40°C:
 *		- Dauermagnet hat ca. 0.4% Verlust => 0.020% Verlust pro Kelvin
 *		- Elektromagnet hat ca. 5.6% Verlust => 0.267% Verlust pro Kelvin
 *==========================================================================*/
{
	int16_t i16_Temperature;
	int16_t	i16_SComp = i16_SUnComp;
	
	//Temperatur auslesen
	i16_Temperature = DrvRtc_GetTemp();

	// Ist die Temperatur höher als 20°C wird der Faktor zum aktuellen H-Feld Wert dazuaddiert (H-Feld bei 20°C ist grösser als gemessener Wert bei erhöhter Temp.)
	if (i16_Temperature > 20)
	{
		//Differenz bilden
		i16_Temperature = i16_Temperature - 20;
		
		//Temperaturkompensation
		i16_SComp = i16_SUnComp + i16_SUnComp * i16_Temperature * 267 / 100000;
	}
	// Ist die Temperatur geringer als 20°C wird der Faktor vom aktuellen H-Feld Wert subtrahiert (H-Feld bei 20°C ist kleiner als gemessener Wert bei niedriger Temp.)
	else if (i16_Temperature < 20)
	{
		//Differenz bilden
		i16_Temperature = 20 - i16_Temperature;
		
		//Temperaturkompensation
		i16_SComp = i16_SUnComp + i16_SUnComp * i16_Temperature * 267 / 100000;
	}
	
	
	return i16_SComp;
}
int16_t ObjSample_Adc2Gauss(int16_t adcValue)
/*============================================================================
 *
 *  Funktion:		ObjSample_Adc2Gauss
 *  Ü-Parameter:	Vom ADC ausgelesener Digitalwert
 *  R-Parameter:	umgerechneter H-Feld Wert in Gauss
 *  Beschreibung:	Die Funktion erhält den ADC Wert des H-Feldes und rechnet ihn in einen
 *					Wert in Gauss um.
 *==========================================================================*/
{	
	float sensitivity = 0.00125;		// Sensitivität Hall-Sensor in [V/G]
	float lsb = 3.3 / 1024;	// Auflösung ADC in [V/Digit]
	int16_t res = 0;
	
	res = lsb * adcValue / sensitivity;
	
	// Die Differenz zwischen der Hälfte des ADC-Werts und dem gemessenen Wert bildet den Effektiven Wert in Gauss, da
	// Der Sensor im Leerlauf im Bereich 512 liegt. Wird ein Magnetfeld erzeugt, schlägt er in die positive bzw negative
	// Richtung aus (je nach Magnetfeld)
	
	return (int16_t)res;
}

int16_t ObjSample_calib(void)
/*============================================================================
 *
 *  Funktion:		ObjSample_calib
 *  Ü-Parameter:	
 *  R-Parameter:	
 *  Beschreibung:	Der ADC hat einen negativ Gain, da der Offset mit steigendem
					Spannungswert am ADC Kanal immer kleiner wird. Über einen
					Spannungsteiler und einem Hex Rotary Switch werden 8 verschiedene
					Spannungsreferenzen zugeschaltet. Diese ADC Werte werden im EEPROM
					abgelegt und zur Berechnung der Kompensationsfaktoren verwendet.
 *==========================================================================*/
{
	int16_t i16_measVal = 0;
	uint8_t u8_calibFlag = 1;
	char	val[10];
	
	ObjLcd_ClearDispBuf();
	ObjLcd_SetBufPos(0,0);
	ObjLcd_Puts("Kalibration");
	ObjLcd_SetBufPos(1,0);
	ObjLcd_Puts("Drehschalter auf 1");
	ObjLcd_Handler();
	
	DrvAdc_Select(ADC_U_CALIB);		//Richtigen ADC Kanal auswählen
	
	// Stellung 1
	while (u8_calibFlag == 1)
	{
		_delay_ms(1000);
		i16_measVal = DrvAdc_Read();
	
		if (i16_measVal > 265 && i16_measVal < 285)
		{
			ObjLcd_ClearDispBuf();					//Bildschirm loeschen
			ObjLcd_SetBufPos(0,0);
			
			// Wert ins EEPROM schreiben
			eeprom_write_word(gudt_eeprAdr[0], (uint16_t)i16_measVal);
			 
			u8_calibFlag = 3;
			
			// Ausgabe
			// Konvertiert den gemessenen 16 Bit integer Wert in einen dezimalen String
			// 2 = binary
			// 10 = decimal
			// 16 = hexadecimal
			itoa(i16_measVal,val,10);
			ObjLcd_Puts("ADC Value: ");
			ObjLcd_Puts(val);
			
			ObjLcd_SetBufPos(1,0);
			ObjLcd_Puts("Drehschalter auf 3");
			ObjLcd_Handler();		
		}	
	}
	
	// Stellung 3
	while (u8_calibFlag == 3)
	{	
		_delay_ms(1000);
		i16_measVal = DrvAdc_Read();
	
		if (i16_measVal > 320 && i16_measVal < 345)
		{
			ObjLcd_ClearDispBuf();					//Bildschirm loeschen
			ObjLcd_SetBufPos(0,0);			

			// Wert ins EEPROM schreiben
			eeprom_write_word(gudt_eeprAdr[2], (uint16_t)i16_measVal);
			  
			u8_calibFlag = 5;
			
			// Ausgabe
			// Konvertiert den gemessenen 16 Bit integer Wert in einen dezimalen String
			// 2 = binary
			// 10 = decimal
			// 16 = hexadecimal
			itoa(i16_measVal,val,10);
			ObjLcd_Puts("ADC Value: ");
			ObjLcd_Puts(val);
			
			ObjLcd_SetBufPos(1,0);
			ObjLcd_Puts("Drehschalter auf 5");	
			ObjLcd_Handler();	
		}	
	}
	
	// Stellung 5
	while (u8_calibFlag == 5)
	{	
		_delay_ms(1000);
		i16_measVal = DrvAdc_Read();
	
		if (i16_measVal > 285 && i16_measVal < 315)
		{
			ObjLcd_ClearDispBuf();					//Bildschirm loeschen
			ObjLcd_SetBufPos(0,0);
			
			// Wert ins EEPROM schreiben
			eeprom_write_word(gudt_eeprAdr[1], (uint16_t)i16_measVal);
			 
			u8_calibFlag = 7;
			
			// Ausgabe
			// Konvertiert den gemessenen 16 Bit integer Wert in einen dezimalen String
			// 2 = binary
			// 10 = decimal
			// 16 = hexadecimal
			itoa(i16_measVal,val,10);
			ObjLcd_Puts("ADC Value: ");
			ObjLcd_Puts(val);
			
			ObjLcd_SetBufPos(1,0);
			ObjLcd_Puts("Drehschalter auf 7");	
			ObjLcd_Handler();	
		}	
	}
	
	// Stellung 7
	while (u8_calibFlag == 7)
	{	
		_delay_ms(1000);
		i16_measVal = DrvAdc_Read();
	
		if (i16_measVal > 350 && i16_measVal < 380)
		{
			ObjLcd_ClearDispBuf();					//Bildschirm loeschen
			ObjLcd_SetBufPos(0,0);
			
			// Wert ins EEPROM schreiben
			eeprom_write_word(gudt_eeprAdr[3], (uint16_t)i16_measVal);
			    
			u8_calibFlag = 9;
			
			// Ausgabe
			// Konvertiert den gemessenen 16 Bit integer Wert in einen dezimalen String
			// 2 = binary
			// 10 = decimal
			// 16 = hexadecimal
			itoa(i16_measVal,val,10);
			ObjLcd_Puts("ADC Value: ");
			ObjLcd_Puts(val);
			
			ObjLcd_SetBufPos(1,0);
			ObjLcd_Puts("Drehschalter auf 9");	
			ObjLcd_Handler();	
		}	
	}
	
	// Stellung 9
	while (u8_calibFlag == 9)
	{	
		_delay_ms(1000);
		i16_measVal = DrvAdc_Read();
	
		if (i16_measVal > 540 && i16_measVal < 565)
		{
			ObjLcd_ClearDispBuf();					//Bildschirm loeschen
			ObjLcd_SetBufPos(0,0);
			
			// Wert ins EEPROM schreiben
			eeprom_write_word(gudt_eeprAdr[4], (uint16_t)i16_measVal);
			
			u8_calibFlag = 11;
			
			// Ausgabe
			// Konvertiert den gemessenen 16 Bit integer Wert in einen dezimalen String
			// 2 = binary
			// 10 = decimal
			// 16 = hexadecimal
			itoa(i16_measVal,val,10);
			ObjLcd_Puts("ADC Value: ");
			ObjLcd_Puts(val);
			
			ObjLcd_SetBufPos(1,0);
			ObjLcd_Puts("Drehschalter auf B");	
			ObjLcd_Handler();	
		}	
	}
	
	// Stellung B
	while (u8_calibFlag == 11)
	{	
		_delay_ms(1000);
		i16_measVal = DrvAdc_Read();
	
		if (i16_measVal > 790 && i16_measVal < 810)
		{
			ObjLcd_ClearDispBuf();					//Bildschirm loeschen
			ObjLcd_SetBufPos(0,0);
			
			// Wert ins EEPROM schreiben
			eeprom_write_word(gudt_eeprAdr[6], (uint16_t)i16_measVal);
			 
			u8_calibFlag = 13;
			
			// Ausgabe
			// Konvertiert den gemessenen 16 Bit integer Wert in einen dezimalen String
			// 2 = binary
			// 10 = decimal
			// 16 = hexadecimal
			itoa(i16_measVal,val,10);
			ObjLcd_Puts("ADC Value: ");
			ObjLcd_Puts(val);
			
			ObjLcd_SetBufPos(1,0);
			ObjLcd_Puts("Drehschalter auf D");	
			ObjLcd_Handler();	
		}	
	}
	
	// Stellung D
	while (u8_calibFlag == 13)
	{	
		_delay_ms(1000);
		i16_measVal = DrvAdc_Read();
	
		if (i16_measVal > 635 && i16_measVal < 650)
		{
			ObjLcd_ClearDispBuf();					//Bildschirm loeschen
			ObjLcd_SetBufPos(0,0);
			
			// Wert ins EEPROM schreiben
			eeprom_write_word(gudt_eeprAdr[5], (uint16_t)i16_measVal);
			 
			u8_calibFlag = 15;
			
			// Ausgabe
			// Konvertiert den gemessenen 16 Bit integer Wert in einen dezimalen String
			// 2 = binary
			// 10 = decimal
			// 16 = hexadecimal
			itoa(i16_measVal,val,10);
			ObjLcd_Puts("ADC Value: ");
			ObjLcd_Puts(val);
			
			ObjLcd_SetBufPos(1,0);
			ObjLcd_Puts("Drehschalter auf F");	
			ObjLcd_Handler();	
		}	
	}
	
	// Stellung F
	while (u8_calibFlag == 15)
	{	
		_delay_ms(1000);
		i16_measVal = DrvAdc_Read();
	
		if (i16_measVal > 1010 && i16_measVal < 1024)
		{
			ObjLcd_ClearDispBuf();					//Bildschirm loeschen
			ObjLcd_SetBufPos(0,0);
			
			// Wert ins EEPROM schreiben
			eeprom_write_word(gudt_eeprAdr[7], (uint16_t)i16_measVal);
			 
			u8_calibFlag = 0;
			
			// Ausgabe
			// Konvertiert den gemessenen 16 Bit integer Wert in einen dezimalen String
			// 2 = binary
			// 10 = decimal
			// 16 = hexadecimal
			itoa(i16_measVal,val,10);
			ObjLcd_Puts("ADC Value: ");
			ObjLcd_Puts(val);
			
			ObjLcd_SetBufPos(1,0);
			ObjLcd_Puts("Kalibration Ende");	
			ObjLcd_Handler();
			_delay_ms(2000);	
		}	
	}
}

int16_t ObjSample_compOffs(int16_t i16_adcVal)
/*============================================================================
 *
 *  Funktion:		ObjSample_compOffs
 *  Ü-Parameter:	
 *  R-Parameter:	i16_realVal
 *  Beschreibung:	Holt die Referenzspannungswerte aus dem EEPROM und bildet 
					die entsprechenden Kompensationsfaktoren, mit denen ein
					gemessener ADC Wert multipliziert werden muss, um den realen,
					korrekten Wert zu erhalten.
 *==========================================================================*/
{
	int16_t i16_adcReal[8], i16_realVal;
	uint8_t i;
	float compFac[8];
	
	for (i = 0; i < 8; i++)
	{
		i16_adcReal[i] = (int16_t)eeprom_read_word(gudt_eeprAdr[i]);
		compFac[i] = (float)gudt_adcIdeal[i]/(float)i16_adcReal[i];
	}
	
	if (i16_adcVal > 0 && i16_adcVal < 280)
	{
		i16_realVal = i16_adcVal * compFac[0];
	}
	if (i16_adcVal > 280 && i16_adcVal < 303)
	{
		i16_realVal = i16_adcVal * compFac[1];
	}
	if (i16_adcVal > 303 && i16_adcVal < 333)
	{
		i16_realVal = i16_adcVal * compFac[2];
	}
	if (i16_adcVal > 333 && i16_adcVal < 365)
	{
		i16_realVal = i16_adcVal * compFac[3];
	}
	if (i16_adcVal > 365 && i16_adcVal < 552)
	{
		i16_realVal = i16_adcVal * compFac[4];
	}
	if (i16_adcVal > 552 && i16_adcVal < 647)
	{
		i16_realVal = i16_adcVal * compFac[5];
	}
	if (i16_adcVal > 647 && i16_adcVal < 803)
	{
		i16_realVal = i16_adcVal * compFac[6];
	}
	if (i16_adcVal > 803)
	{
		i16_realVal = i16_adcVal * compFac[7];
	}
	
	return i16_realVal;
}

int16_t ObjSample_HallRead(uint8_t u8_type, int16_t i16_offsetHall)
{
	int16_t i16_measVal = 0;
	int16_t i16_measValDM = 0;
	uint16_t u16_timer = 0;
	int8_t i8_pol_dm = 0;
	uint8_t u8_CoilFlag = 0;
	
	switch (u8_type)
	{
		// Hall-Messung und Temperaturkompensation des Dauermagnets
		case DAUERMAGNET:
		{
			// Setzt rote LED, so dass der Ring orange leuchtet --> signalisiert Messung
			SET_LED_GN;
			SET_LED_RT;
		
			// Messung starten
			DrvAdc_Select(ADC_U_HALL);		//Richtigen ADC Kanal auswählen
			i16_measVal = DrvAdc_Read();
			
			// Polung des Dauermagnets überprüfen
			if (i16_measVal < 500) i8_pol_dm = 1;
			else if(i16_measVal > 600) i8_pol_dm = 2;
			
			// Prüfen ob Magnet richtig gepolt
			if (i8_pol_dm == 1)
			{
				// Gain Offset Kompensieren
				i16_measVal = ObjSample_compOffs(i16_measVal);
				i16_measVal = i16_offsetHall - i16_measVal;
			}
			// Wenn Dauermagnet falsch gepolt, Rote LED 2x aufblinken und Ausgabe, dass der Magnet verpolt ist
			else if(i8_pol_dm == 2)
			{
				ObjLcd_ClearDispBuf();					//Bildschirm loeschen
				ObjLcd_SetBufPos(0,0);
				ObjLcd_Puts("Dauermagnet verpolt!");
				ObjLcd_Handler();
				
				u16_timer = DrvTim_StartTimer();
				while (DrvTim_ReadTimer(u16_timer) < 5000)
				{
					// Blink
					CLR_LED_RT;
					_delay_ms(100);
					SET_LED_RT;
					_delay_ms(100);
				}
				break;
			}
			
			// Umrechnung Digitaler Wert in Gauss
			i16_measVal = ObjSample_Adc2Gauss(i16_measVal);
			
			// Temperaturkompensation
			i16_measVal = ObjSample_TempCompDM(i16_measVal);
			
			// In der Struktur ablegen
			gudt_ObjSmplIntf.udt_TD.i16_measured_Values[0] = i16_measVal;	
			
			// Prüfung Messresultat
			ObjSample_CheckDM();			
			
			// Ausgabe am Display
			ObjSample_Ausgabe(DAUERMAGNET, i16_measVal);
			
			// PASS/FAIL Auswertung
			ObjSample_PassFail(DAUERMAGNET);
			
			break;
		}
		case SPULE:
		{		
			// Spulenspannung ausschalten
			CLR_U_EXT;
			
			// Dauermagnet nochmal messen
			DrvAdc_Select(ADC_U_HALL);
			i16_measValDM = DrvAdc_Read();
			i16_measValDM = ObjSample_compOffs(i16_measValDM);
			
			// Spannung auf die Zylinderspule geben
			SET_U_EXT;
			
			u16_timer = DrvTim_StartTimer();
			while(DrvTim_ReadTimer(u16_timer) < 15000 && u8_CoilFlag == 0)
			{
				i16_measVal = DrvAdc_Read();
				if(i16_measVal < 100)
				{
					// CoiFlag signalisiert eingestecktes Ventil
					u8_CoilFlag = 1;
					
					// Spulenspannung ausschalten
					CLR_U_EXT;
					
					// Kompensation ADC Gain
					i16_measVal = ObjSample_compOffs(i16_measVal);
			
					// Berechnung des effektiven Spulenwerts
					i16_measVal = i16_measValDM - i16_measVal;
			
					// Digitaler ADC Wert in Gauss Wert umrechnen
					i16_measVal = ObjSample_Adc2Gauss(i16_measVal);
			
					// Temperaturkompensation
					i16_measVal = ObjSample_TempCompS(i16_measVal);
			
					// In der Struktur ablegen
					gudt_ObjSmplIntf.udt_TD.i16_measured_Values[1] = i16_measVal;
			
					// Zeitstempel holen
					DrvRtc_GetDateTime(&gudt_ObjSmplIntf.udt_TD.TS);
			
					// Resultate prüfen
					ObjSample_CheckCoil();
			
					// Ausgabe am Display
					ObjSample_Ausgabe(SPULE, i16_measVal);
			
					//PASS/FAIL Auswertung
					ObjSample_PassFail(SPULE);
			
					// Testdaten ins EEPROM schreiben
					ObjSample_SaveTestData();
				}
			}
			
			CLR_U_EXT;
			break;
		}
	}
	
	//ADC anhalten
	DrvAdc_Stop();
	
	return i16_measVal;
}
/*============================================================================
 *
 *  Funktion:		ObjSample_Ausgabe
 *  Ü-Parameter:	u8_type
 *  R-Parameter:	-
 *  Beschreibung:	die Messdaten am Display ausgeben
 *==========================================================================*/
void ObjSample_Ausgabe(uint8_t u8_type, int16_t i16_measVal)
{
	char		hallDM[10];
	char		hallS[10];

	switch (u8_type)
	{
		case DAUERMAGNET:
		{
			// Zeile 1 löschen
			ObjLcd_ClearDispBufZeile1();
			
			// Konvertiert den gemessenen 16 Bit integer Wert in einen dezimalen String
			// 2 = binary
			// 10 = decimal
			// 16 = hexadecimal
			itoa(i16_measVal,hallDM,10);
			ObjLcd_SetBufPos(0,0);
			ObjLcd_Puts("H-Feld DM: ");
			ObjLcd_Puts(hallDM);
			break;
		}
		case SPULE:
		{
			// Zeile 2 löschen
			ObjLcd_ClearDispBufZeile2();
			
			// Ausgabe
			// Konvertiert den gemessenen 16 Bit integer Wert in einen dezimalen String
			// 2 = binary
			// 10 = decimal
			// 16 = hexadecimal
			itoa(i16_measVal,hallS,10);
			ObjLcd_SetBufPos(1,0);
			ObjLcd_Puts("H-Feld S: ");
			ObjLcd_Puts(hallS);
			break;
		}
	}
	
	ObjLcd_Handler();
	_delay_ms(100);
}

/*============================================================================
 *
 *  Funktion:		ObjSample_PassFail
 *  Ü-Parameter:	-
 *  R-Parameter:	-
 *  Beschreibung:	Gibt Anhand des roten/grünen Lichts eine Aussage
 *					ob die Messung PASS oder FAIL war
 *==========================================================================*/
void ObjSample_PassFail(uint8_t u8_type)
{
	switch(u8_type)
	{
		case DAUERMAGNET:
		{
			if(gudt_ObjSmplIntf.udt_TD.u8_ResultDM != 0)
			{
				SET_LED_RT;
				CLR_LED_GN;
				_delay_ms(2000);
			}
			else
			{
				SET_LED_GN;
				SET_LED_RT;
			}
			break;
		}
		case SPULE:
		{
			if(gudt_ObjSmplIntf.udt_TD.u8_ResultCoil != 0)
			{
				SET_LED_RT;
				_delay_ms(2000);
			}
			else
			{
				CLR_LED_RT;
				SET_LED_GN;
				_delay_ms(2000);
			}
			break;
		}
	}
}

/*int16_t ObjSample_Handler(void)
{
	int16_t i16_retval = 0;
	int16_t i16_Poti[OBJSAMPLE_POTI_CNT];
	uint8_t i;	//Schleifenvariable
	int16_t i16_Poti_kontrolle;
	
	//Bei Taste oder Endschalter die Messung starten (solange messen, bis zwei aufeinanderfolgende Messungen identisch sind)
	if(gudt_GpioIntf.u8_Key || (gudt_GpioIntf.u8_Endschlater && gudt_auto_start == 1))		
	{
		gudt_auto_start = 0;
		//Anzeige, dass wir im Messmode sind
		SET_LED_RT;
		SET_LED_GN;
		ObjLcd_ClearDispBuf();					//Bildschirm loeschen
				
		//warten, bis Taste wieder losgelassen
		while(gudt_GpioIntf.u8_Key != 0 )
		{
			// Tastenzustand aktualisieren; Abbruch, wenn Kalibrierung lief
			if(DrvGpio_Handler() == DRVGPIO_CALIB_DONE)
			{
				_delay_ms(1000);
				CLR_LED_GN;
		
				return i16_retval;
			}
		}

		 		//ADC auslesen, Kalibrierung anwenden
 		i16_Poti_kontrolle = DrvAdc_ReadPoti(0,DRVADC_FLAG_USE_NO_CALIB);

		if (i16_Poti_kontrolle > OBJSAMPLE_NO_BATBOX)		//Toleranz des Poti0
		{
			//1. Messungen durchfuehren
			for (i = 0; i < OBJSAMPLE_POTI_CNT; i++)
			{
				//ADC auslesen, Kalibrierung anwenden
				i16_Poti[i] = DrvAdc_ReadPoti(i, DRVADC_FLAG_USE_CALIB);
			}
			_delay_ms(100);
			
			//2. Messung durchfuehren
			for (i = 0; i < OBJSAMPLE_POTI_CNT; i++)
			{
				//ADC auslesen, Kalibrierung anwenden
				gudt_ObjSmplIntf.udt_TD.i16_Poti[i] = DrvAdc_ReadPoti(i, DRVADC_FLAG_USE_CALIB);
			}

			//solange weitermessen, bis 2 aufeinander folgende Messungen ident sind
			while( (i16_Poti[0] < gudt_ObjSmplIntf.udt_TD.i16_Poti[0]-gudt_IntEedata.udt_TestPara.u8_Tol) ||
			(i16_Poti[1] < gudt_ObjSmplIntf.udt_TD.i16_Poti[1]-gudt_IntEedata.udt_TestPara.u8_Tol) ||
			(i16_Poti[0] > gudt_ObjSmplIntf.udt_TD.i16_Poti[0]+gudt_IntEedata.udt_TestPara.u8_Tol) ||
			(i16_Poti[1] > gudt_ObjSmplIntf.udt_TD.i16_Poti[1]+gudt_IntEedata.udt_TestPara.u8_Tol))
			{
				_delay_ms(100);

				//alte Daten sichern
				for (i = 0; i < OBJSAMPLE_POTI_CNT; i++)
				{
					i16_Poti[i] = gudt_ObjSmplIntf.udt_TD.i16_Poti[i];
				}
					
				//neueMessung durchfuehren
				for (i = 0; i < OBJSAMPLE_POTI_CNT; i++)
				{
					//ADC auslesen, Kalibrierung anwenden
					gudt_ObjSmplIntf.udt_TD.i16_Poti[i] = DrvAdc_ReadPoti(i, DRVADC_FLAG_USE_CALIB);
				}
			}

			//Messdaten auswerten
			ObjSample_Check();

			//Messdaten anzeigen
			ObjSample_DispTestData(1);

			// Zeitstempel holen
			i16_retval = (int16_t)DrvRtc_GetDateTime(&gudt_ObjSmplIntf.udt_TD.TS);
				
			//Auswertung
			if (gudt_ObjSmplIntf.udt_TD.u8_Result == OBJSMPL_RESCODE_OK)
			{
				//i.O.
				CLR_LED_RT;
			}
			else
			{
				//Fehler
				ObjSample_DispTestData(0);
				CLR_LED_GN;
			}
				
			//Messdaten ablegen
			ObjSample_SaveTestData();
			
			// Prellzeit abwarten (>50ms)
			_delay_ms(400);
		}
		else
		{
			CLR_LED_GN;
			ObjLcd_ShowAction(2);									//Anzeige "BatterieBoxDeckel einlegen"
		}
		gudt_ObjSmplIntf.u16_TS = DrvTim_StartTimer();
	}
	else	//wenn keine Taste gedrueckt
	{		
		//x Sek. Messung anzeigen unsd nicht während der Monitor Kalibrierung
		if (DrvTim_ReadTimer(gudt_ObjSmplIntf.u16_TS) > OBJSAMPLE_RESULT_DISPLAY  && gu8_FirstRun == 1) 
		{
			gudt_ObjSmplIntf.u16_TS = DrvTim_StartTimer();
			gudt_ObjSmplIntf.u8_Flags &=  ~BM_FLAG_HOLD;	//Flag loeschen
			ObjLcd_ShowAction(1);
			CLR_LED_RT;
			CLR_LED_GN;
			if(!gudt_GpioIntf.u8_Endschlater)
			{
				gudt_auto_start = 1;
			}			
		}
	}
	return i16_retval;
}*/

//Pruefung der letzten Messwerte
/*static void ObjSample_Check(void)
{
	uint8_t u8_retVal = 0;	// true (pruefung ok); sonst 0 (false)

	for(int i = 0; i < OBJSAMPLE_POTI_CNT; i++)
	{
		//Auf Unterschreitung hin pruefen
		if(gudt_ObjSmplIntf.udt_TD.i16_Poti[i] < gudt_IntEedata.udt_TestPara.i16_minTol[i])
		{
			u8_retVal |= (1<<i);
		}
		//Auf Ueberschreitung hin pruefen
		else if(gudt_ObjSmplIntf.udt_TD.i16_Poti[i] > gudt_IntEedata.udt_TestPara.i16_maxTol[i])
		{
			u8_retVal |= (1<<(i+4));
		}//kein else
	}
	
	gudt_ObjSmplIntf.udt_TD.u8_Result = u8_retVal;
}*/

/*
// Prüfung der Messwerte
static void ObjSample_Check(void)
{
	uint8_t u8_retVal = 0;	// true (pruefung ok); sonst 0 (false)

	for(int i = 0; i < OBJSAMPLE_HALL; i++)
	{
		//Auf Unterschreitung hin pruefen
		if(gudt_ObjSmplIntf.udt_TD.i16_measured_Values[i] < gudt_IntEedata.udt_TestPara.i16_minTol[i])
		{
			u8_retVal |= (1<<i);
		}
		//Auf Ueberschreitung hin pruefen
		else if(gudt_ObjSmplIntf.udt_TD.i16_measured_Values[i] > gudt_IntEedata.udt_TestPara.i16_maxTol[i])
		{
			u8_retVal |= (1<<(i+4));
		}//kein else
	}
	
	gudt_ObjSmplIntf.udt_TD.u8_Result = u8_retVal;
}*/
// Prüfung Messwert Dauermagnet
void ObjSample_CheckDM(void)
{
	uint8_t u8_retVal = 0;	// true (pruefung ok); sonst 0 (false)

	// Auf Unterschreitung hin pruefen
	if(gudt_ObjSmplIntf.udt_TD.i16_measured_Values[0] < gudt_IntEedata.udt_TestParaDM.i16_minTolDM)
	{
		u8_retVal |= (1<<0);
	}
		
	// Auf Ueberschreitung hin pruefen
	else if(gudt_ObjSmplIntf.udt_TD.i16_measured_Values[0] > gudt_IntEedata.udt_TestParaDM.i16_maxTolDM)
	{
		u8_retVal |= (1<<(0+4));
	}

	gudt_ObjSmplIntf.udt_TD.u8_ResultDM = u8_retVal;
}

// Prüfung Messwert Spule
void ObjSample_CheckCoil(void)
{
	uint8_t u8_retVal = 0;	// true (pruefung ok); sonst 0 (false)

	// Auf Unterschreitung hin pruefen
	if(gudt_ObjSmplIntf.udt_TD.i16_measured_Values[1] < gudt_IntEedata.udt_TestParaCoil.i16_minTolCoil)
	{
		u8_retVal |= (1<<1);
	}
		
	// Auf Ueberschreitung hin pruefen
	else if(gudt_ObjSmplIntf.udt_TD.i16_measured_Values[1] > gudt_IntEedata.udt_TestParaCoil.i16_maxTolCoil)
	{
		u8_retVal |= (1<<(1+4));
	}
	
	gudt_ObjSmplIntf.udt_TD.u8_ResultCoil = u8_retVal;
}

//Berechnet die Pruefsumme der aus dem Eeprom ausgelesenen Daten
uint8_t ObjSample_CalcChkSum(uint8_t* pudt_Data, uint8_t u8_Size)
{
	uint8_t 	u8_ChkSum=0;
	uint8_t*	pu8_Data = pudt_Data;

	while (pu8_Data <( pudt_Data+u8_Size))
	{
		u8_ChkSum += *pu8_Data;
		pu8_Data++;
	}

	return (0x00-u8_ChkSum);
}


//Auf Terminal eine Legende fuer die Pruefdaten ausgeben
void ObjSample_PutsLeg()//Tabellenkopf auf UART ausgeben
{
	//Zaehlerstand ausgeben
	DrvUart_Puts(&gudt_MoniIntf, "\r\nDate\t\tTime\t\tResult\tDauermagnet\tSpule\r\n");
}


//einen Pruefdatensatz in einer Zeile anzeigen
void ObjSmpl_ShowTestData(tTestData* pudt_X)
{
	tTestData* pudt_TD = pudt_X;
	uint8_t i;

	//Datum ausgeben
	if (Tag(pudt_TD->TS) < 10)	DrvUart_Puts(&gudt_MoniIntf, "0");
	DrvUart_Putbyte(&gudt_MoniIntf, Tag(pudt_TD->TS));
	DrvUart_Puts(&gudt_MoniIntf, ".");
	if (Monat(pudt_TD->TS) < 10)	DrvUart_Puts(&gudt_MoniIntf, "0");
	DrvUart_Putbyte(&gudt_MoniIntf, Monat(pudt_TD->TS));
	DrvUart_Puts(&gudt_MoniIntf, ".20");
	if (Jahr(pudt_TD->TS) < 10)	DrvUart_Puts(&gudt_MoniIntf, "0");
	DrvUart_Putbyte(&gudt_MoniIntf, Jahr(pudt_TD->TS));
	DrvUart_Puts(&gudt_MoniIntf, "\t");

	//Zeit ausgeben
	if (Stunden(pudt_TD->TS) < 10)	DrvUart_Puts(&gudt_MoniIntf, "0");
	DrvUart_Putbyte(&gudt_MoniIntf, Stunden(pudt_TD->TS));
	DrvUart_Puts(&gudt_MoniIntf, ":");
	if (Minuten(pudt_TD->TS) < 10)	DrvUart_Puts(&gudt_MoniIntf, "0");
	DrvUart_Putbyte(&gudt_MoniIntf, Minuten(pudt_TD->TS));
	DrvUart_Puts(&gudt_MoniIntf, ":");
	if (Sekunden(pudt_TD->TS) < 10)	DrvUart_Puts(&gudt_MoniIntf, "0");
	DrvUart_Putbyte(&gudt_MoniIntf, Sekunden(pudt_TD->TS));
	DrvUart_Puts(&gudt_MoniIntf, "\t");

	//Ergebnis ausgeben
	/*DrvUart_Putbyte(&gudt_MoniIntf, pudt_TD->u8_Result);
	DrvUart_Puts(&gudt_MoniIntf, "\t");*/
	
	DrvUart_Putbyte(&gudt_MoniIntf, pudt_TD->u8_ResultDM);
	DrvUart_Puts(&gudt_MoniIntf, "\t");
	
	DrvUart_Putbyte(&gudt_MoniIntf, pudt_TD->u8_ResultCoil);
	DrvUart_Puts(&gudt_MoniIntf, "\t");
	
	//hx ausgeben
	for(i = 0; i < OBJSAMPLE_HALL; i++)
	{
		//DrvUart_Putint(&gudt_MoniIntf, (pudt_TD->i16_Poti[i]));
		DrvUart_Putint(&gudt_MoniIntf, (pudt_TD->i16_measured_Values[i]));
		DrvUart_Puts(&gudt_MoniIntf, "\t\t");
	}

	//Zeilenumbruch
	DrvUart_Newline(&gudt_MoniIntf);

	while(gudt_MoniIntf.udt_txbuf.u8_count > 0)
		DrvUart_Transmit(&gudt_MoniIntf);
}

void ObjSample_InitParameter()
{
	int16_t		i16_Ergebnis = 0;

	//Daten des internen Eeprom laden
	i16_Ergebnis = ObjSample_LoadIntEedata();

	gudt_IntEedata.u32_CycleCnt = 0;

	//wenn CS i.O.
	DrvUart_Puts(&gudt_MoniIntf, "\r\nEEPROM ");
	if (i16_Ergebnis != 0)
	{
		//naechste Schreibposition im Eeprom finden
		gudt_ObjSmplIntf.u16_ExtEepromWritePtr = ObjSample_ExtEepromGetNextWritePos(); 
		gudt_IntEedata.u16_ExtEepromWritePtr = gudt_ObjSmplIntf.u16_ExtEepromWritePtr - 1;
		
		//Daten i.O. -> Pruefung fortsetzen
		DrvUart_Puts(&gudt_MoniIntf, "ok");
	}
	else
	{
		DrvUart_Puts(&gudt_MoniIntf, "restored");

		//Eepromdaten wiederherstellen
		memcpy (&gudt_IntEedata.udt_TestParaDM, &gudt_TestParaDMDefault, sizeof(gudt_TestParaDM));
		memcpy (&gudt_IntEedata.udt_TestParaCoil, &gudt_TestParaCoilDefault, sizeof(gudt_TestParaCoil));
				
		//Zaehler auf Null setzen
		gudt_ObjSmplIntf.u16_ExtEepromWritePtr = 0;

		//EEpromdaten schreiben
		ObjSample_SaveIntEedata();

		//ext. Eeprom loeschen
		DrvEep_CE();
	}
}


int16_t ObjSample_LoadIntEedata()
{
	uint8_t		u8_CS = 1;
	int16_t		i16_rv = 0;	

	//den EEprom-Header lesen
	eeprom_read_block(&gudt_IntEedata, 0, sizeof(gudt_IntEedata));

	//die Pruefsumme checken
	u8_CS = ObjSample_CalcChkSum((uint8_t*)&gudt_IntEedata, sizeof(gudt_IntEedata));

	//wenn CS i.O.
	if (u8_CS == 0)
		i16_rv = 1;	// true

	return i16_rv;
}


void ObjSample_SaveIntEedata()
{
	//Pruefsumme berechnen
	gudt_IntEedata.u8_CS = ObjSample_CalcChkSum((uint8_t*)&gudt_IntEedata, sizeof(gudt_IntEedata)-1);

	//EEprom schreiben
	eeprom_write_block(&gudt_IntEedata, 0, sizeof(gudt_IntEedata));
}

//zeigt auf dem Monitor die EEPROMdaten an
void ObjSample_ShowIntEedata()
{
	uint8_t i;

	DrvUart_Puts(&gudt_MoniIntf, "\r\nCyc:    ");
	DrvUart_Putu32(&gudt_MoniIntf, gudt_IntEedata.u32_CycleCnt);
	DrvUart_Puts(&gudt_MoniIntf, "\r\nEeFill: ");
	DrvUart_Putuint(&gudt_MoniIntf, gudt_IntEedata.u16_ExtEepromWritePtr);
	DrvUart_Puts(&gudt_MoniIntf, "\r\nnegTol: ");
	/*
	for(i = 0; i < OBJSAMPLE_POTI_CNT; i++)
	{
		DrvUart_Putint(&gudt_MoniIntf, gudt_IntEedata.udt_TestPara.i16_minTol[i]);
		DrvUart_Puts(&gudt_MoniIntf, " ");
	}
	
	DrvUart_Puts(&gudt_MoniIntf, "\r\nposTol: ");
	for(i = 0; i < OBJSAMPLE_POTI_CNT; i++)
	{
		DrvUart_Putint(&gudt_MoniIntf, gudt_IntEedata.udt_TestPara.i16_maxTol[i]);
		DrvUart_Puts(&gudt_MoniIntf, " ");
	}*/
	
	DrvUart_Putint(&gudt_MoniIntf, gudt_IntEedata.udt_TestParaDM.i16_minTolDM);
	DrvUart_Puts(&gudt_MoniIntf, " ");
	
	DrvUart_Putint(&gudt_MoniIntf, gudt_IntEedata.udt_TestParaCoil.i16_minTolCoil);
	DrvUart_Puts(&gudt_MoniIntf, " ");
	
	DrvUart_Putint(&gudt_MoniIntf, gudt_IntEedata.udt_TestParaDM.i16_maxTolDM);
	DrvUart_Puts(&gudt_MoniIntf, " ");
	
	DrvUart_Putint(&gudt_MoniIntf, gudt_IntEedata.udt_TestParaCoil.i16_maxTolCoil);
	DrvUart_Puts(&gudt_MoniIntf, " ");

	/*DrvUart_Puts(&gudt_MoniIntf, "\r\nTolerance: ");
	DrvUart_Putbyte(&gudt_MoniIntf, gudt_IntEedata.udt_TestPara.u8_Tol);

	DrvUart_Puts(&gudt_MoniIntf, "\r\nKalibOffset: ");
	DrvUart_Putint(&gudt_MoniIntf, gudt_IntEedata.udt_TestPara.i16_KalibOffset);*/

	DrvUart_Puts(&gudt_MoniIntf, "\r\nCS:     0x");
	DrvUart_Putbyteh(&gudt_MoniIntf, gudt_IntEedata.u8_CS);
	DrvUart_Newline(&gudt_MoniIntf);
}


//Darstellung der aktuellen Testergebnisse
/*void ObjSample_DispTestData(uint8_t u8_flagRefreshData)
{
	int16_t	h[OBJSAMPLE_POTI_CNT];
	uint16_t u16_time;
	uint8_t i;
	u16_time = DrvTim_StartTimer();		//den System-Millisekundenzaehler auslesen
	
	for(i = 0;  i < OBJSAMPLE_POTI_CNT; i++)
	{
		h[i] = gudt_ObjSmplIntf.udt_TD.i16_Poti[i];	//Kopien der Messwerte anlegen und in 1/100-tel umrechnen 
	}
	
	//1.Zeile waehlen
	ObjLcd_SetBufPos(0,0);
	
	//nur im HOLD-Mode wechselnde Anzeige
	if(u8_flagRefreshData == 0)
	{	
		if((OBJSMPL_RESCODE_PLUS_ZUHOCH & gudt_ObjSmplIntf.udt_TD.u8_Result) != 0)
		{
			if ((OBJSMPL_RESCODE_MINUS_ZUHOCH & gudt_ObjSmplIntf.udt_TD.u8_Result) != 0)
			{
				ObjLcd_Puts(" K- und K+ zu hoch  ");
			}
			else if ((OBJSMPL_RESCODE_MINUS_ZUTIEF & gudt_ObjSmplIntf.udt_TD.u8_Result) != 0)
			{
				ObjLcd_Puts("- zu tief + zu hoch ");
			}
			else
			{
				ObjLcd_Puts("     K+ zu hoch     ");
			}
		}
		else if ((OBJSMPL_RESCODE_PLUS_ZUTIEF & gudt_ObjSmplIntf.udt_TD.u8_Result) != 0)
		{
			if ((OBJSMPL_RESCODE_MINUS_ZUHOCH & gudt_ObjSmplIntf.udt_TD.u8_Result) != 0)
			{
				ObjLcd_Puts("- zu hoch + zu tief ");
			}
			else if ((OBJSMPL_RESCODE_MINUS_ZUTIEF & gudt_ObjSmplIntf.udt_TD.u8_Result) != 0)
			{
				ObjLcd_Puts(" K- und K+ zu tief  ");
			}
			else
			{
				ObjLcd_Puts("     K+ zu tief     ");
			}
		}
		else
		{
			if ((OBJSMPL_RESCODE_MINUS_ZUHOCH & gudt_ObjSmplIntf.udt_TD.u8_Result) != 0)
			{
				ObjLcd_Puts("     K- zu hoch     ");
			}
			else
			{
				ObjLcd_Puts("     K- zu tief     ");
			}
		}
	}
	else	//sonst fixe Anzeige
	{
		//1.Zeile fix
		ObjLcd_Puts("     K-      K+     ");

		//2.Zeile anzeigen
		ObjLcd_SetBufPos(1,0);
		ObjLcd_Puts("   ");
		
		for(i = 0; i < OBJSAMPLE_POTI_CNT; i++)
		{
			//Kontakthoehe i anzeigen
			if (h[i] >1023)	//wenn ungueltige Hoehenangabe
			{
				ObjLcd_Puts("  -.--");
				ObjLcd_Puts("  ");
			}
			else
			{
				if (h[i]<0)		//ggf. neg. Vorzeichen anzeigen
				{
					h[i]*= -1;
					ObjLcd_Puts("-");
				}
				else
				{
					ObjLcd_Puts(" ");
				}	
				
				if (h[i] > 99) 
				{
					if(h[i] > 999)
					{
						ObjLcd_PutUByte(h[i]/100); 
					}
					else
					{
						ObjLcd_Puts(" ");
						ObjLcd_PutUByte(h[i]/100); 
					}
					
				}
				else 
				{
					ObjLcd_Puts(" 0");
				}
				h[i]%= 100;
				
				ObjLcd_Puts(".");
			
				if (h[i] > 9)	
				{
					ObjLcd_PutUByte(h[i]/10);
				} 
				else 
				{
					ObjLcd_Puts("0");
				}
				h[i]%= 10;
				
				ObjLcd_PutUByte(h[i]);
				ObjLcd_Puts("  ");
			}
		}
		ObjLcd_Puts(" ");
	}	
}*/


//Darstellung der aktuellen Testergebnisse
/*void ObjSample_DispCalibData(void)
{
	int16_t	h[OBJSAMPLE_POTI_CNT];
	uint8_t 	i;
	
	for(i = 0; i < OBJSAMPLE_POTI_CNT; i++)
	{
		h[i] = gudt_ObjSmplIntf.i16_Calib[i];	//Kopien der Messwerte anlegen und in 1/100-tel umrechnen 
	}
	
	//1.Zeile unveraendert

	//2.Zeile
	ObjLcd_SetBufPos(1,0);

	for(i = 0; i < OBJSAMPLE_POTI_CNT; i++)
	{
		ObjLcd_Puts("    ");

		//Kontakthoehe i anzeigen
		if (h[i] <= 0)	//wenn ungueltige Hoehenangabe
		{
			ObjLcd_Puts("----");
		}
		else
		{			
			if(h[i] <1000)	// ausender 
				ObjLcd_Puts(" ");
			else
				ObjLcd_PutUByte(h[i]/1000);
			h[i]%=1000;
				
			if(h[i] <100)	//Hunderter 
				ObjLcd_Puts("0");
			else
				ObjLcd_PutUByte(h[i]/100);
			h[i]%=100;
				
			if(h[i] <10)	//Zehner 
				ObjLcd_Puts("0");
			else
				ObjLcd_PutUByte(h[i]/10);
			h[i]%=10;

			ObjLcd_PutUByte(h[i]);	//Einer
		}
	}
}*/

//den Byteindex der nächsten freien Schreibposition im externen Eeprom finden und zurueckgeben
static uint16_t ObjSample_ExtEepromGetNextWritePos(void)
{
	uint16_t 	u16_rv = 0;				// initial auf Null setzen
	uint16_t 	i;						// Schleifenvariable
	tDateTime 	TS;						// Zeitstempel zum vergleichen mit den Eepromdaten
	tTestData	TD;						// Datenstruktur eines Pruefergebnisses

	//Zeit so initialisieren, dass sie garantiert in der Vergangenheit liegt
	TS.jhr = 18;
	TS.mon = 1;
	TS.tag = 1;
	TS.std = 0;
	TS.min = 0;
	TS.sek = 0;
	
	//von Begin an durch das Eeprom gehen und den neuesten Datensatz suchen
	for(i = 1; i < (EE_DATA_SIZE/sizeof(tTestData)); i++)
	{
		//Testdatensatz lesen
		DrvEep_Read(((uint32_t)i)*sizeof(tTestData), (uint8_t*)((&TD)), sizeof(tTestData));

		//Pruefsumme checken (Abbruch, wenn ungueltiger Datensatz gefunden wurde
		if (ObjSample_CalcChkSum((uint8_t*)&TD, sizeof(tTestData)) > 0)
		{
			break;
		}

		//wenn Datensatz gueltig, dann Datum vergleichen
		if (DrvEep_ToSec(TD.TS) >= DrvEep_ToSec(TS))
		{
			u16_rv = i;	// aktuelleren Datensatz gefunden und index merken
		}
	}

	//rv auf den naechsten freien Datensatz schieben
	u16_rv++;
	
	// DEBUG
	DrvUart_Puts(&gudt_MoniIntf, " [");
	DrvUart_Putuint(&gudt_MoniIntf, u16_rv);
	DrvUart_Puts(&gudt_MoniIntf, "] ");
	
	return u16_rv;
}

//aktuellen Messdatensatz in ext. Eeprom schreiben
void ObjSample_SaveTestData()
{
	tTestData td;
	
	memcpy(&td, &gudt_ObjSmplIntf.udt_TD, sizeof(tTestData));
	//Schreibvorgang anstossen und naechste freie EEPROMadresse setzen

	//Ueberlauf des Eeproms verhindern (wenn voll, werden alte datensaetze zuerst ueberschrieben
	gudt_ObjSmplIntf.u16_ExtEepromWritePtr %= (uint16_t)(((uint32_t)EE_DATA_SIZE)/(uint32_t)sizeof(tTestData));

	//Pruefsumme des Pruefdatensatzes berechnen
	td.CS = ObjSample_CalcChkSum((uint8_t*)&td, sizeof(tTestData)-1); 

	//Daten an naechste freie Position bzw. ueber die aeltesten Daten schreiben
	DrvEep_Write((uint32_t)(gudt_ObjSmplIntf.u16_ExtEepromWritePtr)*sizeof(tTestData), (uint8_t*)&td, sizeof(tTestData));

	gudt_ObjSmplIntf.u16_ExtEepromWritePtr++;
	gudt_IntEedata.u16_ExtEepromWritePtr++;
	gudt_IntEedata.u32_CycleCnt++;
}

/*int16_t ObjSample_DoCalib()
{
	uint8_t 	i;
	uint16_t	u16_TS;
	int16_t		i16_tmp;
	int32_t		i32_tmp;

	//beide LEDs aus
	CLR_LED_RT;
	CLR_LED_GN;

	//Displaytext anzeigen
	ObjLcd_ClearDispBuf();	// Displaybuffer leeren
	ObjLcd_SetBufPos(0,0);	// 1.Zeile waehlen
	ObjLcd_Puts("*** Kalibrierung ***");
	ObjLcd_Handler();
				
	//Timer starten
	u16_TS = DrvTim_StartTimer();

	//warten, bis Taster losgelassen
	while(KEY_STATE == 0);
	_delay_ms(100);
				
	//Min-Array initialisieren
	for(i = 0; i < OBJSAMPLE_POTI_CNT; i++)
	{
		gudt_ObjSmplIntf.i16_Calib[i] = 0;
	}
				
	//Kalibrierung , bis Taste
	while(1)
	{
		//Wechsel-Anzeige
		if((DrvTim_ReadTimer(gudt_GpioIntf.u16_TS)%500) < 250)
		{
			//gruene LED
			CLR_LED_RT;
			SET_LED_GN;
		}
		else
		{
			//rote LED
			CLR_LED_GN;
			SET_LED_RT;
		}
					
		//alle 100ms messen
		if(DrvTim_ReadTimer(u16_TS) > 100)
		{
			//Zeitstempel neu setzen
			u16_TS = DrvTim_StartTimer();
						
			//... messen und vergleichen
			for(i = 0; i < OBJSAMPLE_POTI_CNT; i++)
			{
				i16_tmp = DrvAdc_ReadPoti(i, DRVADC_FLAG_USE_NO_CALIB);// Messwert holen
				if (i16_tmp > gudt_ObjSmplIntf.i16_Calib[i]) 
				{
					gudt_ObjSmplIntf.i16_Calib[i] = i16_tmp;		// ggf. neues Maximum uebernehmen
				}//kein else
			}

			//Kalibrierwerte anzeigen
			ObjSample_DispCalibData();
			ObjLcd_Handler();
		}
					
		//Abbruch
		if (KEY_STATE == 0)
		{
			//warten, bis losgelassen
			while(KEY_STATE == 0);
						
			//wenn noch nicht alle werte Kalibriert...
			if ( (gudt_ObjSmplIntf.i16_Calib[0]==0) || (gudt_ObjSmplIntf.i16_Calib[1]==0))
			{
				CLR_LED_GN;
				SET_LED_RT;

				ObjLcd_SetBufPos(0,0);	//1.Zeile waehlen
				ObjLcd_Puts("Kalib. nicht vollst!");
				ObjLcd_Handler();

				_delay_ms(2000);
							
				CLR_LED_RT;

				ObjLcd_SetBufPos(0,0);	// 1.Zeile waehlen
				ObjLcd_Puts("*** Kalibrierung ***");
				ObjLcd_Handler();
			}
			else // sonst fertig!
				break;
		}
	}
				
	//Kalibrieroffset in Digits umrechnen
	i32_tmp = gudt_IntEedata.udt_TestPara.i16_KalibOffset;
	if(i32_tmp != 0)
	{
		i32_tmp *= 1024;
		i32_tmp /= 1100;
		i32_tmp -= 1;	//wg. rundungsfehlern
	}//

	//Kalibrieroffset anwenden
	for(i = 0; i < OBJSAMPLE_POTI_CNT; i++)
	{
		gudt_ObjSmplIntf.i16_Calib[i] += (int16_t)i32_tmp;
	}
								
	//Verhindern, dass wir beim naechsten durchlauf wieder in die Kalibrierung geraten
	gudt_GpioIntf.u16_TS = DrvTim_StartTimer();
	gudt_GpioIntf.u8_Key = 0;
	gudt_GpioIntf.u8_LastKey = 0;
				
	//kont. Messung wieder freigeben 
	gudt_ObjSmplIntf.u8_Flags &= ~BM_FLAG_HOLD;
				
	return DRVGPIO_CALIB_DONE;
}*/