Jon Freeman / Mbed 2 deprecated Alternator2020_06

Dependencies:   mbed BufferedSerial Servo2 PCT2075 I2CEeprom FastPWM

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers field.cpp Source File

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