Thread: programming speedometer

  1. #1
    Registered User
    Join Date
    Apr 2009
    Posts
    3

    programming speedometer

    ive been trying to program a simple speedometer for a bike. as of right now the hardware end is all finished. got a hall effect sensor as the input, and a 2digit 7-segment display. using a pic16f690 microcontroller.

    so far ive written a short bit of code to test the 7-segment display. what i need help with is making the 7-segment display use the input from the hall effect sensor, whichll be a frequency.

    can anyone point me in the right direction (or help me) to make the 7-segment display not run through 0-99, but rather display the frequency coming off the hall effect sensor?

    thanks

    Code:
    unsigned int advalue = 0;			//variable to store potentiometer input
    unsigned char digit, digit1, digit2;	//used to store BCD values for display
    int x,y;
    
    main()
    {
    ANSEL =	0;			// No analog inputs yet.
    CM1CON0 = 0;			// Initialize Comparator 1 off
    CM2CON0 = 0;			// Initialize Comparator 2 off
    
    PORTA = 0;			//Clear PortA
    TRISA = 0xFF;		//All PortA I/O inputs
    
    ANSEL = 0b00000000;		//Analog input AN0 (potentiometer) 
    ADCON0 = 0b00000001;	//AtoD on, Left justified, Channel AN0/RA0 selected initially
    ADCON1 = 0b00111000;	//Internal RC clock for A/D conversion
    
    PORTC = 0x0F;			//Initialize PortC port
    TRISC = 0x00;			//All PortC I/O outputs
    
    
    while(1==1)				//loop forever
    	{
    
    	for(x=0;x<=99;x++)
    		{	
    	   	   	ADCON0 = 0b00000001;	//AtoD on, Left justified, Channel AN0/RA0 selected initially
    			pause(1);
    			GODONE = 1;	    //Start A/D process; need to account for overhead of ADC.
    				while (GODONE ==1)	//wait for A/D to finish (average time?)
    				{
    				}
    
    			advalue = ADRESH;
    
    		for(y=0;y<=advalue;y++)
    		{
    		digit1=0;
    		digit2=0;
    		digit = x;
    		while(digit >= 10) 
    		{
    			digit2++;
    			digit=digit-10;
    		}
    		digit1=digit;
    
    		digit = digit1<<4;
    		digit = (digit|0b00000111)&0b11111110;
    		PORTC = digit;
    		pause(1);
    
    		digit = digit2<<4;
    		digit = (digit|0b00000111)&0b11111101;
    		PORTC = digit;
    		pause(10);
    
    
    		}
    		}
    		continue;
    	}	//End while
    
    }	//end main

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    I assume you're able to read what number the frequency is, yes? If so, assuming those loops are doing your math correctly, and that you don't need a decimal place, replace:
    Code:
    advalue = ADRESH;
    With:
    Code:
    advalue = FREQUENCY;
    Where FREQUENCY is whatever variable is storing your current frequency. Assuming your loop converts whatever number ADRESH is to its two digit integer form, that should be all you need instead. If not, replace it anyway, figure out how far off the number displayed is from the actual frequency, and adjust your math.


    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Apr 2009
    Posts
    3
    Quote Originally Posted by quzah View Post
    I assume you're able to read what number the frequency is, yes?
    unfortunately no. the output for the sensor is port RA0. once i can get it to display the output frequency from the sensor i just throw in speed= frequency * wheel circumference * 3600 to get mph.

    i guess my main question is how to alter this part of the code to have an input from RA0 as the frequency

    Code:
    main()
    {
    ANSEL =	0;			// No analog inputs yet.
    CM1CON0 = 0;			// Initialize Comparator 1 off
    CM2CON0 = 0;			// Initialize Comparator 2 off
    
    PORTA = 0;			//Clear PortA
    TRISA = 0xFF;		//All PortA I/O inputs
    
    ANSEL = 0b00000000;		//Analog input AN0 (potentiometer) 
    ADCON0 = 0b00000001;	//AtoD on, Left justified, Channel AN0/RA0 selected initially
    ADCON1 = 0b00111000;	//Internal RC clock for A/D conversion
    
    PORTC = 0x0F;			//Initialize PortC port
    TRISC = 0x00;			//All PortC I/O outputs

  4. #4
    Registered User
    Join Date
    Apr 2009
    Posts
    3
    attempt at updated code

    Code:
    void pause( unsigned short usvalue );		//Establish pause routine function
    void msecbase( void );						//Establish millisecond base function
    unsigned long capture_interval(unsigned int prescale); //
    
    unsigned long period2, RPM, SPEED;
    unsigned short period, vhigh, vlow;
    unsigned int advalue = 0;					//Create A/D storage value and clear it
    unsigned char digit, digit1, digit2;
    int x,y;
    
    
    main()
    {
    ANSEL =	0;			// No analog inputs yet.
    CM1CON0 = 0;			// Initialize Comparator 1 off
    CM2CON0 = 0;			// Initialize Comparator 2 off
    
    PORTA = 0;			//Clear PortA
    TRISA = 0xFF;		//All PortA I/O inputs
    
    ANSEL = 0b00000000;		//Analog input AN0 (potentiometer) 
    ADCON0 = 0b00000001;	//AtoD on, Left justified, Channel AN0/RA0 selected initially
    ADCON1 = 0b00111000;	//Internal RC clock for A/D conversion
    
    PORTC = 0x0F;			//Initialize PortC port
    TRISC = 0x00;			//All PortC I/O outputs
    
    CCP1CON = 0b00000101;	// configure capture feature (every rising edge)
    T1CON = 0b00110000;		// configure timer 1 (prescale by 8)
    
    
    while(1==1)				//loop forever
    	{
    
    	for(x=0;x<=99;x++)
    		{	
    	   	   	ADCON0 = 0b00000001;	//AtoD on, Left justified, Channel AN0/RA0 selected initially
    			pause(1);
    			GODONE = 1;	    //Start A/D process; need to account for overhead of ADC.
    				while (GODONE ==1)	//wait for A/D to finish (average time?)
    				{
    				}
    			period2 = 64*capture_interval(8);
    			RPM = 60000000/period2;
    			SPEED = RPM*60*0.00043495983  //rpm * 60min per hour * wheel circumference (0.000434 miles)
    			advalue = SPEED;
    
    		for(y=0;y<=advalue;y++)
    		{
    		digit1=0;
    		digit2=0;
    		digit = x;
    		while(digit >= 10) 
    		{
    			digit2++;
    			digit=digit-10;
    		}
    		digit1=digit;
    
    		digit = digit1<<4;
    		digit = (digit|0b00000111)&0b11111110;
    		PORTC = digit;
    		pause(1);
    
    		digit = digit2<<4;
    		digit = (digit|0b00000111)&0b11111101;
    		PORTC = digit;
    		pause(10);
    
    
    		}
    		}
    		continue;
    	}	//End while
    
    }	//end main
    anything, or rather, what am i doing wrong?

    thanks

  5. #5
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    That depends. What does it do, and how does that compare to what you expect it to do?


    Quzah.
    Hope is the first step on the road to disappointment.

  6. #6
    Registered User
    Join Date
    Aug 2006
    Posts
    100
    Why are you setting 'digit = x' in your for x loop?

  7. #7
    Registered User
    Join Date
    May 2009
    Posts
    4
    Quote Originally Posted by rdrast View Post
    Why are you setting 'digit = x' in your for x loop?
    Exactly what I'm thinking. If digit is going to be the output on the 7 segment led why are you setting it equal to the loop iteration rather than the Speed?

Popular pages Recent additions subscribe to a feed