C:\> Rostislav Persion's Projects

.:: PIC Speedometer ::.
Measures speed of wheel and displays a binary speed in miles per hour






This project uses a PIC microcontroller to measure the speed of rotation and then displays the miles per hour value in binary format. The above screen shot is my software running on a "Real PIC Simulator", allowing me to test the microcontroller in action without actually building anything. In the future I will connect the binary output to a 2 digit, 7 segment, LED module.

















This is a debouncing circuit that will smooth any spikes caused by imperfections in a real world switch. Debouncing can be done either with hardware or sofware. I chose the hardware aproach to make the code more readable.



HI-TECH PIC C COMPILER (PINA0 to sensor, PORTB to display)

   1:  #include <htc.h>
   2:  #define _XTAL_FREQ 8000000
   3:   
   4:  void main()
   5:  {
   6:      // init
   7:      long wheel_diameter = 26;
   8:      long time_counter = 0;
   9:      int speed = 0;
  10:   
  11:      TRISA=0XFF; // A input
  12:      TRISB=0X00; // B output
  13:   
  14:      // status
  15:      for (int i=0;i<10;i++)
  16:      {
  17:          PORTB = 255;
  18:          __delay_ms(50);
  19:          PORTB = 0;
  20:          __delay_ms(50);
  21:      }
  22:      
  23:      // measure speed
  24:      while(1)
  25:      {
  26:          time_counter = 0;
  27:          while(RA0 == 0){}
  28:          while(RA0 == 1){}
  29:          while(RA0 == 0)
  30:          {
  31:              __delay_ms(1);
  32:              if (time_counter < 5000)
  33:              {
  34:                  time_counter++;
  35:              }
  36:          }
  37:          while(RA0 == 0){}
  38:   
  39:          speed = (int)((178 * wheel_diameter) / time_counter);
  40:          PORTB = speed;
  41:          __delay_ms(1000);
  42:   
  43:      }
  44:  }


CCS PIC C COMPILER (PINA0 to sensor, PORTB to display)

   1:  #include <main.h>
   2:  #use delay(clock=8000000)
   3:  #FUSES NOWDT                    //No Watch Dog Timer 
   4:  #FUSES RC                       //Resistor/Capacitor Osc with CLKOUT 
   5:  #FUSES NOPUT                    //No Power Up Timer 
   6:  #FUSES NOPROTECT                //Code not protected from reading 
   7:  #FUSES NODEBUG                  //No Debug mode for ICD 
   8:  #FUSES NOBROWNOUT               //No brownout reset 
   9:  #FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O 
  10:  #FUSES NOCPD                    //No EE protection 
  11:  #FUSES NOWRT 
  12:     
  13:  void main(int args[])
  14:  {
  15:   
  16:     // init
  17:     long const wheel_diameter = 26;
  18:     long time_counter = 0;
  19:     long speed = 0;
  20:     
  21:     set_tris_a(0b11111111); // PORTA input
  22:     set_tris_b(0b00000000); // PORTB output
  23:     
  24:     // status
  25:     for (int i=0;i<10;i++)
  26:     {
  27:        output_b(255);
  28:        delay_ms(50);
  29:        output_b(0);
  30:        delay_ms(50);
  31:     }
  32:     
  33:     // measure speed
  34:     while(1)
  35:     {
  36:        time_counter = 0;
  37:        while(input(pin_A0) == 0){}
  38:        while(input(pin_A0) == 1){}
  39:        while(input(pin_A0) == 0)
  40:        {
  41:           delay_ms(1);
  42:           if (time_counter < 5000)
  43:           {
  44:              time_counter++;
  45:           }
  46:        }
  47:        while(input(pin_A0) == 0){}
  48:        speed = (int)((178 * wheel_diameter) / time_counter);
  49:        output_b(speed);
  50:        delay_ms(1000);
  51:     }
  52:  }


HI-TECH PIC C COMPILER - Allows you to set wheel diameter (PINA0 to sensor, PINA1 increments/sets wheel diameter, PORTB to display), saves setting to EEPROM

   1:  #include <htc.h>
   2:  #define _XTAL_FREQ 8000000
   3:   
   4:  void main()
   5:  {
   6:      // init
   7:      long wheel_diameter = EEPROM_READ(0); // Read wheel diameter from EEPROM
   8:      long time_counter = 0;
   9:      int speed = 0;
  10:   
  11:      TRISA=0XFF; // A input
  12:      TRISB=0X00; // B output
  13:   
  14:      // status
  15:      for (int i=0;i<5;i++)
  16:      {
  17:              PORTB = 255;
  18:              __delay_ms(100);
  19:              PORTB = 0;
  20:              __delay_ms(100);
  21:      }
  22:   
  23:   
  24:      // set wheel diameter, RA1 moment = increment, RA1 hold = set
  25:      int looping = 1;
  26:      int cnt = 0;
  27:      PORTB = wheel_diameter; // display new wheel diameter
  28:      while(looping == 1)
  29:      {
  30:          while (RA1 == 0) {} // wait for button to go from 0 to 1
  31:          while (RA1 == 1) // loop while button is pressed
  32:          {
  33:              __delay_ms(10);
  34:              cnt++;
  35:              if (cnt > 100) // if loop count exceeds thresh, break out
  36:              {
  37:                  looping = 0;
  38:                  break;
  39:              }
  40:          }
  41:          cnt = 0;
  42:          if (looping == 0) {break;} // break out if looping stops
  43:          wheel_diameter++; // otherwise increment wheel diameter
  44:          if (wheel_diameter > 40) // if wheel diameter exceeds limit, set to 1
  45:          {
  46:              wheel_diameter = 1;
  47:          }
  48:          PORTB = wheel_diameter; // display new wheel diameter
  49:      }
  50:      EEPROM_WRITE(0,wheel_diameter); // Write wheel diameter to EEPROM
  51:   
  52:      // status
  53:      for (int i=0;i<5;i++)
  54:      {
  55:              PORTB = 255;
  56:              __delay_ms(100);
  57:              PORTB = 0;
  58:              __delay_ms(100);
  59:      }
  60:      // measure speed
  61:      while(1)
  62:      {
  63:          time_counter = 0;
  64:          while(RA0 == 0){}
  65:          while(RA0 == 1){}
  66:          while(RA0 == 0)
  67:          {
  68:              __delay_ms(1);
  69:              if (time_counter < 5000)
  70:              {
  71:                  time_counter++;
  72:              }
  73:          }
  74:          while(RA0 == 0){}
  75:   
  76:          speed = (int)((178 * wheel_diameter) / time_counter);
  77:          PORTB = speed;
  78:          __delay_ms(1000);
  79:   
  80:      }
  81:  }


CCS PIC C COMPILER - Allows you to set wheel diameter (PINA0 to sensor, PINA1 increments/sets wheel diameter, PORTB to display), saves setting to EEPROM

   1:  #include <main.h>
   2:   
   3:  #use delay(clock=8000000)
   4:  #FUSES NOWDT                    //No Watch Dog Timer 
   5:  #FUSES RC                       //Resistor/Capacitor Osc with CLKOUT 
   6:  #FUSES NOPUT                    //No Power Up Timer 
   7:  #FUSES NOPROTECT                //Code not protected from reading 
   8:  #FUSES NODEBUG                  //No Debug mode for ICD 
   9:  #FUSES NOBROWNOUT               //No brownout reset 
  10:  #FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O 
  11:  #FUSES NOCPD                    //No EE protection 
  12:  #FUSES NOWRT                    //Program memory not write protected
  13:    
  14:   void main()
  15:   {
  16:         // init
  17:         long wheel_diameter = read_eeprom(0); // Read wheel diameter from EEPROM
  18:         long time_counter = 0;
  19:         int speed = 0;
  20:      
  21:         set_tris_a(0b11111111); // PORTA input
  22:         set_tris_b(0b00000000); // PORTB output
  23:      
  24:         // status
  25:        for (int i=0;i<5;i++)
  26:        {
  27:           output_b(255);
  28:           delay_ms(100);
  29:           output_b(0);
  30:           delay_ms(100);
  31:        }
  32:   
  33:         // set wheel diameter, RA1 moment = increment, RA1 hold = set
  34:         int looping = 1;
  35:         int cnt = 0;
  36:         output_b(wheel_diameter);
  37:         while(looping == 1)
  38:         {
  39:           while (input(pin_A1) == 0) {} // wait for button to go from 0 to 1
  40:           while (input(pin_A1) == 1) // loop while button is pressed
  41:           {
  42:              delay_ms(10);
  43:              cnt++;
  44:              if (cnt > 100) // if loop count exceeds thresh, break out
  45:              {
  46:                  looping = 0;
  47:                  break;
  48:              }
  49:           }
  50:           cnt = 0;
  51:           if (looping == 0) {break;} // break out if looping stops
  52:           wheel_diameter++; // otherwise increment wheel diameter
  53:           if (wheel_diameter > 40) // if wheel diameter exceeds limit, set to 1
  54:           {
  55:             wheel_diameter = 1;
  56:           }
  57:           output_b(wheel_diameter); // display new wheel diameter
  58:        }
  59:        
  60:        write_eeprom(0,wheel_diameter); // Write wheel diameter to EEPROM
  61:   
  62:         // status
  63:        for (int j=0;j<5;j++)
  64:        {
  65:           output_b(255);
  66:           delay_ms(100);
  67:           output_b(0);
  68:           delay_ms(100);
  69:        }
  70:         
  71:        // measure speed
  72:        while(1)
  73:        {
  74:           time_counter = 0;
  75:           while(input(pin_A0) == 0){}
  76:           while(input(pin_A0) == 1){}
  77:           while(input(pin_A0) == 0)
  78:           {
  79:              delay_ms(1);
  80:              if (time_counter < 5000)
  81:              {
  82:                 time_counter++;
  83:              }
  84:           }
  85:           while(input(pin_A0) == 0){}
  86:           speed = (int)((178 * wheel_diameter) / time_counter);
  87:           output_b(speed);
  88:           delay_ms(1000);
  89:        }
  90:    }