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.

Revision:
3:b4592b0ae1e3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/diode_current_flow.h	Sat Apr 02 03:48:37 2016 +0000
@@ -0,0 +1,90 @@
+/* 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