Arduino compare

Excuse me! I have a question: Is it possible to use Arduino DUE's compare match to compare sine wave and carrier wave to change the duty ratio of PWM?

compare in what way? amplitude, frequency, phase

By comparing the target sine wave with the triangle wave generated by the timer programmed in the Arduino DUE's Atmel SAM3X8E microcontroller, we can change the PWM duty ratio as shown in the figure.

not sure what purpose the triangle wave serves other than a sampling period.

why not generate a PWM proportional to the sine wave amplitude?

Interesting graphics. Isn't this a Class D audio amplifier?

I want to use PWM control to control a motor, and I want to change the duty ratio by comparing the carrier wave and sine wave, which is a common control method.

That's right! I would like to implement this with Arduino and use the value obtained from the current sensor to control PWM.

Hi,

You want to do what a commercial/industrial VFD/VSD does.
Uses a variable duty cycle HIGH frequency signal to produce IN EFFECT a sinewave.

arduino vfd project

Tom...

Thank you, I'll look into it.

can you explain what is being compared?

I wonder if this is an XY problem.

What "carrier wave" are you talking about? I do understand the basic idea - by putting a triangle wave into one input of an op-amp, and a variable voltage into the other, you can get a variable mark-space ratio output from the op-amp, at the same frequency as the triangle wave input.

But that was a system used when it was necessary to avoid the use of a microcontroller, either for cost or availability reasons.

So I repeat: what is this "carrier wave" and where is it coming from? What do you actually want to achieve? Could you step back a bit from the detail and give us the full picture?

This carrier wave is a sine wave that can be realized programmatically by introducing math.h and using the sine function. The time of this sine function is going to be updated every time the ADC is turned on.

In order to control the motor PI, we first input the output voltage of the current sensor to the Arduino DUE and convert it to AD. This AD conversion is triggered by a PWM overflow interrupt. The dq conversion requires some technical knowledge to understand, so please check it out. If the sine wave is larger than the triangle wave, the PWM is turned on and the PWM is output.

Hi,
I think you mean you want the Sinewave to be the REFERENCE waveform to then get the PWM output to track amplitude to Duty cycle.

Then you can adjust the duty cycle to change the output amplitude.

What sort of motor and do you have a driver circuit to interface controller and motor?

Tom...

I haven't decided which motor to use yet, and I'm going to use a three-phase inverter made by a friend of mine for the driver circuit, but for now I'd like to use an oscilloscope to see if I can change the PWM duty ratio by comparing the carrier wave and triangle wave.

Hi,
What do you want to control, torque, speed or both?
AND 3 phase?

Thanks.. Tom..

I think it controls the torque. I would also like to control three phase PWM.

I've been studying electronics for about three years, but I started this research this year, and I've only been using Arduino and programming for a few months.
The program currently looks something like this

``````#define LED_PIN 13//割り込み確認用
#include <math.h>      // 数学関数用ヘッダ

/*配列に格納*/
float a[200];//u相
float b[200];//v相
float c[200];//w相

int n=0;
int p=0;
int x = 0, y=0, z=0, w=0, t=0 ;
double average = 0 ;
double average1 = 0 ;

/*1相目（ｕ相）の値A0ピン*/
float value1 = 0;
float volt1 = 0;
float current1 = 0;

/*2相目（v相）の値A1ピン*/
float value2 = 0;
float volt2 = 0;
float current2 = 0;

/*3相目（w相）の値A2ピン*/
float value3 = 0;
float volt3 = 0;
float current3 = 0;

void setup(){

Serial.begin(115200);
tc_setup();
pwm_setup();
pinMode(LED_PIN,OUTPUT);
}

/*************  Timer Counter 0 Channel 2 to generate PWM pulses thru TIOA2  ************/
void tc_setup() {

PMC->PMC_PCER0 |= PMC_PCER0_PID27;                      //TC2 power ON : Timer Counter 0 channel 2 IS TC2
TC0->TC_CHANNEL[2].TC_CCR = TC_CCR_SWTRG | TC_CCR_CLKEN; // Software trigger TC2 counter and enable

}

pmc_set_writeprotect(false);            // PMC controller write protection disable.

PMC->PMC_PCER1 |= PMC_PCER1_PID37;                    // ADC power on

}

void pwm_setup(){
REG_PMC_PCER1 |= PMC_PCER1_PID36; // PWMの有効化

uint16_t CounterPeriod;

//キャリア周波数10Hz、デッドタイム約1.2usの場合の設定

REG_PWM_CLK = PWM_CLK_PREA(0) | PWM_CLK_DIVA(1); // PWMクロックレートを84MHzに設定 (84MHz/1)

CounterPeriod = 16800;  //84MHz/5KHz = 16800

REG_PWM_CPRD0 = CounterPeriod; //CPRDは三角波のトップ
REG_PWM_CPRD1 = CounterPeriod;
REG_PWM_CPRD2 = CounterPeriod;
REG_PWM_CPRD3 = CounterPeriod;

//REG_PWM_CDTY0 = 2000;
REG_PWM_CDTY1 = 8500;      // Set the PWM duty cycle = (CDTY/CPRD) * 100 %

REG_PWM_CDTY2 = 8500;
REG_PWM_CDTY3 = 8500;

//set PC2 = PWML0, PC3 = PWMH0, PC4 = PWML1 and PC5 = PWMH1//
PIOC->PIO_PDR = PIO_PDR_P3                          // Set the pin to the peripheral PWM, not the GPIO
| PIO_PDR_P4
| PIO_PDR_P5
| PIO_PDR_P6
| PIO_PDR_P7
| PIO_PDR_P8
| PIO_PDR_P9;
PIOC->PIO_ABSR |=  PIO_PC4B_PWML1                    // Set PWM pin perhipheral type B
| PIO_PC5B_PWMH1
| PIO_PC6B_PWML2
| PIO_PC7B_PWMH2
| PIO_PC8B_PWML3
| PIO_PC9B_PWMH3;

//REG_PWM_CDTY1 = 21000;  //Channel Duty Cycle Register
REG_PWM_CMR0 = PWM_CMR_CALG | PWM_CMR_CPRE_MCK;  //CALG senter Alg
REG_PWM_CMR1 = PWM_CMR_DTE | PWM_CMR_CALG | PWM_CMR_CPRE_MCK;
REG_PWM_CMR2 = PWM_CMR_DTE | PWM_CMR_CALG | PWM_CMR_CPRE_MCK;
REG_PWM_CMR3 = PWM_CMR_DTE | PWM_CMR_CALG | PWM_CMR_CPRE_MCK;

//PIOのディセーブルレジスタ
REG_PIOC_PDR = PIO_PDR_P9 | PIO_PDR_P8 | PIO_PDR_P7 | PIO_PDR_P6 | PIO_PDR_P5 | PIO_PDR_P4;
//ペリフェラルABセレクタ 相補にしている
REG_PIOC_ABSR |= PIO_ABSR_P9 | PIO_ABSR_P8 | PIO_ABSR_P7 | PIO_ABSR_P6 | PIO_ABSR_P5 | PIO_ABSR_P4;

PWM->PWM_CMP[0].PWM_CMPM = PWM_CMPM_CEN;                       // PWM0の比較を有効化
PWM->PWM_ELMR[1] = PWM_ELMR_CSEL0;                             // PWMイベントライン1にPWM0を設定
PWM->PWM_CMP[0].PWM_CMPV = PWM_CMPV_CV(CounterPeriod - 10);  // PWM0のDUTYを設定

NVIC_EnableIRQ(TC2_IRQn);  // TC2 NVIC enable
NVIC_SetPriority(PWM_IRQn, 0); // PWMコントローラのNVIC(Nested Vector Interrupt Controller)の優先度を0(最高)にする
NVIC_EnableIRQ(PWM_IRQn); // PWMコントローラをNested Vector Interrupt Controller (NVIC)に接続する。
PWM->PWM_ENA |= PWM_ENA_CHID0 | PWM_ENA_CHID0; // PWMチャンネルを有効にする
PWM->PWM_IER1 |= PWM_IER1_CHID0; // イベント割り込みを有効にする
REG_PWM_IER1 = PWM_IER1_CHID0; // Interrupt on PWM Channel 0 counter

// PWM0~3の開始
REG_PWM_ENA = PWM_ENA_CHID3 | PWM_ENA_CHID2 | PWM_ENA_CHID1 | PWM_ENA_CHID0;
}

void loop(){

if(x==2199){
for(int u=0 ;u>=0 && u<=199;u=u+1){
Serial.print("U相電流 ： ");
Serial.println(a[u]);
}

for(int v=0 ;v>=0 && v<=199;v=v+1){
Serial.print("V相電流 ： ");
Serial.println(b[v]);
}
for(int w=0 ;w>=0 && w<=199;w=w+1){
Serial.print("W相電流 ： ");
Serial.println(c[w]);
}
}
}

void PWM_Handler(){
if (REG_PWM_ISR1 & PWM_ISR1_CHID0)    // Check if an update condition has occured
{

}
}

//電流センサ計算部分//
volt1 = ((value1-17)*(3.3/ 4095.0)) ;
volt2 = ((value2-17)*(3.3/ 4095.0)) ;
volt3 = ((value3-17)*(3.3/ 4095.0)) ;

current1 = ((volt1 - 2.5)*40) ;
current2 = ((volt2 - 2.5)*40) ;
current3 = ((volt3 - 2.5)*40) ;

//配列に値を格納//

x++;
if(2000<=x && x<=2199){

//A/D変換の値を格納//
a[y] = value1;
b[z] = value2;
c[w] = value3;

//電流値を格納//
/* a[y] = current1;
b[z] = current2;
c[w] = current3;*/

y++;
z++;
w++;
}

//PIOB->PIO_ODSR ^= PIO_ODSR_P27; //Lチカ用

if(n%2==0){
digitalWrite(LED_PIN,HIGH);
n++;
}else{
digitalWrite(LED_PIN,LOW);
n++;
}

}

``````

Please translate the Japanese part of the comment.