
/***********************************************************************************


 ein Vorschlag vom Josef: http://www.mikrocontroller.net/topic/14792

 Allerdings: korrigiert von mir bei Ausgabe von negativen Temperaturen 


***********************************************************************************/


#include "main.h"
#include "HD44780_2.h"

#define MIT_NAMEN	1		// 0= ohne, 1=mit Namen in DS1820

void start_meas( void ){
  if( W1_IN & 1<< W1_PIN ){
    w1_command( CONVERT_T, NULL );
    W1_OUT |= 1<< W1_PIN;
    W1_DDR |= 1<< W1_PIN;			// parasite power on

 _delay_ms(600);                     // Verzögerung wg parasite power 

  }
}

#if MIT_NAMEN
#define	DS18B20_12bit	0x7F

//           #define THERMOanzahlMax	3	// auch thermoNamen anpassen!
#define THERMOanzahlMax	2	// auch thermoNamen anpassen!

//                          "123456123456123456"
//   #define THERMO1WNAMEN	"    T1    T2    T3"	// Überschrift, rechtsbündig

#define THERMO1WNAMEN	"    T1    T2"	// Überschrift, rechtsbündig

#define THERMO1NameLen	6
#define THERMO1NameOffset	(THERMO1NameLen-2) // hier steht das 1. Zeichen
static	char	thermoNamen[] =	THERMO1WNAMEN;	// ToDo PROGMEM

static	float	thermoValues[THERMOanzahlMax];

static	uint8_t initReady;
#if (THERMOanzahlMax<=8)
	static uint8_t valid; 	// Indizes mit gültigen Namen merken, je 1 bit
#else
	static uint16_t valid;
#endif

static uint8_t NameValid( char * name ) {
	// prüft, ob Name aus scratch mit Name aus Tabelle übereinstimmt
	// wenn ja, ret = index+1!!!; andernfalls 0
	uint8_t ret = 0;
	char * pC = thermoNamen+THERMO1NameOffset;
	while (ret++ < THERMOanzahlMax) {
		if ( *(int16_t*) name== *(int16_t*) pC)	// 2 Byte vergleichen
			return ret;
		pC += THERMO1NameLen;
	}
	return 0;
}
#endif

void read_meas( void )
{
  uchar id[8], diff;
  char s[30];
  uchar i;
  int16_t temp1,temp2;
  float temp=0;

  for( diff = SEARCH_FIRST; diff != LAST_DEVICE; ){
    diff = w1_rom_search( diff, id );

    if( diff == PRESENCE_ERR ){

      break;
    }
    if( diff == DATA_ERR ){

      break;
    }
    if( id[0] == 0x28 || id[0] == 0x10 ){	// temperature sensor
#if !MIT_NAMEN
		
		//Wert der ID ausgeben
		for( i = 0; i < 8; i++ ){
			sprintf (s, "ID: %02X ", id[i] );

		LCD_GoTo_2(0); 
        LCD_WriteText(s);
	                            }
#endif

      w1_byte_wr( READ );			// read command
      temp1 = w1_byte_rd();			// low byte
      temp2 = w1_byte_rd();		    // high byte

      temp=(float)(temp1+(temp2*256))/16;


#if MIT_NAMEN
		char name[2]; uint8_t nIndex;

		name[0] = w1_byte_rd();			// high Index
		name[1] = w1_byte_rd();			// low	Index

		if (!initReady)	{			// nur beim 1. Durchgang
			// PrintId( id, name );	//	erkannte Sensoren mit Namen ausgeben, z.B. auf Uart


/*************************************		
          LCD_GoTo_2(5); 
          LCD_WriteText(name);
          LCD_WriteText(" ");
**************************************/


		}
		if ((nIndex = NameValid(name))) {

			thermoValues[--nIndex] = temp;

			valid |= (1<<nIndex);
		} else if (initReady==1){ // alle im 0. Durchgang als gültig erkannten sind ausnahmsweise noch gesetzt
			i = 0;
			while ((1<<i++) & valid); 	// 1. freien Platz finden (i ist dann 1 zu groß)
			if (--i<THERMOanzahlMax) {	// also vorher 1 abziehen
				valid |= (1<<i);					// jetzt belegt
				i *= THERMO1NameLen;
				i += THERMO1NameOffset;
				w1_command( WRITE, id );
				w1_byte_wr( name[0]=thermoNamen[i++] );
				w1_byte_wr( name[1]=thermoNamen[i] );
				w1_byte_wr( DS18B20_12bit );	// ggf. anpassen für anderen Sensor!
				w1_command( EE_WRITE, id );
				// PrintId( id, name );			// Namensänderung protokollieren
			}
		}

#else
	  //Messwert in Grad Celsius auf LCD ausgeben

                      dtostrf(temp, 3, 1, s);  

	      LCD_GoTo_3(2); 
          LCD_WriteText(s);
          LCD_WriteData (2);        //  " Grad "
          LCD_WriteText("C");
          LCD_WriteText("   ");

#endif
    }
  }

#if MIT_NAMEN

	for( i=0; i<THERMOanzahlMax; i++) {	// Error-Detection

/*******************************************************************************************
		* es treten gelegentlich Lesefehler auf (Detektor wird nicht gefunden).
		 * 	Ausgelassene Werte machen viel Arbeit in Excel und verunstalten die Grafik.
		 * 	Deshalb jetzt: alten Messwert +/- Konstante, z.B. 1°=0x10 (1*16).
		 * 	und das letzte Bit gibt an, ob addiert oder subtrahiert werden muss (abwechselnd)
		 *  Wenn man das nicht braucht, kann man auch einfach einen sonst nicht vorkommenden
		 *  Wert einsetzen, z.B. 0.
*******************************************************************************************/

           temp=thermoValues[i];    

		if (!(valid &(1<<i))) {	// keinen neuen Wert gelesen ?
			                    // dann den alten nehmen 
			thermoValues[i]=temp;
		                       }      
							     
		       dtostrf(temp, 3, 1, s); 
			    
//             die Überschrift muss ggf. an die Stellenzahl dieser Ausgabe angepasst werden
		 
		 		  
          LCD_GoTo_4(i*10); 
  
          LCD_WriteText("  ");
          LCD_WriteText(s);
          LCD_WriteData (2);        //  " Grad "         
          LCD_WriteText("C");
		  LCD_WriteText("   ");
	                                  }

	if (initReady)
		valid = 0;

		// d.h. beim ersten Durchgang stehen lassen für Erkennung der freien Plätze für unbekannte Sensoren
	if (initReady<255)	// Überlauf verhindern
		++initReady;
#endif
}
