3 square wave generater

i want to generate three square wave by Arduino with frequency 30 khz and duty cycle 80% with phase shift 120 degree between the signals can any one help me with this code iam using Arduino mega .

Hi, @oday-saad
Welcome to the forum.

Please read the post at the start of any forum , entitled "How to use this Forum".

Have you Googled;

3 phase squarewave arduino

What is the application?
Can you please tell us your electronics, programming, arduino, hardware experience?

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

There's enough timers in the MEGA to do this in hardware.

You can use TIM3, TIM4, and TIM5 for the three signals (PWM 30kHz at 80% duty), and TIM1 to synchronize the START to generate the PHASE shift

30,000 doesn't divide into 16 MHz evenly. Is 30018.76 Hz close enough?

I would use Timer1 overflow and compare interrupts to do the timing. The total tick count would be 533 to get the frequency. The overflow ISR would set the PhaseA pin ON, set OCR1B to 105, and reset the pointer to the table of what to do for each interrupt. The OCR1B ISR would get instructions from the table of which pin to change, what to change it to, and what to set OCR1B to. After the 5th OCR1B interrupts there would be an overflow interrupt to start everything over again. Something roughly like this:

const byte PhaseAPin = 4;
const byte PhaseBPin = 5;
const byte PhaseCPin = 6;

struct ActionTable
{
  byte pin;
  boolean newState;
  unsigned OCRVal;
};

const ActionTable Action[] =
{
  {PhaseAPin, HIGH, 105},
  {PhaseBPin, LOW, 177},
  {PhaseBPin, HIGH, 283},
  {PhaseCPin, LOW, 355},
  {PhaseCPin, HIGH, 461},
  {PhaseAPin, LOW, 600} // Will overflow before reaching 600
};
byte ActionIndex = 0;

void OverflowISR()
{
  ActionIndex = 0;
  digitalWrite(Action[ActionIndex].pin, Action[ActionIndex].newState);
  OCR1B = Action[ActionIndex].OCRVal;
  ActionIndex++;
}

void OCR1BInterrupt()
{
  digitalWrite(Action[ActionIndex].pin, Action[ActionIndex].newState);
  OCR1B = Action[ActionIndex].OCRVal;
  ActionIndex++;
}

three phase dc/dc boost converter

thank you for help but when i upload this code this message appear and uploading dont completed

exit status 1

Error compiling for board Arduino Mega or Mega 2560.

That is not a complete sketch, just something to get you started. If you add these two lines at the bottom it will be a complete sketch. It still won't actually do anything but it will compile without errors or warnings. You have to learn how to use the Timer1 hardware.

void setup() {}
void loop() {}
1 Like

TIM3 (R-phase), TIM4 (Y-phase), and TIM4 (B-phase) will generate 3 free running 30 kHz sqaure wave signals. These three signals must be locked in the following ways:

1. When rising edge of R-phase occurs, then after a delay of about 22 us (equivalent to 120 degree) the Y-phase must start, stays ON for 80% and stays OFF until rising edge of R-phase appears.

2. When rising edge of Y-phase occurs, then after a delay of about 22 us (equivalent to 120 degree) the B-phase must start, stays ON for 80% and stays OFF until rising edge of Y-phase appears.

3. and the cycle repeats.

Would appreciate to see your idea of how TIM1 will maintain the above requirements.

1 Like

please can you write the code i don't understand because aim not specific in Arduino but i need this code in my work . can you help me please .thank you for all.

Hi @oday-saad

You might be better to try in the "Jobs and Paid Consultancy" part of the forum, if you want someone to code for you.

Is the 3phase DC-DC converter an industrial or school/university job?

What sort of power are you aiming to convert?
What input voltage are you aiming to start with?
What output voltages are you aiming to output?

Can you please tell us your electronics, programming, arduino, hardware experience?

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

thank you for answer
i want to control three transistor or mosfet for university job to operate the DC/DC converter
the mosfet connected to arduino by using optocoupler .
the dc/dc converter boost the dc voltage from 32 v to 480v dc

You only really need TIM1 to start the three timers with the 22us interval. You can use the output compare interrupts A, B, and C for the three intervals, then let it overflow and stop itself

ISR(TIMER1_COMPA_vect)
{
	// start TIM3 at 16Mhz
	TCCR3B = 1<<WGM33 | 1<<WGM32 | 0<<CS32 | 0<<CS31 | 1<<CS30;
}

ISR(TIMER1_COMPB_vect)
{
	// start TIM4 at 16Mhz
	TCCR4B = 1<<WGM43 | 1<<WGM42 | 0<<CS42 | 0<<CS41 | 1<<CS40;
}

ISR(TIMER1_COMPC_vect)
{
	// start TIM5 at 16Mhz
	TCCR5B = 1<<WGM53 | 1<<WGM52 | 0<<CS52 | 0<<CS51 | 1<<CS50;
}

ISR(TIMER1_OVF_vect)
{
	// stop TIM1
	TCCR1B = 0;
	TCNT1 = 0;
}

Since TIM3, TIM4, and TIM5 are independent, all you need is to set them up for the 80% duty cycle at 30 kHz. You can use Fast PWM mode for this.

void setup_timers345(void)
{
	/***********************************
	set up timers 3,4,5
	Fast PWM with TOP at OCRxA
	***********************************/
	
	/*************
	TIMER3
	*************/
	TCCR3A = 1<<COM3B1 | 0<<COM3B0 | 1<<COM3C1 | 0<<COM3C0 | 1<<WGM31 | 1<<WGM30;
	TCCR3B = 1<<WGM33 | 1<<WGM32;
	
	// ~30 kHz at 16Mhz
	OCR3A = 533;
	
	// 80% duty cycle
	OCR3B = 426;
	OCR3C = 426;
	
	TCNT3 = 0;
	
	/*************
	TIMER4
	*************/
	TCCR4A = 1<<COM4B1 | 0<<COM4B0 | 1<<COM4C1 | 0<<COM4C0 | 1<<WGM41 | 1<<WGM40;
	TCCR4B = 1<<WGM43 | 1<<WGM42;
	
	// ~30 kHz at 16Mhz
	OCR4A = 533;
	
	// 80% duty cycle
	OCR4B = 426;
	OCR4C = 426;
	
	TCNT4 = 0;
	
	/*************
	TIMER5
	*************/
	TCCR5A = 1<<COM5B1 | 0<<COM5B0 | 1<<COM5C1 | 0<<COM5C0 | 1<<WGM51 | 1<<WGM50;
	TCCR5B = 1<<WGM53 | 1<<WGM52;
	
	// ~30 kHz at 16Mhz
	OCR5A = 533;
	
	// 80% duty cycle
	OCR5B = 426;
	OCR5C = 426;
	
	TCNT5 = 0;
	
	return;
}

Once the timers 3, 4, and 5 are setup, just start timer1

void start_timer1(void)
{
	/*************
	Master timer
	TIMER1
	normal mode
	*************/
	TCCR1A = 0;
	
	// compare matches to generate phase shift (22us intervals)
	OCR1A = 100;
	OCR1B = 144;
	OCR1C = 188;
	
	TCNT1 = 0;
	
	// enable all interrupts
	TIMSK1 = 1<<OCIE1C | 1<<OCIE1B | 1<<OCIE1A | 1<<TOIE1;
	
	// start timer1 at 2Mhz
	TCCR1B = 0<<CS12 | 1<<CS11 | 0<<CS10;
	
	return;
}

This one compiles but I don't have an O-scope to verify



/*****************************
interrupt vectors
*****************************/
ISR(TIMER1_COMPA_vect)
{
  // start TIM3 at 16Mhz
  TCCR3B = 1<<WGM33 | 1<<WGM32 | 0<<CS32 | 0<<CS31 | 1<<CS30;
}

ISR(TIMER1_COMPB_vect)
{
  // start TIM4 at 16Mhz
  TCCR4B = 1<<WGM43 | 1<<WGM42 | 0<<CS42 | 0<<CS41 | 1<<CS40;
}

ISR(TIMER1_COMPC_vect)
{
  // start TIM5 at 16Mhz
  TCCR5B = 1<<WGM53 | 1<<WGM52 | 0<<CS52 | 0<<CS51 | 1<<CS50;
}

ISR(TIMER1_OVF_vect)
{
  // stop TIM1
  TCCR1B = 0;
  TCNT1 = 0;
}



void setup() {
  // setup timer outputs

  // phase-A (D2 and D3)
  DDRE |= 1<<PIN5 | 1<<PIN4;

  // phase-B (D7 and D8)
  DDRH |= 1<<PIN5 | 1<<PIN4;

  // phase-C (D44 and D45)
  DDRL |= 1<<PIN5 | 1<<PIN4;

  // configure timers
  setup_timers345();

  // let it rip
  start_timer1();
  
}

void loop() {
  // put your main code here, to run repeatedly:

}


/*****************************
setup timers 3, 4, and 5
*****************************/
void setup_timers345(void)
{
  /***********************************
  set up timers 3,4,5
  Fast PWM with TOP at OCRxA
  ***********************************/
  
  /*************
  TIMER3
  *************/
  TCCR3A = 1<<COM3B1 | 0<<COM3B0 | 1<<COM3C1 | 0<<COM3C0 | 1<<WGM31 | 1<<WGM30;
  TCCR3B = 1<<WGM33 | 1<<WGM32;
  
  // ~30 kHz at 16Mhz
  OCR3A = 533;
  
  // 80% duty cycle
  OCR3B = 426;
  OCR3C = 426;
  
  TCNT3 = 0;
  
  /*************
  TIMER4
  *************/
  TCCR4A = 1<<COM4B1 | 0<<COM4B0 | 1<<COM4C1 | 0<<COM4C0 | 1<<WGM41 | 1<<WGM40;
  TCCR4B = 1<<WGM43 | 1<<WGM42;
  
  // ~30 kHz at 16Mhz
  OCR4A = 533;
  
  // 80% duty cycle
  OCR4B = 426;
  OCR4C = 426;
  
  TCNT4 = 0;
  
  /*************
  TIMER5
  *************/
  TCCR5A = 1<<COM5B1 | 0<<COM5B0 | 1<<COM5C1 | 0<<COM5C0 | 1<<WGM51 | 1<<WGM50;
  TCCR5B = 1<<WGM53 | 1<<WGM52;
  
  // ~30 kHz at 16Mhz
  OCR5A = 533;
  
  // 80% duty cycle
  OCR5B = 426;
  OCR5C = 426;
  
  TCNT5 = 0;
  
  return;
}


/*****************************
setup timer 1
*****************************/
void start_timer1(void)
{
  /*************
  Master timer
  TIMER1
  normal mode
  *************/
  TCCR1A = 0;
  
  // compare matches to generate phase shift (22us intervals)
  OCR1A = 100;
  OCR1B = 144;
  OCR1C = 188;
  
  TCNT1 = 0;
  
  // enable all interrupts
  TIMSK1 = 1<<OCIE1C | 1<<OCIE1B | 1<<OCIE1A | 1<<TOIE1;
  
  // start timer1 at 2Mhz
  TCCR1B = 0<<CS12 | 1<<CS11 | 0<<CS10;
  
  return;
}

Hi,

Thanks for that, what power are you aiming to get out of the 480Vdc?
Wouldn't it be easier to go from mains AC voltage to 480Vdc?

Tom... :smiley: :+1: :coffee: :australia:

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.