PIC-varvtäknare modell F1

Berätta om dina pågående projekt.
bearing
Inlägg: 11675
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: PIC-varvtäknare modell F1

Inlägg av bearing »

Nja, som jag uppfattar det mäter PULSIN pulslängd. Ifall ECUn ger en symmetrisk signal, eller signal med konstant pulslängd på ena delen av signalen, vore det ju möjligt att använda PULSIN för det här. Men jag håller med dig. Jag skulle nog skrotat PULSIN. Men jag skulle ju också skrotat hela programmeringsspråket, och istället skrivit i C.

Jag är rätt säker på att man kan ställa in CCP att automatiskt nollställa Timer1 vid varje Capture, vilket gör att vid en Capture kommer registret CCPR kommer få värdet motsvarande pulslängden direkt, vilket gör att det inte behövs någon subtraktion.
Quinna
Inlägg: 24
Blev medlem: 6 mars 2011, 13:55:57

Re: PIC-varvtäknare modell F1

Inlägg av Quinna »

Men tror ni att mitt exempel skulle kunna fungera? För visst borde jag få ut tiden mellan två pulser i variabeln Pulse_Time om jag gör så? Nu vet jag att många av er kanske inte skriver med samma språk, men det känns som att det är hyfsat lätt att ta till sig.

Och om jag nu får ett värde i Pulse_Time som motsvarar tiden mellan två rising edge, visst borde det helt enkelt bara vara att skriva ett If/Else som tänder släcker dioder beroende värdet i Pulse_Time?

Sen en fundering till. Om det nu är som jag skrev ovan, vad blir värdet med en 48MHz processor? Hur många enheter blir det per ms eller vad man nu ska säga?
bearing
Inlägg: 11675
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: PIC-varvtäknare modell F1

Inlägg av bearing »

CCP-enheten använder Timer1, och den klockas med Fosc/(4*prescaler). Timer1 har prescaler 1, 2, 4 eller 8, vilket betyder att den med Fosc=48MHz kan räkna upp med frekvensen 12MHz, 6MHz, 3MHz eller 1,5MHz.

Eftersom att Timer1 är 16 bitar kan den räkna upp till högst 65536 värden. Med prescaler 8 kan den mäta pulsavstånd som är högst 65536/1500000 sekunder = 0.043s. Eftersom att motorn ger 2 pulser per varv blir det minsta varvtalet den kan mäta 60/(2*0.043)=686 RPM. Ifall varvtalet är lägre kommer Timer1 slå runt innan Capture.

För att beräkna antalet pulser vid olika varvtal blir ekvationen:
CCPR = 60*12000000/(prescaler*varvtal*2)

EDIT: la till en 2:a i sista uttrycket eftersom att motorn ger 2 pulser per varv.
Senast redigerad av bearing 15 mars 2011, 15:13:49, redigerad totalt 1 gång.
Quinna
Inlägg: 24
Blev medlem: 6 mars 2011, 13:55:57

Re: PIC-varvtäknare modell F1

Inlägg av Quinna »

Utmärkt.

Ska sätta mig och räkna på dom värden jag är intresserad av så återkommer jag med resultat sen.
Användarvisningsbild
Icecap
Inlägg: 26632
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: PIC-varvtäknare modell F1

Inlägg av Icecap »

Och det är rimligt enkelt att expandera Timer1 till 32 bit, detta sköts medelst en interrupt med Timer-Overflow. Då kan man mäta mycket långa tider med hög upplösning och räkna på dessa med vanlig 32-bitars matte.

Alltså är lägsta varvtalet med 32 bit 686 RPM / 65536 vilket ger... löjligt litet och därför inget att gnälla över. Man kan då minska prescaler osv. och då få högre upplösning men det är ju frågan för om det behövs.
Senast redigerad av Icecap 15 mars 2011, 21:26:52, redigerad totalt 1 gång.
Quinna
Inlägg: 24
Blev medlem: 6 mars 2011, 13:55:57

Re: PIC-varvtäknare modell F1

Inlägg av Quinna »

Jag har suttit och plockat ihop lite IF_ELSE förfaranden och räknat lite på exemplet ovan så jag har lite siffror att sätta in i min kod, men efter flertalet försök att söka sig till svar på div ställen så lyckas jag inte hitta hur fan jag får till en prescaler. Alltså HUR det ska skrivas i koden. Är det nån här som har bättre koll på basic än mig och som har lust att visa?

Stämmer matten förresten?

CCPR = 60*12000000/(prescaler*varvtal*2) =>
CCPR = 720000000/(8*7000*2) =>
CCPR = 720000000/112000 =>
CCPR = 6429

Sen då typ:

If Pulse_Time > 6429 Then
High LED
Else
Low LED
EndIf
ToPNoTCH
Inlägg: 5142
Blev medlem: 21 december 2009, 17:59:48

Re: PIC-varvtäknare modell F1

Inlägg av ToPNoTCH »

Kan vi göra klart i huruvida det MÅSTE vara skrivet i Proton Basic eller inte, så kommer det här gå lättare.

Den rätta vägen är att använda capture med interrupt, det är de flesta överens om. Men om trådskaparen nu vill ha det hela löst i Proton Basic, så verkar ju det inte vara en option.

Om vi återgår till PULSIN så tycker jag problemet är att kommandot är lite dåligt förklarat:

Kod: Markera allt

- When the state on the pin changes to the state specified, the clock starts counting. 
- When the state on the pin changes again, the clock stops. 
Rad två om status ändras "igen" ?
1.) Är det till "specificerad status" då med som gäller, så mäter man stigande flank till stigande flank och då har man ju tiden mellan pulserna.
2.) Är det "förändring", så mäter man stigande flank till fallande flank och då har man ju tiden för pulsen.

Jag har aldrig skrivit i Proton Basic, men däremot i PIC Basic. Dom verkar "besläktade" och där är det pulsbredd som mäts med kommandot.
Av denna anledning tror jag det är alternativ 2 ovan som gäller, och det är därför jag tror att kommandot inte passar för det trådskaparen vill (tror icecap var inne på samma sak).

Det kanske krävs något mer "fantasifullt" för att lösa det i Proton Basic.
Jag tror perssonligen fortfarande att COUNTER skulle funka, men det verkar ju inte vara intressant.
ToPNoTCH
Inlägg: 5142
Blev medlem: 21 december 2009, 17:59:48

Re: PIC-varvtäknare modell F1

Inlägg av ToPNoTCH »

Det finns en komplett kod i post #10 i denna tråd.

Vet inte om den funkar rätt av i Proton Basic, men den kan vara värd att titta på

http://www.edaboard.com/thread24602.html
bearing
Inlägg: 11675
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: PIC-varvtäknare modell F1

Inlägg av bearing »

För att få till en prescaler behöver du gå in i databladet och läsa om Timer1, eller mer specifikt "T1CON: TIMER1 CONTROL REGISTER". Du behöver sätta några bitar i det registret för att ställa in prescalern och sätta igång timern, bl.a.

ToPNoTCH:
Problemet med att räkna pulser under tid är att för att få tillräcklig noggrannhet måste pulserna räknas så länge att varvtalet har hunnit förbi varvtalet som kommer visas på lysdioderna när det väl visas, ifall accelerationen är hög.
ToPNoTCH
Inlägg: 5142
Blev medlem: 21 december 2009, 17:59:48

Re: PIC-varvtäknare modell F1

Inlägg av ToPNoTCH »

Jo jag bemödade mig faktiskt att räkna på det innan jag postade :P

Mätning under 0.1 sek = 100 RPM fel
Mätning under 0.2 sek = 50 RPM fel
osv.

Sen är ju resten en fråga om hur ofta man behöver uppdatera och hur exakt på varven dioderna skall växla.

Saken är den att vi fortfarande inte fått veta om det är OK med en lösning som inte baseras på Proton Basic eller ej.

Det här är ju en skitsak om man kan (får) använda CCPM, och det finns massa exempel i assembler på nätet.

Vill TS bara ha det löst eller är det en "skola" i hans kommande utveckling som "Proton Basic hackare" osv. osv.

Själv tycker jag det är ett skolexempel på varför Basic spåret är "Dead end"
bearing
Inlägg: 11675
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: PIC-varvtäknare modell F1

Inlägg av bearing »

Det går ju lika bra att ställa in register och läsa flaggor med Basic som med vilket annat språk som helst. Basic som kompileras innan det skickas till en mikrocontroller är ju i princip bara ett högnivåspråk i mängden, fast med Basic-syntax och ett bibliotek med funktioner som t.ex. PULSIN. Men jag kan hålla med dig om att det går lite emot Basic-språkets syfte att börja skriva till bitar i register och sånt. Basic ska ju vara enkelt.

Vid kraftig acceleration på låg växel kommer ju motorn kunna ha ökat 1000 rpm under de där 0,1 sekunderna. Jag gissar att själva anledningen till att han vill göra den här grejen är för att kunna få en indikation på när det är dags att växla, vilket jag tror betyder att 0,1s fördröjning med 500 rpm fel inte duger till.

Och stämmer det verkligen att bara 0,1 sekund räcker för att få 100 rpm noggrannhet? Vid 6000 rpm ger motorn 200 pulser per sekund, dvs 20 pulser under 0,1 sekund. Skillnaden i varvtal mellan ifall räknaren räknar 19 eller 20 pulser är ca 300 rpm.
Quinna
Inlägg: 24
Blev medlem: 6 mars 2011, 13:55:57

Re: PIC-varvtäknare modell F1

Inlägg av Quinna »

Som bearing skriver så är det kritiskt att denna avläsning blir exakt. Ett översteg på 300rpm för att man har en fördröjning i koden skulle kunna innebära ett rejält dyrt motorhaveri.

< Kan vi göra klart i huruvida det MÅSTE vara skrivet i Proton Basic eller inte, så kommer det här gå lättare.

Det måste absolut inte göras i Proton Basic. Om någon här känner sig så vass på dessa funktioner så är det mer än välkommet att denna individ knåpar ihop en kod och skapar en HEX-fil och skickar till mig så jag får detta att fungera. Jag kan i såna fall förse med all info om pinnar och liknande som kan tänkas behövas för att skapa koden. Skälet till att jag använder Basic som nybörjare är att det ska vara just enkelt.
Användarvisningsbild
AndersG
EF Sponsor
Inlägg: 9089
Blev medlem: 25 februari 2008, 17:10:58
Ort: Mariehamn
Kontakt:

Re: PIC-varvtäknare modell F1

Inlägg av AndersG »

Jag har en i princip klar varvräknarkod in assembler för 16F690 som du kan få om du vill.. Dvs den använder en tidbas och en 32-bitars räknare för att räkna tid mellan två pulser.
Quinna
Inlägg: 24
Blev medlem: 6 mars 2011, 13:55:57

Re: PIC-varvtäknare modell F1

Inlägg av Quinna »

För er som har koll på hur mycket skillnad det är, hur mycket jobb kan det tänkas vara att översätta denna till min 18F och få allt att fungera?
bearing
Inlägg: 11675
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: PIC-varvtäknare modell F1

Inlägg av bearing »

Mer arbete än att skriva klart programmet i Basic, tror jag. Använder du USB för kommunikation också? i så fall behöver ju även USB-delen skrivas.

Jag tycker det ser väldigt enkelt ut att lägga in mätning via CCP i nuvarande Basic-programmet. Det behövs bara 10-20 rader till kod.

EDIT:
Jag la in CCP-mätning i ditt program. Förmodligen kommer det vara en del syntaxfel som du måste åtgärda, eftersom att jag vanligtvis inte programmerar Basic. Det kan också vara någon bugg, eftersom jag inte har lagt någon tid på att leta buggar. En bugg vet jag om, och det är en bugg som kommer göra att lysdioderna tänds slumpmässigt under ca 650 RPM, eftersom att Timer1 slår runt. Det går att lösa genom att ha ett interrupt som håller koll på hur många gånger Timer1 slår över, och sedan jämföra variablerna period och lastPeriod med varandra.

Kod: Markera allt

Device = 18F2455                        ' Choose a device with on-board full speed USB
Xtal = 48                              ' Set the oscillator speed to 48MHz (using a 20MHz crystal)
Reminders = OFF                           ' Disable all reminders                         
'USB_DESCRIPTOR = "CDCDESC.INC"               ' Point to the CDC DESCRIPTOR file (located in the INC\USB_18 folder)
Declare PROTON_START_ADDRESS = $1000            'För microchips bootloader.
Config_Start
   CP0 = On                                      ; Code Protection
   CP1 = On                                      ; Code Protection 
   CP2 = On                                      ; Code Protection
   CPB = On                                      ; Code Protection Boot blockc
   CCP2MX = On                                   ; CCP2 input/output is multiplexed with RC1
   PLLDIV = 1                                    ; Divide by 5 (20 MHz oscillator input)
   CPUDIV = OSC1_PLL2                            ; [OSC1/OSC2 Src: /4][96 MHz PLL Src: /6]
   USBDIV = 2                                    ; USB clock source comes from the 96 MHz PLL divided by 2
   FOSC = HSPLL_HS                               ; HS oscillator, HS used by USB
   VREGEN = On                                   ; USB voltage regulator enabled
   PWRT = On                                     ; PWRT enabled
   BOR = OFF                                     ; Brown-out Reset disabled in hardware and software
   WDT = OFF                                     ; HW Disabled - SW Controlled
   WDTPS = 1                                     ; 1:1
   PBADEN = off                                 
   MCLRE = On                                    ; RE3 input pin enabled; MCLR disabled
   STVREN = On                                   ; Stack full/underflow will cause Reset
   LVP = OFF                                     ; Single-Supply ICSP disabled
   XINST = OFF                                   ; Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
   Debug = OFF                                   ; Background debugger disabled, RB6 and RB7 configured as general purpose I/O pins
Config_End




TRISC.0 = 0

TRISB.0 = 0 ' sätter port B.0 som output (1=input) (0=output)
TRISB.1 = 0
TRISB.2 = 0
TRISB.3 = 0
TRISB.4 = 0
TRISB.5 = 0
TRISB.6 = 0
TRISB.7 = 0
Symbol LED1 = PORTB.0 ' Deklarerar en port som LED.
Symbol LED2 = PORTB.1
Symbol LED3 = PORTB.2
Symbol LED4 = PORTB.3
Symbol LED5 = PORTB.4
Symbol LED6 = PORTB.5
Symbol LED7 = PORTB.6
Symbol LED8 = PORTB.7
Symbol LEDS = PORTB



Dim Pulser As Word          ' Declare a word size variable
               
TRISA.0 = 1

'*****************************************************************************************

setupCCP1:
Symbol captureFlag = PIR1.2
Symbol timer1Overflow = PIR1.0
Symbol timer1ON = T1CON.0
Symbol oneRPMperiod = (60*12000000/8/2)
Dim period As Word
Dim lastPeriod As Word
period = 0
lastPeriod = 0

'Configure Timer1
'1:8 Prescale value, Internal clock (FOSC/4)
T1CON = %00110000
TMR1L = 0
TMR1H = 0

'Configure CCP1
'Capture mode: every falling edge
CCP1CON = %00000100

'Configure Input
TRISC.2 = 1


waitForFirstPulse:
while PORTC.2 = 1
	'do nothing
wend
while PORTC.2 = 0
	'Reset flags,  and turn off LEDS
	captureFlag = 0
	timer1Overflow = 0
	LEDS = 0
wend
timer1ON = 1


Start:

'wait for Capture
while CaptureFlag = 0
	'do nothing
wend
captureFlag = 0

'Calculate the pulse period
period = CCPR1H << 8
period = period + CCPR1L

period = period - lastPeriod

lastPeriod = CCPR1H << 8
lastPeriod = lastPeriod + CCPR1L

' Display the reading
Print Dec period, " "


LEDS = 0
'Turn on some LEDS
if period < (oneRPMperiod/3500) then LED1 = 1
if period < (oneRPMperiod/4000) then LED2 = 1
if period < (oneRPMperiod/4500) then LED3 = 1
if period < (oneRPMperiod/5000) then LED4 = 1
if period < (oneRPMperiod/5500) then LED5 = 1
if period < (oneRPMperiod/6000) then LED6 = 1
if period < (oneRPMperiod/6500) then LED7 = 1
if period < (oneRPMperiod/7000) then LED8 = 1


If PORTA.0 = 1 Then
    High PORTC.0
Else
    Low PORTC.0
EndIf
     
GoTo start
Senast redigerad av bearing 17 mars 2011, 10:42:49, redigerad totalt 1 gång.
Skriv svar