Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Display the Speed of a small propellers using a PIC18F452

Status
Not open for further replies.

Franck84

Newbie level 4
Joined
Feb 5, 2012
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,415
Hi,

My name is Franck. I want to display on LCD the speed of a propeller using a C program via a PIC18F452.
I put a small dc motor connected to the propeller and add a tiny magnet on one blade.
For one revolution of the propeller I obtain a pulse (from 0 to 5V) using a hall effect sensor.

The problem is I don't know how convert these pulses into a smooth increase speed. I was thinking about converting the pulses into a average linear voltage and than use a speed formula on the program part to transfert the voltage into a speed. But I did not find the right ressources to help me on that.

If someone can give me a help that will be super cool.

Thanks
 

Frank84,
Sounds like quite a good idea to me, but I'm afraid my know how is too elementary for me to be able to help.
There are several well tried low cost optional solutions of course but I'm sure you are aware of these.
Maybe if you explain why you want to pursue this approach help might be a bit more forthcoming.
Good luck
 

Hi,

My name is Franck. I want to display on LCD the speed of a propeller using a C program via a PIC18F452.
I put a small dc motor connected to the propeller and add a tiny magnet on one blade.
For one revolution of the propeller I obtain a pulse (from 0 to 5V) using a hall effect sensor.

The problem is I don't know how convert these pulses into a smooth increase speed. I was thinking about converting the pulses into a average linear voltage and than use a speed formula on the program part to transfert the voltage into a speed. But I did not find the right ressources to help me on that.

If someone can give me a help that will be super cool.

Thanks

You can set up some of the digital input registers as counters that interrupt after a certain number of pulses is reached. It's been awhile since I did this with a PIC. If I recall correctly, you set up a global variable with (max_count - desired_count) as it's initial value. Say for a 16-bit MCU, the max count is 65535. If you want to count 1000 pulses before triggering the counter-reset interrupt, you'd set up the global variable with 64535. The input pulses feed into a digital input pin that is configured as an interrupt for the counter ISR (Interrupt Service Routine). When a pulse is received, the ISR function says to increment the global variable. When the global variable overflows (65535 = 1111 1111 1111 1111, so +1 = 0000 0000 0000 0000; thus the variable "overflows" and returns to zero). This overflow event triggers another ISR, which does something like check the current time, subtract it from the time stored when the counter was initialized, do a little math and display it to an LCD. (Time now - time then)/1000 = seconds per 1000 revs, which can be easily converted into RPMs with a little algebra.

That's the rough and dirty of the concept. For implementation, I'd suggest you search these forums for keywords like PIC, 16, counter, interrupt, ISR, interrupt handler, etc. I'm sure someone has some code on here, or on the web on how to set up a counter.

My memory or implementation may not be 100% correct, but I think it should give you a good place to get started. The nice thing about interrupt routines is that they are only called as needed (when a pulse comes in). For each pulse, the MCU will pause what it's doing, jump into the ISR function, add 1 to an integer variable, then it will go back to whatever code it was processing before.
 

Thanks Peterlonz and Enjunear to have replied. Enjunear, Great informations.I will try to make it.Thanks
 

Need some help.Here is my program to measure the speed of the propeller using the interrupt registers and Timers. I'm not very good in programming so It took me a lot of time to understand the interrupts.
Here is what I have done so far. Please feel free to modify it and to ask me any question.

1)For the time, I set the Timer0 as a timer (60 seconds)
2)With one revolution(1 pulses) of the propeller I get the Start_time (current time of the Timer0)
3)After five Revolutions(5 pulses) I get the End_time(current time of the Timer0), These 5 pulses are counted via Timer1 but I'm not sure about how to set the TMR1H and TMR1L to write 65532 into it.
4) Then I work out the Speed.


//I need to put the "#include" and the declarations.
//May be I will need to use "#define"
#pragma Interrupt ISR


unsigned char counter=0;//Overflow counter
unsigned char counter_second=0;
unsigned int counter_overflow=1;

//Main Interrupt Service Routine (ISR)
void ISR()
{

// TIMER0 is used to count in Second.
if(TMR0IE && TMR0IF) //TNR0IF set a flag at each overflow.
{
if(counter_overflow==76)// After 76 overflow of the Timer0 that is 1 second
//TMR0 Overflow ISR
{
counter_second++; //Increment by 1 second at each Over Flow of the Counter
}
if (counter_second==60)
{
counter_second=0; //Reset the counter after 60 Seconds.
}
INTCON.TMR0IF=0;
}



if(TMR1H==65533) // The first pulse makes the if condition true. The counter TIMER1 Module goes from 65532 to 65536.
{
Start_time=counter_second; // Take the actual time
INTCON.TMR0IF=0;
}


if(TMR1IE && TMR1IF)
{
End_time=counter_second;

Time= Start_time-End_time;

Speed = REV/Time;

PIR1.TMR1IF=0; // Turn off the flag on the register PIR1(Peripheral Interrupt Request (Flag)register.
}

}
}

////////////////////////////////////////////////////////////////////////////////////////////
// I need to find the equivalent coding for the C18 compiler and to determine the jobs of each
//timers: TIMER0, TIMER1, TIMER2. Because now the TIMER0 the code I have use TIMER0 for 3 differents use I need to separate them to different timers.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void main()
{
//Setup Timer0

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Register T0CON (Setting for the time) //
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
T0PS0=1; //Prescaler is divide by 256
T0PS1=1;
T0PS2=1;

PSA=0; //Timer Clock Source is from Prescaler
T0CS=0; //It means TIMER0 works in "Timer mode" and Prescaler gets clock from FCPU (5MHz)->20MHz/4
T08BIT=1; //8 BIT MODE
TMR0ON=1; //Now start the timer! (It runs itself)

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Register T1CON (Setting for the time) //
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


T1OSCEN=0; // The inverter and the feedback resistor are turned off. This eliminates power drain
TMR1CS=1;

T1CKPS0=0; // For T1CKPSO and T1CKPS1 equal to zero, the prescaler is 1:1, which means there is no impact on the FCPU/4
T1CKPS1=0;

T1SYNC=1; // Do not synchronize external clock input
TMR1CS=1;

TMR1ON=1; // Enables Timer1

RD16=1; // Enables register Read/Write of Timer1 in one 16-bit operation (Check it because there is possibility of two 8-bit)


TMR1H=65532; // Initialisation of the TIMER1 at 65532.After counting 65536 a flag is polled (overflow of the register)

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Register INTCON //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

TMR0IE=1; //Enable TIMER0 Interrupt
PEIE=1; //Enable Peripheral Interrupt
GIE=1; //Enable INTs globally

//////////////////////////////////////////////////////////////
//Need to set Timer2 at 251 intially before it reachs the overflow means 5 pulses has been counted and a flag(TMR2IF) alert the measure of the End_time within the ISR.
////////////////////////////////////////////////////////////////////////


while(1); // End of program (Everythings runs by itself)

}


//Need to find how to write on 16 Bit register TMR1 (TMR1H and TMR1L) see line 92
// Need to implement a Watchdog to check if the proppeller turn. The Watch dog polled a flag if there is not 5 pulses within a period. This flag in a If condition has a single instruction which is speed =0)
//Need to put the "# include" and may be some "#define" for the constant like TMR1L= 65532

---------- Post added at 00:13 ---------- Previous post was at 00:06 ----------

Do not pay attention to comments when I talk about timer2 because I'm only using Timer0 (for the time)and Timer1 (to count the pulses)
I didn't put yet the correct "#include" and "declarations"
 

Hi,

I just made the program a bit more clean including "#includes", "Declarations" and removing useless comments. The build up via the compiler C18 (MPLAB) works but I still don't know how to write into the Register TMR1 to obtained a flag after the 5 pulses .


// Hall_Effect.c by FK DOTSOU, 16 Feb 2012
#include <p18f452.h>
#pragma config WDT=OFF , OSC=EC , PWRT = ON, LVP=OFF
#include <timers.h>
#include <delays.h>


#pragma interrupt ISR


unsigned char counter=0;//Overflow counter
unsigned char counter_second=0;
unsigned int counter_overflow=1;
unsigned int Start_time;
unsigned int End_time;
unsigned int Time;
unsigned int Rev;
unsigned int Speed;
unsigned int Pulse;

//Main Interrupt Service Routine (ISR)
void ISR(void)
{

// TIMER0 is used to count in Second.
if(INTCONbits.TMR0IE==1 && INTCONbits.TMR0IF==1) //TNR0IF set a flag at each overflow.
{
if(counter_overflow==76)// After 76 overflow of the Timer0 that is 1 second
//TMR0 Overflow ISR
{
counter_second++; //Increment by 1 second at each Over Flow of the Counter
}
if (counter_second==60)
{
counter_second=0; //Reset the counter after 60 Seconds.
}
INTCONbits.TMR0IF=0;
}



if(TMR1H==65533) // The first pulse makes the if condition true. The counter TIMER1 Module goes from 65532 to 65536.
{
Start_time=counter_second; // Take the actual time
INTCONbits.TMR0IF=0;
}


if(PIE1bits.TMR1IE && PIR1bits.TMR1IF)
{
End_time=counter_second;

Time= Start_time-End_time;

Speed = Rev/Time;

PIR1bits.TMR1IF=0; // Turn off the flag on the register PIR1(Peripheral Interrupt Request (Flag)register.
}

if(counter_second==5&&PIR1bits.TMR1IF==0) /* Reset the speed to 0 if 5 pulses are not made within 5 Seconde (Kind of Watchdog)
otherwise the variable "Speed" will show the last measure even if the propeller is not turning anymore*/
{
Speed=0;
}
}


void main()
{
//Setup Timer0

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Register T0CON (Setting for the time) //
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
T0CONbits.T0PS0=1; //Prescaler is divide by 256
T0CONbits.T0PS1=1;
T0CONbits.T0PS2=1;

T0CONbits.PSA=0; //Timer Clock Source is from Prescaler
T0CONbits.T0CS=0; //It means TIMER0 works in "Timer mode" and Prescaler gets clock from FCPU (5MHz)->20MHz/4
T0CONbits.T08BIT=1; //8 BIT MODE
T0CONbits.TMR0ON=1; //Now start the timer! (It runs itself)

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Register T1CON (Setting for the counter) //
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


T1CONbits.T1OSCEN=0; // The inverter and the feedback resistor are turned off. This eliminates power drain
T1CONbits.TMR1CS=1;

T1CONbits.T1CKPS0=0; // For T1CKPSO and T1CKPS1 equal to zero, the prescaler is 1:1, which means there is no impact on the FCPU/4
T1CONbits.T1CKPS1=0;

T1CONbits.T1SYNC=1; // Do not synchronize external clock input
T1CONbits.TMR1CS=1;

T1CONbits.TMR1ON=1; // Enables Timer1

T1CONbits.RD16=1; // Enables register Read/Write of Timer1 in one 16-bit operation (Check it because there is possibility of two 8-bit)


TMR1H=65532; // Initialisation of the TIMER1 at 65532.After counting 65536 a flag is polled (overflow of the register)

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Register INTCON //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

INTCONbits.TMR0IE=1; //Enable TIMER0 Interrupt
INTCONbits.PEIE=1; //Enable Peripheral Interrupt
INTCONbits.GIE=1; //Enable INTs globally

while(1); // End of program (Everythings runs by itself)

}


//Need to find how to write on 16 Bit register TMR1 (TMR1H and TMR1L) see line 92
//Need to put the "# include" and may be some "#define" for the constant like TMR1L= 65532

---------- Post added at 03:48 ---------- Previous post was at 02:59 ----------

I've rectified some error in the ISR

void ISR(void)
{

// TIMER0 is used to count in Second.
if(INTCONbits.TMR0IE==1 && INTCONbits.TMR0IF==1) //TNR0IF set a flag at each overflow.
{
counter_overflow= counter_overflow++;
if(counter_overflow==76)// After 76 overflow of the Timer0 that is 1 second
//TMR0 Overflow ISR
{
counter_second++; //Increment by 1 second at each Over Flow of the Counter
counter_overflow=0;
}
if (counter_second==60)
{
counter_second=0; //Reset the counter after 60 Seconds.
}
INTCONbits.TMR0IF=0;
}
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top