Jon Freeman / Mbed 2 deprecated Alternator2020_06

Dependencies:   mbed BufferedSerial Servo2 PCT2075 I2CEeprom FastPWM

Committer:
JonFreeman
Date:
Mon Jul 27 08:44:59 2020 +0000
Revision:
3:43cb067ecd00
End of July after good day out at Ashton Court

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JonFreeman 3:43cb067ecd00 1 #include "mbed.h"
JonFreeman 3:43cb067ecd00 2 #include "rpm.h"
JonFreeman 3:43cb067ecd00 3 #include "field.h"
JonFreeman 3:43cb067ecd00 4 #include "Alternator.h"
JonFreeman 3:43cb067ecd00 5 #include "BufferedSerial.h"
JonFreeman 3:43cb067ecd00 6 extern BufferedSerial pc;
JonFreeman 3:43cb067ecd00 7
JonFreeman 3:43cb067ecd00 8 extern ee_settings_2020 user_settings;
JonFreeman 3:43cb067ecd00 9 extern Timer microsecs; // 64 bit counter, rolls over in half million years
JonFreeman 3:43cb067ecd00 10
JonFreeman 3:43cb067ecd00 11 FieldControl::FieldControl (PinName pwmoscin, PinName vext) : pwm_osc_in (pwmoscin), V_ext (vext) {
JonFreeman 3:43cb067ecd00 12 pwm_osc_in.period_us (PWM_PERIOD_US); // about 313Hz * 2
JonFreeman 3:43cb067ecd00 13 pwm_osc_in.pulsewidth_us (PWM_PERIOD_US - 2);
JonFreeman 3:43cb067ecd00 14 V_ext.rise (callback(this, &FieldControl::VextRise)); // Attach handler to the rising interruptIn edge
JonFreeman 3:43cb067ecd00 15 V_ext.fall (callback(this, &FieldControl::VextFall)); // Attach handler to the falling interruptIn edge
JonFreeman 3:43cb067ecd00 16 t_on = t_off = measured_pw_us = measured_period = rise_count = fall_count = 0L;
JonFreeman 3:43cb067ecd00 17 // maketable () ;
JonFreeman 3:43cb067ecd00 18 set_for_speed (0);
JonFreeman 3:43cb067ecd00 19 old_percent = 1000; // i.e. out of percentage range to force exec on first pass
JonFreeman 3:43cb067ecd00 20 }
JonFreeman 3:43cb067ecd00 21
JonFreeman 3:43cb067ecd00 22 void FieldControl::VextRise () // InterruptIn interrupt service
JonFreeman 3:43cb067ecd00 23 { // Here is possible to read back how regulator has controlled pwm - may or may not be useful
JonFreeman 3:43cb067ecd00 24 uint64_t tmp = microsecs.read_high_resolution_us();
JonFreeman 3:43cb067ecd00 25 measured_period = tmp - t_on;
JonFreeman 3:43cb067ecd00 26 t_on = tmp;
JonFreeman 3:43cb067ecd00 27 rise_count++;
JonFreeman 3:43cb067ecd00 28 }
JonFreeman 3:43cb067ecd00 29
JonFreeman 3:43cb067ecd00 30 void FieldControl::VextFall () // InterruptIn interrupt service
JonFreeman 3:43cb067ecd00 31 {
JonFreeman 3:43cb067ecd00 32 fall_count++;
JonFreeman 3:43cb067ecd00 33 t_off = microsecs.read_high_resolution_us();
JonFreeman 3:43cb067ecd00 34 measured_pw_us = t_off - t_on;
JonFreeman 3:43cb067ecd00 35 }
JonFreeman 3:43cb067ecd00 36
JonFreeman 3:43cb067ecd00 37 double FieldControl::get_duty_ratio () {
JonFreeman 3:43cb067ecd00 38 if (measured_period == 0) {
JonFreeman 3:43cb067ecd00 39 if (V_ext == 1)
JonFreeman 3:43cb067ecd00 40 return 2.0; // Impossible value indicates error
JonFreeman 3:43cb067ecd00 41 return -1.0; // Impossible value indicates error
JonFreeman 3:43cb067ecd00 42 }
JonFreeman 3:43cb067ecd00 43 return (double) measured_pw_us / (double) measured_period;
JonFreeman 3:43cb067ecd00 44 } ;
JonFreeman 3:43cb067ecd00 45
JonFreeman 3:43cb067ecd00 46
JonFreeman 3:43cb067ecd00 47 void FieldControl::maketable () { // Uses first 17 nums of user_settings relating to lim to be applied at 0, 500, 1000 --- 8000 RPM
JonFreeman 3:43cb067ecd00 48 // Makes table of 400 entries to 8000 RPM regardless of engine type data. 20 RPM per fine step
JonFreeman 3:43cb067ecd00 49 // 21 User input table entries 200 RPM apart for MAX_RPM_LIMIT up to 4000, 400 RPM for up to 8000
JonFreeman 3:43cb067ecd00 50 double tabvals[28];
JonFreeman 3:43cb067ecd00 51 double diff, val = 0.0;
JonFreeman 3:43cb067ecd00 52 uint32_t tabptr = 0, user_entry_rpm_step, divor;
JonFreeman 3:43cb067ecd00 53 user_entry_rpm_step = MAX_RPM_LIMIT > 4000 ? 400 : 200;
JonFreeman 3:43cb067ecd00 54 divor = MAX_RPM_LIMIT > 4000 ? 20 : 20;
JonFreeman 3:43cb067ecd00 55 for (int i = 0; i < 21; i++) {
JonFreeman 3:43cb067ecd00 56 tabvals[i] = (double)user_settings.rd (i);
JonFreeman 3:43cb067ecd00 57 pc.printf ("%d\t%.0f\r\n", i * user_entry_rpm_step, tabvals[i]);
JonFreeman 3:43cb067ecd00 58 }
JonFreeman 3:43cb067ecd00 59 for (int i = 1; i < 21; i++) {
JonFreeman 3:43cb067ecd00 60 diff = tabvals[i] - tabvals[i - 1]; // Either 200 or 400 RPM apart, either 10 or 20 small steps to fill
JonFreeman 3:43cb067ecd00 61 diff /= divor; // 50 entries 20RPM apart per kRPM
JonFreeman 3:43cb067ecd00 62 for (int j = 0; j < divor; j++) {
JonFreeman 3:43cb067ecd00 63 privatemadetab[tabptr++] = (uint8_t) val;
JonFreeman 3:43cb067ecd00 64 val += diff;
JonFreeman 3:43cb067ecd00 65 }
JonFreeman 3:43cb067ecd00 66 }
JonFreeman 3:43cb067ecd00 67 pc.printf ("Final tab entry posn %d, calculated = %d percent, divor = %d\r\n", tabptr, (uint8_t) val, divor);
JonFreeman 3:43cb067ecd00 68 while (tabptr < sizeof(privatemadetab))
JonFreeman 3:43cb067ecd00 69 privatemadetab[tabptr++] = (uint8_t) val;
JonFreeman 3:43cb067ecd00 70 }
JonFreeman 3:43cb067ecd00 71
JonFreeman 3:43cb067ecd00 72 uint32_t FieldControl::set_for_speed (uint32_t rpm) { // May 2020
JonFreeman 3:43cb067ecd00 73 uint32_t index, pcent;
JonFreeman 3:43cb067ecd00 74 double pwm = 0.0;
JonFreeman 3:43cb067ecd00 75 if (rpm > MAX_RPM_LIMIT)
JonFreeman 3:43cb067ecd00 76 rpm = MAX_RPM_LIMIT;
JonFreeman 3:43cb067ecd00 77 // index = rpm / 25; // to fit lut spacing of 25rpm intervals, turns rpm into index
JonFreeman 3:43cb067ecd00 78 index = rpm / 10; // to fit lut spacing of 10rpm intervals, turns rpm into index
JonFreeman 3:43cb067ecd00 79 pcent = privatemadetab[index];
JonFreeman 3:43cb067ecd00 80 if (pcent != old_percent) {
JonFreeman 3:43cb067ecd00 81 old_percent = pcent;
JonFreeman 3:43cb067ecd00 82 pwm = (double)pcent;
JonFreeman 3:43cb067ecd00 83 pwm /= 100.0;
JonFreeman 3:43cb067ecd00 84 set_pwm (pwm);
JonFreeman 3:43cb067ecd00 85 }
JonFreeman 3:43cb067ecd00 86 return old_percent;
JonFreeman 3:43cb067ecd00 87 }
JonFreeman 3:43cb067ecd00 88
JonFreeman 3:43cb067ecd00 89 extern double Read_Field_Volts () ;
JonFreeman 3:43cb067ecd00 90
JonFreeman 3:43cb067ecd00 91 void FieldControl::set_pwm (double d) {
JonFreeman 3:43cb067ecd00 92 double t = Read_Field_Volts () ;
JonFreeman 3:43cb067ecd00 93 if (t > ALTERNATOR_DESIGN_VOLTAGE)
JonFreeman 3:43cb067ecd00 94 t = ALTERNATOR_DESIGN_VOLTAGE / t;
JonFreeman 3:43cb067ecd00 95 else
JonFreeman 3:43cb067ecd00 96 t = 1.0;
JonFreeman 3:43cb067ecd00 97 uint32_t i;
JonFreeman 3:43cb067ecd00 98 if (d < 0.0)
JonFreeman 3:43cb067ecd00 99 d = 0.0;
JonFreeman 3:43cb067ecd00 100 if (d > 1.0)
JonFreeman 3:43cb067ecd00 101 d = 1.0;
JonFreeman 3:43cb067ecd00 102 i = (uint32_t)(d * t * (double)PWM_PERIOD_US); // pwm_factor 0.5 when using 12v alternator in 24v system
JonFreeman 3:43cb067ecd00 103 pwm_osc_in.pulsewidth_us (PWM_PERIOD_US - i); // Note PWM is inverted as MCP1630 uses inverted OSC_IN signal
JonFreeman 3:43cb067ecd00 104 }
JonFreeman 3:43cb067ecd00 105