2

For a battery charging project, i am using an ARDUINO UNO which is driving a buck converter to provide the battery with the charging current. I am using external ADCs to measure the battery's charging voltage and current. The test setup is working fine, but right now i am just measuring the voltage and current at random time instants. However to measure it correctly, battery voltage reading should be done at an instant when the controller's PWM output is LOW (OFF duty cycle), and battery current reading should be done when PWM output is HIGH (ON duty cycle). So i was thinking how i can do that, since i am using analogueWrite() function to give PWM output, i thought if i could access analogueWrite() fucntion, may be i could there insert the function of read_ADC_Voltage() during the LOW time, and read_ADC_Current() during the HIGH time.

Is my approach right ? If yes then can please anyone tell me how can i access and use this analogueWrite() function ? And if someone has any other idea to do the readings correctly, please suggest. I shall be grateful.

3 Answers 3

1

Add a pin-change-interrupt (PCI) handler (See eg PinChangeInt at arduino.cc); clear the flag and enable the interrupt whenever you want to take readings, and disable that PCI after you have the reading. As noted in the link, PCIs are available on all signal pins (possibly not on A6 and A7 on the 328), so are available on any of the PWM pins.

3
  • i tried to, but i am confused as the code isnt working as it is supposed to, in my opinion, so i posted my problem as an answer, as the code wont fit in comment box. Can you please tell what i am doing wrong?
    – yiipmann
    Nov 11, 2015 at 14:05
  • I suggest that you copy your 'answer' to a new question. I'm not going to evaluate that 'answer' here because use of comments for such evaluation is cumbersome -- comments can't be edited after their first five minutes -- and it does not tie into the stackexchange reputation system. Anyhow, post that as a separate question and I'll be glad to answer. Note, when you get another 5 points of reputation, you can start upvoting answers you find useful. Also, you can accept answers that best address questions you ask. Accepting and upvoting answers gives more people incentive to answer well. Nov 11, 2015 at 19:28
  • i just did..here is the link to it.
    – yiipmann
    Nov 11, 2015 at 19:54
1

P.S I am writing it as an answer since my code wont fit in comment

I looked into interrupts and learned about them that there are 2 types of interrupts in Arduino namely "external", and "pin change". So i downloaded the "PinChangeInt Library" to test it. I wrote a small program where a PWM of 62.5kHz is being generated on pin3, and i am calling rising and falling edge triggered interrupts on this pin, i.e to display one value when rising edge occurs, and other value when falling edge occurs. My code looks like following:

    #include <PinChangeInt.h>
    #define pw 3
    int pwm;


    void setup() {
      // put your setup code here, to run once:
      pinMode(pw, OUTPUT) ;
      pwm_setup();             // Set PWM to a frequency of 62.5kHz

      PCintPort::attachInterrupt(pw,rise,RISING);    // call void rise() when PWM is HIGH
      PCintPort::attachInterrupt(pw,fall,FALLING);   // call void fall() when PWM is LOW


      Serial.begin(9600);
    }

    void loop() {
      // put your main code here, to run repeatedly:
      pwm = 127;                                                // 50% duty cycle
      pwm_on(pwm);

    }
    void pwm_setup()
    {

      TCCR2A = 0x23 ;
      TCCR2B = 0x09 ; // mode 7, clock prescale by 1
      OCR2A = 256-1 ;  // 256 clock periods = 16us per cycle
      OCR2B =0 ;
      TCNT2 =0 ;

    }
    void pwm_on(double)
     {
        OCR2B = pwm ;
     }

    void rise()
    {
      Serial.println("RISE");
    }

void fall()
{
  Serial.println("fall");
}

But it is not working the way i think it should. It keeps on displaying "fall" every time, whereas according to me it should display "RISE" and "fall" alternatively, right ? However if i remove the "PCintPort::attachInterrupt(pw,fall,FALLING); " line, it starts to display "RISE" as it is supposed to.

Since its my first time programming with Arduino, and i am just a beginning level programmer, i might be making some stupid mistake here. So can you point it out please ?

0

No, in my opinion changing functions in the Arduino Core is not a good approach. You would have to change it back for any other project you are going to do and secondly, if you insert a function in the part where analogWrite is low it will result in a change in the duty cycle. Which may not be a big problem, but just don't.

My advice would be to use a timer to run a callback function every x seconds. Then in that function temporarily set the PWM to 0 and read your values. This is indeed not the most efficient approach, but we're talking about microseconds here... This approach is completely intterupt driven so you could run other things while it is running it's PWM and checking the voltage periodically.

It sounds as if you have gotten pretty far by yourself, so I'm not going to write you example code. You can a tutorial on how to use a timer to periodically call a function here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.