// monitor Battery in line 4 or line2, if a two line display 
void Bat_update(uint8_t tt) {
  if((tt % 16) == 0) {
 #if (LCD_LINES > 3)
     lcd_line4();
     Battery_check();
 #else
     wait_about1s();	/* time delay before overwiting line2 with Bat= message */
  #if (LCD_LINES == 3)
     lcd_line3();	// use the last line for Bat=
  #else
     lcd_line2();	// use the last line for Bat=
  #endif
     Battery_check();
     wait_about2s();	/* time delay for reading the Bat= message */
 #endif
  }
};	/* end Bat_update() */
Beispiel #2
0
/* ****************************************************************** */
void function_menu() {
  uint8_t ii;
  uint8_t func_number;
#ifdef PAGE_MODE
  uint8_t page_nr;
  uint8_t p_nr;
  uint8_t ff;
  page_nr = MODE_LAST;
 #ifdef WITH_ROTARY_SWITCH
  rotary.count = 0;
 #endif
#endif

  func_number = 0;
 #ifdef POWER_OFF
  uint8_t ll;
  for (ll=0;ll<((MODE_LAST+1)*10);ll++) 
 #else
  while (1)		/* without end, if no power off specified */
 #endif
  {
     if (func_number > MODE_LAST) func_number -= (MODE_LAST + 1);
     message_key_released(SELECTION_str);
#ifdef FOUR_LINE_LCD
 #ifdef PAGE_MODE
     ff = 0;
     if (func_number == page_nr) ff = 1;	// number is found
     p_nr = page_nr + 1;
     if (p_nr > MODE_LAST) p_nr -= (MODE_LAST + 1);
     if (func_number == p_nr) ff = 1;		// number is found
     p_nr = page_nr + 2;
     if (p_nr > MODE_LAST) p_nr -= (MODE_LAST + 1);
     if (func_number == p_nr) ff = 1;		// number is found
     if (ff == 0) {
        // func_number is not in page list
  #ifdef WITH_ROTARY_SWITCH
        if (rotary.count >= 0) {
           page_nr = (func_number + MODE_LAST -1);  // page_nr = func_number - 2
        } else {
           page_nr = func_number;	// for backward, set page_nr to func_number
        }
       if (page_nr > MODE_LAST) page_nr -= (MODE_LAST + 1);
  #else
        page_nr = func_number;
  #endif
     }
     
     if (ff == 0) {
        lcd_line2();
        lcd_clear_line();			// clear line 2
     }
     lcd_line2();				// reset cursor to begin of line 2
     if (func_number == page_nr) {
        lcd_data('>');
     } else {
        lcd_space();				// put a blank to 1. row of line 2
     }
     message2line(page_nr);			// show first page function
     if (ff == 0) {
        lcd_line3();
        lcd_clear_line();			// clear line 3
     }
     lcd_line3();				// reset cursor to begin of line 3
     p_nr = page_nr + 1;
     if (p_nr > MODE_LAST) p_nr -= (MODE_LAST + 1);
     if (func_number == p_nr) {
        lcd_data('>');
     } else {
        lcd_space();				// put a blank to 1. row of line 3
     }
     message2line(p_nr);			// show 2. page function
     if (ff == 0) {
        lcd_line4();
        lcd_clear_line();			// clear line 4
     }
     lcd_line4();				// reset cursor to begin of line 4
     p_nr = page_nr + 2;
     if (p_nr > MODE_LAST) p_nr -= (MODE_LAST + 1);
     if (func_number == p_nr) {
        lcd_data('>');
     } else {
        lcd_space();				// put a blank to 1. row of line 4
     }
     message2line(p_nr);			// show 3. page function
 #else	/* no PAGE_MODE */
     lcd_line2();
     lcd_clear_line();				// clear line 2
     lcd_line2();				// reset cursor to begin of line 2
     lcd_space();				// put a blank to 1. row of line 2
     message2line(func_number + MODE_LAST);	// show lower (previous) function
     lcd_line3();
     lcd_clear_line();				// clear line 3
     lcd_line3();				// reset cursor to begin of line 3
     lcd_data('>');				// put a '>' marker to row 1 of line 3
     message2line(func_number);			// show selectable function
     lcd_line4();
     lcd_clear_line();				// clear line 4
     lcd_line4();				// reset cursor to begin of line 4
     lcd_space();				// put a blank to 1. row of line 4
     message2line(func_number + 1);		// show higher (next) function
 #endif         /* PAGE_MODE */
#else	/* no FOUR_LINE_LCD */
     lcd_line2();
     lcd_clear_line();				// clear line 2
     lcd_line2();				// reset cursor to begin of line 2
     message2line(func_number);
#endif /* FOUR_LINE_LCD */
#ifdef POWER_OFF
     ii = wait_for_key_ms(SHORT_WAIT_TIME);	// wait about 5 seconds
     if (ii > 0) ll = 0;			// reset timer, operator present
#else
     ii = wait_for_key_ms(0);			// wait endless
#endif
#ifdef WITH_ROTARY_SWITCH
     if ((ii >= MIN_SELECT_TIME) || ((rotary_switch_present != 0) && (ii > 0)))
#else
     if (ii >= MIN_SELECT_TIME)
#endif
     {
        // selection only with key-press
        if (func_number == MODE_TRANS) break;		// return to TransistorTester
        if (func_number == MODE_FREQ) GetFrequency(0);
 #if PROCESSOR_TYP == 644
        if (func_number == MODE_HFREQ) GetFrequency(1);	// measure high frequency with 16:1 divider
        if (func_number == MODE_H_CRYSTAL) GetFrequency(5); // HF crystal input + 16:1 divider
        if (func_number == MODE_L_CRYSTAL) GetFrequency(6); // LF crystal input, 1:1 divider
 #endif
        if (func_number == MODE_FGEN) {
           make_frequency();		// make some sample frequencies
        }
        if (func_number == MODE_PWM) {
           do_10bit_PWM();		// generate 10bit PWM
        }
        if (func_number == MODE_ESR) {
           show_C_ESR();		// measure capacity and ESR at TP1 and TP3
        }
        if (func_number == MODE_ROTARY) {
           CheckRotaryEncoder();		// check rotary encoder
        }
  #ifdef WITH_SELFTEST
        if (func_number == MODE_SELFTEST) AutoCheck(0x11);	// Full selftest with calibration
  #endif
        if (func_number == MODE_VEXT) show_vext();
  #if (LCD_ST_TYPE == 7565)
        if (func_number == MODE_CONTRAST) set_contrast();
  #endif
        if (func_number == MODE_SHOW) {
           ShowData();			// Show Calibration Data
        }
        if (func_number == MODE_OFF) {
           ON_PORT &= ~(1<<ON_PIN);              //switch off power
           wait_for_key_ms(0); //never ending loop 
        }
        // don't increase function number for easier selection the same function
        ii = 0;			// function was executed before, do not increase func_number
#ifdef WITH_ROTARY_SWITCH
        rotary.incre = 0;	// reset all rotary information
        rotary.count = 0;
#endif
     } /* end if (ii >= MIN_SELECT_TIME) */
#ifdef WITH_ROTARY_SWITCH
     if (rotary.incre >= FAST_ROTATION) break; // to much rotation
 #ifdef POWER_OFF
     if (rotary.count != 0) ll = 0; 	// someone is working, reset timer
 #endif
     if (rotary.count >= 0) {
        func_number += rotary.count;	// function number is increased by rotary steps
     } else {
        func_number += (MODE_LAST + 1 + rotary.count);	// function is decreased by rotary steps
     }
#endif
     if (ii > 0) func_number++;	// increase the function number with key press
  } /* end for ll */
  return;
 } // end function_menu()
Beispiel #3
0
/* *************************************************** */
void make_frequency() {
#define MAX_FREQ_NR 19
  uint8_t key_pressed;
  uint8_t freq_nr;
  uint8_t old_freq;

  message_key_released(F_GEN_str);	// display f-Generator and wait for key released
  // OC1B is connected with 680 Ohm resistor to TP2 (middle test pin) 
  TCCR1A = (0<<COM1B1) | (1<<COM1B0) | (0<<WGM11) | (0<<WGM10); // CTC mode, count to OCR1A
  TIMSK1 = 0;		// no interrupt used
  OCR1A = 1;		// highest frequency
  OCR1B	= 0;		// toggle OC1B at this count
  TIFR1 = (1<<OCF1A) | (1<<OCF1A) | (1<<TOV1);	// reset interrupt flags
  TCCR1C = 0;
  TCCR1B = (0<<WGM13) | (1<<WGM12) | (0<<CS12) | (0<<CS11) | (0<<CS10); // set counter mode 
  R_PORT = 0;		// set all resistor port outputs to GND
#if PROCESSOR_TYP == 644
  R_DDR = (1<<PIN_RL1) | (1<<PIN_RL2) | (1<<PIN_RL3);		// set TP1, DDD4(TP2) and TP3 to output
#else
  R_DDR = (1<<PIN_RL1) | (1<<PIN_RL3);		// set TP1 and TP3 to output
#endif
  ADC_PORT = TXD_VAL;
  ADC_DDR = (1<<TP1) | TXD_MSK;			//connect TP1 to GND
  DDRB  |= (1<<DDB2);	// set output enable
  TCCR1B = (0<<WGM13) | (1<<WGM12) | (0<<CS12) | (0<<CS11) | (1<<CS10); // no clock divide
  old_freq = 0;
  freq_nr = MAX_FREQ_NR - 1;	// start with 1 MHz
#ifdef POWER_OFF
  uint8_t new_points;		// one point for every 30 seconds wait time
  uint8_t shown_points;		// one point for every 30 seconds wait time
  uint8_t times;		// total wait time
  shown_points = 0;
  for (times=0; times<240; times++) 
#else
  while (1)			/* wait endless without option POWER_OFF */
#endif
  {
#define KEYPRESS_LENGTH_10ms 0
#ifdef POWER_OFF
     new_points = (times+10) / 30;
     if (new_points != shown_points) {
        // count of points has changed, build LCD line1 new
        lcd_line1();
        lcd_clear_line();	// clear line 1 
        lcd_line1();
        lcd_MEM2_string(F_GEN_str);	// display f-Generator
        shown_points = new_points;
        for (new_points=0; new_points<shown_points ;new_points++) {
           lcd_data('.');		// show elapsed time, one point is 30 seconds
        }
     }
#undef KEYPRESS_LENGTH_10ms 
#define KEYPRESS_LENGTH_10ms 20		/* change frequency only with >200ms key press */
#endif
     if (old_freq != freq_nr) {
       // new frequency is selected
       if (freq_nr > MAX_FREQ_NR) freq_nr -= (MAX_FREQ_NR + 1);
       old_freq = freq_nr;	// update the last active frequency number
#ifdef FOUR_LINE_LCD
       lcd_line2();
       lcd_clear_line();	// clear line 2 for previous frequency
       lcd_line2();
       lcd_space();		// add a space to row 1 of line2
       switch_frequency(freq_nr + MAX_FREQ_NR);
       lcd_line4();
       lcd_clear_line();	// clear line 4 for next frequency
       lcd_line4();
       lcd_space();		// add a space to row 1 of line4
       switch_frequency(freq_nr + 1);
       lcd_line3();
       lcd_clear_line();	// clear line 3 for new frequency
       lcd_line3();
       lcd_data('>');
       switch_frequency(freq_nr);
#else
       lcd_line2();
       lcd_clear_line();	// clear line 2 for next frequency
       lcd_line2();
       switch_frequency(freq_nr);
#endif
     } /* end if (old_freq != freq_nr) */
     key_pressed = wait_for_key_ms(1000);
#ifdef POWER_OFF
 #ifdef WITH_ROTARY_SWITCH
     if ((key_pressed != 0) || (rotary.incre > 0)) times = 0;	// reset counter, operator is active
 #else
     if (key_pressed != 0)  times = 0;	// reset counter, operator is active
 #endif
#endif
#ifdef WITH_ROTARY_SWITCH
     if (rotary.incre > FAST_ROTATION) break;		// fast rotation ends voltage measurement
     if (rotary.count >= 0) {
        freq_nr += rotary.count;		// increase the frequency number by rotary.count
     } else {
        freq_nr += (MAX_FREQ_NR + 1 + rotary.count);	// decrease the frequency by rotary.count
     }
#endif
     if (key_pressed > KEYPRESS_LENGTH_10ms) freq_nr++; // longer key press select next frequency
     if(key_pressed >= 80) break;	// more than 0.8 seconds
  } /* end for times */
  TCCR1B = 0;		// stop counter
  TCCR1A = 0;		// stop counter
  ADC_DDR =  TXD_MSK;	// disconnect TP1 
  R_DDR = 0;		// switch resistor ports to Input
  DDRB  &= ~(1<<DDB2);	// disable output 

} /* end make frequency */
Beispiel #4
0
 // not enough Flash space for ShowIcons at ATmega328
// Show all Icons on the screen, up to four at one screen
void ShowIcons(void) {
#define ShowTime 15000  /* 15 seconds wait time, or key press, or rotary encoder movement */
 uint8_t cc;
 lcd_clear();
 lcd_big_icon(BJT_NPN|LCD_UPPER_LEFT);
 lcd_update_icon_opt(bmp_vakdiode, OPT_VREVERSE);
 lcd_big_icon(BJT_NPN|LCD_UPPER_RIGHT);
 lcd_update_icon(bmp_pnp);	// update for PNP
 lcd_set_cursor(5,0);
 lcd_MEM_string(NPN_str);
 lcd_set_cursor(5,(LCD_LINE_LENGTH / 2));
 lcd_MEM_string(PNP_str);
 wait_for_key_ms(ShowTime);

 lcd_clear();
 lcd_big_icon(N_JFET|LCD_LOWER_LEFT);
 lcd_big_icon(N_JFET|LCD_LOWER_RIGHT);
 lcd_update_icon(bmp_p_jfet);	// update to P_JFET
 lcd_set_cursor(2,1);
 lcd_data('N');		// N-Type
 lcd_data('-');
 lcd_MEM_string(jfet_str);
 lcd_set_cursor(2,1+(LCD_LINE_LENGTH / 2));
 lcd_data('P');		// P-Type
 lcd_data('-');
 lcd_MEM_string(jfet_str);
 wait_for_key_ms(ShowTime);

 lcd_clear();
 lcd_big_icon(N_E_IGBT|LCD_UPPER_LEFT);
 lcd_big_icon(N_E_IGBT|LCD_UPPER_RIGHT);
 lcd_update_icon(bmp_p_e_igbt);	// update to P-E-IGBT
 lcd_set_cursor(5,0);
 lcd_data('N');		// N-Type
 lcd_data('-');
 lcd_data('E');		// Enhancement Type
 lcd_MEM_string(igbt_str);
 lcd_set_cursor(6,(LCD_LINE_LENGTH / 2));
 lcd_data('P');		// P-Type
 lcd_data('-');
 lcd_data('E');		// Enhancement Type
 lcd_MEM_string(igbt_str);
 wait_for_key_ms(ShowTime);

 lcd_clear();
 lcd_big_icon(N_E_IGBT|LCD_LOWER_LEFT);
 lcd_update_icon(bmp_n_d_igbt);	// update to N-D-IGBT
 lcd_big_icon(N_E_IGBT|LCD_LOWER_RIGHT);
 lcd_update_icon(bmp_p_d_igbt);	// update to P-D-IGBT
 lcd_set_cursor(1,0);
 lcd_data('N');		// N-Type
 lcd_data('-');
 lcd_data('D');		// Depletion Type
 lcd_MEM_string(igbt_str);
 lcd_set_cursor(2,(LCD_LINE_LENGTH / 2));
 lcd_data('P');		// P-Type
 lcd_data('-');
 lcd_data('D');		// Depletion Type
 lcd_MEM_string(igbt_str);
 wait_for_key_ms(ShowTime);

 lcd_clear();
 lcd_big_icon(N_E_MOS|LCD_UPPER_LEFT);
 lcd_big_icon(N_E_MOS|LCD_UPPER_RIGHT);
 lcd_update_icon(bmp_p_e_mos);  // update to P-E-MOS
 lcd_set_cursor(5,0);
 lcd_data('N');		// N-Type
 lcd_data('-');
 lcd_data('E');		// Enhancement Type
 lcd_MEM_string(mosfet_str);
 lcd_set_cursor(6,(LCD_LINE_LENGTH / 2));
 lcd_data('P');		// P-Type
 lcd_data('-');
 lcd_data('E');		// Enhancement Type
 lcd_MEM_string(mosfet_str);
 wait_for_key_ms(ShowTime);

 lcd_clear();
 lcd_big_icon(N_E_MOS|LCD_LOWER_LEFT);
 lcd_update_icon(bmp_n_d_mos);  // update to N-D-MOS
 lcd_big_icon(N_E_MOS|LCD_LOWER_RIGHT);
 lcd_update_icon(bmp_p_d_mos);  // update to P-D-MOS
 lcd_set_cursor(1,1);
 lcd_data('N');		// N-Type
 lcd_data('-');
 lcd_data('D');		// Depletion Type
 lcd_MEM_string(mosfet_str);
 lcd_set_cursor(2,1+(LCD_LINE_LENGTH / 2));
 lcd_data('P');		// P-Type
 lcd_data('-');
 lcd_data('D');		// Depletion Type
 lcd_MEM_string(mosfet_str);
 wait_for_key_ms(ShowTime);
 #if (ICON_ELEMENTS == 14)
 lcd_clear();
 lcd_big_icon(TRIAC|LCD_UPPER_LEFT);
 lcd_big_icon(THYRISTOR|LCD_UPPER_RIGHT);
 wait_for_key_ms(ShowTime);

 lcd_clear();
 lcd_big_icon(INDUCTOR|LCD_LOWER_LEFT);
 lcd_big_icon(CAPACITOR|LCD_LOWER_RIGHT);
 lcd_big_icon(RESISTOR|LCD_UPPER_LEFT);
 lcd_big_icon(RESISTORS|LCD_UPPER_RIGHT);
 wait_for_key_ms(ShowTime);

 lcd_clear();
 lcd_big_icon(DIODE_C_A|LCD_UPPER_LEFT);
 lcd_big_icon(DIODES_C_A_C_A|LCD_UPPER_RIGHT);
 lcd_big_icon(DIODES_A_C_C_A|LCD_LOWER_LEFT);
 lcd_big_icon(DIODES_C_A_A_C|LCD_LOWER_RIGHT);
 wait_for_key_ms(ShowTime);
 #endif

 
 lcd_clear();
 lcd_line1();
 lcd_MEM_string(Resistor_str);    // -[=]-
 lcd_line2();
 lcd_MEM_string(Inductor_str);         // -ww-
 lcd_line3();
 lcd_MEM_string(CapZeich);          // capacitor sign
 lcd_line4();
 lcd_MEM_string(AnKat_str);       //"->|-"
 lcd_space();
 lcd_MEM_string(KatAn_str);       //"-|<-"


// show character set
 for (cc=0;cc<(0x7f-0x20);cc++) {
   if ((cc%16) == 0) {
     // begin new line
     if((cc%64) == 0) {
       wait_for_key_ms(ShowTime);
       lcd_clear();
     }
     lcd_set_cursor(((cc/16)%4)*2,0);
   }
  lcd_data(cc+0x20);
 } /* end for cc */
 wait_for_key_ms(ShowTime);

 lcd_clear();
  #ifdef LCD_CYRILLIC
 for (cc=0;cc<((Cyr_ja+1-Cyr_B)+(Cyr_schtsch+1-Cyr_D));cc++) {
   if ((cc%16) == 0) {
     // begin new line
     lcd_set_cursor(((cc/16)%4)*2,0);
   }
   if (cc <= (Cyr_ja-Cyr_B))
   {
     lcd_data(cc + Cyr_B);
   } else {
     lcd_data(cc + Cyr_D - (Cyr_ja + 1 - Cyr_B));
   }
 } /* end for cc */
 wait_for_key_ms(ShowTime);

 lcd_clear();
  #endif

}
Beispiel #5
0
//=================================================================
void ReadInductance(void) {
#if FLASHEND > 0x1fff
  // check if inductor and measure the inductance value
  unsigned int tmpint;
  unsigned int umax;
  unsigned int total_r;		// total resistance of current loop
  unsigned int mess_r;		// value of resistor used for current measurement
  unsigned long inductance[4];	// four inductance values for different measurements
  union t_combi{
  unsigned long dw;     // time_constant
  uint16_t w[2];
  } timeconstant;
  uint16_t per_ref1,per_ref2;	// percentage
  uint8_t LoPinR_L;	// Mask for switching R_L resistor of low pin
  uint8_t HiADC;	// Mask for switching the high pin direct to VCC
  uint8_t ii;
  uint8_t count;	// counter for the different measurements
  uint8_t cnt_diff;     // resistance dependent offset
  uint8_t LowPin;	// number of pin with low voltage
  uint8_t HighPin;	// number of pin with high voltage 
  int8_t ukorr;		// correction of comparator voltage
  uint8_t nr_pol1;	// number of successfull inductance measurement with polarity 1
  uint8_t nr_pol2;	// number of successfull inductance measurement with polarity 2


  inductor_lpre = 0;	// H units, mark inductor as 0
  if(PartFound != PART_RESISTOR) {
     return;	//We have found no resistor  
  }
  if (ResistorsFound != 1) {
     return;	// do not search for inductance, more than 1 resistor
  }
     if (resis[0].rx > 21000) return;

     // we can check for Inductance, if resistance is below 2100 Ohm
     for (count=0;count<4;count++) {
        // Try four times (different direction and with delayed counter start)
        if (count < 2) {
           // first and second pass, direction 1
           LowPin = resis[0].ra;
           HighPin = resis[0].rb;
        } else {
           // third and fourth pass, direction 2
           LowPin = resis[0].rb;
           HighPin = resis[0].ra;
        }
        HiADC = pgm_read_byte(&PinADCtab[HighPin]);	// Table of ADC Pins including | TXD_VAL
        LoPinR_L = pgm_read_byte(&PinRLtab[LowPin]);	//R_L mask for HighPin R_L load
        //==================================================================================
        // Measurement of Inductance values
        R_PORT = 0;		// switch R port to GND
        ADC_PORT =   TXD_VAL;		// switch ADC-Port to GND
        if ((resis[0].rx < 240) && ((count & 0x01) == 0)) {
           // we can use PinR_L for measurement
           mess_r = RR680MI - R_L_VAL;			// use only pin output resistance
           ADC_DDR = HiADC | (1<<LowPin) | TXD_MSK;	// switch HiADC and Low Pin to GND, 
        } else {
           R_DDR = LoPinR_L;   		// switch R_L resistor port for LowPin to output (GND)
           ADC_DDR = HiADC | TXD_MSK;	// switch HiADC Pin to GND 
           mess_r = RR680MI;			// use 680 Ohm and PinR_L for current measurement
        }
        // Look, if we can detect any current
        for (ii=0;ii<20;ii++) {
            // wait for current is near zero
            umax = W10msReadADC(LowPin);
            total_r =  ReadADC(HighPin);
            if ((umax < 2) && (total_r < 2)) break;	// low current detected
        }
        // setup Analog Comparator
        ADC_COMP_CONTROL = (1<<ACME);			//enable Analog Comparator Multiplexer
        ACSR =  (1<<ACBG) | (1<<ACI)  | (1<<ACIC);	// enable, 1.3V, no Interrupt, Connect to Timer1 
        ADMUX = (1<<REFS0) | LowPin;			// switch Mux to Low-Pin
        ADCSRA = (1<<ADIF) | AUTO_CLOCK_DIV; //disable ADC
   
      // setup Counter1
        timeconstant.w[1] = 0;		// set ov counter to 0
        TCCR1A = 0;			// set Counter1 to normal Mode
        TCNT1 = 0;			//set Counter to 0
        TI1_INT_FLAGS = (1<<ICF1) | (1<<OCF1B) | (1<<OCF1A) | (1<<TOV1);	// reset TIFR or TIFR1
//        HiADC |= TXD_VAL;
        wait200us();			// wait for bandgap to start up
        if ((count & 0x01) == 0 ) {
           //first start counter, then start current
           TCCR1B =  (1<<ICNC1) | (0<<ICES1) | (1<<CS10);	//start counter 1MHz or 8MHz
           ADC_PORT = HiADC;		// switch ADC-Port to VCC
        } else {
           //first start current, then start counter with delay
           //parasitic capacity of coil can cause high current at the beginning
           ADC_PORT = HiADC;		// switch ADC-Port to VCC
      #if F_CPU >= 8000000UL
           wait3us();		// ignore current peak from capacity
      #else
           wdt_reset();			// delay
           wdt_reset();			// delay
      #endif
           TI1_INT_FLAGS = (1<<ICF1);	// Reset Input Capture
           TCCR1B =  (1<<ICNC1) | (0<<ICES1) | (1<<CS10);	//start counter 1MHz or 8MHz
        }
      
      //******************************
        while(1) {
           // Wait, until  Input Capture is set
           ii = TI1_INT_FLAGS;		//read Timer flags
           if (ii & (1<<ICF1))  {
              break;
           }
           if((ii & (1<<TOV1))) {		// counter overflow, 65.536 ms @ 1MHz, 8.192ms @ 8MHz
              TI1_INT_FLAGS = (1<<TOV1);	// Reset OV Flag
              wdt_reset();
              timeconstant.w[1]++;		// count one OV
              if(timeconstant.w[1] == (F_CPU/100000UL)) {
                 break; 	//Timeout for Charging, above 0.13 s
              }
           }
        }
        TCCR1B = (0<<ICNC1) | (0<<ICES1) | (0<<CS10);  // stop counter
        TI1_INT_FLAGS = (1<<ICF1);			// Reset Input Capture
        timeconstant.w[0] = ICR1;		// get previous Input Capture Counter flag
      // check actual counter, if an additional overflow must be added
        if((TCNT1 > timeconstant.w[0]) && (ii & (1<<TOV1))) {
           // this OV was not counted, but was before the Input Capture
           TI1_INT_FLAGS = (1<<TOV1);		// Reset OV Flag
           timeconstant.w[1]++;			// count one additional OV
        }

        ADC_PORT = TXD_VAL;		// switch ADC-Port to GND
        ADCSRA = (1<<ADEN) | (1<<ADIF) | AUTO_CLOCK_DIV; //enable ADC
        for (ii=0;ii<20;ii++) {
            // wait for current is near zero
            umax = W10msReadADC(LowPin);
            total_r =  ReadADC(HighPin);
            if ((umax < 2) && (total_r < 2)) break;	// low current detected
        }
  #define CNT_ZERO_42 6
  #define CNT_ZERO_720 7
//#if F_CPU == 16000000UL
//  #undef CNT_ZERO_42
//  #undef CNT_ZERO_720
//  #define CNT_ZERO_42 7
//  #define CNT_ZERO_720 10
//#endif
        total_r = (mess_r + resis[0].rx + RRpinMI);
//        cnt_diff = 0;
//        if (total_r > 7000) cnt_diff = 1;
//        if (total_r > 14000) cnt_diff = 2;
        cnt_diff = total_r / ((14000UL * 8) / (F_CPU/1000000UL));
        tmpint = ref_mv_offs;		// corrected reference voltage (for C)
        if (mess_r < R_L_VAL) {
           // measurement without 680 Ohm
           cnt_diff = CNT_ZERO_42;
           if (timeconstant.dw < 225) {
              ukorr = (timeconstant.w[0] / 5) - 20;
           } else {
              ukorr = 25;
           }
           tmpint -= (((REF_L_KORR * 10) / 10) + ukorr);
        } else {
           // measurement with 680 Ohm resistor
           // if 680 Ohm resistor is used, use REF_L_KORR for correction
           cnt_diff += CNT_ZERO_720;
           tmpint += REF_L_KORR;
        }
        if (timeconstant.dw > cnt_diff) timeconstant.dw -= cnt_diff;
        else          timeconstant.dw = 0;
       
        if ((count&0x01) == 1) {
           // second pass with delayed counter start
           timeconstant.dw += (3 * (F_CPU/1000000UL))+10;
        }
        if (timeconstant.w[1] >= (F_CPU/100000UL)) timeconstant.dw = 0; // no transition found
        if (timeconstant.dw > 10) {
           timeconstant.dw -= 1;
        }
        // compute the maximum Voltage umax with the Resistor of the coil
        umax = ((unsigned long)mess_r * (unsigned long)ADCconfig.U_AVCC) / total_r;
        per_ref1 = ((unsigned long)tmpint * 1000) / umax;
//        per_ref2 = (uint8_t)MEM2_read_byte(&LogTab[per_ref1]);	// -log(1 - per_ref1/100)
        per_ref2 = get_log(per_ref1);		// -log(1 - per_ref1/1000)
/* ********************************************************* */
#if 0
          if (count == 0) {
             lcd_line3();
             DisplayValue(count,0,' ',4);
             DisplayValue(timeconstant.dw,0,'+',4);
             DisplayValue(cnt_diff,0,' ',4);
             DisplayValue(total_r,-1,'r',4);
             lcd_space();
             DisplayValue(per_ref1,-1,'%',4);
             lcd_line4();
             DisplayValue(tmpint,-3,'V',4);
             lcd_space();
             DisplayValue(umax,-3,'V',4);
             lcd_space();
             DisplayValue(per_ref2,-1,'%',4);
             wait_about4s();
             wait_about2s();
          }
#endif
/* ********************************************************* */
        // inductor_lx in 0.01mH units,  L = Tau * R
        per_ref1 = ((per_ref2 * (F_CPU/1000000UL)) + 5) / 10;
        inductance[count] = (timeconstant.dw * total_r ) / per_ref1;
        if (((count&0x01) == 0) && (timeconstant.dw > ((F_CPU/1000000UL)+3))) {
           // transition is found, measurement with delayed counter start is not necessary
           inductance[count+1] = inductance[count];	// set delayed measurement to same value
           count++;		// skip the delayed measurement
        }
        wdt_reset();
     }  //end for count
     ADC_PORT = TXD_VAL;		// switch ADC Port to GND
     wait_about20ms();
     nr_pol1 = 0;
     if (inductance[1] > inductance[0]) { nr_pol1 = 1; } 
     nr_pol2 = 2;
     if (inductance[3] > inductance[2]) { nr_pol2 = 3; } 
     if (inductance[nr_pol2] < inductance[nr_pol1]) nr_pol1 = nr_pol2;
     inductor_lx = inductance[nr_pol1];
     inductor_lpre = -5;	// 10 uH units
     if (((nr_pol1 & 1) == 1) || (resis[0].rx >= 240)) {
        // with 680 Ohm resistor total_r is more than 7460
        inductor_lpre = -4;	// 100 uH units
        inductor_lx = (inductor_lx + 5) / 10;
     } 
     if (inductor_lx == 0) inductor_lpre = 0;	//mark as zero

  // switch all ports to input
  ADC_DDR =  TXD_MSK;		// switch all ADC ports to input
  R_DDR = 0;			// switch all resistor ports to input
#endif
  return;
 } // end ReadInductance()
void GetFrequency(uint8_t range) {
  unsigned char taste;			// set if key is pressed during measurement
 #if PROCESSOR_TYP == 644
  unsigned long freq_count;		// the counted pulses in 1 second
 #endif
  unsigned long long ext_period;
  unsigned long freq_from_per;
  uint8_t ii;
  uint8_t mm;
  /* range has set the lowest bit to use the 16:1 frequency divider permanently. */
  /* The upper bits of range specifies the input selection. */
  /* 0 = external input, 2 = channel 2, 4 = HF Quartz, 6 = LF Quartz */
  
 #if PROCESSOR_TYP == 644
  FDIV_DDR |= (1<<FDIV_PIN);		//switch to output
  if ((range & 0x01) == 0) {
     FDIV_PORT &= ~(1<<FDIV_PIN);	// switch off the 16:1 divider
  } else {
     FDIV_PORT |= (1<<FDIV_PIN);	// use frequency divider for next measurement
  }
  FINP_DDR |= (1<<FINP_P0) | (1<<FINP_P1);	// switch both pins to output

 FINP_PORT &= ~(1<<FINP_P0);		// clear lower bit of input selection
 FINP_PORT &= ~(1<<FINP_P1);		// clear higher bit of input selection
 if (range == 0) {  
    message_key_released(FREQ_str);	// Frequency: in line 1
 } else if (range == 1) { 
    message_key_released(HFREQ_str);	// High Frequency: in line 1
 } else if (range < 4) { /* 2+3 */
    FINP_PORT |= (1<<FINP_P0);		// set lower bit of input selection
    FINP_PORT &= ~(1<<FINP_P1);		// clear higher bit of input selection
 } else if (range < 6) { /* 4+5 */
    FINP_PORT &= ~(1<<FINP_P0);		// clear lower bit of input selection
    FINP_PORT |= (1<<FINP_P1);		// set higher bit of input selection
    message_key_released(H_CRYSTAL_str);	// HF Quarz: in line 1
 } else {  /* 6+7 */
    FINP_PORT |= (1<<FINP_P0);		// set lower bit of input selection
    FINP_PORT |= (1<<FINP_P1);		// set higher bit of input selection
    message_key_released(L_CRYSTAL_str);	// LF Quarz: in line 1
 }

 #else
  message_key_released(FREQ_str);	// Frequency: in line 1
 #endif
  taste = 0;				// reset flag for key pressed
  for (mm=0;mm<240;mm++) {
     // *************************************************************************
     // *********** straight frequency measurement by counting 1 second *********
     // *************************************************************************
     //set up Counter 0
     // Counter 0 is used to count the external signal connected to T0 (PD4 or PB0)
     FREQINP_DDR &= ~(1<<FREQINP_PIN);	// switch frequency pin to input
     wait1ms();				// let capacitor time to load to 2.4V input
#if PROCESSOR_TYP == 1280
     TCCR3A = 0; 			// normal operation, no output
     TCNT3 = 0;				// set counter 3 to zero
     ext_freq.dw = 0;			// set external frequency to zero
     TIFR3 = (1<<TOV3);			// clear OV interrupt of timer 3
     TIMSK3 = (1<<TOIE3);		// enable OV interrupt of timer 3
#else
     TCCR0A = 0; 			// normal operation, no output
     TCNT0 = 0;				// set counter to zero
     ext_freq.dw = 0;			// set external frequency to zero
     TIFR0 = (1<<TOV0);			// clear OV interrupt of timer 0
     TIMSK0 = (1<<TOIE0);		// enable OV interrupt of timer 0
#endif
     // start counter after starting second counter timer 1

     // set up counter 1 to measure one second
     TCCR1A = 0;			// normal operation
#define CNT1_END_VAL ((F_CPU / 256UL) + 1)
#define CNT1_DIVIDER (1<<CS12)
#if CNT1_END_VAL > 0xffff
 #undef CNT1_END_VAL
 #undef CNT1_DIVIDER
 #define CNT1_END_VAL ((F_CPU / 1024UL) + 1)
 #define CNT1_DIVIDER ((1<<CS12) | (1<<CS10))
 #if F_CPU != ((F_CPU / 1024UL) * 1024UL)
  #warning F_CPU can not be divided by 1024, measured frequency is wrong!
 #endif
#else 
 #if F_CPU != ((F_CPU / 256UL) * 256UL)
  #warning F_CPU can not be divided by 256, measured frequency is wrong!
 #endif
#endif
     OCR1B = CNT1_END_VAL;		// set to 1 second  (counter 0 is started with 1)
     OCR1A = 1;				// start counter 0 with first count
     TCNT1 = 0;				// set counter to zero
     GTCCR  |= (1<<PSRSYNC);		// reset clock precounter
     TIFR1 = (1<<OCF1B) | (1<<OCF1A);	// clear Output compare match
     TIMSK1 = (1<<OCIE1B) | (1<<OCIE1A);	// enable the Compare A match and Compare B match interrupt
     sei();				// set interrupt enable
     TCCR1B = CNT1_DIVIDER;		// divide CPU clock by 256, start counter
     // both counter are running now, wait for counter 1 reach OCR1A
     for (ii=0;ii<50;ii++) {
        wait20ms();			// first count of counter 1 (<32us) has started the counter 0
        wdt_reset();
        if (!(RST_PIN_REG & (1<<RST_PIN))) taste = 1;	// user request stop of operation
#if PROCESSOR_TYP == 1280
        if (TCCR3B == 0) break;		// timer 3 is stopped by interrupt
#else
        if (TCCR0B == 0) break;		// timer 0 is stopped by interrupt
#endif
     }
     // one second is counted
#if PROCESSOR_TYP == 1280
     TCCR3B = 0;		// stop timer 3, if not stopped by timer 1 compare interrupt
     ext_freq.w[0] = TCNT3;	// add lower 16 bit to get total counts
#else
     TCCR0B = 0;		// stop timer 0, if not stopped by timer 1 compare interrupt
     ext_freq.b[0] = TCNT0;	// add lower 8 bit to get total counts
#endif
 #if PROCESSOR_TYP == 644
     freq_count = ext_freq.dw;	// save the frequency counter
 #endif
 #if (LCD_LINES > 3)
     lcd_line3();
     lcd_clear_line();
     lcd_line4();
     lcd_clear_line();
     lcd_clear_line2();
 #else
     lcd_clear();		// clear total display
 #endif
     lcd_data('f');
     lcd_equal();		// lcd_data('=');
 #if PROCESSOR_TYP == 644
     if ((FDIV_PORT&(1<<FDIV_PIN)) == 0) {
        Display_Hz(ext_freq.dw, 7);
     } else {
        // frequency divider is activ
        Display_Hz(ext_freq.dw*FREQ_DIV, 7);
     }
 #else
     Display_Hz(ext_freq.dw, 7);
 #endif
 #if PROCESSOR_TYP == 644
     lcd_space();
     if ((FDIV_PORT&(1<<FDIV_PIN)) != 0) {
        lcd_data('/');		// Frequency divider is activ
     } else {
        lcd_space();		// Frequency divider is not activ
     }
 #endif
     FREQINP_DDR &= ~(1<<FREQINP_PIN);	// switch frequency pin to input
     if (TCCR1B != 0) {
       // Exact 1000ms period is only with "end of period" from timer1 interrupt.
       // When stopped with the for loop, the time is too long because wait call does not
       // respect CPU time used for interrupts and loop itself.
       // For this case show ? behind the Hz. 
       lcd_data('?');
     }
     TCCR1B = 0;		// stop timer 1
     TIMSK1 = 0;		// disable all timer 1 interrupts
     if ((ext_freq.dw < FMAX_PERIOD) && (ext_freq.dw > 0)) {
     // *************************************************************************
     // ******** Period measurement by counting some periods ******************** 
     // *************************************************************************
        pinchange_max = ((10 * (unsigned long)ext_freq.dw) + MHZ_CPU) / MHZ_CPU;	// about 10000000 clock tics
        pinchange_max += pinchange_max;	// * 2 for up and down change
        FREQINP_DDR &= ~(1<<FREQINP_PIN);	// switch frequency pin to input
        wait1ms();			// let capacitor time to load to 2.4V input
#if PROCESSOR_TYP == 1280
        TCNT3 = 0;			// set counter 3 to zero
        ext_freq.dw = 0;		// reset counter to zero
        TIFR3 = (1<<TOV3);		// clear OV interrupt
        TIMSK3 = (1<<TOIE3);		// enable OV interrupt
        // counter 3 ist started with first pin change interrupt
        pinchange_count = 0;
	EICRB = (0<<ISC61) | (1<<ISC60); // set int6 pin change
        EIFR  |= (1<<INTF6);		// clear interrupt 6 flag
        PCMSK_FREQ |= (1<<PCINT_FREQ); // enable int6
#else
        TCNT0 = 0;			// set counter 0 to zero
        ext_freq.dw = 0;		// reset counter to zero
        TIFR0 = (1<<TOV0);		// clear OV interrupt
        TIMSK0 = (1<<TOIE0);		// enable OV interrupt
        // counter 0 ist started with first pin change interrupt
        pinchange_count = 0;
        PCIFR  = (1<<PCI_CLEAR_BIT);		// clear Pin Change Status
        PCICR  |= (1<<PCI_ENABLE_BIT);		// enable pin change interrupt
#endif
        sei();
        PCMSK_FREQ |= (1<<PCINT_FREQ);	// monitor PD4 PCINT20 or PB0 PCINT8 pin change
        for (ii=0;ii<250;ii++) {
           wait20ms();
           wdt_reset();
           if (!(RST_PIN_REG & (1<<RST_PIN))) taste = 1;	// user request stop of operation
           if ((PCMSK_FREQ & (1<<PCINT_FREQ)) == 0) break;		// monitoring is disabled by interrupt
        } /* end for ii */
#if PROCESSOR_TYP == 1280
        TCCR3B = 0;		// stop counter 3
        PCMSK_FREQ &= ~(1<<PCINT_FREQ); // disable int6
        ext_freq.w[0] = TCNT3;		// add lower 16 bit to get total counts
#else
        TCCR0B = 0;		// stop counter 0
        PCMSK_FREQ &= ~(1<<PCINT_FREQ);		// stop monitor PD4 PCINT20 or PB0 PCINT8 pin change
        PCICR &= ~(1<<PCI_ENABLE_BIT);	// disable the interrupt
        ext_freq.b[0] = TCNT0;		// add lower 8 bit to get total counts
#endif
//        lcd_clear_line2();
//        wait50ms();		// let LCD flicker to 
 #if (LCD_LINES > 3)
        lcd_line3();		// use line3 to report the period with 4-line LCD
 #else
        lcd_line2();		// report period on line 2 of 2-line LCD
 #endif
        lcd_data('T');
        lcd_equal();		// lcd_data('=');
        ext_period = ((unsigned long long)ext_freq.dw * (200000/MHZ_CPU)) / pinchange_max;
 #if PROCESSOR_TYP == 644
        if ((FDIV_PORT&(1<<FDIV_PIN)) != 0) {
           // frequency divider is activ, period is measured too long
           ext_period = ext_period / FREQ_DIV;
        }
 #endif
        if (pinchange_max > 127) {
           DisplayValue(ext_period,-11,'s',7);	// show period converted to 0.01ns units
        } else {
           //prevent overflow of 32-Bit
           DisplayValue((unsigned long)(ext_period/100),-9,'s',7);	// show period converted to 1ns units
        }
        if (ii == 250) {
           lcd_data('?');		// wait loop has regular finished
        } else {
           if (ext_period > 249500) {
 #if (LCD_LINES > 3)
              lcd_line4();		// use line 4 of 4-line LCD to report the computed frequency
 #else
              lcd_line1();		// overwrite line 1 of 2-line LCD to report the computed frequency
 #endif
              lcd_data('f');
              lcd_equal();		// lcd_data('=');
              if (ext_period > 1000000000) {
                 // frequency in 0.000001Hz (1e11*1e6)/(0.01ns count)
                 freq_from_per = (unsigned long long)(100000000000000000) / ext_period;
                 DisplayValue(freq_from_per,-6,'H',7);  // display with  0.000001 Hz resolution
              } else {
                 // prevent unsigned long overflow, scale to 0.0001 Hz
                 // frequency in 0.0001Hz (1e11*1e4)/(0.01ns count)
                 freq_from_per = (unsigned long long)(1000000000000000) / ext_period;
                 DisplayValue(freq_from_per,-4,'H',7);  // display with  0.0001 Hz resolution
              }
              lcd_data('z');
              FREQINP_DDR &= ~(1<<FREQINP_PIN);	// switch frequency pin to input
           }
        }
     }  /* end if 1 < ext_freq < FMAX_PERIOD */
 #if PROCESSOR_TYP == 644
     if ((FDIV_PORT & (1<<FDIV_PIN)) == 0) {
        // frequency divider is not activ
        if ( ((freq_count >= FMAX_PERIOD) && (freq_count < ((unsigned long)FMAX_PERIOD*FREQ_DIV))) ||
            (freq_count > FMAX_INPUT) ){
           FDIV_PORT |= (1<<FDIV_PIN);			// use frequency divider for next measurement
        }
     } else {
        // frequency divider is activ
        if ((freq_count < (FMAX_PERIOD/FREQ_DIV)) && ((range & 0x01) == 0)) {
           FDIV_PORT &= ~(1<<FDIV_PIN);			// switch off the 16:1 divider
        }
     }
 #endif
//     taste += wait_for_key_ms(SHORT_WAIT_TIME/2);
     TIMSK0 = 0;		// disable all timer 0 interrupts
     taste += wait_for_key_ms(2000);
 #ifdef WITH_ROTARY_SWITCH
     if ((taste != 0) || (rotary.incre > 2)) break;
 #else
     if (taste != 0) break;
 #endif
  }  /* end for mm  */
 
  return;
 } // end GetFrequency()
Beispiel #7
0
void AutoCheck(uint8_t test_mode) {
  /* (test_mode & 0x0f) == 0 , only calibration without T1-T7 */
  /* (test_mode & 0x0f) == 1 , calibration and additional T1-T7 */
  /* (test_mode & 0xf0) == 0 , check for shorted probes, if unshorted, return */
  /* (test_mode & 0xf0) == 0x10 , ask for shorted probes */

 uint8_t ww;		// counter for repeating the tests
 int  adcmv[7];
 #ifdef EXTENDED_TESTS
  uint16_t u680;	// 3 * (Voltage at 680 Ohm)
  uint8_t taste;	// ist key pressed? 0 = no
 #else
  #ifndef NO_TEST_T1_T7
  #warning "Selftest without extended tests T1 to T7!"
  #endif
 #endif
 #if defined(EXTENDED_TESTS) || defined(WITH_MENU)
  uint8_t tt;		// number of running test
 #endif

 #ifdef FREQUENCY_50HZ
  uint8_t ff50;		// loop counter for 2s
 #endif

// define the maximum count of repetitions MAX_REP
#define MAX_REP 4

 #ifdef AUTO_CAL
uint8_t cap_found;	// counter for found capacitor
  #ifdef AUTOSCALE_ADC
int8_t udiff;		// difference between ADC Voltage with VCC or Bandgap reference
int8_t udiff2;
  #endif
 #endif
PartFound = PART_NONE;		// no part found before
if ((test_mode & 0xf0) == 0) {
  // probed should be shorted already to begin selftest
  if (AllProbesShorted() != 3) return;
  lcd_clear();
  lcd_MEM_string(SELFTEST);		// "Selftest mode.."
  lcd_line2();
  lcd_data('?');			// wait for key pressed for confirmation
  if (wait_for_key_ms(2000) > 10) goto begin_selftest;	// key is pressed again
 #ifdef WITH_MENU
} else {
  // report to user, that probes should be shorted
  ww = 0;
  for (tt=0;tt<150;tt++) {	/* wait about 30 seconds for shorted probes */
    lcd_clear();
    lcd_MEM2_string(SHORT_PROBES_str);	// message "Short probes!" to LCD
    if (AllProbesShorted() == 3) {
       ww++;	// all probes now shorted
    } else {
       ww = 0;	// connection not stable, retry
    }
    if (ww > 3) break;	// connection seems to be stable
    lcd_refresh();		// write the pixels to display, ST7920 only
    wait_about200ms();			// wait 200ms and try again
  }  /* end for (tt...) */
  if (tt < 150) goto begin_selftest;		// is shorted before time limit
  goto no_zero_resistance;			// skip measuring of the zero resistance
 #endif
}
// no key pressed for 2s
lcd_clear();
lcd_MEM_string(VERSION_str);	//"Version ..."
return;

begin_selftest:
lcd_line2();
lcd_MEM2_string(R0_str);		// "R0="
eeprom_write_byte((uint8_t *)(&EE_ESR_ZEROtab[2]), (uint8_t)0);	// clear zero offset
eeprom_write_byte((uint8_t *)(&EE_ESR_ZEROtab[3]), (uint8_t)0);	// clear zero offset
eeprom_write_byte((uint8_t *)(&EE_ESR_ZEROtab[1]), (uint8_t)0);	// clear zero offset

adcmv[0] = GetESR(TP3, TP1);
adcmv[1] = GetESR(TP3, TP2);
adcmv[2] = GetESR(TP2, TP1);
DisplayValue16(adcmv[0],-2,' ',3);
DisplayValue16(adcmv[1],-2,' ',3);
DisplayValue16(adcmv[2],-2,LCD_CHAR_OMEGA,3);
if (adcmv[0] >= 90) {
  adcmv[0] = ESR_ZERO;	// set back to default value
}
eeprom_write_byte((uint8_t *)(&EE_ESR_ZEROtab[2]), (uint8_t)adcmv[0]);	// fix zero offset
if (adcmv[1] >= 90) {
  adcmv[1] = ESR_ZERO;	// set back to default value
}
eeprom_write_byte((uint8_t *)(&EE_ESR_ZEROtab[3]), (uint8_t)adcmv[1]);	// fix zero offset
if (adcmv[2] >= 90) {
  adcmv[2] = ESR_ZERO;	// set back to default value
}
eeprom_write_byte((uint8_t *)(&EE_ESR_ZEROtab[1]), (uint8_t)adcmv[2]);	// fix zero offset
last_line_used = 2;
wait_for_key_5s_line2();		// wait up to 5 seconds and clear line 2

 #ifdef WITH_MENU
no_zero_resistance:
 #endif
 #ifdef EXTENDED_TESTS
#define TEST_COUNT 8
if((test_mode & 0x0f) == 1) {  /* full test requested */

for(tt=1;tt<TEST_COUNT;tt++) {		// loop for all Tests
for(ww=0;ww<MAX_REP;ww++) {	// repeat the test MAX_REP times
   lcd_clear_line2();		// clear total line 2
   lcd_clear_line1();		// clear total line 1
   lcd_data('T');			//output the Testmode "T"
   u2lcd(tt);		//lcd_string(utoa(tt, outval, 10));	//output Test number
   lcd_space();
				//############################################
   if (tt == 1) {   // output of reference voltage and factors for capacity measurement
      lcd_MEM2_string(URef_str);	//"URef="
      Calibrate_UR();		// get Reference voltage, Pin resistance
      Display_mV(ref_mv,4);
      lcd_line2();			//Cursor to column 1, row 2
      lcd_MEM2_string(RHfakt_str);	//"RHf="
      u2lcd(RHmultip);	//lcd_string(utoa(RHmultip, outval, 10));
      ADCconfig.Samples = R_ANZ_MESS;	// set number of ADC reads near to maximum
   }
				//############################################
   if (tt == 2) { // how equal are the RL resistors? 
      u680 = ((long)ADCconfig.U_AVCC * (PIN_RM + R_L_VAL) / (PIN_RM + R_L_VAL + R_L_VAL + PIN_RP));
      R_PORT = 1<<PIN_RL1;		//RL1 to VCC
      R_DDR = (1<<PIN_RL1) | (1<<PIN_RL2);	//RL2 to -
      adcmv[0] = W20msReadADC(TP1);
      adcmv[0] -= u680;
      R_DDR = (1<<PIN_RL1) | (1<<PIN_RL3);	//RL3 to -
      adcmv[1] = W20msReadADC(TP1);
      adcmv[1] -= u680;
      R_PORT = 1<<PIN_RL2;		//RL2 to VCC
      R_DDR = (1<<PIN_RL2) | (1<<PIN_RL3);	//RL3 to -
      adcmv[2] = W20msReadADC(TP2);
      adcmv[2] -= u680;
      lcd_MEM_string(RLRL_str);	// "RLRL"
   }
				//############################################
   if (tt == 3) { // how equal are the RH resistors
      R_PORT = 1<<PIN_RH1;		//RH1 to VCC
      R_DDR = (1<<PIN_RH1) | (1<<PIN_RH2);	//RH2 to -
      adcmv[0] = W20msReadADC(TP1);
      adcmv[3] = ADCconfig.U_AVCC / 2;
      adcmv[0] -= adcmv[3];
      R_DDR = (1<<PIN_RH1) | (1<<PIN_RH3);	//RH3 to -
      adcmv[1] = W20msReadADC(TP1);
      adcmv[1] -= adcmv[3];
      R_PORT = 1<<PIN_RH2;		//RH2 to VCC
      R_DDR = (1<<PIN_RH2) | (1<<PIN_RH3);	//RH3 to -
      adcmv[2] = W20msReadADC(TP2);
      adcmv[2] -= adcmv[3];
      lcd_MEM_string(RHRH_str);	// "RHRH"
   }
				//############################################
   if (tt == 4) { // Text release probes
      lcd_MEM_string(RELPROBE);	// "Release Probes"
      if (AllProbesShorted() != 0) ww = MAX_REP-2;
   }
				//############################################
   if (tt == 5) { // can we switch the ADC pins to GND across R_H resistor?
      R_PORT = 0;
      R_DDR = 1<<PIN_RH1;		//Pin 1 over R_H to GND
      adcmv[0] = W20msReadADC(TP1);

      R_DDR = 1<<PIN_RH2;		//Pin 2 over R_H to GND
      adcmv[1] = W20msReadADC(TP2);

      R_DDR = 1<<PIN_RH3;		//Pin 3 over R_H to GND
      adcmv[2] = W20msReadADC(TP3);
      lcd_MEM_string(RH1L_str);	// "RH_Lo="
   }
				//############################################
   if (tt == 6) { // can we switch the ADC pins to VCC across the R_H resistor?
      R_DDR = 1<<PIN_RH1;		//Pin 1 over R_H to VCC
      R_PORT = 1<<PIN_RH1;
      adcmv[0] = W20msReadADC(TP1) - ADCconfig.U_AVCC;
      R_DDR = 1<<PIN_RH2;		//Pin 2 over R_H to VCC
      R_PORT = 1<<PIN_RH2;
      adcmv[1] = W20msReadADC(TP2) - ADCconfig.U_AVCC;
      R_DDR = 1<<PIN_RH3;		//Pin 3 over R_H to VCC
      R_PORT = 1<<PIN_RH3;
      adcmv[2] = W20msReadADC(TP3) - ADCconfig.U_AVCC;
      lcd_MEM_string(RH1H_str);	// "RH_Hi="
   }
   if (tt == 7) { // is the voltage of all R_H / R_L dividers correct?
      u680 = ((long)ADCconfig.U_AVCC * (PIN_RM + R_L_VAL) / (PIN_RM + R_L_VAL + (unsigned long)R_H_VAL*100));
      R_PORT = 1<<PIN_RH1;		//RH1 to VCC
      R_DDR = (1<<PIN_RH1) | (1<<PIN_RL1);	//RH1 to +, RL1 to -
      adcmv[0] = W20msReadADC(TP1);
      adcmv[0] -= u680;
      R_PORT = 1<<PIN_RH2;		//RH2 to VCC
      R_DDR = (1<<PIN_RH2) | (1<<PIN_RL2);	//RH2 to +, RL2 to -
      adcmv[1] = W20msReadADC(TP2);
      adcmv[1] -= u680;
      R_PORT = 1<<PIN_RH3;		//RH3 to VCC
      R_DDR = (1<<PIN_RH3) | (1<<PIN_RL3);	//RH3 to +, RL3 to -
      adcmv[2] = W20msReadADC(TP3);
      adcmv[2] -= u680;
      lcd_MEM_string(RHRL_str);	// "RH/RL"
   }
				//############################################
   if (tt > 1) {	// output 3 voltages 
      lcd_line2();			//Cursor to column 1, row 2
      i2lcd(adcmv[0]);		// lcd_string(itoa(adcmv[0], outval, 10));	//output voltage 1
      lcd_space();
      i2lcd(adcmv[1]);		// lcd_string(itoa(adcmv[1], outval, 10));	//output voltage 2
      lcd_space();
      i2lcd(adcmv[2]);		// lcd_string(itoa(adcmv[2], outval, 10));	//output voltage 3
   }
   ADC_DDR =  TXD_MSK;		// all-Pins to Input
   ADC_PORT = TXD_VAL;		// all ADC-Ports to GND
   R_DDR = 0;			// all R-Ports to Input
   R_PORT = 0;
   taste = wait_for_key_ms(1000);	// wait up to 1 second or key is pressed
   if ((tt != 4) && (taste > 10)) {
      // don't finish repetition  for T4 with pressed key
      break; // if key is pressed, don't repeat
   }
} //end for ww
wait_for_key_ms(1000);	// wait up to 1 second or key is pressed
} //end for tt
  #if PROCESSOR_TYP == 1280
lcd_clear();
lcd_testpin(TP1);
lcd_data('L');
lcd_equal();			// lcd_data('=');
ADC_PORT = TXD_VAL;
ADC_DDR = (1<<TP1) | TXD_MSK;
R_PORT = (1<<PIN_RL1);
R_DDR = (1<<PIN_RL1);
adcmv[0] = W5msReadADC(TP1);
ADCSRB = (1<<MUX5);		// switch to upper 8 MUX inputs
adcmv[1] = ReadADC(PIN_RL1);
ADCSRB = 0;			// switch back to lower 8 MUX inputs
ResistorVal[0] = (adcmv[0] * (unsigned long)R_L_VAL) / (adcmv[1] - adcmv[0]);
DisplayValue(ResistorVal[0],-1,LCD_CHAR_OMEGA,3);
lcd_space();
lcd_data('H');
lcd_equal();			// lcd_data('=');
ResistorVal[1] = ((ADCconfig.U_AVCC - adcmv[1]) * (unsigned long)R_L_VAL) / (adcmv[1] - adcmv[0]);
DisplayValue(ResistorVal[1],-1,LCD_CHAR_OMEGA,3);
lcd_line2();
lcd_testpin(TP1);
lcd_space();
lcd_data('H');
lcd_equal();			// lcd_data('=');
ADC_PORT = (1<<TP1) | TXD_VAL;
R_PORT = 0;
adcmv[0] = W5msReadADC(TP1);
ADCSRB = (1<<MUX5);		// switch to upper 8 MUX inputs
adcmv[1] = ReadADC(PIN_RL1);
ADCSRB = 0;			// switch back to lower 8 MUX inputs
ResistorVal[1] = ((ADCconfig.U_AVCC - adcmv[0]) * (unsigned long)R_L_VAL) / (adcmv[0] - adcmv[1]);
DisplayValue(ResistorVal[1],-1,LCD_CHAR_OMEGA,3);
lcd_space();
lcd_data('L');
lcd_equal();			// lcd_data('=');
ResistorVal[0] = (adcmv[1] * (unsigned long)R_L_VAL) / (adcmv[0] - adcmv[1]);
DisplayValue(ResistorVal[0],-1,LCD_CHAR_OMEGA,3);
wait_about1s();			// only for mega1280
last_line_used = 2;
wait_for_key_5s_line2();		// wait up to 5 seconds and clear line 2
// 
lcd_clear();
lcd_testpin(TP2);
lcd_data('L');
lcd_equal();			// lcd_data('=');
ADC_PORT = TXD_VAL;
ADC_DDR = (1<<TP2) | TXD_MSK;
R_PORT = (1<<PIN_RL2);
R_DDR = (1<<PIN_RL2);
adcmv[0] = W5msReadADC(TP2);
ADCSRB = (1<<MUX5);		// switch to upper 8 MUX inputs
adcmv[1] = ReadADC(PIN_RL2);
ADCSRB = 0;			// switch back to lower 8 MUX inputs
ResistorVal[0] = (adcmv[0] * (unsigned long)R_L_VAL) / (adcmv[1] - adcmv[0]);
DisplayValue(ResistorVal[0],-1,LCD_CHAR_OMEGA,3);
lcd_space();
lcd_data('H');
lcd_equal();			// lcd_data('=');
ResistorVal[1] = ((ADCconfig.U_AVCC - adcmv[1]) * (unsigned long)R_L_VAL) / (adcmv[1] - adcmv[0]);
DisplayValue(ResistorVal[1],-1,LCD_CHAR_OMEGA,3);
lcd_line2();
lcd_testpin(TP2);
lcd_data('H');
lcd_equal();			// lcd_data('=');
ADC_PORT = (1<<TP2) | TXD_VAL;
R_PORT = 0;
adcmv[0] = W5msReadADC(TP2);
ADCSRB = (1<<MUX5);		// switch to upper 8 MUX inputs
adcmv[1] = ReadADC(PIN_RL2);
ADCSRB = 0;			// switch back to lower 8 MUX inputs
ResistorVal[1] = ((ADCconfig.U_AVCC - adcmv[0]) * (unsigned long)R_L_VAL) / (adcmv[0] - adcmv[1]);
DisplayValue(ResistorVal[1],-1,LCD_CHAR_OMEGA,3);
lcd_space();
lcd_data('L');
lcd_equal();			// lcd_data('=');
ResistorVal[0] = (adcmv[1] * (unsigned long)R_L_VAL) / (adcmv[0] - adcmv[1]);
DisplayValue(ResistorVal[0],-1,LCD_CHAR_OMEGA,3);
wait_about1s();			// only for mega1280
last_line_used = 2;
wait_for_key_5s_line2();		// wait up to 5 seconds and clear line 2
//
lcd_clear();
lcd_testpin(TP3);
lcd_data('L');
lcd_equal();			// lcd_data('=');
ADC_DDR = (1<<TP3) | TXD_MSK;
R_PORT = (1<<PIN_RL3);
R_DDR = (1<<PIN_RL3);
adcmv[0] = W5msReadADC(TP3);
ADCSRB = (1<<MUX5);		// switch to upper 8 MUX inputs
adcmv[1] = ReadADC(PIN_RL3);
ADCSRB = 0;
ResistorVal[0] = (adcmv[0] * (unsigned long)R_L_VAL) / (adcmv[1] - adcmv[0]);
DisplayValue(ResistorVal[0],-1,LCD_CHAR_OMEGA,3);
lcd_space();
lcd_data('H');
lcd_equal();			// lcd_data('=');
ResistorVal[1] = ((ADCconfig.U_AVCC - adcmv[1]) * (unsigned long)R_L_VAL) / (adcmv[1] - adcmv[0]);
DisplayValue(ResistorVal[1],-1,LCD_CHAR_OMEGA,3);
lcd_line2();
lcd_testpin(TP3);
lcd_data('H');
lcd_equal();			// lcd_data('=');
ADC_PORT = (1<<TP3) | TXD_VAL;
R_PORT = 0;
adcmv[0] = W5msReadADC(TP3);
ADCSRB = (1<<MUX5);		// switch to upper 8 MUX inputs
adcmv[1] = ReadADC(PIN_RL3);
ADCSRB = 0;			// switch back to lower 8 MUX inputs
ResistorVal[1] = ((ADCconfig.U_AVCC - adcmv[0]) * (unsigned long)R_L_VAL) / (adcmv[0] - adcmv[1]);
DisplayValue(ResistorVal[1],-1,LCD_CHAR_OMEGA,3);
lcd_space();
lcd_data('L');
lcd_equal();			// lcd_data('=');
ResistorVal[0] = (adcmv[1] * (unsigned long)R_L_VAL) / (adcmv[0] - adcmv[1]);
DisplayValue(ResistorVal[0],-1,LCD_CHAR_OMEGA,3);
wait_about1s();			// only for mega1280
last_line_used = 2;
wait_for_key_5s_line2();		// wait up to 5 seconds and clear line 2
  #endif	/* PROCESSOR_TYP == 1280 */
}	/* end if((test_mode & 0x0f) == 1) */
 #endif		/* end EXTENDED_TESTS */

for (ww=0;ww<120;ww++) {
  // wait up to 1 minute for releasing the probes
  if (AllProbesShorted() == 0) break;
  lcd_clear_line2();		// clear total line2
  lcd_MEM_string(RELPROBE);	// "Release Probes"
  lcd_refresh();		// write the pixels to display, ST7920 only
  wait_about500ms();
}



lcd_clear();
lcd_MEM_string(RIHI_str);	// "RiHi="
DisplayValue16(RRpinPL,-1,LCD_CHAR_OMEGA,3);
lcd_line2();
lcd_MEM_string(RILO_str);	// "RiLo="
DisplayValue16(RRpinMI,-1,LCD_CHAR_OMEGA,3);
last_line_used = 2;
wait_for_key_5s_line2();		// wait up to 5 seconds and clear line 2

//measure Zero offset for Capacity measurement
PartFound = PART_NONE;
lcd_clear();
lcd_MEM_string(C0_str);			//output "C0 "
ReadCapacity(TP3, TP1);
adcmv[5] = (unsigned int) cap.cval_uncorrected.dw;	//save capacity value of empty Pin 1:3
ReadCapacity(TP3, TP2);
adcmv[6] = (unsigned int) cap.cval_uncorrected.dw;	//save capacity value of empty Pin 2:3
ReadCapacity(TP2, TP1);
adcmv[2] = (unsigned int) cap.cval_uncorrected.dw;	//save capacity value of empty Pin 1:2
ReadCapacity(TP1, TP3);
adcmv[1] = (unsigned int) cap.cval_uncorrected.dw;	//save capacity value of empty Pin 3:1
ReadCapacity(TP2, TP3);
adcmv[4] = (unsigned int) cap.cval_uncorrected.dw;	//save capacity value of empty Pin 3:2
ReadCapacity(TP1, TP2);
adcmv[0] = (unsigned int) cap.cval_uncorrected.dw;	//save capacity value of empty Pin 2:1
 #ifdef WITH_MENU
if (((test_mode & 0x0f) == 1) || (UnCalibrated == 2))
 #else
if (UnCalibrated == 2)
 #endif
{
  adcmv[3] = adcmv[0] + 2;		// mark as uncalibrated until Cap > 100nF has success
} else {
  adcmv[3] = adcmv[0];			// mark as calibrated, short calibration is finished
  UnCalibrated = 0;			// clear the UnCalibrated Flag
  lcd_cursor_off();			// switch cursor off
}
u2lcd_space(adcmv[5]);	//DisplayValue(adcmv[5],0,' ',3);		//output cap0 1:3
u2lcd_space(adcmv[6]);	//DisplayValue(adcmv[6],0,' ',3);		//output cap0 2:3
DisplayValue(adcmv[2],-12,'F',3);		//output cap0 1:2
 #ifdef AUTO_CAL
for (ww=0;ww<7;ww++) {			//checking loop
if ((adcmv[ww] > 190) || (adcmv[ww] < 10)) goto no_c0save;
}
for (ww=0;ww<7;ww++) {
  // write all zero offsets to the EEprom 
  (void) eeprom_write_byte((uint8_t *)(&c_zero_tab[ww]),adcmv[ww]+(COMP_SLEW1 / (CC0 + CABLE_CAP + COMP_SLEW2)));
}
lcd_line2();
lcd_MEM_string(OK_str);		// output "OK"
no_c0save:
 #endif
last_line_used = 2;
wait_for_key_5s_line2();		// wait up to 5 seconds and clear line 2

#ifdef SamplingADC
  sampling_cap_calibrate();		// measure zero capacity for samplingADC
#endif

 #ifdef AUTO_CAL
  #ifdef WITH_MENU
if (((test_mode & 0x0f) == 1) || (UnCalibrated == 2))
  #endif
// without menu function the capacitor is requested every time,
// because there is no way to request recaltbration again
// With menu function the capacitor is only requested for first time 
// calibration (UnCalibrated = 2) or for the full selftest call (test_mode = 1) 
// of the menu function, not with the automatically call (test_mode = 1).
{
// for full test or first time calibration, use external capacitor
// Message C > 100nF at TP1 and TP3
cap_found = 0;
for (ww=0;ww<64;ww++) {
  init_parts();
  #if (TPCAP >= 0)
  CalibrationCap();	// measure with internal calibration capacitor
  #else
  lcd_clear();
  lcd_testpin(TP1);
  lcd_MEM_string(CapZeich);	// "-||-"
  lcd_testpin(TP3);
  lcd_MEM2_string(MinCap_str); // " >100nF!"
  PartFound = PART_NONE;
  ReadCapacity(TP3, TP1);	// look for capacitor > 100nF
  #endif
  while (cap.cpre < -9) {
   cap.cpre++;
   cap.cval /= 10;
  }
  if ((cap.cpre == -9) && (cap.cval > 95) && (cap.cval < 22000) &&
    (load_diff > -150) && (load_diff < 150)) {
   cap_found++;
  } else {
   cap_found = 0;		// wait for stable connection
  }
  if (cap_found > 4) {
     // value of capacitor is correct
     (void) eeprom_write_word((uint16_t *)(&ref_offset), load_diff);	// hold zero offset + slew rate dependend offset
     lcd_clear();
     lcd_MEM2_string(REF_C_str);	// "REF_C="
     i2lcd(load_diff);		// lcd_string(itoa(load_diff, outval, 10));	//output REF_C_KORR
     RefVoltage();			// new ref_mv_offs and RHmultip
  #if 0
//#######################################
   // Test for switching level of the digital input of port TP3
   for (tt=0;tt<8;tt++) {
     ADC_PORT =  TXD_VAL;	//ADC-Port 1 to GND
     ADC_DDR = 1<<TP1 | TXD_MSK;	//ADC-Pin  1 to output 0V
     R_PORT = 1<<PIN_RH3;		//Pin 3 over R_H to VCC
     R_DDR = 1<<PIN_RH3;		//Pin 3 over R_H to VCC
     while (1) {
        wdt_reset();
        if ((ADC_PIN&(1<<TP3)) == (1<<TP3)) break;
     }
     R_DDR = 0;		//Pin 3 without current
     R_PORT = 0;
     adcmv[0] = ReadADC(TP3);
     lcd_line3();
     Display_mV(adcmv[0],4);
     R_DDR = 1<<PIN_RH3;		//Pin 3 over R_H to GND
     while (1) {
        wdt_reset();
        if ((ADC_PIN&(1<<TP3)) != (1<<TP3)) break;
     }
     R_DDR = 0;		//Pin 3 without current
     lcd_line4();
     adcmv[0] = ReadADC(TP3);
     Display_mV(adcmv[0],4);
     last_line_used = 2;
     wait_for_key_5s_line2();		// wait up to 5 seconds and clear line 2
   }
//#######################################
  #endif
  #ifdef AUTOSCALE_ADC
   #if (TPCAP >= 0)
    #define CAP_ADC TPCAP	/* Cap >100nF is integrated at TPCAP */
   TCAP_PORT &= ~(1<<TCAP_RH);	// 470k resistor to GND
   TCAP_DDR |= (1<<TCAP_RH);	// enable output
   #else
    #define CAP_ADC TP3		/* Cap >100nF at TP3 */
   ADC_PORT =  TXD_VAL;	//ADC-Port 1 to GND
   ADC_DDR = 1<<TP1 | TXD_MSK;	//ADC-Pin  1 to output 0V
   R_DDR = 1<<PIN_RH3;		//Pin 3 over R_H to GND
   #endif
   do {
      adcmv[0] = ReadADC(CAP_ADC);
   } while (adcmv[0] > 980);
   #if (TPCAP >= 0)
   TCAP_DDR &= ~(1<<TCAP_RH);	// 470k resistor port to input mode
   #else
   R_DDR = 0;		//all Pins to input 
   #endif
   ADCconfig.U_Bandgap = 0;	// do not use internal Ref
   adcmv[0] = ReadADC(CAP_ADC);  // get cap voltage with VCC reference
   ADCconfig.U_Bandgap = adc_internal_reference;
   adcmv[1] = ReadADC(CAP_ADC);	// get cap voltage with internal reference
   adcmv[1] += adcmv[1];		// double the value
   ADCconfig.U_Bandgap = 0;	// do not use internal Ref
   adcmv[2] = ReadADC(CAP_ADC);  // get cap voltage with VCC reference
   ADCconfig.U_Bandgap = adc_internal_reference;
   udiff = (int8_t)(((signed long)(adcmv[0] + adcmv[2] - adcmv[1])) * adc_internal_reference / adcmv[1])+REF_R_KORR;
   lcd_line2();
   lcd_MEM2_string(REF_R_str);	// "REF_R="
   udiff2 = udiff + (int8_t)eeprom_read_byte((uint8_t *)(&RefDiff));
   (void) eeprom_write_byte((uint8_t *)(&RefDiff), (uint8_t)udiff2);	// hold offset for true reference Voltage
   i2lcd(udiff2);		// output correction voltage
   RefVoltage();			// set new ADCconfig.U_Bandgap
  #endif	/* end AUTOSCALE_ADC */
   last_line_used = 2;
   wait_for_key_5s_line2();		// wait up to 5 seconds and clear line 2
   UnCalibrated = 0;		// clear the UnCalibrated Flag
   lcd_cursor_off();		// switch cursor off
   cap_found = eeprom_read_byte((uint8_t *)&c_zero_tab[0]);	// read first capacity zero offset
   eeprom_write_byte((uint8_t *)&c_zero_tab[3], cap_found);	// mark as calibrated permanent
   break;			// leave the ww for loop
  }  /* end if (cap_found > 4) */
  lcd_line2();
  DisplayValue(cap.cval,cap.cpre,'F',4);
  lcd_refresh();		// write the pixels to display, ST7920 only
  wait_about200ms();			// wait additional time
} // end for ww
}	/* end if((test_mode & 0x0f) == 1) */
 #endif  /* end AUTO_CAL */

ADCconfig.Samples = ANZ_MESS;	// set to configured number of ADC samples

#ifdef SamplingADC
  sampling_lc_calibrate();	// Cap for L-meas
#endif


 #ifdef FREQUENCY_50HZ
//#define TEST_SLEEP_MODE	/* only select for checking the sleep delay */
 lcd_clear();
 lcd_MEM_string(T50HZ);	//" 50Hz"
 lcd_refresh();		// write the pixels to display, ST7920 only
 ADC_PORT = TXD_VAL;
 ADC_DDR = 1<<TP1 | TXD_MSK;	// Pin 1 to GND
 R_DDR = (1<<PIN_RL3) | (1<<PIN_RL2);
 for(ww=0;ww<30;ww++) {	// repeat the signal up to 30 times (1 minute)
   for (ff50=0;ff50<100;ff50++) {	// for 2 s generate 50 Hz
      R_PORT = (1<<PIN_RL2);	// Pin 2 over R_L to VCC, Pin 3 over R_L to GND
  #ifdef TEST_SLEEP_MODE
      sleep_5ms(2); 		// test of timing of sleep mode call 
  #else
      wait10ms();		// normal delay
  #endif
      R_PORT = (1<<PIN_RL3);	// Pin 3 over R_L to VCC, Pin 2 over R_L to GND
  #ifdef TEST_SLEEP_MODE
      sleep_5ms(2); 		// test of timing of sleep mode call 
  #else
      wait10ms();		// normal delay
  #endif
      wdt_reset();
   } /* end for ff50 */
   if (!(RST_PIN_REG & (1<<RST_PIN))) {
      // if key is pressed, don't repeat
      break;
   }
 } /* end for ww */
 #endif		/* end FREQUENCY_50HZ */
lcd_clear();
lcd_MEM_string(VERSION_str);	//"Version ..."
lcd_line2();
lcd_MEM_string(ATE);		//"Selftest End"
PartFound = PART_NONE;
     last_line_used = 2;
wait_for_key_5s_line2();		// wait up to 5 seconds and clear line 2
} /* end AutoCheck */ 
Beispiel #8
0
//=================================================================
void GetVloss() {
#if FLASHEND > 0x1fff
  // measure voltage drop after load pulse
  unsigned int tmpint;
  unsigned int adcv[4];
  union t_combi{
  unsigned long dw;     // capacity value  in 100nF units
  uint16_t w[2];
  } lval;
  uint8_t ii;
  uint8_t HiPinR_L;
  uint8_t LoADC;

  if (cap.v_loss > 0) {
     return;		// Voltage loss is already known (big Capacitor)
  }
#if (((PIN_RL1 + 1) != PIN_RH1) || ((PIN_RL2 + 1) != PIN_RH2) || ((PIN_RL3 + 1) != PIN_RH3))
  LoADC = pgm_read_byte((&PinRLRHADCtab[6])+cap.ca-TP_MIN) | TXD_MSK;
#else
  LoADC = pgm_read_byte((&PinRLRHADCtab[3])+cap.ca-TP_MIN) | TXD_MSK;
#endif
  HiPinR_L = pgm_read_byte(&PinRLRHADCtab[cap.cb-TP_MIN]);	//R_L mask for HighPin R_L load

  EntladePins();			// discharge capacitor
  ADC_PORT = TXD_VAL;			// switch ADC-Port to GND
  R_PORT = 0;				// switch R-Port to GND
  ADC_DDR = LoADC;			// switch Low-Pin to output (GND)
  R_DDR = HiPinR_L;			// switch R_L port for HighPin to output (GND)
  adcv[0] = ReadADC(cap.cb);		// voltage before any load 
// ******** should adcv[0] be measured without current???
  if ((cap.cpre_max > -9) || (cap.cpre_max < -12)) return;	// too much or too less capacity
  lval.dw = cap.cval_max;
  for (ii=cap.cpre_max+15;ii<7;ii++) {
     lval.dw = (lval.dw + 5) / 10;
  }
  if (lval.dw > 5000) {
     /* capacity more than 50uF, Voltage loss is already measured  */
     return;
  }
  if (lval.w[0] < 5) return;		// Capacity below 5nF
  R_PORT = HiPinR_L;			//R_L to 1 (VCC) 
  R_DDR = HiPinR_L;			//switch Pin to output, across R to GND or VCC
  for (tmpint=0;tmpint<lval.w[0];tmpint+=2) {
//     wait50us();			// wait exactly 50us
     wait5us();			// wait exactly 5us
  }
  R_DDR = 0;				// switch back to input
  R_PORT = 0;			// no Pull up
 // wait10us();			//wait a little time
  wdt_reset();
  // read voltage without current
  ADCconfig.Samples = 5;		// set ADC to only 5 samples
  adcv[2] = ReadADC(cap.cb);
  if (adcv[2] > adcv[0]) {
     adcv[2] -= adcv[0];		//difference to beginning voltage
  } else {
     adcv[2] = 0;			// voltage is lower or same as beginning voltage
  }
  // wait 2x the time which was required for loading
  for (tmpint=0;tmpint<lval.w[0];tmpint++) {
//     wait50us();
     wait5us();
  }
  adcv[3] = ReadADC(cap.cb);	// read voltage again, is discharged only a little bit ?
  ADCconfig.Samples = ANZ_MESS;		// set ADC back to configured No. of samples
  wdt_reset();
  if (adcv[3] > adcv[0]) {
     adcv[3] -= adcv[0];		// difference to beginning voltage
  } else {
     adcv[3] = 0;			// voltage is lower or same as beginning voltage
  }
  if (adcv[2] > adcv[3]) {
     // build difference to load voltage
     adcv[1] = adcv[2] - adcv[3];	// lost voltage during load time wait
  } else {
     adcv[1] = 0;			// no lost voltage
  }
  // compute voltage drop as part from loaded voltage
  if (adcv[1] > 0) {
     // there is any voltage drop (adcv[1]) !
     // adcv[2] is the loaded voltage.
     cap.v_loss = (unsigned long)(adcv[1] * 500UL) / adcv[2];
  }
#if 0
  lcd_line3();
  DisplayValue16(adcv[2],0,' ',4);
  DisplayValue16(adcv[1],0,' ',4);
  lcd_line4();
  DisplayValue16(lval.w[0],0,'x',4);
#endif

  // discharge capacitor again
  EntladePins();		// discharge capacitors
  //ready
  // switch all ports to input
  ADC_DDR =  TXD_MSK;		// switch all ADC ports to input
  ADC_PORT = TXD_VAL;		// switch all ADC outputs to GND, no pull up
  R_DDR = 0;			// switch all resistor ports to input
  R_PORT = 0; 			// switch all resistor outputs to GND, no pull up
#endif
  return;
 } // end GetVloss()
Beispiel #9
0
// first discharge any charge of capacitors
void EntladePins() {
  uint8_t adc_gnd;		// Mask of ADC-outputs, which can be directly connected to GND
  unsigned int adcmv[3];	// voltages of 3 Pins in mV
  unsigned int clr_cnt;		// Clear Counter
  uint8_t lop_cnt;		// loop counter
// max. time of discharge in ms  (10000/20) == 10s
#define MAX_ENTLADE_ZEIT  (10000/20)

  for(lop_cnt=0;lop_cnt<10;lop_cnt++) {
     adc_gnd = TXD_MSK;		// put all ADC to Input
     ADC_DDR = adc_gnd;
     ADC_PORT = TXD_VAL;		// ADC-outputs auf 0
     R_PORT = 0;			// R-outputs auf 0
//     R_DDR = (1<<PIN_RH3) | (1<<PIN_RH2) | (1<<PIN_RH1); // R_H for all Pins to GND
     R_DDR = (1<<PIN_RH3) | (1<<PIN_RL3) | (1<<PIN_RH2) | (1<<PIN_RL2) | (1<<PIN_RH1) | (1<<PIN_RL1); // R_H and R_L for all Pins to GND
     adcmv[0] = W5msReadADC(PC0);	// which voltage has Pin 1?
     adcmv[1] = ReadADC(PC1);	// which voltage has Pin 2?
     adcmv[2] = ReadADC(PC2);	// which voltage has Pin 3?
     if ((PartFound == PART_CELL) || (adcmv[0] < CAP_EMPTY_LEVEL) & (adcmv[1] < CAP_EMPTY_LEVEL) & (adcmv[2] < CAP_EMPTY_LEVEL)) {
        ADC_DDR = TXD_MSK;		// switch all ADC-Pins to input
        R_DDR = 0;			// switch all R_L Ports (and R_H) to input
#if FLASHEND > 0x3fff
        cell_mv[0] = adcmv[0];		// save the voltage of pin 1
        cell_mv[1] = adcmv[1];		// save the voltage of pin 2
        cell_mv[2] = adcmv[2];		// save the voltage of pin 3
#endif
        return;			// all is discharged
     }
     // all Pins with voltage lower than 1V can be connected directly to GND (ADC-Port)
     if (adcmv[0] < 1000) {
        adc_gnd |= (1<<PC0);	//Pin 1 directly to GND
     }
     if (adcmv[1] < 1000) {
        adc_gnd |= (1<<PC1);	//Pin 2 directly to GND
     }
     if (adcmv[2] < 1000) {
        adc_gnd |= (1<<PC2);	//Pin 3 directly to  GND
     }
     ADC_DDR = adc_gnd;		// switch all selected ADC-Ports at the same time

     // additionally switch the leaving Ports with R_L to GND.
     // since there is no disadvantage for the already directly switched pins, we can
     // simply switch all  R_L resistors to GND
//     R_DDR = (1<<PIN_RL3) | (1<<PIN_RL2) | (1<<PIN_RL1);	// Pins across R_L resistors to GND
     for(clr_cnt=0;clr_cnt<MAX_ENTLADE_ZEIT;clr_cnt++) {
        wdt_reset();
        adcmv[0] = W20msReadADC(PC0);	// which voltage has Pin 1?
        adcmv[1] = ReadADC(PC1);	// which voltage has Pin 2?
        adcmv[2] = ReadADC(PC2);	// which voltage has Pin 3?
        if (adcmv[0] < 1300) {
           ADC_DDR |= (1<<PC0);	// below 1.3V , switch directly with ADC-Port to GND
        }
        if (adcmv[1] < 1300) {
           ADC_DDR |= (1<<PC1);	// below 1.3V, switch directly with ADC-Port to GND
        }
        if (adcmv[2] < 1300) {
           ADC_DDR |= (1<<PC2);	// below 1.3V, switch directly with ADC-Port to GND
        }
        if ((adcmv[0] < (CAP_EMPTY_LEVEL+2)) && (adcmv[1] < (CAP_EMPTY_LEVEL+2)) && (adcmv[2] < (CAP_EMPTY_LEVEL+2))) {
           break;
        }
     }
     if (clr_cnt == MAX_ENTLADE_ZEIT) {
        PartFound = PART_CELL;	// mark as Battery
        // there is charge on capacitor, warn later!
     }
#if DebugOut == 99
        lcd_line4();
        u2lcd(adcmv[0];		// lcd_string(utoa(adcmv[0], outval, 10));
        lcd_space();
        u2lcd(adcmv[1];		// lcd_string(utoa(adcmv[1], outval, 10));
        lcd_space();
        u2lcd(adcmv[2];		// lcd_string(utoa(adcmv[2], outval, 10));
#endif
     for(adcmv[0]=0;adcmv[0]<clr_cnt;adcmv[0]++) {
        // for safety, discharge 5% of discharge  time
        wait1ms();
     }
  } // end for lop_cnt
 }
Beispiel #10
0
void ShowData(void) {
#ifdef WITH_ROTARY_SWITCH
show_page_1:
#endif
  lcd_clear();
  lcd_MEM2_string(VERSION_str);	// "Version x.xxk"
  lcd_line2();
  lcd_MEM2_string(R0_str);	// "R0="
  DisplayValue(eeprom_read_byte(&EE_ESR_ZEROtab[2]),-2,' ',3);
  DisplayValue(eeprom_read_byte(&EE_ESR_ZEROtab[3]),-2,' ',3);
  DisplayValue(eeprom_read_byte(&EE_ESR_ZEROtab[1]),-2,LCD_CHAR_OMEGA,3);
#ifdef FOUR_LINE_LCD
  lcd_line3();
#else
  wait_for_key_ms(MIDDLE_WAIT_TIME);
 #ifdef WITH_ROTARY_SWITCH
  if (rotary.incre > FAST_ROTATION) return;	// fast rotation ends the function
  if (rotary.count < 0) goto show_page_1;
show_page_2:
 #endif
  lcd_clear();
#endif
  /* output line 3 */
  lcd_MEM_string(RIHI); // "RiHi="
  DisplayValue(RRpinPL,-1,LCD_CHAR_OMEGA,3);
#ifdef FOUR_LINE_LCD
  lcd_line4();
#else
  lcd_line2();
#endif
  /* output line 4 */
  lcd_MEM_string(RILO); // "RiLo="
  DisplayValue(RRpinMI,-1,LCD_CHAR_OMEGA,3);

  wait_for_key_ms(MIDDLE_WAIT_TIME);
#ifdef WITH_ROTARY_SWITCH
  if (rotary.incre > FAST_ROTATION) return;	// fast rotation ends the function
 #ifdef FOUR_LINE_LCD
  if (rotary.count < 0) goto show_page_1;
 #else
  if (rotary.count < -1) goto show_page_1;
  if (rotary.count < 0) goto show_page_2;
 #endif
show_page_3:
#endif
  lcd_clear();
  lcd_MEM_string(C0_str);                       //output "C0 "
  DisplayValue(eeprom_read_byte(&c_zero_tab[5]),0,' ',3);		//output cap0 1:3
  DisplayValue(eeprom_read_byte(&c_zero_tab[6]),0,' ',3);		//output cap0 2:3
  DisplayValue(eeprom_read_byte(&c_zero_tab[2]),-12,'F',3);		//output cap0 1:2
  lcd_line2();
  lcd_space();
  lcd_space();
  lcd_space();
  DisplayValue(eeprom_read_byte(&c_zero_tab[1]),0,' ',3);		//output cap0 3:1
  DisplayValue(eeprom_read_byte(&c_zero_tab[4]),0,' ',3);		//output cap0 3:2
  DisplayValue(eeprom_read_byte(&c_zero_tab[0]),-12,'F',3);		//output cap0 2:1
#ifdef FOUR_LINE_LCD
  lcd_line3();
#else
  wait_for_key_ms(MIDDLE_WAIT_TIME);
 #ifdef WITH_ROTARY_SWITCH
  if (rotary.incre > FAST_ROTATION) return;	// fast rotation ends the function
  if (rotary.count < -2) goto show_page_1;
  if (rotary.count < -1) goto show_page_2;
  if (rotary.count < 0) goto show_page_3;
show_page_4:
 #endif
  lcd_clear();
#endif
  /* output line 7 */
  lcd_MEM2_string(REF_C_str);	// "REF_C="
  i2lcd((int16_t)eeprom_read_word((uint16_t *)(&ref_offset)));
#ifdef FOUR_LINE_LCD
  lcd_line4();
#else
  lcd_line2();
#endif
  /* output line 8 */
  lcd_MEM2_string(REF_R_str);  // "REF_R="
  i2lcd((int8_t)eeprom_read_byte((uint8_t *)(&RefDiff)));
  wait_for_key_ms(MIDDLE_WAIT_TIME);
#ifdef WITH_ROTARY_SWITCH
  if (rotary.incre > FAST_ROTATION) return;	// fast rotation ends the function
 #ifdef FOUR_LINE_LCD
  if (rotary.count < -1) goto show_page_1;
  if (rotary.count < 0) goto show_page_3;
 #else
  if (rotary.count < -3) goto show_page_1;
  if (rotary.count < -2) goto show_page_2;
  if (rotary.count < -1) goto show_page_3;
  if (rotary.count < 0) goto show_page_4;
 #endif
#endif
}