Помогите пожалуйста с решением задачи!!! Ардуино используется для ШИМ разгона (для начала диода) и одновременно надо им же измерять напряжение на диоде. Но возникают две проблемы: Как одновременно выполнять ШИМ разгон и измерять напряжение? Как сделать чтобы выводилось среднее значение напряжения на диоде(При измерении без ШИМ разгона показывает значения 0 и 4,05-4,08, а необходимо среднее значение как на обычном вольтметре)?
Код (Text): const byte PIN_LED = 13; const byte PIN_V_SENSE = A0; const byte PIN_V_CTL = A1; const int AVERAGE_COUNT = 1000; const float V_REF = 5.0; int level = 0; int count = 0; long int sum = 0; void setup() { Serial.begin(9600); pinMode(PIN_LED,OUTPUT); level = analogRead(PIN_V_CTL); analogWrite(PIN_LED, level); } void loop() { { int new_level = analogRead(PIN_V_CTL); if (level != new_level) { level = new_level; analogWrite(PIN_LED, level); } } if (count < AVERAGE_COUNT) { sum += analogRead(PIN_V_SENSE); count++; } else { float average = V_REF*((float)sum/(float)AVERAGE_COUNT); Serial.print("V_avg = "); Serial.print(average); Serial.println("V"); sum = 0; count = 0; } }
Для ШИМ настройте таймер, для замера напряжения настройте АЦП и прерывание завершения АЦП конвертации. Для примера код для ардутины, где ШИМ от таймера настроен и отлавливается прерывание аналогового компаратора, вам вместо него нужно запилить прерывание АЦП Код (Text): #include <avr/io.h> #include <avr/interrupt.h> #include <avr/sleep.h> #include <util/delay.h> const int delay_tome = 1000; const int max_lumen = 255; const int min_lumen = 1; int pwm_pb2; int pwm_pb3; int pwm_pd5; enum { DOWN, UP }; int ch_red() { static int direct; static int value = 1; if (value >= max_lumen) { direct = DOWN; } else if (value <= min_lumen) { direct = UP; }; if (direct == UP) { value *= 2; } else { if (value >= min_lumen) value /= 2; else value = min_lumen; }; if (value >= max_lumen) value = max_lumen; if (value <= min_lumen) value = min_lumen; return value; } int ch_green() { static int direct; static int value = 1; if (value >= max_lumen) { direct = DOWN; } else if (value <= min_lumen) { direct = UP; }; if (direct == UP) { value *= 2; } else { value /= 2; }; if (value >= max_lumen) value = max_lumen; if (value <= min_lumen) value = min_lumen; return value; } int ch_blue() { static int direct; static int value = 1; if (value >= max_lumen) { direct = DOWN; } else if (value <= min_lumen) { direct = UP; }; if (direct == UP) { value *= 2; } else { value /= 2; }; if (value >= max_lumen) value = max_lumen; if (value <= min_lumen) value = min_lumen; return value; } void loop_step() { static int st = 0; if (st <= 6) st++; pwm_pb2 = ch_red(); if (st >= 3) pwm_pb3 = ch_green(); if (st >= 6) pwm_pd5 = ch_blue(); //пауза _delay_ms(delay_tome); } void ioinit(void) { ADCSRB &= ~(_BV(ACME)); ACSR |= _BV(ACIE); // | _BV(ACBG); ACSR &= ~(_BV(ACIS0) | _BV(ACIS1) | _BV(ACD)); // DDRB = 0x00; // PORTB = 0x00; //PB3 и PB4 на выход DDRB |= _BV(PB0) | _BV(PB1) | _BV(PB2) | _BV(PB3); //PD5 на выход DDRD |= _BV(PD5); //ножки PD6,PD7 высокоомный вход(без внутренних подтягивающих сопротивлений) PORTD &= ~(_BV(PD6)) & ~(_BV(PD7)); //TCNT0 = 255; OCR0A = 0; OCR0B = 0; //TCNT1 = 0; OCR1A = 0; OCR1B = 0; //TCNT2 = 0; OCR2A = 0; OCR2B = 0; /* Timer 0 is 8-bit PWM. */ TCCR0A = _BV(COM0B1) | _BV(WGM01) | _BV(WGM00); TCCR0B |= _BV(CS02) | _BV(WGM02); /* Timer 1 is 8-bit PWM. */ TCCR1A = _BV(COM1B1) | _BV(WGM11) | _BV(WGM10); TCCR1B |= _BV(CS12) | _BV(WGM12); /* Timer 2 is 8-bit PWM. */ TCCR2A = _BV(COM2A1) | _BV(WGM21) | _BV(WGM20); TCCR2B |= _BV(CS22) | _BV(WGM22); // GTCCR TIMSK0 |= _BV(TOIE0);// | _BV(OCIE0B); TIMSK1 |= _BV(TOIE1);// | _BV(OCIE1B); TIMSK2 |= _BV(TOIE2);// | _BV(OCIE2A); sei (); } void chech_aco() { if (ACSR & _BV(ACO)) { PORTB &= ~(_BV(PB0)); PORTB |= _BV(PB1); } else { PORTB |= _BV(PB0); PORTB &= ~(_BV(PB1)); } } int main(void) { ioinit(); chech_aco(); /* loop forever, the interrupts are doing the rest */ for (;;) loop_step(); //sleep_mode(); return (0); } ISR(ANALOG_COMP_vect) { chech_aco(); } ISR(TIMER0_OVF_vect) { OCR0A = pwm_pd5; } ISR(TIMER1_OVF_vect) { OCR1B = pwm_pb2; } ISR(TIMER2_OVF_vect) { OCR2A = pwm_pb3; }