#include #include #include #include #include #include "buffer.h" void modbusGet(void); volatile buffer_t adc_buf[4]; volatile float adc_avrg[4]; volatile float output; volatile struct pid controller; volatile float setpoint_1 = 180 * 102 / 34; volatile float setpoint_2 = 150 * 102 / 34; volatile float setpoint_3 = 150 * 102 / 34; struct pid { // Controller gains float kP; float kI; float kD; // State variables float lastError; float integral; }; float pid_step(volatile struct pid* controller, float dt, float error) { // Calculate p term float p = error * controller->kP; // Calculate i term ATOMIC_BLOCK(ATOMIC_FORCEON){ controller->integral += error * dt * controller->kI; if(controller->integral > 80) controller->integral = 80; if(controller->integral < -80) controller->integral = -80; } // Calculate d term, taking care to not divide by zero float d = dt == 0 ? 0 : ((error - controller->lastError) / dt) * controller->kD; controller->lastError = error; return p + controller->integral + d; } void initADC(void) { ADMUX = 1 << REFS0 | 0 << REFS1; //Select external Vref //ADC Status Register A ADCSRA = 1 << ADEN //Enable ADC | 1 << ADIE //Enable ISR after conversion complete //| 1< 128) output = 128; if(output >= 1){ uint32_t tmp = output * 512; if(tmp >= 0x10000) tmp = 0xFFFE; OCR1A = tmp; PORTB |= 0x0E; } else OCR1A = 1000; //if(adc_avrg[0] < 99 && !(PORTB & 0x01)) // PORTB |= 1 << 0; //if(adc_avrg[0] > 99 && (PORTB & 0x01)) // PORTB &= ~(1 << 0); } ISR(TIMER1_COMPA_vect) { PORTB &= ~(0x0E); } ISR(ADC_vect) { static uint8_t init[4] = {0,0,0,0}; static uint8_t current_channel = 0; //Reading 10bit conversion result uint16_t ADC_reading = ADCL; //copy the first LSB bits ADC_reading |= ADCH << 8; //copy remaing byte ADC_reading *= 10; insert_to_buffer(ADC_reading, &adc_buf[current_channel]); if(adc_buf[current_channel].position == BUFFER_SIZE-1){ if(init[current_channel]){ float tmp = 99*adc_avrg[current_channel]; tmp += get_buffer_mean(&adc_buf[current_channel])/30; adc_avrg[current_channel] = tmp/100; } else{ adc_avrg[current_channel] = get_buffer_mean(&adc_buf[current_channel])/30; init[current_channel]=0; } } current_channel++; if(current_channel == 4) current_channel = 0; set_ADC_Channel(current_channel); ADCSRA |= (1 << ADSC); //Start next conversion }