Menu

all about electronic and microcontrollers
Showing posts with label PWM. Show all posts
Showing posts with label PWM. Show all posts

Tuesday, December 14, 2010

Lesson nr.20-Sound generation

Hardware setup:


Circuit Diagram:
For those who want to build it on their own breadboard or other platform, here is the electronic scheme built in Eagle Cad, free version:


Software:
Here is the C program written for MikroC PRO for PIC 2010 (version v4.15).
/*
'*******************************************************************************
'  Lesson nr.20:
'          Sound generation.
'  Done by:
'          Aureliu Raducu Macovei, 2010.
'  Description:
'          In this experiment we will work with sounds.
'          I'll show how to generate and make sound helped by microcontroller 
'          and some buttons.
'          Communication with the buzzer will be performed  at PORT RB3 ( as PWM mode).
'          The Push buttons are connected to PORT RA4 (generates Tone1), RA6
'          (generates Tone2) and RA7(generates melody2). 
'          Of course we need pull-up resistors (4k7 is required).
'  Test configuration:
'    MCU:                        PIC16F628A
'    Test.Board:                 WB-106 Breadboard 2420 dots
'    SW:                         MikroC PRO for PIC 2010 (version v4.15)
'  Configuration Word
'    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
'    Watchdog Timer:             OFF
'    Power up Timer:             Disabled
'    Master Clear Enable:        Enabled
'    Browun Out Detect:          Enabled
'    Low Voltage Program:        Disabled
'    Data EE Read Protect:       Disabled
'    Code Protect:               OFF
'*******************************************************************************
*/
void Tone1()
{
 Sound_Play(5000, 1000);         // Frequency = 659Hz, duration = 250ms
}

void Tone2() 
{
 Sound_Play(4000, 1000);         // Frequency = 698Hz, duration = 250ms
 }

void Tone3() 
{
 Sound_Play(3000, 1000);         // Frequency = 784Hz, duration = 250ms
 }

void Melody1()                  // Make funny melody 1;
{
 Tone1(); Tone2(); Tone3();
 Tone3(); Tone2(); Tone1();
 Tone1(); Tone3(); Tone2();
 Tone3(); Tone2(); Tone1(); Tone3();
 Tone1(); Tone2(); Tone3();
 Tone3(); Tone1(); Tone2(); Tone2(); Tone1();
 }

void ToneA()                    // Tone A;
{
 Sound_Play(1618, 50);          // (frequency, duration)
}

void ToneB()                    // Tone B;
{
 Sound_Play(1918, 50);          // (frequency, duration)
}

void ToneC()                    // Tone C;
{
 Sound_Play(2212, 50);          // (frequency, duration)
}

void Melody2()                  // Make funny melody 2;
{
 unsigned short i;
 for (i = 12; i > 0; i--)
 {
  ToneA(); ToneB(); ToneC();
  }
 }

void main() 
{
 CMCON |=7;                     // Disable comparator
 TRISB = 0xF0;                  // Pins RB7-RB4 are configured as inputs,
                                // RB3 is configured as an output
 Sound_Init(&PORTB, 3);
 Sound_Play(5000,100);          // Start with this song (frequency, duration)

 while (1)                      // infinite loop
 {
  if (Button(&PORTA,4,1,0))     // RB4 generates Tone1
  Tone1();
  
  if (Button(&PORTA,6,1,0))     // RB6 generates Tone2
  Tone2();

  if (Button(&PORTA,7,1,0))     // RA7 generates melody 2
  {
   Melody2();
   Delay_ms(1500);              // Delay 1,5s
   Melody2();
   Delay_ms(1500);              // Delay 1,5s
   Melody2();
   }
  }
}

Sunday, October 17, 2010

Lesson nr.10-Software PWM & RGB LED

Hardware setup:
This time we will implement software PWM mode, to control the light intensity of an RGB Led (Red Green Blue, which represents a pixel) .PORT RA0~RA2 and PORT RB0~RB2 will be used for this experiment.
Port B is used, to see more easier transitions between RBG colors.



Circuit Diagram:
For those who want to build it on their own breadboard or other platform, here is the electronic scheme built in Eagle Cad, free version:



Software:
Here is the C program written for MikroC PRO for PIC 2010 (version v4.15).
/*
'*******************************************************************************
'  Lesson nr.10:
'          Software PWM & RGB LED
'  Written by:
'          Aureliu Raducu Macovei, 2010.
'  Description:
'          In this experiment we will show how to implement software PWM to
'          control an RBG LED. PORT RA0~RA2 and PORT RB0~RB2 will be used for this experiment.
'  Test configuration:
'    MCU:                        PIC16F628A
'    Test.Board:                 WB-106 Breadboard 2420 dots
'    SW:                         MikroC PRO for PIC 2010 (version v4.15)
'  Configuration Word
'    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
'    Watchdog Timer:             OFF
'    Power up Timer:             Disabled
'    Master Clear Enable:        Enabled
'    Browun Out Detect:          Enabled
'    Low Voltage Program:        Disabled
'    Data EE Read Protect:       Disabled
'    Code Protect:               OFF
'*******************************************************************************
*/
// LED RGB module connections
sbit RED1 at RA0_bit;
sbit GREEN1 at RA1_bit;
sbit BLUE1 at RA2_bit;
sbit RED2 at RB0_bit;
sbit GREEN2 at RB1_bit;
sbit BLUE2 at RB2_bit;

sbit RED1_Direction at TRISA0_bit;
sbit GREEN1_Direction at TRISA1_bit;
sbit BLUE1_Direction at TRISA2_bit;
sbit RED2_Direction at TRISB0_bit;
sbit GREEN2_Direction at TRISB1_bit;
sbit BLUE2_Direction at TRISB2_bit;
// End LED RGB module connections

int i = 0 ,PWN_COUNTER = 256;

void PWM_FADE_0_TO_1(void);
void PWM_FADE_1_TO_0(void);
void Delay(int num);

void main(void)
{
 CMCON  |= 7;                     //  Comparator is Off
 TRISA = 0;
 PORTA = 0;
 TRISB = 0;
 PORTB = 0;

 while(1){
          PWM_FADE_0_TO_1();
          PWM_FADE_1_TO_0();
          }
}

void PWM_FADE_0_TO_1(void)        // Duty cycle -  0%  to  100%
{
 for (i = 0; i < PWN_COUNTER; i++)
 {
  RED1 = 0;
  RED2 = 0;
  Delay(PWN_COUNTER - i);
  RED1 = 1;
  RED2 = 1;
  Delay(i);
  }
 for (i = 0; i < PWN_COUNTER; i++)
 {
  GREEN1 = 0;
  GREEN2 = 0;
  Delay(PWN_COUNTER - i);
  GREEN1 = 1;
  GREEN2 = 1;
  Delay(i);
  }
 for (i = 0; i < PWN_COUNTER; i++)
 {
  BLUE1 = 0;
  BLUE2 = 0;
  Delay(PWN_COUNTER - i);
  BLUE1 = 1;
  BLUE2 = 1;
  Delay(i);
  }
}

void PWM_FADE_1_TO_0(void)         // Duty cycle -  100% to 0%
{
 for (i = 0; i < PWN_COUNTER; i++)
 {
  RED1 = 1;
  RED2 = 1;
  Delay(PWN_COUNTER - i);
  RED1 = 0;
  RED2 = 0;
  Delay(i);
  }
 for (i = 0; i < PWN_COUNTER; i++)
 {
  GREEN1 = 1;
  GREEN2 = 1;
  Delay(PWN_COUNTER - i);
  GREEN1 = 0;
  GREEN2 = 0;
  Delay(i);
  }
 for (i = 0; i < PWN_COUNTER; i++)
 {
  BLUE1 = 1;
  BLUE2 = 1;
  Delay(PWN_COUNTER - i);
  BLUE1 = 0;
  BLUE2 = 0;
  Delay(i);
  }
}

void Delay(int num)
{
 while(num>0)
 num--;
}

Lesson nr.09-Using PWM to control DC Motor Speed

Hardware setup:
In this experiment we will work again with PWM, but this time, as a consumer, I will use a DC (Direct Current) motor. To avoid burning RB3 port, due to high consumption of the motor, consumption which can not be given by the port of the microcontroller, we will use an extension consisting of a transistor (our case, BC547/NPN) connected in switching mode (ON / OFF ). The current to drive the motor is provided by the collector current in the transistor. The diode is for EMF (ElectroMagnetic Field) protection. Protection provided to our transistor. I will use a small 5V DC motor from an old CD-Rom.



Circuit Diagram:
For those who want to build it on their own breadboard or other platform, here is the electronic scheme built in Eagle Cad, free version:


Software:
Here is the C program written for MikroC PRO for PIC 2010 (version v4.15).
/*
'*******************************************************************************
'  Lesson nr.09:
'          Using PWM to control DC Motor Speed
'  Written by:
'          Aureliu Raducu Macovei, 2010.
'  Description:
'          In this experiment we will show how to work with module CCP1 as PWM mode.
'          The PORT RB3 is used for this experiment (as output, for DC Motor)
'          and RA4-RA6 (as imput, for buttons) which controls the pulse width.
'  Test configuration:
'    MCU:                        PIC16F628A
'    Test.Board:                 WB-106 Breadboard 2420 dots
'    SW:                         MikroC PRO for PIC 2010 (version v4.15)
'  Configuration Word
'    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
'    Watchdog Timer:             OFF
'    Power up Timer:             Disabled
'    Master Clear Enable:        Enabled
'    Browun Out Detect:          Enabled
'    Low Voltage Program:        Disabled
'    Data EE Read Protect:       Disabled
'    Code Protect:               OFF
'*******************************************************************************
*/
// LCD module connections
sbit LCD_RS at RB5_bit;                 // LCD_RS assigned to PORT RB5;
sbit LCD_EN at RB6_bit;                 // LCD_EN assigned to PORT RB6;
sbit LCD_D4 at RB0_bit;                 // LCD_D4 assigned to PORT RB0;
sbit LCD_D5 at RB1_bit;                 // LCD_D5 assigned to PORT RB1;
sbit LCD_D6 at RB2_bit;                 // LCD_D6 assigned to PORT RB2;
sbit LCD_D7 at RB4_bit;                 // LCD_D7 assigned to PORT RB4;

sbit LCD_RS_Direction at TRISB5_bit;    // LCD_RS assigned to TRIS B5;
sbit LCD_EN_Direction at TRISB6_bit;    // LCD_EN assigned to TRIS B6;
sbit LCD_D4_Direction at TRISB0_bit;    // LCD_D4 assigned to TRIS B0;
sbit LCD_D5_Direction at TRISB1_bit;    // LCD_D5 assigned to TRIS B1;
sbit LCD_D6_Direction at TRISB2_bit;    // LCD_D6 assigned to TRIS B2;
sbit LCD_D7_Direction at TRISB4_bit;    // LCD_D7 assigned to TRIS B4;
// End LCD module connections

char message1[]="ON ";
char message2[]="OFF";

unsigned short Last_Duty, Current_Duty;
void main()                             // main;
{
 CMCON |= 7;                            // turn off analogue comparator and make PORTA to digital I/O;
 TRISA4_bit=1;
 TRISA6_bit=1;
 PORTA = 0;
 TRISB = 0;                             // make rb3 as output;
 PORTB = 0;                             // turn off LEDs on PORTB;
 Current_Duty = 0;                      // Initial value of variable current_duty;
 Last_Duty = 0;                         // Reset variable last_duty;
 
 Lcd_init();
 Lcd_cmd(_LCD_Clear);
 Lcd_cmd(_LCD_Cursor_Off);
 Lcd_out(1,6,"PWM and");
 Lcd_out(2,2,"DC Motor Speed");
 Delay_ms(3000);
 Lcd_cmd(_LCD_clear);
 Lcd_out(1,1,"switch1:");
 Lcd_out(2,1,"switch2:");

 Pwm1_Init(5000);                       // PWM module initialization (5KHz);
 Pwm1_Start();                          // Start PWM1 module;
 Pwm1_Set_Duty(Last_Duty);
 do {
     while(Last_Duty >= 0 <= 255)
     {
      if (Button(&PORTA, 4,1,0))
      {
       Last_Duty = Last_Duty + 5;       // If the button connected to RA4 is pressed
       Pwm1_Set_Duty(Last_Duty);
       Lcd_out(1,9,message1);
       }
      else
      Lcd_out(1,9,message2);
      Delay_ms(100);

      if (Button(&PORTA, 6,1,0))
      {
       Last_Duty = Last_Duty - 5;       // If the button connected to RA6 is pressed
       Pwm1_Set_Duty(Last_Duty);
       Lcd_out(2,9,message1);
       }
      else
      Lcd_out(2,9,message2);
      Delay_ms(100);
      }
     Delay_ms(200);                     // 200mS delay
     } while(1);                        // Do forever;
}                                       // End.

Lesson nr.08-Using PWM to control LED brightness

Hardware setup:
Like in the last Lesson, nr.07, we will work with CCP1 in PWM mode, to control the luminous intensity of a L.E.D, but here we will not use buttons to vary the width form of our signal. The pulse width will automatically vary between 0% and 100% and vice versa.
Button S1 and (pull-up) resistance with value of 4.7 K will provide the manual reset mode to the microcontroller.



Circuit Diagram:
For those who want to build it on their own breadboard or other platform, here is the electronic scheme built in Eagle Cad, free version:



Software:
Here is the C program written for MikroC PRO for PIC 2010 (version v4.15).
/*
'*******************************************************************************
'  Lesson nr.08:
'          Using PWM to control LED brightness
'  Written by:
'          Aureliu Raducu Macovei, 2010.
'  Description:
'          In this experiment we will work with module CCP1 as PWM mode, to 
'          control LED brightness. PORT RB.3 will be used for this experiment.
'  Test configuration:
'    MCU:                        PIC16F628A
'    Test.Board:                 WB-106 Breadboard 2420 dots
'    SW:                         MikroC PRO for PIC 2010 (version v4.15)
'  Configuration Word
'    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
'    Watchdog Timer:             OFF
'    Power up Timer:             Disabled
'    Master Clear Enable:        Enabled
'    Browun Out Detect:          Enabled
'    Low Voltage Program:        Disabled
'    Data EE Read Protect:       Disabled
'    Code Protect:               OFF
'*******************************************************************************
*/
unsigned short i;

void main()             // Main;
{
 TRISB3_bit = 0;        // RB.3 is output;
 PORTB = 0;             // Set PORTB to 0;

 Pwm1_Init(5000);       // Initialize PWM module at 5KHz;
 Pwm1_Start();          // Start PWM;

 do {
     while(i<255){                        // As long as i<255;
                  i = i+1;                // Increment i with 1;
                  Pwm1_Set_Duty(i);       // Set pwm duty;
                  Delay_ms(8);            // 5ms delay;
                  }
     Pwm1_Stop;                           // Stop pwm;
     Delay_ms(5);                         // 5ms delay;
     Pwm1_Start;                          // Start pwm;
     Delay_ms(5);                         // 5ms delay;
     
     while(i>0){                          // As long as i>0;
                i = i-1;                  // decrement i with 1;
                Pwm1_Set_Duty(i);         // Set pwm duty;
                Delay_ms(5);              // 5ms delay;
                }
     Pwm1_Stop;                           // Stop pwm;
     Delay_ms(100);                       // 100ms delay;
     } while(1);                          // Do forever;
}                                         // End.

Lesson nr.07-PWM & Push Button

Hardware setup:
In this experiment we will use the CCP1 as a PWM to control the power to a L.E.D. PWM stands for the Pulse Width Modulation where the width of a digital waveform is varied to control the power delivered to a load (in this case an L.E.D). The underlying principle in the whole process is that the average power delivered is directly proportional to the modulation duty cycle. The term duty cycle describes the proportion of on time to the regular interval or period of time; a low duty cycle corresponds to low power, because the power is off for most of the time. Duty cycle is expressed in percent, 100% being fully on and 0% means off.


Trough  hardware configuration of the microcontroller we will deduct to use the PORT RB3 as PWM output.
Button S1 and (pull-up) resistance with value of 4.7 K will provide the manual reset mode to the microcontroller.
Buttons S2 and S3 will vary the width form of our signal.
ICSP connector provides the connection between the programmer (PicKit 2) and microcontroller (PIC16F628A).



Circuit Diagram:
For those who want to build it on their own breadboard or other platform, here is the electronic scheme built in Eagle Cad, free version:


Software:
Here is the C program written for MikroC PRO for PIC 2010 (version v4.15).
/*
'*******************************************************************************
'  Lesson nr.07:
'          PWM & Push Button
'  Written by:
'          Aureliu Raducu Macovei, 2010.
'  Description:
'          In this experiment we will show how to work with module CCP1 as PWM mode.
'          The PORT RB3 is used for this experiment (as output, for a led)
'          and RA6-RA7 (as imput, for buttons).
'  Test configuration:
'    MCU:                        PIC16F628A
'    Test.Board:                 WB-106 Breadboard 2420 dots
'    SW:                         MikroC PRO for PIC 2010 (version v4.15)
'  Configuration Word
'    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
'    Watchdog Timer:             OFF
'    Power up Timer:             Disabled
'    Master Clear Enable:        Enabled
'    Browun Out Detect:          Enabled
'    Low Voltage Program:        Disabled
'    Data EE Read Protect:       Disabled
'    Code Protect:               OFF
'*******************************************************************************
*/
unsigned short last_duty, current_duty;
void main()                 // main;
{
 CMCON |= 7;                // turn off analogue comparator and make PORTA to digital I/O;
 trisb3_bit = 0;            // make rb3 as output;
 portb = 0;                 // turn off LEDs on PORTB;
 current_duty = 0;          // Initial value of variable current_duty;
 last_duty = 0;             // Reset variable last_duty;
 pwm1_init(5000);           // PWM module initialization (5KHz);
 pwm1_start();              // Start PWM1 module;
 pwm1_set_duty(last_duty);
 do {
     while(last_duty>0<255){
                            if (Button(&PORTA, 6,1,0))
                            last_duty = last_duty +2;       // If the button connected to 
                                                            // RA0 is pressed
                            Pwm1_Set_Duty(last_duty);
                            delay_ms(100);

                            if (Button(&PORTA, 7,1,0))
                            last_duty = last_duty -2;       // If the pressed button is 
                                                            // connected to RA1
                            Pwm1_Set_Duty(last_duty);
                            delay_ms(100);
                            }
     delay_ms(200);                       // 200mS delay
     } while(1);                          // Do forever;
}                                         // End.