Battery IR Meter Circuitboard! - RC Groups
Thread Tools
Jan 06, 2017, 11:28 PM
Registered User
vollrathd's Avatar
Build Log

Battery IR Meter Circuitboard!


This project started out with a fairly simple voltage divider network to sample the various cell voltages of the battery under test. This circuit worked, but had issues with accuracy, due to the requirement of 0.1% accuracy resistors, and a whole lot of other things. It evolved to a re-do of the circuit, using 14 Electronic Relays. The relays switch each cell to the microcontroller's A/D input, one at a time. This allows the full voltage of the cell to be applied directly to the A/D input, allowing maximum use of the 1/4096 resolution of the PicChip 18F25K80.

I've checked the accuracy of this configuration against my Fluke 87V. (The 87V is accurate to 0.05% on DC Volts) The results show the Voltage accuracy of the BattIR meter is good to better than 0.5% on each and every cell in the battery pack under test. Add the plus/minus accuracy of the two 50 Watt, 1% power resistors, overall accuracy is on the order of 1.5% or so. The software has a calibration number that can be altered if desired to match exactly the readings of a digital meter with 0.1% accuracy. It's within 1% or so without "tweaking" the calibration.

Only two 1% resistors are used on the circuit board, and they have nothing to do with the IR meter. The two resistors are used to check the condition of the 9 Volt Battery. All of the remaining resistors can be common 5% or so, but surface mount resistors typically are 1% anyhow.

The bad thing about this circuit, it doesn't allow the use of the battery under test to power the IR meter. A separate 9 volt Alkaline battery must be used. Current drain is rather low on the 9 Volt battery, so it should last a long time.

The mode of operation. It first displays all cell voltages to X.XXX display. It allows checking all cell voltages while running your electric motor st full power, for example.

The display indicates "Key", pushing the switch advances to the 5 Ohm load, again displaying all cell voltages to four digits. Key again, the unit switches to the 5 Ohm plus 2 Ohm loads, and again displays all voltage measurements. Key again, and all of the IR values are displayed.

As for cost, the most expensive items are the LCD display, and the circuit board. The LCD display MUST be capable of working with a 4 bit digital input. The circuit boards from ExpressPCB run $55 for three boards. The LCD display runs $22 from Digikey. The parts cost of all other electronic parts runs around $30.00, not counting cables, switches, and project box.

The attached Zip file includes the schematic and board ExpressPCB files. The ExpressPCB schematic has the parts listing, along with the Digikey part numbers available for a printout.

I've got two remaining circuit boards, and am debating if I want to sell them along with a programmed Pic18F25K80. We'll see.

I've compared the readings of this unit against my Cellpro PL8 units. There is a very large difference in their readings. The Cellpro PL8 shows IR values around 1/2 of this unit. Interesting.

So how does this unit do in the real world? I used the 2.66 milliohm value on cell #1, to calculate the cell voltage at 64 Amps. The 2.66 milliohms times 64 Amps is a 0.172 Volt drop. The 3.80 Volt no load minus 0.172 Volt drop is 3.628 Volts.

I measured 3.614 Volts on the motor load of 64 Amps. Within about 1/2%.
Last edited by vollrathd; Jan 07, 2017 at 11:41 AM.
Sign up now
to remove ads between posts
Jan 07, 2017, 02:38 AM
Registered User
Nice work!

Only remark: You should increase the thickness of the load tracks with solder, or even a piece of wire. I get a headache thinking of such a small track carrying 15 amps, even if it is only for small portions of a second.
Jan 07, 2017, 11:10 AM
Registered User
vollrathd's Avatar
Quote:
Originally Posted by learningarduino
Nice work!

Only remark: You should increase the thickness of the load tracks with solder, or even a piece of wire. I get a headache thinking of such a small track carrying 15 amps, even if it is only for small portions of a second.
I just checked the temperature rise of the copper foil with my Fluke 87V with its tiny thermocouple thermometer. The Copper foil temperature rose around 4 degrees F during the high current tests. And, the temperature dropped back to ambient within a few seconds.

At any rate, I've increased the width of the copper foil paths to 0.120 inches to reduce any possibility of a problem. Both the Zip file and the photo have been updated. (Solder won't help much, copper has a much lower resistance than solder)

I won't modify my unit though.

(Years ago, before retiring, Engineering was pulling 18 Amps for around 40 milliseconds through a copper foil path 30/1000 wide. That worked just fine, until the trip coil being driven through that circuit hung up. )
Jan 07, 2017, 11:29 AM
Registered User
vollrathd's Avatar

Battery IR Meter Test Results


Attached are photos of the IR meters LCD display while running through a bunch of batteries, including both A123 and Lipos.
Jan 07, 2017, 11:37 AM
Registered User
vollrathd's Avatar

Battery IR Meter "C" listing for mikroC format


Code:
/*
BATTERY IR METER TEST UNIT RELAY SYSTEM VERSION II
RCGroups - vollrathd

Date 12-13-2016  Project Circuit Board Started
Date 12-25-2016  All is working
Date 12-26-2016  Added 9 Volt DC Monitor
Date 01-06-2017  Final Version of Software
Date 01-09-2017  Added Max Amps to the software
This project applies two different resistor loads to the
battery under test.  Current is calculated by voltage drop
across two precision power resistors.

Project set up to run with the PIC18F25K80 PicChip
The C file is in mikroC format, with the mikroP programmer

*****************************************************************************
* CAUTION! IN ORDER TO USE RC0 AND RC1, SET UP OSCILLATOR CONFIGURATION FOR *
***** DIGITAL (SCLK1) MODE IN CONFIGURATION AND SETUP FILES *****************
**DEFAULT PORT A AND B ARE ANALOG INPUTS.  MUST ASSIGN DIGITAL IN A/D SETUP**
* PicChip clock speed set to 16 Mhz with mikroP in order for LCD to keep up *
*************** PicChip programmed to use internal clock ********************
****DO NOT PROGRAM PICCHIP WITH BATTERY UNDER TEST PLUGGED IN!***************
****THE PROGRAMMER WILL TURN ON THE POWER RESISTORS, OVERHEATING THEM********
*****************************************************************************
Operation modes
1.  Power up, display voltages on all seven cells plus total voltage
2.  Watch for key input for next command
3.  Low volts is 1.428 Ohm load   High Volts is 5 Ohm load
4.  Apply 5 Ohm load for 1.5 seconds to equalize cells
5.  Measure all cell voltages and store to array
6.  Apply  2 + 5 Ohms for 0.5 seconds measure volts and save to Array
7.  Measure battery voltage and calculate current
8.  Do calculations on IR
9.  Display IR for all cells
10. Go back to restart
    Following are the connections to the electronic relays
     cell_1 {porta=0b00001000; portc=0b00000000;}
     cell_2 {porta=0b00100000; portc=0b00000000;}
     cell_3 {porta=0b01000000; portc=0b00000000;}
     cell_4 {porta=0b00000000; portc=0b00000001;}
     cell_5 {porta=0b00000000; portc=0b00000010;}
     cell_6 {porta=0b00000000; portc=0b00000100;}
     cell_7 {porta=0b00000000; portc=0b00001000;}
*/
// Set up PicChip for LCD function per instruction in mikroC manual
     sbit LCD_RS at RB3_bit;
     sbit LCD_EN at RB2_bit;
     sbit LCD_d4 at RC4_bit;
     sbit LCD_d5 at RC5_bit;
     sbit LCD_d6 at RC6_bit;
     sbit LCD_d7 at RC7_bit;

     sbit LCD_RS_Direction at TRISB3_bit;
     sbit LCD_EN_Direction at TRISB2_bit;
     sbit LCD_D4_Direction at TRISC4_bit;
     sbit LCD_D5_Direction at TRISC5_bit;
     sbit LCD_D6_Direction at TRISC6_bit;
     sbit LCD_D7_Direction at TRISC7_bit;
 //set up definitions
     unsigned char lcd_loc ;
     unsigned long mi_volt,milli_read,counter,milli_readavg,Max_IR;
     float Test_Amps,Batt_IR;
     unsigned long CellCnt,BattNL,Batt5ohm,Batt2ohm,Batt_Mah,calc;
     unsigned char ch;
     unsigned char Mah_1000, Mah_100;                       //Batt Mah numbers
     unsigned long tlong   ;
     unsigned char counts ;
     unsigned int ArrayV [8] ;
     unsigned int Array2ohm [8];
     unsigned int Array5ohm [8];
     unsigned long int ArrayIR [8];
//   Look Up tables
     unsigned char LCDRow[] = {1,2,3,4,1,2,3,4}       ;        //LCD Rows
     unsigned char LCDCol[] = {4,4,4,4,15,15,15,15}   ;        //LCD Columns
     unsigned char LCDIRCol[] = {6,6,6,6,17,17,17,17}   ;      //LCD Columns
     unsigned char LCDIRColIR[] = {5,5,5,5,15,15,15,15} ;      //IRLCD Columns
     unsigned char ADChan [] = {8,10,0,1,2,3,4}      ;         //AD Channel
     unsigned char porta_bat[] ={0x08,0x20,0x40,0x00,0x00,0x00,0x00};
     unsigned char portc_bat[] ={0x00,0x00,0x00,0x01,0x02,0x04,0x08};
     #define switch portb.rb1
     #define pressed 1
     #define R2ohm PORTb.rb4
     #define R5ohm PORTb.rb5
     #define on 1
     #define off 0
//*****************************************************************************
//***********Analog Digital Function.  Input, CPU, Output ArrayV **************
//*****************************************************************************
     void ADFunction(void)
{
     ArrayV[0] = 0x00;
     ArrayV[1] = 0x00;
     ArrayV[2] = 0x00;
     ArrayV[3] = 0x00;
     ArrayV[4] = 0x00;
     ArrayV[5] = 0x00;
     ArrayV[6] = 0x00;
     CellCnt = 0;
      for(counts=0;counts<7;counts++)
  {
      porta = (porta_bat[CellCnt]);
      delay_us(2);
      portc = (portc_bat[Cellcnt]);
      delay_ms(40)      ;                         //wait for warm up
      milli_readavg = 0 ;                         //clear milli reader
      for (counter=0; counter<32; counter++)      //adjust calibration
    {
      milli_read=Adc_Read(0);                     //read channel zero
      milli_readavg = (milli_readavg+Milli_read) ;//add up all 100 readings
    }
    
      mi_volt = (milli_readavg*10/259);           //divide by no of reads
      if (mi_volt <100)                           //If zero volts, skip
    {
      ArrayV[CellCnt] = 0x00;                     //enter zero count
    }
      else
    {
      ArrayV[CellCnt] = mi_volt;                  //Store cell volts to array
      CellCnt=CellCnt+1 ;
    }
  }
      portb = 0x00;                               //turn off power resistors
      delay_ms(2);                                //2 ms mikroC bug
      porta = 0x00;
      delay_ms(2);
      portc = 0x00;
}
//****************************************************************************
//***LCD Function Input ArrayV  Output to LCD Display. ***********************
//****************************************************************************
   void LCDFunction(void)
  {
      for (counts=0; counts<(CellCnt);counts++)
     {
       tlong = ArrayV [counts] ;                       //show volts
       LCD_CHR(LCDRow[counts],LCDCol[counts],0x30+ch); //4th digit
       ch = tlong /1000;
       LCD_CHR(LCDRow[counts],LCDCol[counts],0x30+ch); //4th digit

       LCD_CHR_CP ('.');                               // decimal
 
       ch = (tlong/100)%10;
       LCD_CHR_CP(0x30+ch);                            //3rd digit

       ch=(tlong/10)%10;                               //2nd digit
       LCD_CHR_CP(0x30+ch);
                                                       //1st digit
       ch = (tlong /1)%10 ;
       LCD_CHR_CP (0x30+ch);
     }
        delay_ms(50);
  }
//*****************************************************************************
//*****Battery Voltage Function Input batt_adder with tlong output ************
//*****************************************************************************
  void batt_volts(void)
     {
       ch = tlong /10000;
       LCD_CHR(4,15,0x30+ch);//4th digit
       ch = (tlong/1000)%10;
       LCD_CHR_CP(0x30+ch);                        //3rd digit
       LCD_CHR_CP ('.');                           // decimal
       ch=(tlong/100)%10;                          //2nd digit
       LCD_CHR_CP(0x30+ch);
                                                   //1st digit
       ch = (tlong /10)%10 ;
       LCD_CHR_CP (0x30+ch);
     }
//*****************************************************************************
//********Batter Adder  Input ArrayV  Output tlong*****************************
//*****************************************************************************
  void batt_adder(void)
     {
       tlong = ArrayV[0]+ArrayV[1]+ArrayV[2]
       +ArrayV[3]+ArrayV[4]+ArrayV[5]+ArrayV[6];
     }
//*****************************************************************************
//***********This is the main program ****************************t************
//*****************************************************************************
 void main()
 {
//Configure A/D converter
      ANCON0 = 0X01 ;                             //configures channel 0 as A/D
      ANCON1 = 0X00;                              //configure port B as all
      ADCON1 = 0x00;                              // digital default A/D!
      lcd_loc = 0x00 ;
// Configure I/O ports
      trisa = 0b00000011;                   //port a, bit 0,1 are analog inputs
      trisb = 0b00000011  ;                 //make port b, bits 0, 1 inputs
      trisc = 0b00000000;
      portb = 0;                                  //turn off loads
//*********Program End Return Point *******************************************
 reinit:
      Lcd_init();
      Lcd_cmd(_LCD_CLEAR);
      Lcd_cmd(_LCD_CURSOR_OFF);
      portb = 0;               //turn off loads
 //****************************************************************************
//****If switch is pushed, do setup of Battery Mah capacity, else do program***
//*****************************************************************************
      if(switch ==1)
  {                                               //Clear files
        Mah_1000 = 0;
        Mah_100  = 0;
        
        Lcd_Out(1,1,"Battery IR Meter    ");
        Lcd_Out(2,1,"Release Switch      ");
        Lcd_Out(3,1,"Do 1000 Mah Batt    ");
        Lcd_Out(4,1,"Batt Mah Cap        ");
        LCD_CHR(4,15,0x30+Mah_1000);
        LCD_CHR(4,16,0x30+Mah_100);
        LCD_CHR(4,17,0x30);
        LCD_CHR(4,18,0x30);
        if (switch == 1)
     {
        Lcd_Out(2,1,"Release Switch      ");
        delay_ms(600);
        Lcd_Out(2,1,"Push    Switch      ");
     }
        delay_ms(600);
        portb = 0;                                //verify load is off
Switch_push:                                      //do the switch routines
        if (switch == 0)
        goto   Switch_push;
        delay_ms(400);
        Lcd_Out(2,1,"Hold/Release Switch ");

Mah1000_adj:                                      //adjust 1000's Mah
        if (Mah_1000>0x09)                        //if above 9, set to zero
        Mah_1000 = 0;
        LCD_CHR(4,15,0x30+Mah_1000);
        delay_ms(400);
        if(switch == 1)
      {
        Mah_1000 = Mah_1000+1;
        goto Mah1000_adj       ;
      }
 //do 100 mah                                     //adjust 100's Mah
      {
       delay_ms(500);
       Lcd_Out(3,1,"Do 100 Mah Batt        ");
 Switch_pusha:
       Lcd_Out(2,1,"Hold/Release Switch ");
       if (switch == 0)
       goto   Switch_pusha;
  Mah100_adj:
                                                  //if above 9, set to zero
       if (Mah_100>0x09)
       Mah_100 = 0;
       LCD_CHR(4,16,0x30+Mah_100);
       delay_ms(400);
       if(switch == 1)
       {
          Mah_100 = Mah_100+1;
          goto Mah100_adj       ;
       }

     }
        EEPROM_Write (0x00,Mah_1000);             //write both to EEProm
        delay_ms(100);                            //Pause required for writing
        EEPROM_Write (0x01,Mah_100);
  }

Run_Pgm:                                          //Run the program
    {
//Turn off test currents,
      R2ohm = off;
      delay_ms (10);
      R5ohm = off;                                //turn off power resistors

//Do LCD initialization and display functions
      Lcd_init();
      Lcd_cmd(_LCD_CLEAR);
      Lcd_cmd(_LCD_CURSOR_OFF);
      Lcd_Out(1,1,"Battery IR Meter    ");
      Lcd_Out(2,1,"9 Volt Batt         ");
      Lcd_Out(3,1,"Batt Cap      00 Mah");
      Lcd_Out(4,1,"Built 01-10-16  Wait");
      Mah_1000 = EEPROM_Read(0x00);
      delay_ms(100);
      Mah_100 =  EEPROM_Read(0x01);
      Batt_Mah = (Mah_1000*10)+Mah_100;
      LCD_CHR(3,13,0x30+Mah_1000);
      LCD_CHR(3,14,0x30+Mah_100);
      delay_ms (120);                             //wait for battery reading
//get 9 Volt battery value
      tlong=Adc_Read(1);
      tlong = tlong*1000;
      tlong = tlong/2640;
      ch = tlong/1000 ;                           //1000;
      LCD_CHR(2,13,0x30+ch);                      //4th digit
      ch = (tlong/100)%10;
      LCD_CHR_CP(0x30+ch);                        //3rd digit
      LCD_CHR_CP ('.');                           // decimal
      ch=(tlong/10)%10;                           //2nd digit
      LCD_CHR_CP(0x30+ch);
      ch = (tlong /1)%10 ;                        //1st digit
      LCD_CHR_CP (0x30+ch);                       //Don't show last digit
//set off low battery warning if below 6.50 Volts DC
       if (tlong<670)
        {
         Lcd_Out (3,1,"Change 9 VDC Battery");
         delay_ms(2000);
        }
           else
          {
          }
//continue to regular program

      delay_ms(1500);
      Lcd_Out(1,1,"#1      V  #5      V");
      Lcd_Out(2,1,"#2      V  #6      V");
      Lcd_Out(3,1,"#3      V  #7      V");
      Lcd_Out(4,1,"#4      V Bat      V");
 restart:
      portb = 0b00000000;                   //no load battery measurement
      delay_ms(30);                         //  wait for relays to stabilize
      ADFunction();                         //get 7 channel volts
      LCDFunction();                        //display 7 channel volts
      batt_adder ();                        //add up batt volts array
      BattNL = tlong;                       //save batt volts to BattNL
      batt_volts();                         //print batt volts
      delay_ms(10);
  }
 //Test for switch pushed for doing load tests
      if(switch ==0)
      goto restart;
 //do 5 ohm load
      Lcd_cmd(_LCD_CLEAR);
      Lcd_Out(1,1,"Volts on 5 Ohms     ");
      delay_ms(5);
      Lcd_Out(2,1,"5 Ohm Load is ON    ");
      portb = 0b00100000;
      delay_ms(300);                        //on time for 5 ohms - 3 seconds
      ADFunction();                         //read A/D  voltages
      portb = 0x00;                         //turn off 5 ohms
      Array5ohm[0] = ArrayV[0];
      Array5ohm[1] = ArrayV[1];
      Array5ohm[2] = ArrayV[2];
      Array5ohm[3] = ArrayV[3];
      Array5ohm[4] = ArrayV[4];
      Array5ohm[5] = ArrayV[5];
      Array5ohm[6] = ArrayV[6];
      Array5ohm[7] = ArrayV[7];
      Lcd_Out(3,1,"5 Ohm Load is OFF   ");
      delay_ms(500);
      Lcd_Out(1,1,"#1      V  #5      V");
      Lcd_Out(2,1,"#2      V  #6      V");
      Lcd_Out(3,1,"#3      V  #7      V");
      Lcd_Out(4,1,"#4      V loA      V");
      LCDFunction();                        //display it
      batt_adder ();                        //add up batt volts array
      Batt5ohm = tlong;                     //save batt volts to BattNL
      batt_volts();                         //print batt volts
      delay_ms(200);                       //hold display visually
Hold_5ohm:
     if(switch==1)                         //if switch=1, fast forward
     goto do_2ohm;
     Lcd_out(4,11,"Key");
     delay_ms(200);
     Lcd_out(4,11,"   ");
     delay_ms(200);
     goto Hold_5ohm;
  //do 2 ohm load
do_2ohm:
     Lcd_cmd(_LCD_CLEAR);
     Lcd_Out(1,1,"Volts on 1.42 ohms  ");
     delay_ms(5);
     Lcd_Out(2,1,"1.4 Ohm Load is ON  ");
     portb = 0b00110000;
     delay_ms(100);                         //on time for 5 ohms - 1.0 seconds
     ADFunction();                          //read A/D  voltages
     portb = 0x00;                          //turn off 5 ohms
     Lcd_Out(3,1,"1.4 Ohm Load is OFF ");
     Array2ohm[0] = ArrayV[0];              //copy to Array2Ohm for IR calc
     Array2ohm[1] = ArrayV[1];
     Array2ohm[2] = ArrayV[2];
     Array2ohm[3] = ArrayV[3];
     Array2ohm[4] = ArrayV[4];
     Array2ohm[5] = ArrayV[5];
     Array2ohm[6] = ArrayV[6];
     Array2ohm[7] = ArrayV[7];
     delay_ms(500);
     Lcd_Out(1,1,"#1      V  #5      V");
     Lcd_Out(2,1,"#2      V  #6      V");
     Lcd_Out(3,1,"#3      V  #7      V");
     Lcd_Out(4,1,"#4      V HiA      V");
     LCDFunction();                        //display it
     batt_adder ();                        //add up batt volts array
     Batt2ohm = tlong;                     //save batt volts to BattNL
     batt_volts();                         //print batt volts
     delay_ms(200);                       //hold display visually
 Hold_2ohm:
     if(switch ==1)                       //if switch=1, fast forward
     goto      doIR;
     Lcd_out(4,11,"Key");
     delay_ms(200);
     Lcd_out(4,11,"   ");
     delay_ms(200);
     goto hold_2ohm;
     
//do IR calculations here
doIR: Lcd_Out(4,11,"Rls");                //hold here if switch=1
      if (switch ==1)
      goto       doIR;
     Lcd_Out(1,1,"#1ir      #5ir      ");
     Lcd_Out(2,1,"#2ir      #6ir      ");
     Lcd_Out(3,1,"#3ir      #7ir      ");
     Lcd_Out(4,1,"#4ir      Bat  mOhms");
//calculate IR where IR = (Vlow-Vhi)/AmpsHi-AmpsLo)
 
        ArrayIR [0] = 0;                  //clear array for less than 7 cells
        ArrayIR [1] = 0;
        ArrayIR [2] = 0;
        ArrayIR [3] = 0;
        ArrayIR [4] = 0;
        ArrayIR [5] = 0;
        ArrayIR [6] = 0;
        ArrayIR [7] = 0;
      for (counts=0; counts<(CellCnt);counts++)
     {
       Test_Amps = (Batt5ohm/5)-(Batt2ohm/1.428);
       tlong  = (Array5ohm[counts]-Array2ohm[counts]) ;
       tlong = tlong*100000;
       tlong = tlong/Test_Amps;
       ArrayIR [counts] = tlong;
       ch = tlong/1000 ;     //1000;
       LCD_CHR(LCDRow[counts],LCDIRColIR[counts],0x30+ch);   //4th digit
       ch = (tlong/100)%10;
       LCD_CHR_CP(0x30+ch);                       //3rd digit
       LCD_CHR_CP ('.');                          // decimal
       ch=(tlong/10)%10;
       LCD_CHR_CP(0x30+ch);                       //2nd digit
       ch = (tlong /1)%10 ;
       LCD_CHR_CP (0x30+ch);                      //1st digit
     }
      delay_ms(200);
 holdit:
      Lcd_out(4,11,"Key ");
      delay_ms(200);
      Lcd_out(4,11,"    ");
      delay_ms(200);
      portb=0x00;
      if(switch ==0)
      goto holdit;
      Lcd_Out(1,1,"Reference RCGroups  ");
      Lcd_Out(2,1,"Forsyth,Julian,Giles");
      Lcd_Out(3,1,"Max Current is     A");
      Lcd_Out(4,1,"                    ");
//this routine finds the maximum IR value in the IR Array
       for (counts = 0; counts < 7; counts ++)
     {
       if (ArrayIR[0]<ArrayIR[counts])
       ArrayIR[0] = ArrayIR[counts]    ;
     }
       Max_IR = ArrayIR[0];                       //calculate IR for cell
       Calc = 60000*Batt_mah;
       tlong = sqrt (calc/Max_IR)    ;            //do square root on results
       ch = tlong /100;
       LCD_CHR(3,16,0x30+ch); //4th digit
       ch = (tlong/10)%10;
       LCD_CHR_CP(0x30+ch);                       //3rd digit

       ch=(tlong/1)%10;                           //2nd digit
       LCD_CHR_CP(0x30+ch);
                                                  //1st digit
  //     ch = (tlong /1)%10 ;
  //     LCD_CHR_CP (0x30+ch);                    // Don't show
 hold_Max:
        Lcd_out(4,1,"Push/Release Switch ");
        delay_ms(200);
        portb=0x00;
        if(switch ==0)
        {goto hold_Max;}
        {delay_ms(200);
Hold_here:
        if(switch==1)
        goto hold_here;
        goto reinit; }
  }
]
Last edited by vollrathd; Jan 11, 2017 at 12:07 AM. Reason: Updated program
Jan 09, 2017, 07:29 AM
Registered User
Ken Myers's Avatar
Quote:
Originally Posted by vollrathd

I've compared the readings of this unit against my Cellpro PL8 units. There is a very large difference in their readings. The Cellpro PL8 shows IR values around 1/2 of this unit. Interesting.

So how does this unit do in the real world? I used the 2.66 milliohm value on cell #1, to calculate the cell voltage at 64 Amps. The 2.66 milliohms times 64 Amps is a 0.172 Volt drop. The 3.80 Volt no load minus 0.172 Volt drop is 3.628 Volts.

I measured 3.614 Volts on the motor load of 64 Amps. Within about 1/2%.
The CellPro 8 calculates the internal resistance value in a very different way, and it is NOT the true internal resistances. The results of the charger's calculation are only comparable to themselves.

0.00266 Ohms x 64 amps = 0.17024 rounded to 0.170, not 0.172

3.80V - 0.17V = 3.63V That is not really significant, but just wanted to point it out. It still works out to less than 1/2%. Nice job.
Jan 10, 2017, 02:42 AM
Registered User
Hey that's cool, it's simpler than I would have guessed for what it does.

My only suggestion for improvement is a bit of cleanup of the PCB layout. I always use 0, 45 and 90 degree traces, no oddball angles, and I avoid sharp 90 degree bends, preferring a 45-45, the PCB trace equivalent to a long sweep pipe elbow. For those etching the board at home that improves the yield as well as resulting in a cleaner more professional looking board. I may have some OCD tendencies too which that satisfies. Oh and another thing I like to do is move the reference designators so that they're all still visible when the components are installed. Nice project though, I really like the clean layout of the code and the ample comments, and the fact that it's being shared, I might have to build one of those.
Jan 10, 2017, 08:30 PM
Registered User
vollrathd's Avatar

BatteryIR meter now on youtube


I've just posted the video I took showing how this meter works.

BatteryIR Meter (2 min 58 sec)


And updated "C" program, along with the corresponding hex file will be posted tomorrow.

It uses the same exact circuitry, and same exact circuit board.
Jan 10, 2017, 08:37 PM
Registered User
vollrathd's Avatar
Quote:
Originally Posted by James_S
Hey that's cool, it's simpler than I would have guessed for what it does.

My only suggestion for improvement is a bit of cleanup of the PCB layout. I always use 0, 45 and 90 degree traces, no oddball angles, and I avoid sharp 90 degree bends, preferring a 45-45, the PCB trace equivalent to a long sweep pipe elbow. For those etching the board at home that improves the yield as well as resulting in a cleaner more professional looking board. I may have some OCD tendencies too which that satisfies. Oh and another thing I like to do is move the reference designators so that they're all still visible when the components are installed. Nice project though, I really like the clean layout of the code and the ample comments, and the fact that it's being shared, I might have to build one of those.
Yeah
I've made my own circuit boards back a few years ago, what with exposing circuit boards with a UV light, etching, drilling and soldering up. Never had much luck on any traces narrower than around 30/1000 though. One side of the board would be just finished, while the other side of the same circuit board would be under etched to the point where the trace disappeared.

Places like ExpressPCB will produce three 2.5 by 3.8 inch double sided, plated through holes for around $55.00, shipped to your home. In two days. And, there are no issues of what to do with the etchant solution. And, the circuit boards come out perfect. Every time. The ExpressPCB software allows the user to color print the overlay, top and bottom traces, or just the overlay, or the overlay plus top layer, and so on.

As for putting the label near by the component, that works when there is enough room.
Jan 10, 2017, 08:51 PM
Registered User
I use ExpressPCB for my home projects too. If you can fit it on their standard mini board you get a hell of a deal and the quality is first class. The free tools are not the best but for small boards they are ok - and they are free. I worked for a startup a few years back and we used them for some of our prototyping too. I highly recommend them. I have found out the hard way that you have to double and triple check your layout though. Their tools do not do much error checking.
Jan 11, 2017, 12:06 AM
Registered User
vollrathd's Avatar

BatteryIR meter with Maximum Amps "C" program


This is the BatteryIR meter's "C" program, using the mikroC program. Attached is the Hex file generated by the mikroC program.
If anyone has downloaded the previous copy, please delete it, and replace it with this file.

I have been working on the design and software of this unit on and off for about four months.

Do note that the maximum current rating of the battery pack formula at the end of the "C" program was derived by research conducted by Wayne Giles, John Julian (JJ604) and Mark Forsyth (mrforsyth).


Code:
/*
BATTERY IR METER TEST UNIT RELAY SYSTEM VERSION II
RCGroups - vollrathd

Date 12-13-2016  Project Circuit Board Started
Date 12-25-2016  All is working
Date 12-26-2016  Added 9 Volt DC Monitor
Date 01-06-2017  Final Version of Software
Date 01-09-2017  Added Max Amps to the software
This project applies two different resistor loads to the
battery under test.  Current is calculated by voltage drop
across two precision power resistors.

Project set up to run with the PIC18F25K80 PicChip
The C file is in mikroC format, with the mikroP programmer

*****************************************************************************
* CAUTION! IN ORDER TO USE RC0 AND RC1, SET UP OSCILLATOR CONFIGURATION FOR *
***** DIGITAL (SCLK1) MODE IN CONFIGURATION AND SETUP FILES *****************
**DEFAULT PORT A AND B ARE ANALOG INPUTS.  MUST ASSIGN DIGITAL IN A/D SETUP**
* PicChip clock speed set to 16 Mhz with mikroP in order for LCD to keep up *
*************** PicChip programmed to use internal clock ********************
****DO NOT PROGRAM PICCHIP WITH BATTERY UNDER TEST PLUGGED IN!***************
****THE PROGRAMMER WILL TURN ON THE POWER RESISTORS, OVERHEATING THEM********
*****************************************************************************
Operation modes
1.  Power up, display voltages on all seven cells plus total voltage
2.  Watch for key input for next command
3.  Low volts is 1.428 Ohm load   High Volts is 5 Ohm load
4.  Apply 5 Ohm load for 1.5 seconds to equalize cells
5.  Measure all cell voltages and store to array
6.  Apply  2 + 5 Ohms for 0.5 seconds measure volts and save to Array
7.  Measure battery voltage and calculate current
8.  Do calculations on IR
9.  Display IR for all cells
10. Go back to restart
    Following are the connections to the electronic relays
     cell_1 {porta=0b00001000; portc=0b00000000;}
     cell_2 {porta=0b00100000; portc=0b00000000;}
     cell_3 {porta=0b01000000; portc=0b00000000;}
     cell_4 {porta=0b00000000; portc=0b00000001;}
     cell_5 {porta=0b00000000; portc=0b00000010;}
     cell_6 {porta=0b00000000; portc=0b00000100;}
     cell_7 {porta=0b00000000; portc=0b00001000;}
*/
// Set up PicChip for LCD function per instruction in mikroC manual
     sbit LCD_RS at RB3_bit;
     sbit LCD_EN at RB2_bit;
     sbit LCD_d4 at RC4_bit;
     sbit LCD_d5 at RC5_bit;
     sbit LCD_d6 at RC6_bit;
     sbit LCD_d7 at RC7_bit;

     sbit LCD_RS_Direction at TRISB3_bit;
     sbit LCD_EN_Direction at TRISB2_bit;
     sbit LCD_D4_Direction at TRISC4_bit;
     sbit LCD_D5_Direction at TRISC5_bit;
     sbit LCD_D6_Direction at TRISC6_bit;
     sbit LCD_D7_Direction at TRISC7_bit;
 //set up definitions
     unsigned char lcd_loc ;
     unsigned long mi_volt,milli_read,counter,milli_readavg,Max_IR;
     float Test_Amps,Batt_IR;
     unsigned long CellCnt,BattNL,Batt5ohm,Batt2ohm,Batt_Mah,calc;
     unsigned char ch;
     unsigned char Mah_1000, Mah_100;                       //Batt Mah numbers
     unsigned long tlong   ;
     unsigned char counts ;
     unsigned int ArrayV [8] ;
     unsigned int Array2ohm [8];
     unsigned int Array5ohm [8];
     unsigned long int ArrayIR [8];
//   Look Up tables
     unsigned char LCDRow[] = {1,2,3,4,1,2,3,4}       ;        //LCD Rows
     unsigned char LCDCol[] = {4,4,4,4,15,15,15,15}   ;        //LCD Columns
     unsigned char LCDIRCol[] = {6,6,6,6,17,17,17,17}   ;      //LCD Columns
     unsigned char LCDIRColIR[] = {5,5,5,5,15,15,15,15} ;      //IRLCD Columns
     unsigned char ADChan [] = {8,10,0,1,2,3,4}      ;         //AD Channel
     unsigned char porta_bat[] ={0x08,0x20,0x40,0x00,0x00,0x00,0x00};
     unsigned char portc_bat[] ={0x00,0x00,0x00,0x01,0x02,0x04,0x08};
     #define switch portb.rb1
     #define pressed 1
     #define R2ohm PORTb.rb4
     #define R5ohm PORTb.rb5
     #define on 1
     #define off 0
//*****************************************************************************
//***********Analog Digital Function.  Input, CPU, Output ArrayV **************
//*****************************************************************************
     void ADFunction(void)
{
     ArrayV[0] = 0x00;
     ArrayV[1] = 0x00;
     ArrayV[2] = 0x00;
     ArrayV[3] = 0x00;
     ArrayV[4] = 0x00;
     ArrayV[5] = 0x00;
     ArrayV[6] = 0x00;
     CellCnt = 0;
      for(counts=0;counts<7;counts++)
  {
      porta = (porta_bat[CellCnt]);
      delay_us(2);
      portc = (portc_bat[Cellcnt]);
      delay_ms(40)      ;                         //wait for warm up
      milli_readavg = 0 ;                         //clear milli reader
      for (counter=0; counter<32; counter++)      //adjust calibration
    {
      milli_read=Adc_Read(0);                     //read channel zero
      milli_readavg = (milli_readavg+Milli_read) ;//add up all 100 readings
    }
    
      mi_volt = (milli_readavg*10/259);           //divide by no of reads
      if (mi_volt <100)                           //If zero volts, skip
    {
      ArrayV[CellCnt] = 0x00;                     //enter zero count
    }
      else
    {
      ArrayV[CellCnt] = mi_volt;                  //Store cell volts to array
      CellCnt=CellCnt+1 ;
    }
  }
      portb = 0x00;                               //turn off power resistors
      delay_ms(2);                                //2 ms mikroC bug
      porta = 0x00;
      delay_ms(2);
      portc = 0x00;
}
//****************************************************************************
//***LCD Function Input ArrayV  Output to LCD Display. ***********************
//****************************************************************************
   void LCDFunction(void)
  {
      for (counts=0; counts<(CellCnt);counts++)
     {
       tlong = ArrayV [counts] ;                       //show volts
       LCD_CHR(LCDRow[counts],LCDCol[counts],0x30+ch); //4th digit
       ch = tlong /1000;
       LCD_CHR(LCDRow[counts],LCDCol[counts],0x30+ch); //4th digit

       LCD_CHR_CP ('.');                               // decimal
 
       ch = (tlong/100)%10;
       LCD_CHR_CP(0x30+ch);                            //3rd digit

       ch=(tlong/10)%10;                               //2nd digit
       LCD_CHR_CP(0x30+ch);
                                                       //1st digit
       ch = (tlong /1)%10 ;
       LCD_CHR_CP (0x30+ch);
     }
        delay_ms(50);
  }
//*****************************************************************************
//*****Battery Voltage Function Input batt_adder with tlong output ************
//*****************************************************************************
  void batt_volts(void)
     {
       ch = tlong /10000;
       LCD_CHR(4,15,0x30+ch);//4th digit
       ch = (tlong/1000)%10;
       LCD_CHR_CP(0x30+ch);                        //3rd digit
       LCD_CHR_CP ('.');                           // decimal
       ch=(tlong/100)%10;                          //2nd digit
       LCD_CHR_CP(0x30+ch);
                                                   //1st digit
       ch = (tlong /10)%10 ;
       LCD_CHR_CP (0x30+ch);
     }
//*****************************************************************************
//********Batter Adder  Input ArrayV  Output tlong*****************************
//*****************************************************************************
  void batt_adder(void)
     {
       tlong = ArrayV[0]+ArrayV[1]+ArrayV[2]
       +ArrayV[3]+ArrayV[4]+ArrayV[5]+ArrayV[6];
     }
//*****************************************************************************
//***********This is the main program ****************************t************
//*****************************************************************************
 void main()
 {
//Configure A/D converter
      ANCON0 = 0X01 ;                             //configures channel 0 as A/D
      ANCON1 = 0X00;                              //configure port B as all
      ADCON1 = 0x00;                              // digital default A/D!
      lcd_loc = 0x00 ;
// Configure I/O ports
      trisa = 0b00000011;                   //port a, bit 0,1 are analog inputs
      trisb = 0b00000011  ;                 //make port b, bits 0, 1 inputs
      trisc = 0b00000000;
      portb = 0;                                  //turn off loads
//*********Program End Return Point *******************************************
 reinit:
      Lcd_init();
      Lcd_cmd(_LCD_CLEAR);
      Lcd_cmd(_LCD_CURSOR_OFF);
      portb = 0;               //turn off loads
 //****************************************************************************
//****If switch is pushed, do setup of Battery Mah capacity, else do program***
//*****************************************************************************
      if(switch ==1)
  {                                               //Clear files
        Mah_1000 = 0;
        Mah_100  = 0;
        
        Lcd_Out(1,1,"Battery IR Meter    ");
        Lcd_Out(2,1,"Release Switch      ");
        Lcd_Out(3,1,"Do 1000 Mah Batt    ");
        Lcd_Out(4,1,"Batt Mah Cap        ");
        LCD_CHR(4,15,0x30+Mah_1000);
        LCD_CHR(4,16,0x30+Mah_100);
        LCD_CHR(4,17,0x30);
        LCD_CHR(4,18,0x30);
        if (switch == 1)
     {
        Lcd_Out(2,1,"Release Switch      ");
        delay_ms(600);
        Lcd_Out(2,1,"Push    Switch      ");
     }
        delay_ms(600);
        portb = 0;                                //verify load is off
Switch_push:                                      //do the switch routines
        if (switch == 0)
        goto   Switch_push;
        delay_ms(400);
        Lcd_Out(2,1,"Hold/Release Switch ");

Mah1000_adj:                                      //adjust 1000's Mah
        if (Mah_1000>0x09)                        //if above 9, set to zero
        Mah_1000 = 0;
        LCD_CHR(4,15,0x30+Mah_1000);
        delay_ms(400);
        if(switch == 1)
      {
        Mah_1000 = Mah_1000+1;
        goto Mah1000_adj       ;
      }
 //do 100 mah                                     //adjust 100's Mah
      {
       delay_ms(500);
       Lcd_Out(3,1,"Do 100 Mah Batt        ");
 Switch_pusha:
       Lcd_Out(2,1,"Hold/Release Switch ");
       if (switch == 0)
       goto   Switch_pusha;
  Mah100_adj:
                                                  //if above 9, set to zero
       if (Mah_100>0x09)
       Mah_100 = 0;
       LCD_CHR(4,16,0x30+Mah_100);
       delay_ms(400);
       if(switch == 1)
       {
          Mah_100 = Mah_100+1;
          goto Mah100_adj       ;
       }

     }
        EEPROM_Write (0x00,Mah_1000);             //write both to EEProm
        delay_ms(100);                            //Pause required for writing
        EEPROM_Write (0x01,Mah_100);
  }

Run_Pgm:                                          //Run the program
    {
//Turn off test currents,
      R2ohm = off;
      delay_ms (10);
      R5ohm = off;                                //turn off power resistors

//Do LCD initialization and display functions
      Lcd_init();
      Lcd_cmd(_LCD_CLEAR);
      Lcd_cmd(_LCD_CURSOR_OFF);
      Lcd_Out(1,1,"Battery IR Meter    ");
      Lcd_Out(2,1,"9 Volt Batt         ");
      Lcd_Out(3,1,"Batt Cap      00 Mah");
      Lcd_Out(4,1,"Built 01-10-16  Wait");
      Mah_1000 = EEPROM_Read(0x00);
      delay_ms(100);
      Mah_100 =  EEPROM_Read(0x01);
      Batt_Mah = (Mah_1000*10)+Mah_100;
      LCD_CHR(3,13,0x30+Mah_1000);
      LCD_CHR(3,14,0x30+Mah_100);
      delay_ms (120);                             //wait for battery reading
//get 9 Volt battery value
      tlong=Adc_Read(1);
      tlong = tlong*1000;
      tlong = tlong/2640;
      ch = tlong/1000 ;                           //1000;
      LCD_CHR(2,13,0x30+ch);                      //4th digit
      ch = (tlong/100)%10;
      LCD_CHR_CP(0x30+ch);                        //3rd digit
      LCD_CHR_CP ('.');                           // decimal
      ch=(tlong/10)%10;                           //2nd digit
      LCD_CHR_CP(0x30+ch);
      ch = (tlong /1)%10 ;                        //1st digit
      LCD_CHR_CP (0x30+ch);                       //Don't show last digit
//set off low battery warning if below 6.50 Volts DC
       if (tlong<670)
        {
         Lcd_Out (3,1,"Change 9 VDC Battery");
         delay_ms(2000);
        }
           else
          {
          }
//continue to regular program

      delay_ms(1500);
      Lcd_Out(1,1,"#1      V  #5      V");
      Lcd_Out(2,1,"#2      V  #6      V");
      Lcd_Out(3,1,"#3      V  #7      V");
      Lcd_Out(4,1,"#4      V Bat      V");
 restart:
      portb = 0b00000000;                   //no load battery measurement
      delay_ms(30);                         //  wait for relays to stabilize
      ADFunction();                         //get 7 channel volts
      LCDFunction();                        //display 7 channel volts
      batt_adder ();                        //add up batt volts array
      BattNL = tlong;                       //save batt volts to BattNL
      batt_volts();                         //print batt volts
      delay_ms(10);
  }
 //Test for switch pushed for doing load tests
      if(switch ==0)
      goto restart;
 //do 5 ohm load
      Lcd_cmd(_LCD_CLEAR);
      Lcd_Out(1,1,"Volts on 5 Ohms     ");
      delay_ms(5);
      Lcd_Out(2,1,"5 Ohm Load is ON    ");
      portb = 0b00100000;
      delay_ms(300);                        //on time for 5 ohms - 3 seconds
      ADFunction();                         //read A/D  voltages
      portb = 0x00;                         //turn off 5 ohms
      Array5ohm[0] = ArrayV[0];
      Array5ohm[1] = ArrayV[1];
      Array5ohm[2] = ArrayV[2];
      Array5ohm[3] = ArrayV[3];
      Array5ohm[4] = ArrayV[4];
      Array5ohm[5] = ArrayV[5];
      Array5ohm[6] = ArrayV[6];
      Array5ohm[7] = ArrayV[7];
      Lcd_Out(3,1,"5 Ohm Load is OFF   ");
      delay_ms(500);
      Lcd_Out(1,1,"#1      V  #5      V");
      Lcd_Out(2,1,"#2      V  #6      V");
      Lcd_Out(3,1,"#3      V  #7      V");
      Lcd_Out(4,1,"#4      V loA      V");
      LCDFunction();                        //display it
      batt_adder ();                        //add up batt volts array
      Batt5ohm = tlong;                     //save batt volts to BattNL
      batt_volts();                         //print batt volts
      delay_ms(200);                       //hold display visually
Hold_5ohm:
     if(switch==1)                         //if switch=1, fast forward
     goto do_2ohm;
     Lcd_out(4,11,"Key");
     delay_ms(200);
     Lcd_out(4,11,"   ");
     delay_ms(200);
     goto Hold_5ohm;
  //do 2 ohm load
do_2ohm:
     Lcd_cmd(_LCD_CLEAR);
     Lcd_Out(1,1,"Volts on 1.42 ohms  ");
     delay_ms(5);
     Lcd_Out(2,1,"1.4 Ohm Load is ON  ");
     portb = 0b00110000;
     delay_ms(100);                         //on time for 5 ohms - 1.0 seconds
     ADFunction();                          //read A/D  voltages
     portb = 0x00;                          //turn off 5 ohms
     Lcd_Out(3,1,"1.4 Ohm Load is OFF ");
     Array2ohm[0] = ArrayV[0];              //copy to Array2Ohm for IR calc
     Array2ohm[1] = ArrayV[1];
     Array2ohm[2] = ArrayV[2];
     Array2ohm[3] = ArrayV[3];
     Array2ohm[4] = ArrayV[4];
     Array2ohm[5] = ArrayV[5];
     Array2ohm[6] = ArrayV[6];
     Array2ohm[7] = ArrayV[7];
     delay_ms(500);
     Lcd_Out(1,1,"#1      V  #5      V");
     Lcd_Out(2,1,"#2      V  #6      V");
     Lcd_Out(3,1,"#3      V  #7      V");
     Lcd_Out(4,1,"#4      V HiA      V");
     LCDFunction();                        //display it
     batt_adder ();                        //add up batt volts array
     Batt2ohm = tlong;                     //save batt volts to BattNL
     batt_volts();                         //print batt volts
     delay_ms(200);                       //hold display visually
 Hold_2ohm:
     if(switch ==1)                       //if switch=1, fast forward
     goto      doIR;
     Lcd_out(4,11,"Key");
     delay_ms(200);
     Lcd_out(4,11,"   ");
     delay_ms(200);
     goto hold_2ohm;
     
//do IR calculations here
doIR: Lcd_Out(4,11,"Rls");                //hold here if switch=1
      if (switch ==1)
      goto       doIR;
     Lcd_Out(1,1,"#1ir      #5ir      ");
     Lcd_Out(2,1,"#2ir      #6ir      ");
     Lcd_Out(3,1,"#3ir      #7ir      ");
     Lcd_Out(4,1,"#4ir      Bat  mOhms");
//calculate IR where IR = (Vlow-Vhi)/AmpsHi-AmpsLo)
 
        ArrayIR [0] = 0;                  //clear array for less than 7 cells
        ArrayIR [1] = 0;
        ArrayIR [2] = 0;
        ArrayIR [3] = 0;
        ArrayIR [4] = 0;
        ArrayIR [5] = 0;
        ArrayIR [6] = 0;
        ArrayIR [7] = 0;
      for (counts=0; counts<(CellCnt);counts++)
     {
       Test_Amps = (Batt5ohm/5)-(Batt2ohm/1.428);
       tlong  = (Array5ohm[counts]-Array2ohm[counts]) ;
       tlong = tlong*100000;
       tlong = tlong/Test_Amps;
       ArrayIR [counts] = tlong;
       ch = tlong/1000 ;     //1000;
       LCD_CHR(LCDRow[counts],LCDIRColIR[counts],0x30+ch);   //4th digit
       ch = (tlong/100)%10;
       LCD_CHR_CP(0x30+ch);                       //3rd digit
       LCD_CHR_CP ('.');                          // decimal
       ch=(tlong/10)%10;
       LCD_CHR_CP(0x30+ch);                       //2nd digit
       ch = (tlong /1)%10 ;
       LCD_CHR_CP (0x30+ch);                      //1st digit
     }
      delay_ms(200);
 holdit:
      Lcd_out(4,11,"Key ");
      delay_ms(200);
      Lcd_out(4,11,"    ");
      delay_ms(200);
      portb=0x00;
      if(switch ==0)
      goto holdit;
      Lcd_Out(1,1,"Reference RCGroups  ");
      Lcd_Out(2,1,"Forsyth,Julian,Giles");
      Lcd_Out(3,1,"Max Current is     A");
      Lcd_Out(4,1,"                    ");
//this routine finds the maximum IR value in the IR Array
       for (counts = 0; counts < 7; counts ++)
     {
       if (ArrayIR[0]<ArrayIR[counts])
       ArrayIR[0] = ArrayIR[counts]    ;
     }
       Max_IR = ArrayIR[0];                       //calculate IR for cell
       Calc = 60000*Batt_mah;
       tlong = sqrt (calc/Max_IR)    ;            //do square root on results
       ch = tlong /100;
       LCD_CHR(3,16,0x30+ch); //4th digit
       ch = (tlong/10)%10;
       LCD_CHR_CP(0x30+ch);                       //3rd digit

       ch=(tlong/1)%10;                           //2nd digit
       LCD_CHR_CP(0x30+ch);
                                                  //1st digit
  //     ch = (tlong /1)%10 ;
  //     LCD_CHR_CP (0x30+ch);                    // Don't show
 hold_Max:
        Lcd_out(4,1,"Push/Release Switch ");
        delay_ms(200);
        portb=0x00;
        if(switch ==0)
        {goto hold_Max;}
        {delay_ms(200);
Hold_here:
        if(switch==1)
        goto hold_here;
        goto reinit; }
  }
Last edited by vollrathd; Jan 11, 2017 at 12:14 AM.
Jan 11, 2017, 03:19 AM
Registered User
Doesn't ExpressPCB lock you into their service because the software they use is completely non-standard and isn't capable of producing industry standard Gerber files? Seems like that was one of the packages I tried out back when I first started making PCBs, I eventually settled on KiCad after trying half a dozen or so different software packages. Eagle is another popular one but the free version has limitations while KiCad is completely free and works well enough that I've used it to design boards for several commercial products. I use the toner transfer method for etching my own boards when I need one fast, traces down to 10 mil width are no problem using that special blue transfer film, I forget what it's called. Otherwise I was using Seeed Studio and more recently Smart-Prototyping. 10 boards for 10 bucks for small ones, going up a bit with size but it's still incredibly cheap. Quality double sided PCBs with plated through holes, solder mask and silkscreen on both sides, I have no idea how they do it so cheap. It takes a few weeks using the standard shipping but even if you splurge on the fast shipping it's still a bargain.
Jan 11, 2017, 11:29 AM
Registered User
vollrathd's Avatar
Quote:
Originally Posted by James_S
Doesn't ExpressPCB lock you into their service because the software they use is completely non-standard and isn't capable of producing industry standard Gerber files? Seems like that was one of the packages I tried out back when I first started making PCBs, I eventually settled on KiCad after trying half a dozen or so different software packages. Eagle is another popular one but the free version has limitations while KiCad is completely free and works well enough that I've used it to design boards for several commercial products. I use the toner transfer method for etching my own boards when I need one fast, traces down to 10 mil width are no problem using that special blue transfer film, I forget what it's called. Otherwise I was using Seeed Studio and more recently Smart-Prototyping. 10 boards for 10 bucks for small ones, going up a bit with size but it's still incredibly cheap. Quality double sided PCBs with plated through holes, solder mask and silkscreen on both sides, I have no idea how they do it so cheap. It takes a few weeks using the standard shipping but even if you splurge on the fast shipping it's still a bargain.
ExpressPCB does offer a Gerber file, but they charge $60.00 for it. That's the problem with some of those circuit board cad programs. That being their extreme cost. For me, only making a few different PCB's a year doesn't justify it.

I'll have to look at KiCad and the others you've listed.
Jan 11, 2017, 05:36 PM
Registered User
dhooks6's Avatar
Very nice! Have you had a chance to compare readings against a junsi based charger? Or just your PL?
Jan 11, 2017, 05:39 PM
Registered User
I tried probably 6 different packages, getting close to 10 years ago now so things may have changed. These ranged in cost from free to upwards of $10K and my conclusion was that they all suck. They're all buggy and full of quirks, they all have a bit of a learning curve, but most of them will do the job once you learn to work around the quirks. All else being equal, I think Eagle is slightly superior to KiCad, but the free hobbyist version is limited to fairly small boards, only 2 layers, I forget precisely what, and the next tier up is something like $600. KiCad is completely free and open source with no limitations, so while the library management with separate schematic and layout portions is a bone-headed design decision, once you get accustomed to that it's not a big deal. If money were unlimited I would probably go with Altium Designer but that's way, WAY out of my budget and I'm not designing PC motherboards or microwave stuff with loads of layers and GHz frequencies. I decided early on though that the ability to output standard Gerber files was of high importance, I refuse to be locked into one single board supplier and charging $60 to get out is extortion.


Thread Tools