Regelen van de snelheid van een motor met pulsbreedtemodulatie

Alle apparaten die werken op gelijkspanning, ook wel DC-spanning genoemd, vereisen een constante ingangsspanning. Hieronder vallen heel wat elektronische componenten zoals bijvoorbeeld Lego™-motoren en LEDs. De spanning van deze componenten ligt hierbij typisch in een bepaald bereik maar kan vaak verlaagd worden. In het geval van LEDs resulteert een lagere spanning in minder licht en door de ingangsspanning over een motor te regelen kan het toerental ingesteld worden. De motor zal dan sneller of trager beginnen te draaien. De Dwengo-bibliotheek voorziet hiervoor in een aantal handige functies. Op deze pagina gaan we meer in detail en leggen we uit hoe je zelf de PWM-module van de PIC18F4550 kan configureren zodat je de snelheid van motoren gemakkelijk kan regelen.

Wanneer een PWM-signaal met erg hoge frequentie gegenereerd wordt dan lijkt het voor de motor alsof dat signaal een constante spanning heeft. Door de pulsbreedte of duty cycle van het PWM-signaal te regelen kan de amplitude van de gemiddelde spanning verhoogd of verlaagd worden. Overeenkomstig zal de motor dus sneller of trager draaien. Dit is geïllustreerd op de figuur. Hetzelfde concept kan ook gebruikt worden om bijvoorbeeld LEDs te dimmen.

Spanningsregelaar via PWM

Voor het genereren van het PWM-signaal kan je gebruik maken van interrupts of je kan gebruik maken van de PWM-module die in de PIC18F4550 is ingebouwd.

Vooraleer je de PWM-module kan configureren moet je de nodige bibliotheken inladen.

  1. #include <p18f4550.h>
  2. #include <timers.h>
  3. #include <delays.h>
  4. #include <pwm.h>

Zoals steeds is het belangrijk dat we de configuratiebits correct instellen. Hierbij speelt CCP2MX een grote rol omdat we hiermee kunnen instellen of het PWM-signaal van de tweede PWM-module op pin RC1 of op pin RB3 komt te staan. In onderstaand voorbeeld hebben we het zo ingesteld dat het tweede PWM-signaal op pin RC1 komt te staan. Het signaal van de eerste PWM-module komt altijd op pin RC2, daarvoor hoeft niets ingesteld te worden.

De configuratie van de configuratiebits ziet er dan uit als volgt:

  1. // Fuses configuration
  2. #pragma config PLLDIV = 5 // Divide by 5 (20 MHz oscillator input)
  3. #pragma config FOSC = HSPLL_HS // HS oscillator, PLL enabled, HS used by USB
  4. #pragma config IESO = OFF // Oscillator Switchover mode disabled
  5. #pragma config PWRT = OFF // PWRT disabled
  6. #pragma config BOR = OFF // Brown-out Reset enabled in hardware only (SBOREN is disabled)
  7. #pragma config WDT = OFF // HW Disabled - SW Controlled
  8. #pragma config WDTPS = 32768 // 1:32768
  9. #pragma config MCLRE = ON // MCLR pin enabled; RE3 input pin disabled
  10. #pragma config LVP = OFF // Disable low-voltage programming
  11. #pragma config CCP2MX = ON // CCP2 multiplexed to RC1 and not to RB3
  12. #pragma config PBADEN = OFF // PORB digital IO on powerup

Er kunnen twee motoren rechtstreeks op het Dwengo-bord worden aangesloten (M1 en M2 van de motor-connector). Hiervoor worden vier pinnen, RC1, RC2, RA4 en RB3, van de microcontroller gebruikt. Al deze pinnen moeten als uitgang geconfigureerd worden.

  1. TRISAbits.TRISA4 = 0;
  2. TRISBbits.TRISB3 = 0;
  3. TRISCbits.TRISC1 = 0;
  4. TRISCbits.TRISC2 = 0;

Om een DC-motor te laten draaien heb je meestal twee ingangen nodig. Hiervan fungeert één ingang als grond en de andere ingang is de ingangsspanning die de snelheid van de motor zal bepalen. Om twee motoren te laten draaien moeten we dus twee pinnen instellen als grond.

  1. PORTAbits.RA4 = 0;
  2. PORTBbits.RB3 = 0;

Naast de twee pinnen die fungeren als grond moeten we twee pinnen gebruiken als spanningsingang voor de twee motoren. Omdat we de robot sneller en trager willen laten rijden moeten de twee spanningsingangen elk afzonderlijk te regelen zijn. Zoals we eerder uitgelegd hebben doen we dit door een PWM-signaal op elk van deze pinnen te zetten. Bovendien moet het PWM-signaal voor elk van de pinnen afzonderlijk te regelen zijn. Hiervoor stellen we dus twee PWM-modules in met behulp van de functies OpenPWM1 en OpenPWM2. Aan deze functies moeten we een getal meegeven waarmee de periode van het PWM-signaal geregeld wordt volgens volgende formule: PWM-periode = ( + 1)4ToscT2Prescaler. Hierbij is ** het getal dat we meegeven aan de functie *OpenPWM1 of OpenPWM2, Tosc is de periode van de klok en is bij ons gelijk aan 1/48.000.000 seconden en T2Prescaler is een factor waarmee we de timer timer2 die gebruikt wordt door de PWM-modules kunnen vertragen. We zullen bij het instellen van timer2 kiezen voor een factor 4 (zie verder) waardoor de PWM-periode gelijk is aan 85,33 microseconden.

  1. // PWM period = (0xFF + 1)*4*Tosc*T2Prescaler
  2. OpenPWM1(0xFF); // configuring PWM module 1
  3. OpenPWM2(0xFF); // configuring PWM module 2

Vervolgens stellen we timer2 in. Deze timer wordt gebruikt door de PWM-modules om het PWM-signaal te genereren. We stellen timer2 zo in dat deze geen interrupts genereert, dat de prescaler een factor 4 is waardoor timer2 met een factor 4 vertraagd wordt en een postscaler met factor 1 (zonder vertraging).

  1. // Configuring timer 2 which provides timing for PWM
  2. // TIMER_INT_OFF: disable timer interrupt
  3. // T2_PS_1_4: Timer2 prescaling set to 4
  4. // T2_POST_1_1: Timer2 postscaling set to 1
  5. OpenTimer2(TIMER_INT_OFF & T2_PS_1_4 & T2_POST_1_1);

De snelheid van de motoren kan nu geregeld worden door de pulsbreedte van het PWM-signaal in te stellen. Het instellen van de pulsbreedte gebeurt met de functie SetDCPWM1 voor de eerste PWM-module (motor 1) en de functie SetDCPWM2 voor de tweede PWM-module (motor 2). Aan deze functies moet men een getal meegeven tussen 0 (pulsbreedte gelijk aan nul en dus geen puls) en 1023 (pulsbreedte zo breed als PWM-periode en dus motor op volle kracht) waarmee de pulsbreedte wordt bepaald.

  1. SetDCPWM1(1023); // sets PWM duty cycle 100% (full speed)
  2. SetDCPWM2(512); // sets PWM duty cycle 50% (medium speed)