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
00001 #include "mbed.h" 00002 #include "rpm.h" 00003 #include "field.h" 00004 #include "Alternator.h" 00005 #include "BufferedSerial.h" 00006 extern BufferedSerial pc; 00007 00008 extern ee_settings_2020 user_settings; 00009 extern Timer microsecs; // 64 bit counter, rolls over in half million years 00010 00011 FieldControl::FieldControl (PinName pwmoscin, PinName vext) : pwm_osc_in (pwmoscin), V_ext (vext) { 00012 pwm_osc_in.period_us (PWM_PERIOD_US); // about 313Hz * 2 00013 pwm_osc_in.pulsewidth_us (PWM_PERIOD_US - 2); 00014 V_ext.rise (callback(this, &FieldControl::VextRise)); // Attach handler to the rising interruptIn edge 00015 V_ext.fall (callback(this, &FieldControl::VextFall)); // Attach handler to the falling interruptIn edge 00016 t_on = t_off = measured_pw_us = measured_period = rise_count = fall_count = 0L; 00017 // maketable () ; 00018 set_for_speed (0); 00019 old_percent = 1000; // i.e. out of percentage range to force exec on first pass 00020 } 00021 00022 void FieldControl::VextRise () // InterruptIn interrupt service 00023 { // Here is possible to read back how regulator has controlled pwm - may or may not be useful 00024 uint64_t tmp = microsecs.read_high_resolution_us(); 00025 measured_period = tmp - t_on; 00026 t_on = tmp; 00027 rise_count++; 00028 } 00029 00030 void FieldControl::VextFall () // InterruptIn interrupt service 00031 { 00032 fall_count++; 00033 t_off = microsecs.read_high_resolution_us(); 00034 measured_pw_us = t_off - t_on; 00035 } 00036 00037 double FieldControl::get_duty_ratio () { 00038 if (measured_period == 0) { 00039 if (V_ext == 1) 00040 return 2.0; // Impossible value indicates error 00041 return -1.0; // Impossible value indicates error 00042 } 00043 return (double) measured_pw_us / (double) measured_period; 00044 } ; 00045 00046 00047 void FieldControl::maketable () { // Uses first 17 nums of user_settings relating to lim to be applied at 0, 500, 1000 --- 8000 RPM 00048 // Makes table of 400 entries to 8000 RPM regardless of engine type data. 20 RPM per fine step 00049 // 21 User input table entries 200 RPM apart for MAX_RPM_LIMIT up to 4000, 400 RPM for up to 8000 00050 double tabvals[28]; 00051 double diff, val = 0.0; 00052 uint32_t tabptr = 0, user_entry_rpm_step, divor; 00053 user_entry_rpm_step = MAX_RPM_LIMIT > 4000 ? 400 : 200; 00054 divor = MAX_RPM_LIMIT > 4000 ? 20 : 20; 00055 for (int i = 0; i < 21; i++) { 00056 tabvals[i] = (double)user_settings.rd (i); 00057 pc.printf ("%d\t%.0f\r\n", i * user_entry_rpm_step, tabvals[i]); 00058 } 00059 for (int i = 1; i < 21; i++) { 00060 diff = tabvals[i] - tabvals[i - 1]; // Either 200 or 400 RPM apart, either 10 or 20 small steps to fill 00061 diff /= divor; // 50 entries 20RPM apart per kRPM 00062 for (int j = 0; j < divor; j++) { 00063 privatemadetab[tabptr++] = (uint8_t) val; 00064 val += diff; 00065 } 00066 } 00067 pc.printf ("Final tab entry posn %d, calculated = %d percent, divor = %d\r\n", tabptr, (uint8_t) val, divor); 00068 while (tabptr < sizeof(privatemadetab)) 00069 privatemadetab[tabptr++] = (uint8_t) val; 00070 } 00071 00072 uint32_t FieldControl::set_for_speed (uint32_t rpm) { // May 2020 00073 uint32_t index, pcent; 00074 double pwm = 0.0; 00075 if (rpm > MAX_RPM_LIMIT) 00076 rpm = MAX_RPM_LIMIT; 00077 // index = rpm / 25; // to fit lut spacing of 25rpm intervals, turns rpm into index 00078 index = rpm / 10; // to fit lut spacing of 10rpm intervals, turns rpm into index 00079 pcent = privatemadetab[index]; 00080 if (pcent != old_percent) { 00081 old_percent = pcent; 00082 pwm = (double)pcent; 00083 pwm /= 100.0; 00084 set_pwm (pwm); 00085 } 00086 return old_percent; 00087 } 00088 00089 extern double Read_Field_Volts () ; 00090 00091 void FieldControl::set_pwm (double d) { 00092 double t = Read_Field_Volts () ; 00093 if (t > ALTERNATOR_DESIGN_VOLTAGE) 00094 t = ALTERNATOR_DESIGN_VOLTAGE / t; 00095 else 00096 t = 1.0; 00097 uint32_t i; 00098 if (d < 0.0) 00099 d = 0.0; 00100 if (d > 1.0) 00101 d = 1.0; 00102 i = (uint32_t)(d * t * (double)PWM_PERIOD_US); // pwm_factor 0.5 when using 12v alternator in 24v system 00103 pwm_osc_in.pulsewidth_us (PWM_PERIOD_US - i); // Note PWM is inverted as MCP1630 uses inverted OSC_IN signal 00104 } 00105
Generated on Fri Jul 22 2022 15:22:19 by
1.7.2