How to provide Phase difference between PWM pulses from Arduino by Simulink?

15 views (last 30 days)
I want to generate high frequency pulses from Arduino upto 25KHz and the pulses must be such that pulse from pin 12 must lag the pulse from pin 11 by some time however their frequency must be the same. The pulse width is also not necessarily to be same. The point is I am generating one wave with phase lag 0 perfectly of 25KHz from pin 11 but I can't use the pwm block for second wave because there is no provision for phase lag inside the block. I am using a Mega 2560. My desired wave and concerned Simulink blocks are shown in the picture. Any kind of pointers will be highly appreciated! I am using Matlab 2021b.

Answers (1)

Githin George
Githin George on 9 Feb 2024
Hello,
I understand that you would like to generate high frequency pulses from Arduino in pin 12 and pin 11 with the added condition that pin 12 should have a phase lag from that of pin 11.
As you rightly pointed out the “PWM” block in Simulink does not support adding a phase lag parameter therefore the logic for generating the pulses has to be controlled from within the Simulink model.
You will have to generate both the pulses using “PWM” block and make use of timer functions and other interrupts written in C code for precise controlling of the signal generation. I would suggest using MATLAB function blocks to achieve the same. Use “coder.ceval” to include direct calls to C functions if necessary. This approach is similar to the usage of the ISR functionality (Interrupt Service Routine) in Arduino code. See the example code below.
ISR(TIMER1_COMPA_vect) { // Timer1 interrupt service routine
if (toggleState == false) {
digitalWrite(pin11, HIGH);
delayMicroseconds(phaseLag); // Add phase lag
digitalWrite(pin12, HIGH);
toggleState = true;
}
else
{
digitalWrite(pin11, LOW);
digitalWrite(pin12, LOW);
toggleState = false;
}
}
In the above code you can notice the usage of “delayMicroseconds” function which induces the phase lag in pin 12.
For more details on deploying custom C code or Arduino library code in Simulink, please refer to the link below.
I hope this helps.
  1 Comment
youssef Mostafa
youssef Mostafa on 9 Apr 2024 at 5:57
I'm trying to do exactly as you said. I generated 2 PWM signals from my arduino pins using timer1, but I couldn't apply the phase shift between them
void setup() {
interrupts();
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
//InitTimer1
TCNT1 = 0;
TCCR1A = 0;
TCCR1B = 0;
//set to mode 14 fast pwm to ICR1 top value
//non inverted output on pins 9 (A) and 10 (B)
//ICR1 set frequency OCR1A and OCR1B set duty cycle
//prescaler 8 gives .5 microseconds per timer tick
// TCCR1A
// Bit 7 6 5 4 3 2 1 0
// Bit Name COM1A1 COM1A0 COM1B1 COM1B0 ----- ----- WGM11 WGM10
// Initial Value 0 0 0 0 0 0 0 0
// changed to 1 0 1 0 0 0 1 0
TCCR1A = B10100010;
// TCCR1B prescaler 8 .5us/tick
// Bit 7 6 5 4 3 2 1 0
// Bit Name ICNC1 ICES1 ---- WGM13 WGM12 CS12 CS11 CS10
// Initial Value 0 0 0 0 0 0 0 0
// changed to 0 0 0 1 1 0 1 0
TCCR1B = B00011010;
ICR1 = 99;//Set Top Value, -> frequency 20 kHz with 16 MHz internal clock, count is 0 referenced for 100 ticks
OCR1A = 50; //duty cycle pin 9 value 0-99
OCR1B = 30; //duty cycle pin 10 value 0-99
}
bool toggleState;
ISR(TIMER1_CAPT_vect) {// Timer1 interrupt service routine
if (toggleState == false) {
digitalWrite(9, HIGH);
delayMicroseconds(0.025); // Add phase lag
digitalWrite(10, HIGH);
toggleState = true;
}
else
{
digitalWrite(9, LOW);
digitalWrite(10, LOW);
toggleState = false;
}
}
void loop() {}

Sign in to comment.

Categories

Find more on Arduino Hardware in Help Center and File Exchange

Products


Release

R2021b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!