/* * * Half bridge mode SW bulk/boost controller control routine * */ #define PWM_OUT_PIN_H 10 // PIN16 - OC1B #define PWM_OUT_PIN_L 9 // PIN15 - OC1A #define LED_PIN 11 // PIN17 // Setup Timer 0 for PWM mode, two channels void setup_tmr1_pwm(void) { // Enable the port, set for PWM/dual slope mode TCCR1A = (1 << COM1A1) | (0 << COM1A0) | (1 << COM1B1) | (0 << COM1B0) | (1 << WGM10) | (0 << WGM11) ; TCCR1B = (0 << WGM12) | (0 << WGM13) | // Use fix 0xff for top (0 << CS11) | (1 << CS10); // clkIO = /1 // Phase correct, 0xff for top } void set_tmr1_pwm_off(void) { digitalWrite(PWM_OUT_PIN_H, 0); digitalWrite(PWM_OUT_PIN_L, 1); // Disable both port TCCR1A = (0 << COM1A1) | (0 << COM1A0) | (0 << COM1B1) | (0 << COM1B0) | (1 << WGM10) | (0 << WGM11) ; } void inline set_tmr1_pwm(uint8_t ch0, uint8_t ch1) { OCR1AL = ch0; // LOW OCR1BL = ch1; // HIGH } bool bPWMoff = 0; int pwmValue = 0; int Integrate = 0; int in_Integrate = 0; int amp_Integrate = 0; int g_outVValue; int g_outIValue; int g_inVValue; int g_setPoint = 1; float debugf; // the setup routine runs once when you press reset: void setup() { // Not activate MOSFET yet pinMode(PWM_OUT_PIN_L, OUTPUT); digitalWrite(PWM_OUT_PIN_L, 1); pinMode(PWM_OUT_PIN_H, OUTPUT); digitalWrite(PWM_OUT_PIN_H, 0); // initialize serial communication at 9600 bits per second: Serial.begin(115200); bPWMoff = 1; pinMode(LED_PIN, OUTPUT); // Use TIMER0 compare output to drive the mS interrupt OCR0A = 0xAF; TIMSK0 |= _BV(OCIE0A); } // 1mS loop, do not use delay... SIGNAL(TIMER0_COMPA_vect) { digitalWrite(LED_PIN, HIGH); g_inVValue = analogRead(A0); g_outVValue = analogRead(A1); g_outIValue = analogRead(A2); // Analog reading (0 - 1023), resistor divider ratio of 4.3x float voltage = g_outVValue * (4.3 * 5.0 / 1023.0); float in_vol = g_inVValue * (4.3 * 5.0 / 1023.0); float amp = 2.5 - g_outIValue * (5.0 / 1023.0); // Compute difference, hard code the set point // Low voltage is 5.0V // High voltage is 20.0V float diff = 14.0 - voltage; // Low side battery set point //float in_diff = in_vol - 20.0; // High side battery max limit float amp_diff = ((float)g_setPoint * 0.1) - amp; // Current limit debugf = amp; // Integrator, integrate both input and output voltage separately Integrate += diff * 16 * 1; //in_Integrate += in_diff * 16 * 16; amp_Integrate += amp_diff * 16; // Saturation limit of the integrator, at least 255*16 if (Integrate > 4096) Integrate = 4096; if (Integrate < -4096) Integrate = -4096; //if (in_Integrate > 4096) in_Integrate = 4096; //if (in_Integrate < -4096) in_Integrate = -4096; if (amp_Integrate > 4096) amp_Integrate = 4096; if (amp_Integrate < -4096) amp_Integrate = -4096; // Bulk converter - // Start with pwm value set to feedback integrate value pwmValue = Integrate; if (Integrate > amp_Integrate) pwmValue = amp_Integrate; pwmValue /= 16; // Set minimal input voltage to 12V // Minimal input voltage before turn on if (in_vol < 12.0) { Integrate = -4096; // Soft start set_tmr1_pwm_off(); bPWMoff = 1; } else { if (bPWMoff) { bPWMoff = 0; setup_tmr1_pwm(); } } // PWM value limitation if (pwmValue > 255) pwmValue = 255; if (pwmValue < 0) pwmValue = 0; // Boost mode, never go down to 0 set_tmr1_pwm((pwmValue + 5) > 255 ? 255 : (pwmValue + 5), pwmValue); digitalWrite(LED_PIN, LOW); } // the loop routine runs over and over again forever: void loop() { // input on analog pin 0: Supply Voltage // input on analog pin 1: Feedback line voltage // input on analog pin 2: Current sensor voltage if (Serial.available() > 0) { int inch = Serial.read(); //if (inch == 'u') pwmValue++; //if (inch == 'd') pwmValue--; //if (pwmValue < 0) pwmValue = 0; //if (pwmValue > 255) pwmValue = 255; if (inch == 'o') g_setPoint++; if (inch == 'l') g_setPoint--; } Serial.println(pwmValue); //Serial.println(Integrate/16); //Serial.println(in_Integrate/16); //Serial.println(amp_Integrate/16); //Serial.println(debugf); Serial.println(g_setPoint); delay(1000); }