Hello all;
I need to have variable control over PWM maximum using a potentiometer (map AnalogRead function).
In the first version I have control over PWM but the wave form is distorted, it should be a perfect ramp wave (similar to a sawtooth). see pic.
/////////////////////////////////
#include <stdlib.h>
#include <avr/io.h> // Adds useful constants
/// Define Variables ////
int pwmMin=30; // minimum pwm voltage (0-255)
int basePwm=0;
int pwmMax; // maximum pwm voltage (0-255)
int ramplength=15; // us
int INTERVAL=30000; // the repeat delay interval; ms.
int delayStartTime;
static uint32_t StartUs=micros();
static uint32_t StartMs=millis();
static uint8_t Pwm=0;
/// Define pins for ATTiny85 ///
volatile int outPin = 0; // PhysicalPin 5; P0
int ledPin = 1; // PP 6; P1
int pwmMaxPin = 1; // PP 7; P2 Sets Max Ramp hieght.
int ramplengthPin = 2; // PP 3; P4 Sets Ramp length / Mark Time.
int intervalPin = 3; // PP 2; P3 Sets DeadTime inbetween Ramp signals.
///////////////////////////////////////////////////
void setup()
{
/*
Control Register A for Timer/Counter-0 (Timer/Counter-0 is configured using two registers: A and B)
TCCR0A is 8 bits: [COM0A1:COM0A0:COM0B1:COM0B0:unused:unused:WGM01:WGM00]
2<<COM0A0: sets bits COM0A0 and COM0A1, which (in Fast PWM mode) clears OC0A on compare-match, and sets OC0A at BOTTOM
2<<COM0B0: sets bits COM0B0 and COM0B1, which (in Fast PWM mode) clears OC0B on compare-match, and sets OC0B at BOTTOM
3<<WGM00: sets bits WGM00 and WGM01, which (when combined with WGM02 from TCCR0B below) enables Fast PWM mode
*/
TCCR0A = 2<<COM0A0 | 2<<COM0B0 | 3<<WGM00;
/*
Control Register B for Timer/Counter-0 (Timer/Counter-0 is configured using two registers: A and B)
TCCR0B is 8 bits: [FOC0A:FOC0B:unused:unused:WGM02:CS02:CS01:CS00]
0<<WGM02: bit WGM02 remains clear, which (when combined with WGM00 and WGM01 from TCCR0A above) enables Fast PWM mode
1<<CS00: sets bits CS01 (leaving CS01 and CS02 clear), which tells Timer/Counter-0 to not use a prescalar
*/
TCCR0B = 0<<WGM02 | 1<<CS00;
/*
Control Register for Timer/Counter-1 (Timer/Counter-1 is configured with just one register: this one)
TCCR1 is 8 bits: [CTC1:PWM1A:COM1A1:COM1A0:CS13:CS12:CS11:CS10]
0<<PWM1A: bit PWM1A remains clear, which prevents Timer/Counter-1 from using pin OC1A (which is shared with OC0B)
0<<COM1A0: bits COM1A0 and COM1A1 remain clear, which also prevents Timer/Counter-1 from using pin OC1A (see PWM1A above)
1<<CS10: sets bit CS11 which tells Timer/Counter-1 to not use a prescalar
*/
TCCR1 = 0<<PWM1A | 0<<COM1A0 | 1<<CS10;
/*
General Control Register for Timer/Counter-1 (this is for Timer/Counter-1 and is a poorly named register)
GTCCR is 8 bits: [TSM:PWM1B:COM1B1:COM1B0:FOC1B:FOC1A:PSR1:PSR0]
1<<PWM1B: sets bit PWM1B which enables the use of OC1B (since we disabled using OC1A in TCCR1)
2<<COM1B0: sets bit COM1B1 and leaves COM1B0 clear, which (when in PWM mode) clears OC1B on compare-match, and sets at BOTTOM
*/
GTCCR = 1<<PWM1B | 2<<COM1B0;
pinMode(outPin, OUTPUT);
pinMode(ledPin, OUTPUT);
}
//////////////////////////////////////////////////////////
void loop()
{ static int Dir=1;
//static int8_t Dir=1;
if((micros()-StartUs) >= ramplength) // Control ramplength variable;
{
Pwm+=Dir; // Augment Pwm by Direction;
analogWrite(ledPin, Pwm); // Update LedPin;
if(Pwm==pwmMin) // if Pwm == pwmMin;
{
delay(200); // Buck-converer warm-up;
digitalWrite(outPin,HIGH); // Squarewave rising edge start;
if(Pwm=pwmMax) Pwm==pwmMax; // I know this is NOT correct, but it gives some results???
Dir=+1; // & start 'Ramp_Up';
}
StartUs=micros(); // reset micros to startmicros;
}
if(Pwm==basePwm)
{
delayMicroseconds(1000); //Squarewave falling edge delay (buck-converter);
digitalWrite(outPin,LOW); //Squarewave falling edge trigger;
delay(INTERVAL); //delay *INTERVAL*
delayStartTime = micros();
do
{
INTERVAL = map(analogRead(intervalPin),0,1023,800,50000); //800=16ms // adjust all maps according to
pwmMax = map(analogRead(pwmMaxPin),0,1023,160,255); // circuit layout & potentiomenters
ramplength = map(analogRead(ramplengthPin),0,1023,377,5800); //5800=24ms // adjust map for packetcount
}
while(micros()-delayStartTime<=INTERVAL);
}
}
In the next versions of the code, it produces a 'double' ramp and only the first ramp is ajustable via mapAnalogread function: see pic.
void loop()
{
static int8_t Dir=1;
if((micros()-StartUs) >= ramplength) // Control ramplength variable;
{
Pwm+=Dir; // Augment Pwm by Direction;
analogWrite(ledPin, Pwm); // Update LedPin;
if(Pwm==pwmMin) // if Pwm == pwmMin;
{
delay(200); // Buck-converer warm-up;
digitalWrite(outPin,HIGH); // Squarewave rising edge start;
for(int Pwm = basePwm ; Pwm <= pwmMax; Pwm +=Dir ) // & start 'Ramp_Up';
analogWrite(ledPin, Pwm);
}
StartUs=micros(); // reset micros to startmicros;
}
if(Pwm==basePwm)
{
delayMicroseconds(1000); //Squarewave falling edge delay (buck-converter);
digitalWrite(outPin,LOW); //Squarewave falling edge trigger;
delay(INTERVAL); //delay *INTERVAL*
delayStartTime = micros();
do
{
INTERVAL = map(analogRead(intervalPin),0,1023,800,50000); //800=16ms // adjust all maps according to
pwmMax = map(analogRead(pwmMaxPin),0,1023,60,255); // circuit layout & potentiomenters
ramplength = map(analogRead(ramplengthPin),0,1023,377,5800); //5800=24ms // adjust map for packetcount
}
while(micros()-delayStartTime<=INTERVAL);
}
}
In the last version, I tried to link the pwmMax map AnalogRead function to the 'Dir' variable, but it does not respond. see pic.
void loop()
{
static int8_t Dir=1;
if((micros()-StartUs) >= ramplength) // Control ramplength variable;
{
Pwm+=Dir; // Augment Pwm by Direction;
analogWrite(ledPin, Pwm); // Update LedPin;
if(Pwm==pwmMin) // if Pwm == pwmMin;
{
delay(200); // Buck-converer warm-up;
digitalWrite(outPin,HIGH); // Squarewave rising edge start;
if(pwmMin <= Pwm <= pwmMax);
Pwm+=Dir; // & start 'Ramp_Up';
}
StartUs=micros(); // reset micros to startmicros;
}
if(Pwm==basePwm)
{
delayMicroseconds(1000); //Squarewave falling edge delay (buck-converter);
digitalWrite(outPin,LOW); //Squarewave falling edge trigger;
delay(INTERVAL); //delay *INTERVAL*
delayStartTime = micros();
do
{
INTERVAL = map(analogRead(intervalPin),0,1023,800,50000); //800=16ms // adjust all maps according to
pwmMax = map(analogRead(pwmMaxPin),0,1023,60,255); // circuit layout & potentiomenters
ramplength = map(analogRead(ramplengthPin),0,1023,377,5800); //5800=24ms // adjust map for packetcount
}
while(micros()-delayStartTime<=INTERVAL);
}
}
I know that there is some fundamental mistake I am making with this.
Any comment would be really appreciated to get this up and running.
Thanks in advance
lost_bro