Trouble with ADC Interrupts and PWM output.


   hi first post please gentle :) .  have been playing adc , pwm outputs.  attached schematic of setup.  have voltage divider light dependent resistor r1 , center node attached pin pc1 , center post of potentiometer connected pin pc0.  varying resistance of ldr led being driven pwm pin pd6. 
   
   my goal have voltage of voltage divider match voltage coming out of pot.  if turn pot duty cycle of pwm driving led increased making led brighter , bringing voltage voltage divider go match output pot.  here code using.

code: [select]


volatile int pot;
volatile int ldr;
uint8_t channel;
int adcvalue[2];
int error;
int pwmvalue = 0;

void setup() {
 
  cli();
 
  admux |= (1<<refs0);                                    //set adc ref. avcc
  adcsra |= (1<<adps0) | (1<<adps1) | (1<<adps2);         //set prescaler 128
  channel = 0;                                            //set channel 0
  admux = (0xf0 & admux) | channel;                       //set multiplexer adc0
  adcsra |= (1<<aden);                                    //turn on adc
  adcsra |= (1<<adie);                                    //enable adc interrupts
  adcsra |= (1<<adsc);                                    //start first conversion

  ddrd = 0b01000000;                                      //set oc0a output
  tccr0a |= (1<<wgm00) | (1<<wgm01);                      //set fast pwm mode
  tccr0a |= (1<<com0a1);                                  //set compare match mode pwm
  tccr0b |= (1<<cs00) | (1<<cs01);                        //set prescaler 64

  serial.begin(115200);
 
  sei();                                                  //enable global interrupts
}

void loop(){
  error = ldr - pot;
  if (error > 0)  pwmvalue--;
  if (error < 0)  pwmvalue++;

  ocr0a = pwmvalue;

  serial.print("  ");
  serial.print(ldr);
  serial.print("  ");
  serial.print(pot);
  serial.print("  ");
  serial.print(error);
  serial.print("  ");
  serial.print(pwmvalue);
  serial.print("\n");

}


isr (adc_vect){
  adcvalue[channel] = adc;                            //store values adc
  pot = adcvalue[0];                                 
  ldr = adcvalue[1];
  channel++;                                          //increment channel
  if (channel >1) channel = 0;
  admux = (0xf0 & admux) | channel;                   //change multiplexer
  adcsra |= (1<<adsc);                                //start next conversion
               
}



   as right works, if comment out serial.begin(115200) , serial.print lines stops working.  led stays @ 1 fixed brightness , doesn't vary no matter how turn potentiometer.  odd thing wrote same sketch using software driven pwm , works serial.being , serial.print lines commented out , doesn't work if leave them in.  here code.

code: [select]

volatile int pot;
volatile int lsr;
uint8_t channel;
int adcvalue[2];
int error;
int pwmvalue = 0;
int pwmtickcount = 0;
int pwmtotal = 100;
bool pinstate = true;


void setup() {
 
  cli();
 
  admux |= (1<<refs0);                                    //set adc ref. avcc
  adcsra |= (1<<adps0) | (1<<adps1) | (1<<adps2);         //set prescaler 128
  channel = 0;                                            //set channel 0
  admux = (0xf0 & admux) | channel;                       //set multiplexer adc0
  adcsra |= (1<<aden);                                    //turn on adc
  adcsra |= (1<<adie);                                    //enable adc interrupts
  adcsra |= (1<<adsc);                                    //start first conversion

  ddrd = 0b01000000;
  tccr1a = 0;                                             //set entire tccr1a register 0
  tccr1b = 0;                                             //same tccr1b
  tcnt1  = 0;                                             //initialize counter value 0
  ocr1a = 10;                                             //set time each tick
  tccr1b |= (1 << wgm12);                                 //turn on ctc mode
  tccr1b |= (1 << cs11);                                  //set prescaler 256
  timsk1 |= (1 << ocie1a);                                //enable timer compare interrupt
  //serial.begin(115200);
 
  sei();                                                  //enable global interrupts
}

void loop(){
 
  pwmhandle();
 
  error = lsr - pot;
  if (error > 0)  pwmvalue--;
  if (error < 0)  pwmvalue++;


  /*serial.print("  ");
  serial.print(lsr);
  serial.print("  ");
  serial.print(pot);
  serial.print("  ");
  serial.print(error);
  serial.print("  ");
  serial.print(pwmvalue);
  serial.print("\n");*/

}

isr (timer1_compa_vect)
{
  pwmtickcount++;
}

void pwmhandle() {
 
  if(pinstate == true) {
    if(pwmtickcount >= pwmvalue)
      pinstate = false;
    } else {
        if (pwmtickcount >= pwmtotal){
          pinstate = true;
          pwmtickcount = 0;
        }
      }
  if (pinstate == true) {
    portd = (0b01000000);
  }
  if (pinstate == false) {
    portd = (0b00000000);
  }
}


isr (adc_vect){
  adcvalue[channel] = adc;
  pot = adcvalue[0];
  lsr = adcvalue[1];
  channel++;
  if (channel >1) channel = 0;
  admux = (0xf0 & admux) | channel;
  adcsra |= (1<<adsc);
 
}



   i thought might related timer using rewrote both of them using different timers same results.  stumped , appreciate help.

such low level code hard analyze. why don't use standard functions? why interrupts? why t0?
serial.begin() may initialize further registers, don't handle in setup.

even if ldr not fast, may out of kind of square wave, according pwm signal of led.


Arduino Forum > Using Arduino > Project Guidance > Trouble with ADC Interrupts and PWM output.


arduino

Comments

Popular posts from this blog

Error: ‘for’ loop initial declarations are only allowed in C99 or C11 mode - Raspberry Pi Forums

class MPU6050 has no member named begin

missing filename after '-o'