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@3:b4592b0ae1e3, 2016-04-02 (annotated)
- Committer:
- joeata2wh
- Date:
- Sat Apr 02 03:48:37 2016 +0000
- Revision:
- 3:b4592b0ae1e3
basic data log working
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
joeata2wh | 3:b4592b0ae1e3 | 1 | /* Compute Current Flow across Diode |
joeata2wh | 3:b4592b0ae1e3 | 2 | using voltage drop across the diode. |
joeata2wh | 3:b4592b0ae1e3 | 3 | |
joeata2wh | 3:b4592b0ae1e3 | 4 | By Joseph Ellsworth CTO of A2WH |
joeata2wh | 3:b4592b0ae1e3 | 5 | Take a look at A2WH.com Producing Water from Air using Solar Energy |
joeata2wh | 3:b4592b0ae1e3 | 6 | March-2016 License: https://developer.mbed.org/handbook/MIT-Licence |
joeata2wh | 3:b4592b0ae1e3 | 7 | Please contact us http://a2wh.com for help with custom design projects. |
joeata2wh | 3:b4592b0ae1e3 | 8 | |
joeata2wh | 3:b4592b0ae1e3 | 9 | |
joeata2wh | 3:b4592b0ae1e3 | 10 | Based on voltage drop across a diode calculate |
joeata2wh | 3:b4592b0ae1e3 | 11 | current flowing based on known characteristics of that diode. |
joeata2wh | 3:b4592b0ae1e3 | 12 | Unlike a resistor this can not be done with straigt ohms law |
joeata2wh | 3:b4592b0ae1e3 | 13 | because it is temperature specific and is not linear. Instead we |
joeata2wh | 3:b4592b0ae1e3 | 14 | use a lookup table and aproximate between elements to compute |
joeata2wh | 3:b4592b0ae1e3 | 15 | a value. |
joeata2wh | 3:b4592b0ae1e3 | 16 | |
joeata2wh | 3:b4592b0ae1e3 | 17 | A known limitation is that if voltage drop is equal or lower |
joeata2wh | 3:b4592b0ae1e3 | 18 | than smallest value in vDropArr Then all we know is that current is some place |
joeata2wh | 3:b4592b0ae1e3 | 19 | betweeen 0 and that minimum current number. Since all diodes have a minimum drop |
joeata2wh | 3:b4592b0ae1e3 | 20 | for any current flow they are not as effective when measuring very small currents. |
joeata2wh | 3:b4592b0ae1e3 | 21 | The diodes are best used when we do not want to add the |
joeata2wh | 3:b4592b0ae1e3 | 22 | loss of a resistor and we needed the diode in circuit anyway especially when |
joeata2wh | 3:b4592b0ae1e3 | 23 | there may be large current flow such as in a charging circuit. |
joeata2wh | 3:b4592b0ae1e3 | 24 | |
joeata2wh | 3:b4592b0ae1e3 | 25 | If you need a temperature specific value then declare a vDrop for multiple temperature ranges |
joeata2wh | 3:b4592b0ae1e3 | 26 | then compute the voltage drop for the temperature range above and below current temp and |
joeata2wh | 3:b4592b0ae1e3 | 27 | use ratio level computation to compute a weighted average between the two. |
joeata2wh | 3:b4592b0ae1e3 | 28 | |
joeata2wh | 3:b4592b0ae1e3 | 29 | Note: This would be a perfect place to use a differential ADC where |
joeata2wh | 3:b4592b0ae1e3 | 30 | the one line is on the postive side of the Diode and the other is |
joeata2wh | 3:b4592b0ae1e3 | 31 | on the load side. Unfortunately mbed doesn't provide standard support |
joeata2wh | 3:b4592b0ae1e3 | 32 | for the differential. |
joeata2wh | 3:b4592b0ae1e3 | 33 | |
joeata2wh | 3:b4592b0ae1e3 | 34 | Note: Turn off the PWM for the charge circuit and turn the charge |
joeata2wh | 3:b4592b0ae1e3 | 35 | circuit all the way on before taking this reading or it mess up the ADC readings. |
joeata2wh | 3:b4592b0ae1e3 | 36 | |
joeata2wh | 3:b4592b0ae1e3 | 37 | */ |
joeata2wh | 3:b4592b0ae1e3 | 38 | |
joeata2wh | 3:b4592b0ae1e3 | 39 | //#include "ohms.h" |
joeata2wh | 3:b4592b0ae1e3 | 40 | |
joeata2wh | 3:b4592b0ae1e3 | 41 | #ifndef diode_current_flow_H |
joeata2wh | 3:b4592b0ae1e3 | 42 | #define diode_current_flow_H |
joeata2wh | 3:b4592b0ae1e3 | 43 | // T.I SM74611 Smart Bypass Diode |
joeata2wh | 3:b4592b0ae1e3 | 44 | 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}; |
joeata2wh | 3:b4592b0ae1e3 | 45 | 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}; |
joeata2wh | 3:b4592b0ae1e3 | 46 | // must be oriented as lowest current flow (lowest vdrop) to highest, must be terminated with -1 and arrays |
joeata2wh | 3:b4592b0ae1e3 | 47 | // must line up by postion. The more numbers supplied the more accurate the computation will be down to the |
joeata2wh | 3:b4592b0ae1e3 | 48 | // limit of the ADC. |
joeata2wh | 3:b4592b0ae1e3 | 49 | |
joeata2wh | 3:b4592b0ae1e3 | 50 | // NOTE: DEFINE your own diode perfornce characteristics from the Diode datasheet. They vary a lot and |
joeata2wh | 3:b4592b0ae1e3 | 51 | // the SM74611 is a very special diode with very low vdrop so these numbers will not work for other diodes. |
joeata2wh | 3:b4592b0ae1e3 | 52 | |
joeata2wh | 3:b4592b0ae1e3 | 53 | |
joeata2wh | 3:b4592b0ae1e3 | 54 | |
joeata2wh | 3:b4592b0ae1e3 | 55 | /* compute the current flowing across the diode based on the known diode |
joeata2wh | 3:b4592b0ae1e3 | 56 | characteristics and a known voltage drop across the diode The two arrays |
joeata2wh | 3:b4592b0ae1e3 | 57 | must both contain floats, must be the same length and must be terminated with -1.0 |
joeata2wh | 3:b4592b0ae1e3 | 58 | sentinal. |
joeata2wh | 3:b4592b0ae1e3 | 59 | |
joeata2wh | 3:b4592b0ae1e3 | 60 | */ |
joeata2wh | 3:b4592b0ae1e3 | 61 | float ComputeDiodeCurrent(float *vDropArr, float *currentArr, float vDrop) { |
joeata2wh | 3:b4592b0ae1e3 | 62 | int lastNdx = 0; |
joeata2wh | 3:b4592b0ae1e3 | 63 | while (vDropArr[lastNdx] != -1.0) lastNdx++; |
joeata2wh | 3:b4592b0ae1e3 | 64 | lastNdx--; |
joeata2wh | 3:b4592b0ae1e3 | 65 | |
joeata2wh | 3:b4592b0ae1e3 | 66 | // find first vdrop in array that is less than our specified |
joeata2wh | 3:b4592b0ae1e3 | 67 | // vdrop which gives us a range where our vDrop must be so we |
joeata2wh | 3:b4592b0ae1e3 | 68 | // than then interpolate a current across the diode. |
joeata2wh | 3:b4592b0ae1e3 | 69 | if (vDrop >= vDropArr[lastNdx]) return currentArr[lastNdx]; // above our greatest setting |
joeata2wh | 3:b4592b0ae1e3 | 70 | |
joeata2wh | 3:b4592b0ae1e3 | 71 | int ndx = lastNdx; |
joeata2wh | 3:b4592b0ae1e3 | 72 | while ((vDrop < vDropArr[ndx]) && (ndx > 0)) |
joeata2wh | 3:b4592b0ae1e3 | 73 | ndx--; |
joeata2wh | 3:b4592b0ae1e3 | 74 | |
joeata2wh | 3:b4592b0ae1e3 | 75 | if (ndx == 0) return currentArr[0]; // below our lowest setting |
joeata2wh | 3:b4592b0ae1e3 | 76 | if (vDropArr[ndx] == vDrop) return currentArr[ndx]; // exact match |
joeata2wh | 3:b4592b0ae1e3 | 77 | |
joeata2wh | 3:b4592b0ae1e3 | 78 | // Interpolate the ratio we are between the two points found |
joeata2wh | 3:b4592b0ae1e3 | 79 | // and use that to determine our actual current flow. This only |
joeata2wh | 3:b4592b0ae1e3 | 80 | // works assuming it is a relatively straight line between the two |
joeata2wh | 3:b4592b0ae1e3 | 81 | // points. If that is not true then you need to add more points. |
joeata2wh | 3:b4592b0ae1e3 | 82 | float vrange = vDropArr[ndx + 1] - vDropArr[ndx]; |
joeata2wh | 3:b4592b0ae1e3 | 83 | float amtOverLower = vDrop - vDropArr[ndx]; |
joeata2wh | 3:b4592b0ae1e3 | 84 | float portRange = amtOverLower / vrange; |
joeata2wh | 3:b4592b0ae1e3 | 85 | float currRange = currentArr[ndx + 1] - currentArr[ndx]; |
joeata2wh | 3:b4592b0ae1e3 | 86 | float lowCurr = currentArr[ndx]; |
joeata2wh | 3:b4592b0ae1e3 | 87 | float portCurAdd = currRange * portRange; |
joeata2wh | 3:b4592b0ae1e3 | 88 | return lowCurr + portCurAdd; |
joeata2wh | 3:b4592b0ae1e3 | 89 | } |
joeata2wh | 3:b4592b0ae1e3 | 90 | #endif |