Look for in our Blog. You will find multiple applications, solutions, code examples. Navigate using the tag cloud or search using specific criteria

How to generate a different PWM's signals with an arduino based PLC


Introduction

On this example is explained how to generate a PWM with M-DUINO Family  and ARDBOX family equipments.


Requirements


Ethernet or 20 I/Os PLC:      Ethernet PLC        20 I/Os PLC


Methodology


Using our equipments you can generate a PWM on Digital/Analog Ports. But most of these ports have a limitation of frequency (500 Hz approx.). (PIN3 for ARDBOX) and (PIN3 and PIN2 for M-DUINO) don’t have limitation and they can generate a PWM between 100Hz (even less) and 8MHz because they are associated to a hardware timer, which helps to calculate the frequency and provides the requirements to generate a major frequency.

PIN3 for ARDBOX can work as an external output for the Timer/Counter0 Output Compare B (OC0B). And the same on M-DUINO: PIN3 can work as an external output for the Timer/Counter3 Output Compare C (OC3C) and PIN2 can work as an external output for the Timer/Counter3 Output Compare B (OC3B).

But how can we set up the frequency needed?

The microcontroller has different registers to set up the PWM signals on OCnX. In this example is showed how to work with Clear Timer on Compare (CTC mode).


ARDBOX:

Register TCCR0A controls the Output Compare pin (OC0A) behavior and the Timer/Counter0 mode of operation.

Register TCCR0B controls the Output Compare pin (OC0A) behavior, the Timer/Counter0 mode of operation and the prescaler of Timer/Counter0.

IMPORTANT: With ARDBOX if you change the prescaler of default (clk/64) functionality it also changes the time of delay functions.

CTC mode compares OCR0A register with TCNT0 (Timer/Counter), when the value is equal the uC toggles the output signal OC0A to generate the PWM.

For more information see Atmel ATmega32U4 datasheet between pages 94 and 110 for Ardbox (Arduino Leonardo).

Next is showed the implemented code to generate different frequencies on PIN3 using an Ardbox:

void setup() {
  cli();  //stop interrupts
 
  pinMode(3, OUTPUT);
  setFrequencytimer0(2000);

  sei(); //enable interrupts
}

void loop() {
}

void setFrequencytimer0(unsigned long freq) {
  TCCR0A &= 0b00001100; // Clear TCCR0A protecting the reserved bits for uC
  TCCR0A |= 0B00000010; // CTC Mode
  TCCR0B &= 0b00110000; // Clear TCCR0B protecting the reserved bits for uC
  TCCR0B |= 0b00000011; // Select prescaler of 64 and configure Mode operation (CTC)
  OCR0A = (16*10^6) / (freq*64) - 1; //124
} 

ISR(TIMER0_COMPA_vect) //function that calls a hardware timer
{//timer0 interrupt 2kHz toggles pin 3. It enters in this function every 1/2000 sec.
   analogWrite(3, 64); //PWM 25% Duty Cycle
}

 

M-DUINO:

Register TCCR3A controls the Output Compare pin (OC3B and OC3C) behavior and the Timer/Counter3 mode of operation.

Register TCCR0B controls the Output Compare pin (OC3B and OC3C) behavior, the Timer/Counter0 mode of operation and the prescaler of Timer/Counter0.

CTC mode compares OCR3A register with TCNT3 (Timer/Counter), when the value is equal the uC toggles the output signal OC3A to generate the PWM.

For more information see Atmel ATmega2560 datasheet between pages 133 and 160.

Next is showed the implemented code to generate different frequencies on PIN3:

void setup() {
  pinMode(3, OUTPUT);
  setFrequencytimer3(2000); // Value is the wished frequency, in this case 2kHz
}


void loop() {
}

void setFrequencytimer3(unsigned long freq) {
  TCCR3A &= 0b00000000; //Clear TCCR3A
  TCCR3A |= 0B01010100; // Configure OC3C (PIN3) and OC3B (PIN2) as toggle mode 
  TCCR3B &= 0b00100000; // Clear TCCR3B protecting the reserved bit for uC
  TCCR3B |= 0b11001011; // Select prescaler of 64 and configure mode operation (CTC)
  OCR3A = (16000000 / (64 * freq)) - 1;
}

ISR(TIMER3_COMPA_vect) //function that calls a hardware timer
{//timer0 interrupt 2kHz toggles pin 3. It enters in this function every 1/2000 sec.
  analogWrite(3, 192); //PWM 75% Duty Cycle
}

 

Using this steps we have generated on both sketches a PWM signal of 2KHz. But, how can we configure the desired duty cycle of the PWM?

Now we need to define which duty cycle we want for this signal of 2KHz. This is done using the analogWrite() command. 

By using this command we are telling to a PWM pin that we want to put some percentage of the signal in ON state, and the rest at OFF state. This is scaled from a value between 0 and 256, being 0 at 0%, and 256 at 100%. So for a 50% duty cycle, square signal we would need a value of 128. 25 % is a value of 64 and this way each unity adds a percentage value of 0,4%. 

See also


How to reset a PLC using the Ethernet Shield

TCP client on Arduino based PLC

How to connect an Arduino based PLC with an OPC Scada compilant

How to use MAX232 with Arduino based PLC

How to connect a bluetooth module on an Arduino based PLC

Do you want more information?

Open Source technology allows you to develop your installations.

Just fill the form and we will contact you as soon as we can.

Send