Drain batteries through an LM324 controlled CEB6030L from a defunct graphics card
Dependencies: mbed FastAnalogIn PID mbed-rtos
main.cpp
- Committer:
- eisd
- Date:
- 2020-05-16
- Revision:
- 7:3061a3da1c97
- Parent:
- 5:7112e564d33a
File content as of revision 7:3061a3da1c97:
#include "mbed.h" #include "rtos.h" #include "FastAnalogIn.h" #include "PID.h" PID I(10.0, 0.01, 0.0, 0.01); AnalogOut Iset(PTE30); FastAnalogIn Iget(PTE20); AnalogIn Vbat(PTB0); bool active = true; class Lag { float k, v; public: Lag(float seed, float factor = 0.005) { v = seed; k = factor; } float operator()(float in) { return v = k * in + (1 - k) * v; } operator float() { return v; } }; inline float Iin(float x) { return x < 0.0008? 0 : x * 33.07273 + 0.016; } inline float Vin(float x) { return x * 34.08516 + 0.06567447; } Lag iget(Iin(Iget.read())), vbat(Vin(Vbat.read())), vbat_rest(Vin(Vbat.read())); void filter() { if (active) { iget(Iin(Iget.read())); vbat(Vin(Vbat.read())); } if (Iset.read() == 0) vbat_rest(Vin(Vbat.read())); } void rest(const void *) { while (true) { Thread::wait(5000); if (Iset.read() > 0) { active = false; Iset.write_u16(16); Thread::wait(400); Iset.write_u16(0); Thread::wait(100); active = true; } } } int flop = 0; void adjust() { //flop = (flop + 1) % 4; //Iset.write(flop == 0? 0.2/4.61 : 0); if (active) { I.setProcessValue(iget); Iset = I.compute(); } } Serial pc(USBTX, USBRX); void ui(const void*) { while (true) { Thread::wait(100); while (pc.readable()) { int d = pc.getc(); pc.printf("Increasing current: %d\r\n", d); I = I + 0.1; } } } bool header = false; Timer T; float charge = 0; void discharge(const void*) { Thread::wait(3000); I = 2; T.start(); header = true; int lastT = 0; while(vbat_rest > 0.9 && (lastT < 5000000 || iget > I/2)) { int t = T.read_us(); charge += iget * (t - lastT)/3600000.0; lastT = t; Thread::wait(30); } I = 0; PwmOut led(LED1); led.period_ms(2000); led = 0.2; } int main() { pc.baud(115200); I.setInputLimits(0, 100); I.setOutputLimits(0, 1); I = 0; I.setMode(AUTO_MODE); Ticker t2; t2.attach_us(&filter, 1000); Ticker t; t.attach(&adjust, I.getInterval()); Thread t3(&rest); Thread t4(&ui); Thread t5(&discharge); while (true) { if (header) { header = false; pc.printf("Discharging\r\n"); pc.printf("Duration (s)\tVbat (V)\tVbat_rest (V)\tTarget (I)\tDischarge (I)\tCapacity (mAh)\r\n"); } //pc.printf("Iset %f Iget %6d %f Vbat %6d %f \r", Iset.read(), Iget.read_u16(), Iget.read(), Vbat.read_u16(), Vbat.read()); //pc.printf("Iset %f Iget %8d %f %f", Iset.read(), Iget.read_u16(), Iin(Iget.read()), (float)iget); //pc.printf(" Vbat %8d %f %f %f charge %f\r", Vbat.read_u16(), Vin(Vbat.read()), (float)vbat, (float)vbat_rest, charge); if (active) pc.printf("%-8.2f \t%f \t%f \t%f \t%f \t%f\r\n", (T.read_us()/10000)/100.0, (float)vbat, (float)vbat_rest, (float)Iset.read(), (float)iget, charge); Thread::wait(1000); } }