//2conducts, 1 node. directon 2 (IN), muct be PNP/DD-CC type getPartSS_PNP() { u16 test; if (tList[0][2]>(tList[1][2] + DARL_BJT)) { node = 0; return PNP_D; } if (tList[1][2]>(tList[0][2] + DARL_BJT)) { node = 1; return PNP_D; } R_680(tList[0][1], LOW); //B R_0(tList[0][0], HIGH); //E R_680(tList[1][0], LOW); //C test = ReadADC(tList[1][0]); HiZ3(tList[0][0], tList[1][0], tList[0][1]); //if VCE>0V then PNP if (test > CP_LOW) return PNP; //else it's a double diode with CA return CC; }
u16 testPNP() { u8 i, C[2], B[2], E[2]; u16 Vc[2], Vb[2]; u32 hFE[2]; B[0] = B[1] = tList[0][1]; C[0] = E[1] = tList[1][0]; C[1] = E[0] = tList[0][0]; R_470K(B[0], LOW); for (i = 0; i < 2; i++) { R_680(C[i], LOW); R_0(E[i], HIGH); Delay_MS(10); Vc[i] = ReadADC(C[i]); Vb[i] = ReadADC(B[i]); hFE[i] = (u32) Vc[i]*691; hFE[i] = hFE[i] / Vb[i]; } HiZ3(B[0], C[0], E[0]); if (hFE[0] > hFE[1])i = 0; else i = 1; pins[C[i]] = 'C'; pins[B[i]] = 'B'; pins[E[i]] = 'E'; return hFE[i]; }
//2conducts, 1 node, direction 1(OUT), must be NPN/DD-CA type getPartSS_NPN() { u16 test; if (tList[0][2]>(tList[1][2] + DARL_BJT)) { node = 0; return NPN_D; } if (tList[1][2]>(tList[0][2] + DARL_BJT)) { node = 1; return NPN_D; } R_680(tList[0][0], HIGH); //B R_0(tList[1][1], LOW); //E R_680(tList[0][1], HIGH); //C test = ReadADC(tList[0][1]); HiZ3(tList[0][0], tList[0][1], tList[1][1]); //if VCE<5V then NPN if (test < CP_HIGH) return NPN; //else it's a double diode with CA return CA; }
u16 testRES() { u8 R1, R2; u32 v0, v680, v470K, rt680, rt470K, rr; R1 = tList[0][0]; R2 = tList[0][1]; R_0(R2, LOW); R_680(R1, HIGH); Delay_MS(10); v0 = ReadADC(R2); v680 = ReadADC(R1); R_470K(R1, HIGH); Delay_MS(10); v470K = ReadADC(R1); HiZ(R1); HiZ(R2); //When Rx > sqrt(680*470000) the rt470K is more accurate //we calculate if this threshold has been passed below if (v680 > 512) rt680 = v680 - 512; else rt680 = 512 - v680; if (v470K > 512) rt470K = v470K - 512; else rt470K = 512 - v470K; if (rt470K > rt680){ //We will use the value calculated with the 680R resistor if(v680==v0){ //Shortcircuit? rr = 1; //0 is considered error } else{ //Use the common formula for a voltage divisor with some correction //The output is not 5V and 0V for HIGH and LOW, the difference increasses with //lower resistor values, empirically V_low=x, V_high=Vcc-2.80*V_low //R = 680*(v680-v0)/(1023-2.8v0-v680) rr = (5*R680_IDEAL*(v680-v0)) / (5*1023 - 14*v0 - 5*v680); } } else{ //We will use the value calculated with the 470K resistor //Use the common formula for a voltage divisor rr = (R470K_IDEAL*v470K) / (1023 - v470K); } pins[R1] = 'R'; pins[R2] = 'R'; part_unit = 'R'; if (rr > 0x03E7FC18) { //Values that overflow 16bits when divided by 1000 rr /= 1000000; part_unit = 'M'; } else if(rr > 0xFFFF){ //Values that overflow 16bits rr /= 1000; part_unit = 'K'; } return (u16) rr; }
type getPartSS_CAP_RES() { u8 i, j; u16 vT1 = 0, vT2, k2; for (i = 0; i < 2; i++) for (j = i + 1; j < 3; j++) { k2 = 400; quickADCsetup(i); R_0(j, LOW); R_470K(i, HIGH); while (k2--); //Do the ADC acq just after the left over pin is HiZ ADCON0 |= 0b10; //GO/!DONE=1 while (ADCON0 & 0b10); vT1 = ADRES; //Do the ADC acq after some time and see if the value changes Delay_MS(10); ADCON0 |= 0b10; //GO/!DONE=1 while (ADCON0 & 0b10); vT2 = ADRES; //Discharge? R_680(i, LOW); Delay_MS(10); R_0(i, LOW); HiZ(i); HiZ(j); if (vT1 > CP_HIGH) continue; else { tList[0][0] = i; tList[0][1] = j; tList[0][2] = 1023; tList[1][0] = j; tList[1][1] = i; tList[1][2] = 1023; nC = 2; if (vT2 > (vT1 + CAP_DIFF)) return CAP; else return RES; } } return ERROR5; }
u16 checkConduct(u8 A, u8 B, u8 state) { u8 i = TEST_DELAY; u8 C; //Calculate the leftover pin u16 Value; C = 3 - (A + B); //charges the leftover pin to test State and waits for charge R_680(C, state); Delay_MS(10); quickADCsetup(B); //sets up the ADC for a later reading //conects the A pin to 5V throgh 680R 5V--[680]--[A] //brings the leftover pin to HiZ R_680(B, LOW); R_0(A, HIGH); HiZ(C); while (i--); //Do the ADC acq just after the left over pin is HiZ ADCON0 |= 0b10; //GO/!DONE=1 while (ADCON0 & 0b10); Value = 1023 - ADRES; //Discharge? R_0(A, LOW); Delay_MS(10); R_0(B, LOW); Delay_MS(10); HiZ(A); HiZ(B); //If the read value is less the 93% of VCC then it is a conductor if (Value < CP_HIGH) return Value + 1; return 0; //otherwise its not conducting }
u16 testNMOS() { u32 rON; u16 vG, vD; u8 D, S, G; if (tList[2][0] != tList[0][0]) { D = tList[2][0]; S = tList[2][1]; } else { S = tList[2][0]; D = tList[2][1]; } G = 3 - (S + D); R_680(D, HIGH); R_0(S, LOW); R_680(G, LOW); Delay_MS(10); vG = ReadADC(G); if (vG > 10) { HiZ3(S, D, G); return 0; //if gate is lower the vdd it meas current is flowing into it which is not MOS } vD = ReadADC(D); if (vD < 1000) { HiZ3(S, D, G); return 0; //if the VD is higher then 0 when off means its not PMOS } R_680(G, HIGH); Delay_MS(10); vG = ReadADC(G); if (vG < 1000) { HiZ3(S, D, G); return 0; //if gate is higher then 0 it meas current is flowing into it which is not MOS } vD = ReadADC(D); if (vD > 123) { HiZ3(S, D, G); return 0; //if the VD is lower then 0.9*Vdd when ON means its not PMOS } HiZ3(S, D, G); pins[D] = 'D'; pins[S] = 'S'; pins[G] = 'G'; rON = vD * R680_IDEAL; rON = rON / (1023 - vD); return (u16) rON; }
void checkpins(u8 HighPin, u8 LowPin, u8 TristatePin){ u16 InitialADC, HighPinADC,TristatePinADC, LowPinADC; //LowPin 680ohm R to ground R_680(LowPin, LOW); //HighPin to output/high R_0(HighPin, HIGH); Delay_MS(5); DischargePin(TristatePin, LOW); //for MOSFETs //Read ADC on LowPin InitialADC=ReadADC(LowPin); //if ADC >= 200{ //discharge other way for P MOSFETs //discharge; //read ADC again; //} //if(ADC>19) { // N-JFET, N-MOSFET //P-JFET P-MOSFET //} //reset pins //LowPin 680ohm R to ground R_680(LowPin, LOW); //HighPin to output/high R_0(HighPin, HIGH); if(InitialADC<200){ /****************************************/ // // PNP tests // If this PNP: // then collector should be high when base ground and emitter at +5 // /*****************************************/ //C, B low through 680R, E high R_680(TristatePin, LOW); //base to ground through 680R Delay_MS(2); //read LowPin ADC //PNP allows current from Emitter to Collector and should be high LowPinADC=ReadADC(LowPin); if(LowPinADC>700){//PHP active, current flowing to Emitter HiZ(TristatePin);//Base HiZ R_470K(TristatePin, LOW); //Base to 470K low Delay_MS(10); //read LowPin ADC for hfe LowPinADC=ReadADC(LowPin); //read TristatePin ADC, see if base is transistor (>2volts) or FET (<2volts) //save value for uBE too TristatePinADC=ReadADC(TristatePin); if((PartType==PART_TRANSISTOR) || (PartType==PART_FET))RepeatDetect=1; hfe[RepeatDetect]=LowPinADC; vBE[RepeatDetect]=TristatePinADC; //if(PartFound != PART_THYRISTOR) { if(TristatePinADC>200){ //high base voltage is transistor //PNP transistor found PartType=PART_TRANSISTOR; PartMode=PART_MODE_PNP; }else{ //low base voltage is MOSFET //MOSFET and tests PartType=PART_FET; PartMode=PART_MODE_PNP; } c=LowPin; e=HighPin; b=TristatePin; } /****************************************/ // // NPN tests // If this NPN: // then collector should hold pullup low when base high and emitter to ground // /*****************************************/ //B,C high through pullup, E low //LowPin ground R_0(LowPin, LOW); //HighPin and TristatePin 680R high R_680(HighPin, HIGH); R_680(TristatePin, HIGH); //read HighPin ADC to see if NPN holds the 680R pullup low... HighPinADC=ReadADC(HighPin); if(HighPinADC<500){//NPN grounds the weak pullup //THYRISTOR test /***************************************/ // Transistor or MOSFET test // Transistor is current controlled, the base voltage after the resistor will be ~0.6-1volts // MOSFET is voltage controlled, the base voltage after the resistor will be close to the supply (5volts) /***************************************/ //TristatePin 470K high R_470K(TristatePin, HIGH); //read HighPin ADC for hfe HighPinADC=ReadADC(HighPin); //read TristatePin ADC, see if base is transistor (<2volts) or FET (>2volts) //save value for uBE too TristatePinADC=ReadADC(TristatePin); if((PartType==PART_TRANSISTOR) || (PartType==PART_FET))RepeatDetect=1; hfe[RepeatDetect]=1023-HighPinADC; vBE[RepeatDetect]=1023-TristatePinADC; if(TristatePinADC<500){ //low base voltage is transistor //NPN transistor found PartType=PART_TRANSISTOR; PartMode=PART_MODE_NPN; }else{ //high base voltage is MOSFET //MOSFET and tests PartType=PART_FET; PartMode=PART_MODE_NPN; c=((1<<HighPin)<<3); DischargePin(TristatePin, LOW); //for MOSFETs R_470K(TristatePin, HIGH); while(R0_IN&c); gthvoltage=ReadADC(TristatePin); } c=HighPin; e=LowPin; b=TristatePin; }//adc<500 }//adc < 200 //NON transistor tests //Diode and internal part diodes /* //Resistors //LowPin ground R_0(LowPin, LOW); //HighPin 680 high R_680(HighPin, HIGH); LowPinADC1=ReadADC(LowPin); HighPinADC1=ReadADC(HighPin)-LowPinADC1; //HighPin 470K high R_470K(HighPin, HIGH); LowPinADC2=ReadADC(LowPin); HighPinADC2=ReadADC(HighPin)-LowPinADC2; //LowPin 680 ground R_680(LowPin, LOW); //highpin to Vcc R_0(HighPin, HIGH); LowPinADC1+=(1023-ReadADC(HighPin)); //LowPin 470K ground R_470K(HighPin, HIGH); LowPinADC2+=(1023-ReadADC(HighPin)); if(((HighPinADC1 - LowPinADC1) < 900) && ((HighPinADC2 - LowPinADC2) > 20)) goto testend; //not a resistor if(((HighPinADC2 * 32) / 31) < HighPinADC1) { if((PartFound == PART_DIODE) || (PartFound == PART_NONE) || (PartFound == PART_RESISTOR)) { if((tmpPartFound == PART_RESISTOR) && (ra == LowPin) && (rb == HighPin)) { if(!((((adcv[0] + 100) * 6) >= ((rv[0] + 100) * 5)) && (((rv[0] + 100) * 6) >= ((adcv[0] + 100) * 5)) && (((adcv[1] + 100) * 6) >= ((rv[1] + 100) * 5)) && (((rv[1] + 100) * 6) >= ((adcv[1] + 100) * 5)))) { //min. 20% Abweichung => kein Widerstand tmpPartFound = PART_NONE; goto testend; } PartFound = PART_RESISTOR; } rv[0] = adcv[0]; rv[1] = adcv[1]; radcmax[0] = 1023 - adcv[2]; //Spannung am Low-Pin ist nicht ganz Null, sondern rund 0,1V (wird aber gemessen). Der dadurch entstehende Fehler wird hier kompenisert radcmax[1] = 1023 - adcv[3]; ra = HighPin; rb = LowPin; tmpPartFound = PART_RESISTOR; } } */ testend: HiZ(HighPin); HiZ(LowPin); HiZ(TristatePin); }
u16 testCAP() { u32 Rtest; double cap, RC, time; u8 C1, C2, xC; //due to the way the order of testing is done tListp[0][0] can only be 0 or 1 //C combos... 0-1,0-2,and 1-2 this is the first order of testing so pin1 and pin2 comparators are assured... C1 = tList[0][0]; C2 = tList[0][1]; //3d unused pin which could be connected to a 2nd comparator need to be brought low xC = 3 - (C1 + C2); R_0(xC, LOW); //safe discharege R_0(C2, LOW); R_680(C1, LOW); Delay_MS(100); R_0(C1, LOW); Delay_MS(10); //Calculate the time that capacitor needs to get to Vref=2.500V testCMP = 1; testCMPCount = 0; CMP_INTF = 0; //clear comparator IF T0CONbits.T08BIT = 0; //read/write 16 bit values T0CONbits.T0CS = 0; //user internal clock (Fosc/4) T0CONbits.PSA = 1; //bypass prescaler INTCONbits.TMR0IE = 1; //enable timer0 interrupt on overflow INTCONbits.TMR0IF = 0; //clear interrupt flag TMR0H = 0; TMR0L = 0; CMP_INTE = 1; //enable comparator interrupt T0CONbits.TMR0ON = 1; //enable timer0 if (tList[0][2] > CAP_LOWCAP) { Rtest = R470K_IDEAL; R_470K(C1, HIGH); } else { Rtest = R680_IDEAL; R_680(C1, HIGH); } while (testCMP) { if (testCMPCount > 24000000){ // 2s Timeout, ~6uF for 470K, 4.1mF for 680 CMP_INTE = 0; CMP_INTF = 0; T0CONbits.TMR0ON = 0; INTCONbits.TMR0IE = 0; INTCONbits.TMR0IF = 0; part_unit = 'u'; return 0xFFFF; } } //safe discharege R_680(C1, LOW); Delay_MS(100); R_0(C1, LOW); Delay_MS(10); HiZ(C2); HiZ(C1); HiZ(xC); pins[C1] = 'C'; pins[C2] = 'C'; time = testCMPCount/12000000.0; RC = mylog(VCC) - mylog(VCC-2500); RC = RC * (double) Rtest; cap = (double) time / RC; cap = cap * 1e6; if (cap > 65) { part_unit = 'u'; } else { cap = cap * 1e3; if (cap > 65) { part_unit = 'n'; } else { cap = cap * 1e3; part_unit = 'p'; } } return (u16) cap; }
type getPartSS_2nodes() { u32 temp; u16 r470K_1, r470K_2, r680_1, r680_2; u8 tp1 = tList[0][0], tp2 = tList[0][1]; //loading the pin numbers //Getting 2 consecutive reading on the same part, if they change must be a cap //charge with 5V through a 470K resistor quickADCsetup(tp1); R_0(tp2, LOW); R_470K(tp1, HIGH); Delay_MS(1); ADCON0 |= 0b10; //GO/!DONE=1 while (ADCON0 & 0b10); r470K_1 = ADRES; Delay_MS(10); ADCON0 |= 0b10; //GO/!DONE=1 while (ADCON0 & 0b10); r470K_2 = ADRES; //if the difference is larger than noise its a cap if (r470K_2 > (r470K_1 + CAP_DIFF)) { HiZ(tp1); HiZ(tp2); return CAP; //voltage increase over time => CAP } //discharge if anything R_680(tp1, LOW); Delay_MS(20); //charge with 5V through a 680 resistor and do 2 consecutive reading R_680(tp1, HIGH); ADCON0 |= 0b10; //GO/!DONE=1 while (ADCON0 & 0b10); r680_1 = ADRES; Delay_MS(10); ADCON0 |= 0b10; //GO/!DONE=1 while (ADCON0 & 0b10); r680_2 = ADRES; //if the difference is larger than noise its a cap if (r680_2 > (r680_1 + CAP_DIFF)) { HiZ(tp1); HiZ(tp2); return CAP; //voltage increase over time => CAP } //If it's not a cap, it may be a resistor, zenner or anti parallel diode //invert the pins and repeat the last reading quickADCsetup(tp2); R_0(tp1, LOW); R_680(tp2, HIGH); ADCON0 |= 0b10; //GO/!DONE=1 while (ADCON0 & 0b10); r680_2 = ADRES; HiZ(tp1); HiZ(tp2); //if there is a diff larger then spec its a zenner if (r680_1 > (r680_2 + ZENER_DD)) return ZENER; if (r680_2 > (r680_1 + ZENER_DD)) return ZENER; //if there is a difference between the 680 and the 470k series resitors then its a Resistor temp = (r680_1 * 100) / r470K_1; if (temp > RES_DD) return RES; //if the values are close enough its a anti parallel diode. return DD; }