Drain batteries through an LM324 controlled CEB6030L from a defunct graphics card

Dependencies:   mbed FastAnalogIn PID mbed-rtos

Committer:
eisd
Date:
Sat May 16 11:16:47 2020 +0000
Revision:
7:3061a3da1c97
Parent:
5:7112e564d33a
Extra logging

Who changed what in which revision?

UserRevisionLine numberNew contents of line
eisd 0:e7492a4f4b2f 1 #include "mbed.h"
eisd 0:e7492a4f4b2f 2 #include "rtos.h"
eisd 0:e7492a4f4b2f 3 #include "FastAnalogIn.h"
eisd 2:e7ce63ada1d2 4 #include "PID.h"
eisd 2:e7ce63ada1d2 5
eisd 2:e7ce63ada1d2 6 PID I(10.0, 0.01, 0.0, 0.01);
eisd 0:e7492a4f4b2f 7
eisd 0:e7492a4f4b2f 8 AnalogOut Iset(PTE30);
eisd 0:e7492a4f4b2f 9 FastAnalogIn Iget(PTE20);
eisd 0:e7492a4f4b2f 10 AnalogIn Vbat(PTB0);
eisd 2:e7ce63ada1d2 11 bool active = true;
eisd 3:08488e544b3e 12
eisd 3:08488e544b3e 13 class Lag {
eisd 3:08488e544b3e 14 float k, v;
eisd 3:08488e544b3e 15 public:
eisd 3:08488e544b3e 16 Lag(float seed, float factor = 0.005) { v = seed; k = factor; }
eisd 3:08488e544b3e 17 float operator()(float in) { return v = k * in + (1 - k) * v; }
eisd 3:08488e544b3e 18 operator float() { return v; }
eisd 3:08488e544b3e 19 };
eisd 5:7112e564d33a 20 inline float Iin(float x) { return x < 0.0008? 0 : x * 33.07273 + 0.016; }
eisd 3:08488e544b3e 21 inline float Vin(float x) { return x * 34.08516 + 0.06567447; }
eisd 3:08488e544b3e 22
eisd 3:08488e544b3e 23 Lag iget(Iin(Iget.read())), vbat(Vin(Vbat.read())), vbat_rest(Vin(Vbat.read()));
eisd 0:e7492a4f4b2f 24 void filter() {
eisd 2:e7ce63ada1d2 25 if (active) {
eisd 3:08488e544b3e 26 iget(Iin(Iget.read()));
eisd 3:08488e544b3e 27 vbat(Vin(Vbat.read()));
eisd 2:e7ce63ada1d2 28 }
eisd 0:e7492a4f4b2f 29 if (Iset.read() == 0)
eisd 3:08488e544b3e 30 vbat_rest(Vin(Vbat.read()));
eisd 0:e7492a4f4b2f 31 }
eisd 1:712b9b5470d4 32 void rest(const void *) {
eisd 1:712b9b5470d4 33 while (true) {
eisd 1:712b9b5470d4 34 Thread::wait(5000);
eisd 2:e7ce63ada1d2 35 if (Iset.read() > 0) {
eisd 2:e7ce63ada1d2 36 active = false;
eisd 2:e7ce63ada1d2 37 Iset.write_u16(16);
eisd 2:e7ce63ada1d2 38 Thread::wait(400);
eisd 2:e7ce63ada1d2 39 Iset.write_u16(0);
eisd 2:e7ce63ada1d2 40 Thread::wait(100);
eisd 2:e7ce63ada1d2 41 active = true;
eisd 2:e7ce63ada1d2 42 }
eisd 2:e7ce63ada1d2 43 }
eisd 2:e7ce63ada1d2 44 }
eisd 2:e7ce63ada1d2 45 int flop = 0;
eisd 2:e7ce63ada1d2 46 void adjust() {
eisd 2:e7ce63ada1d2 47 //flop = (flop + 1) % 4;
eisd 2:e7ce63ada1d2 48 //Iset.write(flop == 0? 0.2/4.61 : 0);
eisd 2:e7ce63ada1d2 49 if (active) {
eisd 2:e7ce63ada1d2 50 I.setProcessValue(iget);
eisd 2:e7ce63ada1d2 51 Iset = I.compute();
eisd 1:712b9b5470d4 52 }
eisd 1:712b9b5470d4 53 }
eisd 2:e7ce63ada1d2 54
eisd 2:e7ce63ada1d2 55 Serial pc(USBTX, USBRX);
eisd 2:e7ce63ada1d2 56 void ui(const void*) {
eisd 2:e7ce63ada1d2 57 while (true) {
eisd 2:e7ce63ada1d2 58 Thread::wait(100);
eisd 2:e7ce63ada1d2 59 while (pc.readable()) {
eisd 7:3061a3da1c97 60 int d = pc.getc();
eisd 7:3061a3da1c97 61 pc.printf("Increasing current: %d\r\n", d);
eisd 2:e7ce63ada1d2 62 I = I + 0.1;
eisd 2:e7ce63ada1d2 63 }
eisd 2:e7ce63ada1d2 64 }
eisd 2:e7ce63ada1d2 65 }
eisd 2:e7ce63ada1d2 66
eisd 4:fb20b0b3f57d 67 bool header = false;
eisd 4:fb20b0b3f57d 68 Timer T;
eisd 4:fb20b0b3f57d 69 float charge = 0;
eisd 4:fb20b0b3f57d 70 void discharge(const void*) {
eisd 4:fb20b0b3f57d 71 Thread::wait(3000);
eisd 4:fb20b0b3f57d 72 I = 2;
eisd 4:fb20b0b3f57d 73 T.start();
eisd 4:fb20b0b3f57d 74 header = true;
eisd 4:fb20b0b3f57d 75 int lastT = 0;
eisd 4:fb20b0b3f57d 76 while(vbat_rest > 0.9 && (lastT < 5000000 || iget > I/2)) {
eisd 4:fb20b0b3f57d 77 int t = T.read_us();
eisd 4:fb20b0b3f57d 78 charge += iget * (t - lastT)/3600000.0;
eisd 4:fb20b0b3f57d 79 lastT = t;
eisd 4:fb20b0b3f57d 80 Thread::wait(30);
eisd 4:fb20b0b3f57d 81 }
eisd 4:fb20b0b3f57d 82 I = 0;
eisd 4:fb20b0b3f57d 83 PwmOut led(LED1);
eisd 4:fb20b0b3f57d 84 led.period_ms(2000);
eisd 4:fb20b0b3f57d 85 led = 0.2;
eisd 4:fb20b0b3f57d 86 }
eisd 4:fb20b0b3f57d 87
eisd 0:e7492a4f4b2f 88 int main()
eisd 0:e7492a4f4b2f 89 {
eisd 2:e7ce63ada1d2 90 pc.baud(115200);
eisd 2:e7ce63ada1d2 91
eisd 2:e7ce63ada1d2 92 I.setInputLimits(0, 100);
eisd 2:e7ce63ada1d2 93 I.setOutputLimits(0, 1);
eisd 2:e7ce63ada1d2 94 I = 0;
eisd 2:e7ce63ada1d2 95 I.setMode(AUTO_MODE);
eisd 2:e7ce63ada1d2 96
eisd 0:e7492a4f4b2f 97 Ticker t2;
eisd 0:e7492a4f4b2f 98 t2.attach_us(&filter, 1000);
eisd 2:e7ce63ada1d2 99 Ticker t;
eisd 2:e7ce63ada1d2 100 t.attach(&adjust, I.getInterval());
eisd 1:712b9b5470d4 101 Thread t3(&rest);
eisd 2:e7ce63ada1d2 102 Thread t4(&ui);
eisd 0:e7492a4f4b2f 103
eisd 4:fb20b0b3f57d 104 Thread t5(&discharge);
eisd 4:fb20b0b3f57d 105
eisd 0:e7492a4f4b2f 106 while (true) {
eisd 4:fb20b0b3f57d 107 if (header) {
eisd 4:fb20b0b3f57d 108 header = false;
eisd 4:fb20b0b3f57d 109 pc.printf("Discharging\r\n");
eisd 5:7112e564d33a 110 pc.printf("Duration (s)\tVbat (V)\tVbat_rest (V)\tTarget (I)\tDischarge (I)\tCapacity (mAh)\r\n");
eisd 4:fb20b0b3f57d 111 }
eisd 0:e7492a4f4b2f 112 //pc.printf("Iset %f Iget %6d %f Vbat %6d %f \r", Iset.read(), Iget.read_u16(), Iget.read(), Vbat.read_u16(), Vbat.read());
eisd 4:fb20b0b3f57d 113 //pc.printf("Iset %f Iget %8d %f %f", Iset.read(), Iget.read_u16(), Iin(Iget.read()), (float)iget);
eisd 4:fb20b0b3f57d 114 //pc.printf(" Vbat %8d %f %f %f charge %f\r", Vbat.read_u16(), Vin(Vbat.read()), (float)vbat, (float)vbat_rest, charge);
eisd 4:fb20b0b3f57d 115 if (active)
eisd 7:3061a3da1c97 116 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);
eisd 4:fb20b0b3f57d 117 Thread::wait(1000);
eisd 0:e7492a4f4b2f 118 }
eisd 0:e7492a4f4b2f 119 }