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,
#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.