PWM generator

Hello, i want to create a PWM signal so control a IGBT full brigde, i use a arduino uno anda i use this code:

``````double t;
float carrier, Uref;
void setup()
{
Serial.begin(9600);
pinMode(13, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);

}

void loop() {

for (t = 0; t < 10; t = t + 0.00001) {

Uref = 0.95 * sin(2 * PI * 50 * t);
carrier = (2 / PI) * asin(sin(2 * PI * 1650 * t));

if (Uref > carrier) {

digitalWrite(10, HIGH); //PIN 1

digitalWrite(11, LOW); // PIN 3

digitalWrite(12, HIGH); //PIN 11

digitalWrite(13, LOW);// PIN 9

}
else {

digitalWrite(10, LOW);

digitalWrite(11, HIGH);

digitalWrite(12, LOW);

digitalWrite(13, HIGH);

}
}
}
``````

I just compare a Uref and carrier , what i am doing wrong? i am a beginner in this world of arduino.

You haven't explained what your code is doing wrong. You haven't explained what you expect your code to do if it is working. But I don't see the point of comparing "Uref" and "carrier". The values for Uref can be interpreted as a 50Hz sine wave with an amplitude of 0.95, sampled every 10 microseconds. But the values for "carrier" are just an angle sampled every 10 microseconds. What is the equation for "carrier" supposed to represent and, specifically, why are you using asin() ?

Pete

el_supremo: You haven't explained what your code is doing wrong. You haven't explained what you expect your code to do if it is working. But I don't see the point of comparing "Uref" and "carrier". The values for Uref can be interpreted as a 50Hz sine wave with an amplitude of 0.95, sampled every 10 microseconds. But the values for "carrier" are just an angle sampled every 10 microseconds. What is the equation for "carrier" supposed to represent and, specifically, why are you using asin() ?

Pete

Hello Pete. I use the function asin() to generate a triangular wave, and compare the triangular wave with Uref. My problem is how i can generate a PWM signal from a reference waveform?

``````asin(sin(2 * PI * 1650 * t))
``````

Doesn't the asin() just un-do the sin()?!?

Doesn't the asin() just un-do the sin()?!?

Yes, except that it normalizes the input angle into the range -pi/2 to +pi/2 which results in a triangle wave.

Pete

analogWrite() is what you need to generate a PWM.

"Writes an analog value (PWM wave) to a pin. Can be used to light a LED at varying brightnesses or drive a motor at various speeds. After a call to analogWrite(), the pin will generate a steady square wave of the specified duty cycle until the next call to analogWrite() (or a call to digitalRead() or digitalWrite() on the same pin). The frequency of the PWM signal on most pins is approximately 490 Hz. On the Uno and similar boards, pins 5 and 6 have a frequency of approximately 980 Hz. Pins 3 and 11 on the Leonardo also run at 980 Hz.

On most Arduino boards (those with the ATmega168 or ATmega328), this function works on pins 3, 5, 6, 9, 10, and 11. On the Arduino Mega, it works on pins 2 - 13 and 44 - 46. Older Arduino boards with an ATmega8 only support analogWrite() on pins 9, 10, and 11.

The Arduino Due supports analogWrite() on pins 2 through 13, plus pins DAC0 and DAC1. Unlike the PWM pins, DAC0 and DAC1 are Digital to Analog converters, and act as true analog outputs.

You do not need to call pinMode() to set the pin as an output before calling analogWrite()."

Check it out.

The main problem with your code is that it assumes that it is generating a sample of the PWM signal every 10 microseconds. But it takes about 175 microseconds to calculate "Uref" and "carrier". So even if your code was generating PWM, the PWM that it actually outputs is at least 17 times slower than it needs to be. I'm not sure that you could speed up your code enough to be able to calculate Uref and carrier in less than 10 microseconds.

Pete

el_supremo: The main problem with your code is that it assumes that it is generating a sample of the PWM signal every 10 microseconds. But it takes about 175 microseconds to calculate "Uref" and "carrier". So even if your code was generating PWM, the PWM that it actually outputs is at least 17 times slower than it needs to be. I'm not sure that you could speed up your code enough to be able to calculate Uref and carrier in less than 10 microseconds.

Pete

Can you give me a tip , how i can do this? thanks

Can you give me a tip , how i can do this?

1)Use a faster processor. or

2) Pre calculate the values in a look up table.