Go Down

Topic: analogWrite, sets pin high at 255 (Read 116 times) previous topic - next topic

waqaszahid

Hello,

I am working on an arduino controlled lab bench power supply, I have enabled the 10 bit PWM on the arduino timer one in order to get better resolution since the 10 bit PWM will eventually be filtered through a low pass filter and will be fed at the adjust pin of an LM317 regulator. My code is as below,

Code: [Select]
#include <LiquidCrystal595.h>
LiquidCrystal595 lcd(12,5,4); //data latch clock
float voltage1;
float voltage2;
long voltTimer = 0;
volatile int PWM = 0;
volatile int CPWM = 0;
volatile int lastPWM1 = 0;
volatile int lastCPWM1 = 0;
volatile int lastPWM2 = 0;
volatile int lastCPWM2 = 0;
volatile int count = 0;
volatile int counter = 0;
byte flag = 1;
byte lastFlag = 2;
void setup() {
analogReference(EXTERNAL);
lcd.begin(16,2);
lcd.setCursor(0,0);
//lcd.print("DIGITAL CONTROL");
//lcd.setCursor(0,1);
//lcd.print("ARDUINO SUPPLY");
 
 TCCR1B &= ~(1 << CS12); //set bit to 0
 TCCR1B  |=   (1 << CS11); //set bit to 1
 TCCR1B &= ~(1 << CS10); // set bit to 0
                             

/**********************************************************************************/
// Set pwm resolution  to mode 7 (10 bit) applicable on pin 9 and 10 only
/**********************************************************************************/

TCCR1B &= ~(1 << WGM13);    // Timer B clear bit 4
TCCR1B |=  (1 << WGM12);    // set bit 3

TCCR1A |= (1 << WGM11);    //  Timer A set bit 1
TCCR1A |= (1 << WGM10);    //  set bit 0
pinMode(2, INPUT);
pinMode(3, INPUT);
pinMode(9, OUTPUT); //voltage set channel 1
pinMode(10, OUTPUT); //voltage set channel 2
pinMode(8, INPUT_PULLUP);
pinMode(7, INPUT_PULLUP);
pinMode(6, OUTPUT); // current set channel 1
pinMode(11, OUTPUT); //current set channel 2
pinMode(14, INPUT_PULLUP); //A0 pin
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
attachInterrupt(digitalPinToInterrupt(2), rising, FALLING);
delay(10);
attachInterrupt(digitalPinToInterrupt(3), Crising, FALLING);
  // put your setup code here, to run once:

}
void loop() {
  // put your main code here, to run repeatedly:
//if(millis() - lastPress > 900)
if(millis() - voltTimer > 490)
{
voltage1 = analogRead(A2);
delay(1);
voltage2 = analogRead(A1);
delay(1);
voltage1 = voltage1*25/1024;
voltage2 = voltage2*25/1024;
lcd.setCursor(0,0);
lcd.print(voltage1);
lcd.setCursor(6,0);
lcd.print(lastPWM1);
lcd.setCursor(0,1);
lcd.print(voltage2);
lcd.setCursor(6,1);
lcd.print(lastPWM2);
voltTimer = millis();
}
if(digitalRead(14) == LOW)
{
  //lastPress = millis();
  if(lastFlag == 2)
  {
    flag = 2;
    lastFlag = 1;
    PWM = lastPWM2;
    CPWM = lastCPWM2;
    digitalWrite(13, HIGH);
  }
  else if(lastFlag == 1)
  {
    flag = 1;
    lastFlag = 2;
    PWM = lastPWM1;
    CPWM = lastCPWM1;
    digitalWrite(13, LOW);
  }
  delay(750);
}
if(flag == 1)
{
if(PWM < 0)
{
  PWM = 0;
}
if(PWM > 1023)
{
  PWM = 1023;
}
analogWrite(9,PWM);
lastPWM1 = PWM;

if(CPWM < 0)
{
  CPWM = 0;
}
if(CPWM > 255)
{
  CPWM = 255;
}
analogWrite(6,CPWM);
lastCPWM1 = CPWM;
}

if(flag == 2)
{
if(PWM < 0)
{
  PWM = 0;
}
if(PWM > 1023)
{
  PWM = 1023;
}
analogWrite(10,PWM);
lastPWM2 = PWM;
if(CPWM < 0)
{
  CPWM = 0;
}
if(CPWM > 255)
{
  CPWM = 255;
}
analogWrite(11,CPWM);
lastCPWM2 = CPWM; 
}
}

void rising()
{
  static unsigned long last = 0;
  unsigned long current = millis();
  if(current - last > 5)
  {
  count = digitalRead(8);
  if(count == HIGH)
  {
  PWM--;
  }
   else if (count == LOW)
  {
    PWM++;
  }
  last = current;
  }
 
}

void Crising()
{
  static unsigned long Clast = 0;
  unsigned long Ccurrent = millis();
  if(Ccurrent - Clast > 5)
  {
  counter = digitalRead(7);
  if(counter == HIGH)
  {
  CPWM--;
  }
  else if (counter == LOW)
  {
    CPWM++;
  }
  Clast = Ccurrent;
  }

}


My problem is however with analogWrite() function which seems to set the PWM to HIGH whenever you write analogWrite(PWM, 255) this outputs 5 volts on the PWM pin and the voltage output of the power supply goes to a maximum of 25 volts, is there an alternative around this? I like the convenience of the analogWrite function but this is something that needs to be taken care of, luckily I am still in the testing phase and havent connected any delicate load at the output.

waqaszahid

sorry, nevermind, just commented out the digitalWrite(pin, HIGH) under the else if condition for 255 in wiring_analog.c file

This solves the issue

Grumpy_Mike

Quote
My problem is however with analogWrite() function which seems to set the PWM to HIGH whenever you write analogWrite(PWM, 255)
Yes it does, it is designed to do this because it is designed to use an 8 bit timer.

Quote
I like the convenience of the analogWrite function but this is something that needs to be taken care of,
So write your own function, call it something like analogWrite10bit.

waqaszahid

Thanks for the response Mike, I am going to stick with this for now, does the job with minimum effort, its 2:00 AM in this part of the world, I must leave this at that.

Delta_G

does the job with minimum effort
As long as you don't try to use one of the other PWM pins that's on an 8 bit timer.  Then you'll see the problem you created. 
If at first you don't succeed, up - home - sudo - enter.

Robin2

#5
Nov 14, 2017, 11:41 pm Last Edit: Nov 14, 2017, 11:42 pm by Robin2
analogWrite() function which seems to set the PWM to HIGH whenever you write analogWrite(PWM, 255)
That seems perfectly logical to me.

If it causes you a problem why do you let your code use a higher value than 254?

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

waqaszahid

As long as you don't try to use one of the other PWM pins that's on an 8 bit timer.  Then you'll see the problem you created. 
Didn't think of that, could be an issue but anyway I am using the 8 bit PWM channels for setting the current limit only and I dont need that to go beyond a maximum of 2.5 volts anyway.

Delta_G

Still, modifying the core to cover up an issue with your code is a pretty stupid thing to do and you'll more often than not break something else that you didn't mean to break. 
If at first you don't succeed, up - home - sudo - enter.

Go Up