Components and supplies
Push Button
16x2 LCD display with I²C interface
Arduino Nano
Capacitor 470 µF
Tools and machines
Soldering kit
Apps and platforms
Arduino IDE
Project description
Code
code
cpp
...
1/* 2Arduino LED Tester 3DPIN--39R--+--10R---TESTLED---GND 4 | | | 5 470u ATOP ABOT 6 | 7 GND 8 9 Measures LED characteristics by charging up the cap to deliver target current and find forward voltage 10 From target current, we can calculate R to be used with a design supply voltage and a matching part number. 11 */ 12#include <Wire.h> 13#include <LiquidCrystal_I2C.h> 14//lcd update interval 15#define LCDINT 500 16//key check interval 17#define KEYINT 200 18//pin for buttons 19#define KEYPIN A0 20//button constants 21#define btnRIGHT 6 22#define btnUP 5 23#define btnDOWN 4 24#define btnLEFT 3 25#define btnSELECT 2 26#define btnNONE (-1) 27LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD adress 28//Globals for display 29long itest=10; //test current, in mA 30long vset =14000; //display voltage in mV 31long vled,vrr,irr,pset; //LED voltage, Resistor voltage, resistor current, display power 32//resistors in Jaycar 1/2 W range, part nos start at RR0524 for 10R 33#define RCOUNT 121 34long rvals[]={10,11,12,13,15,16,18,20,22,24,27,30,33,36,39,43,47,51,56,62,68,75,82,91,100,110,120,130,150,160,180,200,220,240,270,300,330,360,390,430,470,510,560,620,680,750,820,910,1000,1100,1200,1300,1500,1600,1800,2000,2200,2400,2700,3000,3300,3600,3900,4300,4700,5100,5600,6200,6800,7500,8200,9100,10000,11000,12000,13000,15000,16000,18000,20000,22000,24000,27000,30000,33000,36000,39000,43000,47000,51000,56000,62000,68000,75000,82000,91000,100000,110000,120000,130000,150000,160000,180000,200000,220000,240000,270000,300000,330000,360000,390000,430000,470000,510000,560000,620000,680000,750000,820000,910000,1000000}; 35long lastlcd=0; //time of last lcd update 36long lastkey=0; //time of last key check 37int lcdflash=0; //lcd flashing phase variable 38long pdes; 39long rval; //calculated resistor value for display 40long rindex; //index of selected resistor in rvals[] 41int pwmout=0; //pwm output of current driver 42int rvalid=0; //flag if resistor value is valid 43//pins for test interface 44#define ATOP A2 45#define ABOT A3 46#define DPIN 3 47#define OSAMP 16 48 49void setup() { 50 Serial.begin(9600); 51// lcd.begin(16, 2); //lcd 52 lcd.begin(); 53 lcd.clear(); 54 lcd.backlight(); 55 pinMode(DPIN,OUTPUT); //pwm pin 56} 57 58void loop() { 59 long atop,abot,arr; //analog sample values 60 rvalid=0; //set flag to not valid 61 atop=analogoversample(ATOP,OSAMP)/OSAMP; 62 abot=analogoversample(ABOT,OSAMP)/OSAMP; 63 arr=atop-abot; //this is the analog value across the 10R sense resistor 64 if(arr<0){arr=0;} //sanity check 65 vled=abot*5000/1023; //5000mV=1023 => voltage across LED 66 vrr=arr*5000/1023; //voltage across sense resistor 67 irr=vrr/10; //led and resistor current in mA (cos it's a 10R resistor) 68 69 if(irr<itest){pwmout++;if(pwmout>255){pwmout=255;}} //ramp up current if too low 70 if(irr>itest){pwmout--;if(pwmout<0){pwmout=0;}} //ramp down if too high 71 if(irr>24){pwmout=pwmout-5;if(pwmout<0){pwmout=0;}} //ramp down quick if too too high 72 if(irr>itest*3){pwmout=pwmout-5;if(pwmout<0){pwmout=0;}} //ramp down quick if too too high 73 analogWrite(DPIN,pwmout); //output new PWM 74 rval=(vset-vled)/itest; //mV/mV => ohms resistance of display resistor 75 for(int i=0;i<RCOUNT;i++){ //find next highest E24 value 76 if(rvals[i]>=rval){rindex=i;rval=rvals[rindex];i=RCOUNT+1;rvalid=1;} 77 } 78 if(abs(irr-itest)>(itest/5)+1){rvalid=0;} //has current settled within 20%? 79 if(vled>vset){rvalid=0;} //if vled>vset, no valid resistor exists 80 pset=0; //work out dissipation in ballast resistor if valid) 81 if(rvalid){pset=itest*itest*rval;} //this will be in microwatts (milliamps squared) 82 83 if(millis()-lastlcd>LCDINT){ //check if display due to be updated 84 lastlcd=millis(); 85 dolcd(); //update display 86 lcdflash=1-lcdflash; //toggle flash variable 87 } 88 if(millis()-lastkey>KEYINT){ //check if keys due to be checked 89 lastkey=millis(); 90 dobuttons(); 91 } 92 delay(1); 93} //end of loop 94 95void dolcd(){ 96 lcd.setCursor(0,0); //first line 97 //milliamps 98 if(lcdflash||rvalid){ //show if correct if on flashing phase 99 if(itest>9){lcd.write(((itest/10)%10)+'0');}else{lcd.write(' ');} //blank tens if zero 100 lcd.write((itest%10)+'0'); 101 } 102 else{ //blank if not 103 lcd.write(' ');lcd.write(' '); 104 } 105 lcd.write('m');lcd.write('A');lcd.write(' '); 106 //VLED 107 lcd.write(((vled/1000)%10)+'0'); 108 lcd.write('.'); 109 lcd.write(((vled/100)%10)+'0'); 110 lcd.write('V');lcd.write(' '); 111 112 //actual LED current 113 if(irr>9){lcd.write(((irr/10)%10)+'0');}else{lcd.write(' ');} //blank tens if zero 114 lcd.write((irr%10)+'0'); 115 lcd.write('m');lcd.write('A');lcd.write(' '); 116 if((pset>499999)&&(lcdflash)){lcd.write('P');}else{lcd.write(' ');} //flash P if power above 1/2 watt 117 118 lcd.setCursor(0,1); //second line 119 // 120 if(vset>9999){lcd.write(((vset/10000)%10)+'0');}else{lcd.write(' ');} //tens of vset, blank if zero 121 lcd.write(((vset/1000)%10)+'0'); //units of vset 122 lcd.write('V');lcd.write(' '); 123 124 if(rvalid){ 125 lcdprintrval(rval); //resistor value (4 characters) 126 lcd.write(' '); 127 lcdprintpartno(rindex); //resistor part no (6 characters) 128 if(pset>499999){lcd.write('!');}else{lcd.write(' ');} //show ! if power above 1/2 watt 129 }else{ 130 lcd.write(' '); 131 lcd.write('-'); 132 lcd.write('-'); 133 lcd.write('-'); 134 lcd.write(' '); 135 lcd.write('-'); 136 lcd.write('-'); 137 lcd.write('-'); 138 lcd.write('-'); 139 lcd.write('-'); 140 lcd.write('-'); 141 lcd.write(' '); 142 } 143} 144 145void lcdprintpartno(int index){ 146 //part number 147 lcd.write('R'); 148 lcd.write('R'); 149 lcd.write('0'); 150 lcd.write((((index+524)/100)%10)+'0'); //part no's start at RR0524 for 10R 151 lcd.write((((index+524)/10)%10)+'0'); 152 lcd.write((((index+524))%10)+'0'); 153} 154 155void lcdprintrval(long rval){ //print a value in 10k0 format, always outputs 4 characters 156 long mult=1; 157 long modval; 158 if(rval>999){mult=1000;} 159 if(rval>999999){mult=1000000;} 160 modval=(10*rval)/mult; //convert to final format, save a decimal place 161 if(modval>999){ //nnnM 162 lcd.write(((modval/1000)%10)+'0'); 163 lcd.write(((modval/100)%10)+'0'); 164 lcd.write(((modval/10)%10)+'0'); 165 lcdprintmult(mult); 166 }else{ 167 if(modval>99){ //nnMn 168 lcd.write(((modval/100)%10)+'0'); 169 lcd.write(((modval/10)%10)+'0'); 170 lcdprintmult(mult); 171 lcd.write(((modval)%10)+'0'); 172 }else{ //_nMn 173 lcd.write(' '); 174 lcd.write(((modval/10)%10)+'0'); 175 lcdprintmult(mult); 176 lcd.write(((modval)%10)+'0'); 177 } 178 } 179} 180void lcdprintmult(long mult){ //helper function to print multiplier 181 switch (mult){ 182 case 1: lcd.print('R');break; 183 case 1000: lcd.print('k');break; 184 case 1000000: lcd.print('M');break; 185 default: lcd.print('?');break; 186 } 187} 188int read_LCD_buttons(){ 189 int adc_key_in = 0; 190 adc_key_in = analogRead(KEYPIN); // read the value from the sensor 191 delay(5); //switch debounce delay. Increase this delay if incorrect switch selections are returned. 192 int k = (analogRead(KEYPIN) - adc_key_in); //gives the button a slight range to allow for a little contact resistance noise 193 if (5 < abs(k)) return btnNONE; // double checks the keypress. If the two readings are not equal +/-k value after debounce delay, it tries again. 194 // my buttons when read are centered at these valies: 0, 144, 329, 504, 741 195 // we add approx 50 to those values and check to see if we are close 196 if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result 197 if (adc_key_in < 50) return btnRIGHT; 198 if (adc_key_in < 195) return btnUP; 199 if (adc_key_in < 380) return btnDOWN; 200 if (adc_key_in < 555) return btnLEFT; 201 if (adc_key_in < 790) return btnSELECT; 202 return btnNONE; // when all others fail, return this... 203 204} 205void dobuttons(){ //updates variables. debounces by only sampling at intervals 206 int key; 207 key = read_LCD_buttons(); 208 if(key==btnLEFT){itest=itest-1;if(itest<1){itest=1;}} 209 if(key==btnRIGHT){itest=itest+1;if(itest>20){itest=20;}} 210 if(key==btnUP){vset=vset+1000;if(vset>99000){vset=99000;}} 211 if(key==btnDOWN){vset=vset-1000;if(vset<0){vset=0;}} 212} 213long analogoversample(int pin,int samples){ //read pin samples times and return sum 214 long n=0; 215 for(int i=0;i<samples;i++){ 216 n=n+analogRead(pin); 217 } 218 return n; 219}
Downloadable files
Schematic
...
Schematic.jpg
Comments
Only logged in users can leave comments