Ohms law basic calculations for calculating R2 in voltage divider when R1 is known and to calculate voltage drop ratio when both R1 and R2 are known.

diode_current_flow.h

Committer:
joeata2wh
Date:
2016-04-02
Revision:
3:b4592b0ae1e3

File content as of revision 3:b4592b0ae1e3:

/* Compute Current Flow across Diode
   using voltage drop across the diode.
  
  By Joseph Ellsworth CTO of A2WH
  Take a look at A2WH.com Producing Water from Air using Solar Energy
  March-2016 License: https://developer.mbed.org/handbook/MIT-Licence 
  Please contact us http://a2wh.com for help with custom design projects.

  
  Based on voltage drop across a diode calculate
  current flowing based on known characteristics of that diode.
  Unlike a resistor this can not be done with straigt ohms law
  because it is temperature specific and is not linear.  Instead we 
  use a lookup table and aproximate between elements to compute
  a value. 
  
  A known limitation is that if voltage drop is equal or lower 
  than smallest value in vDropArr Then all we know is that current is some place 
  betweeen 0 and that minimum current number.  Since all diodes have a minimum drop 
  for any current flow they are not as effective when measuring very small currents. 
  The diodes are best used when we do not want to add the 
  loss of a resistor and we needed the diode in circuit anyway especially when 
  there may be large current flow such as in a charging circuit.

  If you need a temperature specific value then declare a vDrop for multiple temperature ranges 
  then compute the voltage drop for the temperature range above and below current temp and 
  use ratio level computation to compute a weighted average between the two.

  Note: This would be a perfect place to use a differential ADC where 
  the one line is on the postive side of the Diode and the other is 
  on the load side.    Unfortunately mbed doesn't provide standard support
  for the differential. 
  
  Note: Turn off the PWM for the charge circuit and turn the charge
  circuit all the way on before taking this reading or it mess up the ADC readings.
  
*/
 
//#include "ohms.h"

#ifndef diode_current_flow_H
#define diode_current_flow_H
// T.I SM74611 Smart Bypass Diode
const float SM74611VDrop85C[] = {0.020, 0.024, 0.037, 0.040,  0.050,  0.057,  0.060,  0.075,  0.080,  0.090,  0.098, 0.106, -1};
const float SM74611Current[]  = {2.000, 4.000, 6.00,  8.000, 10.000, 12.000, 14.000, 16.000, 18.000, 20.000, 22.000,24.000, -1};
// must be oriented as lowest current flow (lowest vdrop) to highest, must be terminated with -1 and arrays
// must line up by postion.  The more numbers supplied the more accurate the computation will be down to the 
// limit of the ADC.

// NOTE: DEFINE your own diode perfornce characteristics from the Diode datasheet.  They vary a lot and 
//  the SM74611 is a very special diode with very low vdrop so these numbers will not work for other diodes.



/* compute the current flowing across the diode based on the known diode 
characteristics and a known voltage drop across the diode  The two arrays
must both contain floats, must be the same length and must be terminated with -1.0
sentinal.  

*/
float ComputeDiodeCurrent(float *vDropArr, float *currentArr, float vDrop) {
  int lastNdx = 0;
  while (vDropArr[lastNdx] != -1.0) lastNdx++;
  lastNdx--;

  // find first vdrop in array that is less than our specified
  // vdrop which gives us a range where our vDrop must be so we 
  // than then interpolate a current across the diode. 
  if (vDrop >= vDropArr[lastNdx]) return currentArr[lastNdx]; // above our greatest setting
  
  int ndx = lastNdx;
  while ((vDrop < vDropArr[ndx]) && (ndx > 0))
    ndx--;

  if (ndx == 0) return currentArr[0]; // below our lowest setting
  if (vDropArr[ndx] == vDrop) return currentArr[ndx]; // exact match
  
  // Interpolate the ratio we are between the two points found 
  // and use that to determine our actual current flow.  This only
  // works assuming it is a relatively straight line between the two
  // points.  If that is not true then you need to add more points.
  float vrange = vDropArr[ndx + 1] - vDropArr[ndx];
  float amtOverLower = vDrop - vDropArr[ndx];
  float portRange = amtOverLower / vrange;
  float currRange = currentArr[ndx + 1] - currentArr[ndx];
  float lowCurr = currentArr[ndx];
  float portCurAdd = currRange * portRange;
  return lowCurr + portCurAdd;
} 
#endif