![]() | ![]() | ![]() |
| | |||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
| | Thread Tools | Display Modes |
| | (permalink) |
| Experienced Member | Microcontroller = PIC16F877A Compiler = MikroBasic Output on PC through SerialPort (cuz i have not LCD) Crystal Frequency = 20MHz Instruction Cycle Time = 200 nano Seconds For lower Speed, I will do: Measuring the Period of a Square Wave For Higher Speed, I will do: Measuring the Period of a Square Wave with Averaging First About Hardware:-I am using a comparator LM393. ![]() As light strike on PhotoDiode, comparator's output goes LOW to HIGH. We will count time periode b/w two Egdes and measure RPM according to it. Second: About Method of Measuring RPM. PIC will be in Capture Mode. It will capture Time b/w two edges and convert this time into RPM. I am using TIMER1 with 1:8 Prescale value. Instruction Cycle Time = 200 nano Seconds. TIMER1 value = 1 means 1.6 microSeconds has been elapsed because of 1:8 PreScaler. Am i right!!! Now some math: x is the time periode "T". x is the time b/w the two Edges and it's value in 1.6 microSeconds ![]() Now Program Code: program RPM_Counter
' variables declaration
Dim i, j, UART_Byte, Over_Flow, Averaging As Byte
Dim Digit as Byte[5]
Dim T As Longint[2]
Dim Capture As word absolute $15
Dim RPM, Period As Longint
'sub procedure procedure_name ' procedures declaration
sub procedure interrupt
if TestBit(PIR1,CCP1IF) = 1 then 'Capture mode Interrupt Flag
IF i > 1 Then
i = 0
End if
T[i] = ( (Over_Flow * 65535) + Capture )
Inc(i)
PIR1.CCP1IF = 0
end if
if TestBit(PIR1,TMR1IF) = 1 then 'TMR1 Interrupt Flag
Inc(Over_Flow)
PIR1.TMR1IF = 0
end if
end sub
Sub procedure Delay_313
Delay_ms(313)
End Sub
'end sub
'sub function function_name ' functions declaration
'end sub
main: ' main program body
Delay_313 'For Stability in Supply
TRISC = 255 ' PORTC all Inputs
PORTC = 0 ' PORTC = 0
T1CON = %00110000 'TIMER1 CONTROL REGISTER
CCP1CON = %00000101
INTCON.GIE = 1
INTCON.PEIE = 1
Averaging = 0
USART_init(19200) ' initialize USART module
Reset_All:
PIE1.CCP1IE = 0 'CCP1 Interrupt Enable bit
T1CON.TMR1ON = 0 'Timer1 On bit
TMR1H = 0
TMR1L = 0
Over_Flow = 0
ReStart:
T1CON.TMR1ON = 1 'Timer1 On bit
PIE1.CCP1IE = 1 'CCP1 Interrupt Enable bit
Delay_313 'Aquire The values of T0 and T2
Convert_RPM:
Period = T[1] - T[0] 'Subtract saved captured time (T0) from
'captured time (T1) and store
IF Averaging = 1 Then 'if CCP1CON = every 16 edge the divide by 16
Period = Period / 16
End IF
IF Period < 75000 Then ' If RPM > 500 then next time
CCP1CON = %00000111 ' Caculate every 16th Egde
Averaging = 1 ' and Measure RPM with Averaging
else ' IF RPM < 500 then next time
CCP1CON = %00000101 ' calculate every rising edge
Averaging = 0 ' Measure RPM without Averaging
End If
RPM = 37500000 / Period 'Convert Time Period in Round/Minute
Into_Digit:
Digit[0] = RPM Div 10000 mod 10
Digit[1] = RPM Div 1000 mod 10
Digit[2] = RPM Div 100 mod 10
Digit[3] = RPM Div 10 mod 10
Digit[4] = RPM mod 10
UsartWrite:
Usart_Write(0x52) ' "R" For indication of RPM
For j = 0 To 4 step 1
UART_Byte = Digit[j] + 48 ' Add 48 for converting into ASCII
Usart_Write(UART_Byte)
Next j
Usart_Write(0x0D) 'CR
Usart_Write(0x0A) 'LF
Goto Reset_All
end. ' end of program Am I Right!!! Muhammad Ahmed. |
| | |
| | (permalink) |
| Experienced Member | Ooo Yes. It is my 350 Post. Plz Find the Error in above project and i will try to remove them. |
| | |
| | (permalink) |
| Experienced Member | Perhaps analyzing your own code would be a great place to start. Simulate it in real life, grind out a few errors, and then ask everyone to have a look. Asking people to find errors in a large program that we have had no involvement in is like asking what a painting looks like with the paint in tins still Unless of course people have a spare hour or two too delve into your train of thought and programming techniques
__________________ Spency. PIC Micro's - Your mind is the limit PIC's and interfacing with other devices - a PIC Basic Guide @ digital-diy.net |
| | |
| | (permalink) |
| Experienced Member | The problem Code: Connected to COM2 Received: R00867 Received: R0/*(- Received: R00(*) Received: R01682 Received: R0/*)' Received: R00(*) Received: R01679 Received: R00867 Received: R00(*( Received: R01680 Received: R00867 Received: R0/*)' Received: R01681 Received: R00867 Received: R0/*(. Received: R00(*) Received: R00867 Received: R0/*)' Received: R00(*) Received: R01679 Received: R00867 Received: R00(*( Received: R01681 Received: R00867 Received: R0/*(0 Received: R01681 Received: R00867 Received: R0/*(. Received: R00(*) Received: R00867 Received: R0/*)' Received: R00(** Received: R01679 Received: R00867 Received: R00(*( Received: R01681 Received: R00867 Received: R0/*(0 I make astable circuit with 555 timer and feed it's output to PIC The frequency is 15.15Hz and it means RPM 909.. I am receiving different valuse and aproxx vale is R00867. Now the main problem is when i use every 16 edge and divide by 16 the result no be the same.. |
| | |
| | (permalink) |
| Experienced Member | Did you see my RPM program in a different recent thread? It was compiled in Proton+ It can be easily modified to allow a UART output. I have sim'd the circuit too 30000 RPM, but it should go much faster than that. No need to make things complicated when theres easier, faster ways to do something
__________________ Spency. PIC Micro's - Your mind is the limit PIC's and interfacing with other devices - a PIC Basic Guide @ digital-diy.net |
| | |
| | (permalink) |
| Experienced Member | Infact my Problem is, I am learning. Yes u r right, we can do this with ease.. (one thing more ur Proton+ is Jungly). But i want to di this with Measuring the Period of a Square Wave |
| | |
| | (permalink) |
| Experienced Member | I found in my opto RPM counter on the Mongoose; I could hook the opto directly to an I/O pin. I use a 4.7K pulldown on the emitters (not a pullup) and tie the collectors to +5. It goes from GND to 4.2V nicely. I tried using the built in comparators but didn't need them. I use RB4&5 as they will cause IRQ on change. PS the gears are IR transparent, black paint on both sides works perfectly. ![]() Last edited by blueroomelectronics; 31st March 2007 at 03:09 PM. |
| | |
| | (permalink) |
| Experienced Member | blueroomelectronics What is ur Method of measuring RPM?? Time periode b/w pulses ??? OR Pulsed received in Known Time??? |
| | |
| | (permalink) |
| Experienced Member | How u guys Measure the periode of a square wave? Am i Right? On first Intrupt i will start TIMER1 module and on seconed intrupt i will get the value of TIMER1H and TIMER1L. and store it into T. Now T is the time periode of our Input wave. Intrupt means Intrupt on every rising edge. Thanks |
| | |
| | (permalink) |
| Experienced Member | The capture function of the CCP module is designed to do exactly this. Mike. |
| | |
| | (permalink) |
| Experienced Member | Yes i am using capture function of the CCP module. But i want to know that how u guys use Capture function ??? In above program i am also using Capture function but result are not right. Any one have example related to Capture function plz share. Last edited by Ayne; 1st April 2007 at 05:39 AM. |
| | |
| | (permalink) |
| Experienced Member | Sorry, I should have looked at your code first. Having now looked at your code, I notice that you don't clear Timer1 when a capture occurs. Timer1 is not automatically reset to zero. A better way is to subtract the timer value from the previous value. Mike |
| | |
| | (permalink) |
| Experienced Member | I wouldnt use the external clock for TMR1 in this application, you have no means by calculating the time period unless you use another TMR for a time reference. Just use the internal clock for TMR1 and an input from a pin to act as the signal Code: Device = 16F877 Xtal = 4 Dim uS as DWord Dim Took_To_Long as Bit Symbol GIE = INTCON.7 ' Global Interrupt Enable Bit Symbol Timer1 = TMR1L.WORD ' A special way of addressing both TMR1L and TMR1H with one register Symbol TMR1_Enable = PIE1.0 ' TMR1 interrupt enable Symbol TMR1_Overflow = PIR1.0 ' TMR1 overflow flag Symbol TMR1_On = T1CON.0 ' Enables TMR1 to start incrementing Declare SERIAL_BAUD 19200 Declare RSOUT_PIN PORTA.1 Declare RSOUT_MODE TRUE Declare RSOUT_PACE 5 ON_INTERRUPT Int_Sub Goto Initialization Int_Sub: GIE = 0 If TMR1_Overflow = 1 And TMR1_Enable = 1 Then Took_To_Long = 1 TMR1_Overflow = 0 EndIf GIE = 1 Context Restore Initialization: ALL_DIGITAL = True High PORTA.1 TRISA.0 = 1 TMR1_Enable = 0 GIE = 0 INTCON.6 = 1 ' Peripheral Interrupts T1CON.1 = 0 ' 1 = External clock from pin RC0/T1OSO/T1CKI (on the rising edge) ' 0 = Internal clock (FOSC/4) T1CON.2 = 1 ' 1 = Do not synchronize external clock input ' 0 = Synchronize external clock input ' When T1CON.1 = 0; ' this bit is ignored. Timer1 uses the internal clock when TMR1CS = 0. T1CON.4 = 1 ' 11 = 1:8 prescale value T1CON.5 = 1 ' 10 = 1:4 prescale value ' 01 = 1:2 prescale value ' 00 = 1:1 prescale value TMR1_Overflow = 0 RSOUT "On",13 TMR1_On = 0 ' Disable TMR1 counting TMR1_Enable = 1 ' Enable TMR1 interrupts GIE = 1 ' Enable Global Interrputs Main: Repeat Until PORTA.0 = 0 ' Wait for PORTA.0 to go Low Repeat Until PORTA.0 = 1 ' Wait for PORTA.0 to go high ' The above two loops ensure we are not entering a pulse mid way, but on ' an actual rising edge Timer1 = 0 ' Reset TMR1 TMR1_On = 1 ' Enable TMR1 counting Repeat Until PORTA.0 = 0 Or Took_To_Long = 1 Repeat Until PORTA.0 = 1 Or Took_To_Long = 1 ' The above 2 Repeat loops wait for a full cycle to occur TMR1_On = 0 ' Disable TMR1 counting If Took_To_Long = 1 Then ' Check if a time out occured Took_To_Long = 0 Goto Main Else Timer1 = Timer1 - 2 ' Number of instructions that are executed while timed ' outside of pulse period uS = Timer1 * 8 ' 1:8 prescaler & 4Mhz clock there for uS = Timer1 * 8 RSOut "Period = ", Dec uS, " uS", 13 RSOut "Frequency = ", Dec(1000000 / uS), " Hz", 13 RSOut "RPM = ", Dec(1000000 / uS * 60), 13, 13 Goto Main EndIf With a 4Mhz OSC and a TMR1 prescale of 1:8, every increment of TMR1 = 1/8th uS. This means that the longest period allowed is 8 * 65535 = 524280uS, or around 1/2 a second. If this occurs, the Took_To_Long flag will be set. The faster the pulses comming in, the less accurate the program will become. Its like any sampling program that doesnt use interrupts too catch changes. Notice that I first I wait for the input to go from low to high. This is so that I am deffinetly starting from a rising edge, and not jumping in half way. Then I wait for that signal to go from high to low and stop the clock. Easy. A little math and an output to see the result, presto.
__________________ Spency. PIC Micro's - Your mind is the limit PIC's and interfacing with other devices - a PIC Basic Guide @ digital-diy.net Last edited by gramo; 1st April 2007 at 08:44 AM. |
| | |
| | (permalink) | |
| Experienced Member | Quote:
You can count low to high and high to low transistions, so 6 per rotation. The motor is 12500RPM at 3V no load. Gear reduction is 4.25:1 to the crown gear, then 3:1 for the sensor gear, and two more 3:1 till it hits the wheels. Therefore the sensor gear rotates once every 12.75 rotations of the main motor and 9 times faster than the wheel axle. With three marking on the sensor gear we can see 54 edge transitions per whell rotation. From the motors point of view... 12500 rpm (more with higher voltage but this is the rated speed at 3V) So 12500/4.25/3 = 980.4 RPM on the sensor gear. 980.4 / 60 (for rotations per second) = 16.34 now multiply that by the 3 black markings each with 2 edges 16.34*3*2= 98 Hz, not too fast for a PIC to count. Using RB4,5 change on interrupt should be a breeze to keep up. PS I'm using both PWM channels to control the dual motor(s) speed, so I don't have the luxury of the CCP capture mode. If 98Hz is too fast or slow add/remove black bands from the gear. I used 3 positions as there are three little circular indents on those gears make it easy to draw the hand painted (with black sharpie paint marker) stripes. ![]() Last edited by blueroomelectronics; 1st April 2007 at 03:26 PM. | |
| | |
| | (permalink) |
| Experienced Member | TIMER1 with 1:8 Prescale value. Crystal Frequency = 20MHz TIMER1 using internal clock cycle(Instruction Cycle). Then increment of TMR1 = ??? My bad math says it is about 1.6 microSeconds... Am I Right!!! |
| | |
| Bookmarks |
| Thread Tools | |
| Display Modes | |
| |
| | ||||
| Thread | Thread Starter | Forum | Replies | Latest |
| Dual counter | bananasiong | Micro Controllers | 45 | 24th March 2007 02:49 AM |
| How we can do it in Assembly..Help Needed | Ayne | Micro Controllers | 37 | 29th December 2006 05:49 PM |
| PIC16f877A Project help | Alex Ng | Micro Controllers | 5 | 26th July 2006 07:47 AM |
| [help] Power consumption issue on bullet counter project * | Lanzer | Electronic Projects Design/Ideas/Reviews | 13 | 26th August 2005 06:06 AM |
| PROJECT: Bowling Pin Counter - 7 Segment Displays | FLCARM1964 | Electronic Projects Design/Ideas/Reviews | 1 | 14th April 2005 01:56 AM |