Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed BufferedSerial Servo2 PCT2075 I2CEeprom FastPWM
field.cpp@3:43cb067ecd00, 2020-07-27 (annotated)
- 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?
| User | Revision | Line number | New 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 |