-
1 Attachment(s)
Counting led blinks..
Hi everyone, I have a coin acceptor that gives out pulse. Coins used are P1, P5 and P10. When I drop P1 it gives 1 blink to my led status, P5 it gives 5 blinks and P10 gives 10 blinks. I want to display the corresponding blinks on the LCD. I tried the following code and connected the .
Code:
DEFINE LCD_DREG PORTBDEFINE LCD_DBIT 0
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 5
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 4
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 2000
DEFINE LCD_DATAUS 50
Define OSC 20
ADCON1 = 7 'Need this to turn off ADC
TRISB = 000011 'Pins A are in input mode
PortB = 0
W1 var byte
Clear
pause 100
Lcdout $fe, 1 ' Clear screen
Lcdout "Blink Counter" ' Display "Test Counter"
Init:
COUNT PORTB.1, 60, W1
Lcdout $fe, 1 ' Clear screen
Lcdout "Digital Designs"
Lcdout $fe, $c0, "Read: " , #W1
pause 1000
GOTO Init 'Do it always
But it displays erratic values. Can anyone guide me on this?
Diagram
Attachment 5998
regards,
tacbanon
-
Re: Counting led blinks..
Hi,
How fast does the LED blink? You're only counting for 60ms so you need to insert the coin at exactly the right time - every time - for it be consistent.
I'd probably do this by setting up one of the PICs timers as a counter and wire the pulse signal to its input.
EDIT: Or something like:
Code:
Init:
While PortB.1 = 0 : WEND
Count PortB.1, 60, W1
Count = Count + 1
'LCDOUT......
'.....
Goto Init
/Henrik.
-
Re: Counting led blinks..
Timer/Counter... motion seconded
-
Re: Counting led blinks..
@Henrik
Hi sorry for the delay, I can not tell exactly how fast it is. Can you give me a very simple example or a link that will help me out, I'm new with timers/counter. I was thinking it will be easy if I can count it like it is a button pressed..then just increment a variable counter.
regards,
tacbanon
-
Re: Counting led blinks..
Hi,
You can count it like it's a button but the way you have it now means that the pulses have to come in exactly during the 60ms you're actually counting. If they start to come before you start to count you'll miss some of them or if the pusles starts 30ms after you've started to count you might stop counting before all pulses have arrived.
Just look at the datasheet for the PIC you're using, TMR0 is probably the easiest to use. Read the section, look at the T0CON register and you'll see how to configure it as a counter. The pulses then goes to T0CKI-pin and you can access the count by reading the TMR0 register.
Give it a try, if it doesn't work post the code (and what PIC you're using) and we'll take a look at it.
/Henrik.
-
Re: Counting led blinks..
Interupt on change or even better a real INT pin. Then you can count all pulses without too much work. A good start is as always DT's instant interupts that makes it fast, fun and flexible.
-
Re: Counting led blinks..
Why any real INT should be less work than any dedicated counter? No advanatage at all.
Q: Sir We need to know when something chagend, a button press
A: Load the counter to 255, on the next press it will generate an overflow interrupt
-
Re: Counting led blinks..
Why? Since he already used PORTB.1 in his code an interrupt solution requires no HW change.
And it was just a example to show an other possibility....
-
Re: Counting led blinks..
Hi, Sorry for the delay. I got a working code that incorporate TMR0.
Code:
CLEAR DEFINE OSC 48
DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 0
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 5
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 4
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 2000
DEFINE LCD_DATAUS 50
asm
;_PLLDIV_2_1L EQU H'F9' ; Divide by 2 (8 MHz oscillator input)
;__CONFIG _CONFIG1L, _PLLDIV_2_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L ' 1
__CONFIG _CONFIG1L, _PLLDIV_5_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L
__CONFIG _CONFIG1H, _FOSC_HSPLL_HS_1H & _FCMEN_OFF_1H & _IESO_OFF_1H
;
;__CONFIG _CONFIG1L, _PLLDIV_1_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L
; ; ; USB clock source comes from the 96 MHz PLL divided by 2
; ; [OSC1/OSC2 Src: /1][96 MHz PLL Src: /2]
; No prescale (4 MHz oscillator input drives PLL directly)
;__CONFIG _CONFIG1H, _FOSC_XTPLL_XT_1H & _FCMEN_OFF_1H & _IESO_OFF_1H '2
; ; ; Oscillator Switchover mode disabled
; ; Fail-Safe Clock Monitor disabled
; XT oscillator, PLL enabled, XT used by USB
__CONFIG _CONFIG2L, _PWRT_ON_2L & _BOR_ON_2L & _BORV_2_2L & _VREGEN_ON_2L
__CONFIG _CONFIG2H, _WDT_OFF_2H
__CONFIG _CONFIG3H, _MCLRE_ON_3H & _LPT1OSC_OFF_3H & _PBADEN_OFF_3H & _CCP2MX_ON_3H
__CONFIG _CONFIG4L, _STVREN_ON_4L & _LVP_OFF_4L & _ICPRT_OFF_4L & _XINST_OFF_4L & _DEBUG_OFF_4L
endasm
INTCON = 100000 ' Enable global and TMR0 interrupts
T0CON = 000000 ' TMR0, CLK internal, prescaler 1:2, T0ON
ALPHA VAR WORD ;this variable counts in the PauseUS loop
BETA VAR BYTE ;this variable counts interrupt ticks
TRISD = 110100 ;sets the 3 output pins in the D port
PORTD = 000000 ;sets all pins low in the D port
ON INTERRUPT GOTO INTERUPTROUTINE ;This line needs to be early in the program, before
;the routine is called in any case.
MAINLOOP: ;Main loop blinks D0 and D1 alternately
IF PORTD.1 = 0 THEN ;]
PORTD.1 = 1 ;]
PORTD.0 = 0 ;] This part of the program blinks two LEDs in
ELSE ;] the foreground
PORTD.1 = 0 ;]
PORTD.0 = 1 ;]
ENDIF ;]
FOR ALPHA = 1 TO 300 ;The long pause is eliminated with this loop
PAUSEUS 100 ;PAUSE command with short latency
NEXT ALPHA ;
GOTO MAINLOOP ;end of loop
DISABLE ;DISABLE and ENABLE must bracket the interrupt routine
INTERUPTROUTINE: ;this information is used by the compiler only.
BETA = BETA + 1 ;
Lcdout $fe, 128, "Digital Output" ' Display
Lcdout $fe, $c0, "Counter: ", #BETA
IF BETA < 61 THEN ENDINTERRUPT ;one second has not yet passed
BETA = 0 ;
IF PORTD.3 = 1 THEN ;Interrupt loop turns D3 on and off every
PORTD.3 = 0 ;61 times through the interrupt routine.
ELSE ;That is about one second per full cycle
PORTD.3 = 1 ;
ENDIF ;
ENDINTERRUPT: ;
INTCON.2 = 0 ;clears the interrupt flag.
RESUME ;resume the main program
ENABLE ;DISABLE and ENABLE must bracket the int routine
END
I used "000 = 1:2 Prescale value( I think this is the fastest)" is this the pin that should be reading the pulse input?
I'm not really sure how to implement interrupt to the program yet, but I understand that its very important to learn this.
regards
tacbanon
-
Re: Counting led blinks..
Hi,
Not sure exactly what you're trying to do with that specific piece of code.... If you're trying to setup a timer interrupt you're on the right track but if you're trying to use TMR0 as a counter to count the pulses it's not what you want.
When TMR0 is in timer-mode, like you have it, it counts internal instruction cycles "thru" the prescaler. If you clock the PIC at 4Mhz, one instruction cycle is 1us so the timer ticks along at 1Mhz/prescaler ratio. When it rolls over from 255 to 0 it sets the interrupt-flag.
When TMR0 is in counter-mode it counts transitions on the T0CKI-pin instead of internal instruction cycles. Again it sets the interrupt flag when it rolls over from 255 to 0 but it may not be of interest here.
Also, it looks like you're trying to set T0CON, INTCON, TRISD and PORTD "in binary" but there's no %-sign in front of the number. Also, try to always include all 8 bits. Like INTCON = %00100000 not INTCON=100000
/Henrik.
-
Re: Counting led blinks..
FYI, the missing % is a new Code Box forum feature...
-
Re: Counting led blinks..
Hi,
I searched in the forum and found a peice of code by Bruce...
Code:
DEFINE LCD_DREG PORTBDEFINE LCD_DBIT 0
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 5
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 4
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 2000
DEFINE LCD_DATAUS 50
PAUSE 100
TRISA.4 = 1 ' RA4/T0CKI = input to TMR0 counter
TRISB.0 = 0 ' RB0 = output for LED
CMCON = 7 ' All digital
i var byte
i=0
' Assign prescaler to WDT for 1:1 prescale on TMR0
' TMR0 clock will be from your external input on RA4/T0CKI
' Increment on high-to-low transitions
OPTION_REG = 111000
' If you prefer, then increment on low-to-high transitions
' OPTION_REG = 101000
Lcdout $fe, 128, "Counter: ", #i
pause 100
Main:
TMR0 = 0 ' Clear TMR0 count before start
Loop1:
WHILE TMR0 = 0 ' Wait for high-to-low transition
WEND ' on RA4/T0CKI
PORTB.0 = 1 ' LED on to indicate transition seen
i=i+1 ' Increment
Lcdout $fe, 128, "Counter: ", #i
PAUSE 200
PORTB.0 = 0 ' LED off
GOTO Main ' Start over
END
Everytime I press RA.4 it toggle RB0, I also put a variable that will display the value to the LCD, from the code I observed (please correct me if I wrong).
a. Timer0 is selected
b. The signal entry is RA.4
c. It increments on low-to-high transitions
d. Pre scale value is 1:2 (000 of Bits 2,1)
d. The configuration setting used OPTION_REG = 111000
So if connect the multi coin acceptor to the RA.4 this should count the number of pulse?
thanks in advance,
tacbanon
-
1 Attachment(s)
Re: Counting led blinks..
Hi,
Yes, that would work. I'd probably add a little pause directly after the WHILE-WEND loop to allow the coin acceptor to push out all the pulses before the code reads the timer.
As for the prescaler, yes, the bits indicate a a 1:2 ratio but since bit 3 is set the prescaler isn't assigned to TMR0 but to the WDT so you get a 1:1 ratio which is what you want in this case.
Steve,
Thanks for the heads-up on the % character, great feature... Must try/verify:
Code:
This is a test, percent char %00110011
This is a test, no percent char 00110011
And here's how my post looks in preview:
Attachment 6018
Looks fine in the preview. (Appologies to tachbanon for trying this here).
EDIT: And in the final post, I don't see a problem... Is it when there's a = infront?
Code:
OPTION_REG = %00110011
Again, looks fine in the preview.
EDIT: And in the final post.
/Henrik.
-
1 Attachment(s)
Re: Counting led blinks..
Hi, now I'm trying to incorporate the coin acceptor, but I observered that when I connect PULSE line to RA4..it continues to count, even if the device is turned off or if I touched the wire. Please see the attachment, I'm using easypic6. What do you think causing it?
regards,
tacbanon
-
Re: Counting led blinks..
Hi,
Try adding a pullup or pulldown resistor on the input.
-
1 Attachment(s)
Re: Counting led blinks..
I tried both using the built in switch to enabled Pull up/down.. no changes.:confused:
Please see attach image, I'm using the blue wire.
thanks,
tacbanon
-
Re: Counting led blinks..
Hi, I finally got it right, what was missing was the GND.:o Thanks Henrik for the help, my next target is to run the codes on PIC18F4550..hope it wont be a problem.
regards,
tacbanon
-
Re: Counting led blinks..
Hi, I'm still having trouble converting my codes From PIC16F877A to PIC18F4550
I'm confused translating
Code:
' Assign prescaler to WDT for 1:1 prescale on TMR0' TMR0 clock will be from your external input on RA4/T0CKI
' Increment on high-to-low transitions
OPTION_REG = 111000 (Pic16F877A) to
T0CON = 10110111 (PIC18F4550) 'T0CON = TMR0ON T08BIT T0CS T0SE PSA T0PS2 T0PS1 T0PS0
Here is the whole code
Code:
'***********************************************************************
DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 0
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 5
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 4
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 2000
DEFINE LCD_DATAUS 50
PAUSE 100
asm
;_PLLDIV_2_1L EQU H'F9' ; Divide by 2 (8 MHz oscillator input)
;__CONFIG _CONFIG1L, _PLLDIV_2_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L
;__CONFIG _CONFIG1L, _PLLDIV_1_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L
; ; ; USB clock source comes from the 96 MHz PLL divided by 2
; ; [OSC1/OSC2 Src: /1][96 MHz PLL Src: /2]
; No prescale (4 MHz oscillator input drives PLL directly)
__CONFIG _CONFIG1L, _PLLDIV_5_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L
__CONFIG _CONFIG1H, _FOSC_XTPLL_XT_1H & _FCMEN_OFF_1H & _IESO_OFF_1H
; ; ; Oscillator Switchover mode disabled
; ; Fail-Safe Clock Monitor disabled
; XT oscillator, PLL enabled, XT used by USB
__CONFIG _CONFIG2L, _PWRT_ON_2L & _BOR_ON_2L & _BORV_2_2L & _VREGEN_ON_2L
__CONFIG _CONFIG2H, _WDT_OFF_2H
__CONFIG _CONFIG3H, _MCLRE_ON_3H & _LPT1OSC_OFF_3H & _PBADEN_OFF_3H & _CCP2MX_ON_3H
__CONFIG _CONFIG4L, _STVREN_ON_4L & _LVP_OFF_4L & _ICPRT_OFF_4L & _XINST_OFF_4L & _DEBUG_OFF_4L
endasm
DEFINE OSC 48
TRISA.4 = 1 ' RA4/T0CKI = input to TMR0 counter
TRISA.0 = 0 ' RA0 = output for LED
CMCON = 7 ' All digital
i var byte
i=0
' Assign prescaler to WDT for 1:1 prescale on TMR0
' TMR0 clock will be from your external input on RA4/T0CKI
' Increment on high-to-low transitions
T0CON = 10110111 'T0CON = TMR0ON T08BIT T0CS T0SE PSA T0PS2 T0PS1 T0PS0
Lcdout $fe, 128, "Counter: ", #i
pause 100
Main:
TMR0 = 0 ' Clear TMR0 count before start
Loop1:
WHILE TMR0 = 0 ' Wait for high-to-low transition
WEND ' on RA4/T0CKI
pause 100
PORTB.0 = 1 ' LED on to indicate transition seen
i=i+1 ' Clear screen
Lcdout $fe, 128, "Counter: ", #i
PAUSE 100
PORTB.0 = 0 ' LED off
GOTO Main ' Start over
END
When compiled Error message..."Error[113] c:\pbp\pbppic18.lib 589 : Symbol not previously defined (TMR0)"
What do I'm missing in setting the bits for T0CON?
thanks in advance,
tacbanon
-
Re: Counting led blinks..
Hi,
Have you looked at the datasheet for the 18F4550 and compared it against the 16F877A? What's the difference regarding TMR0?
First, T0CON = %10110111
Bit7=1: TMR0 ON
Bit6=0: TMR0 is a 16bit timer/counter
Bit5=1: Transition on T0CKI Pin
Bit4=1: Increment on falling edge
Bit3=0: Prescaler assigned to TMR0
Bit2-0 = 1: Prescaler ration 1:256
Is that what you want? Why do want a prescaler ratio of 256? And do you need it to be a 16bit mode?
Try T0CON = %11111000 instead, or change bit4 if you want rising edge.
If you do look in the datasheet(s) you'll see that on the 16F TMR0 is 8bits wide and there is one register for it (TMR0) but on the the 18F it can be either 8bit or 16bit. Therefor they have changed the register name from TMR0 to TMR0L (low) and TMR0H (high). You need to make the corresponding changes in your program.
/Henrik.
-
Re: Counting led blinks..
Hi, Little by little I'm learning to like the datasheet :o, I managed to compile the program, but there is no display on the Lcd, and also I noticed that RB0 is always high.
Code:
DEFINE LCD_DREG PORTBDEFINE LCD_DBIT 0
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 5
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 4
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 2000
DEFINE LCD_DATAUS 50
PAUSE 100
'OSC is 20Mhz
asm
__CONFIG _CONFIG1L, _PLLDIV_5_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L
__CONFIG _CONFIG1H, _FOSC_XTPLL_XT_1H & _FCMEN_OFF_1H & _IESO_OFF_1H
; ; ; Oscillator Switchover mode disabled
; ; Fail-Safe Clock Monitor disabled
; XT oscillator, PLL enabled, XT used by USB
__CONFIG _CONFIG2L, _PWRT_ON_2L & _BOR_ON_2L & _BORV_2_2L & _VREGEN_ON_2L
__CONFIG _CONFIG2H, _WDT_OFF_2H
__CONFIG _CONFIG3H, _MCLRE_ON_3H & _LPT1OSC_OFF_3H & _PBADEN_OFF_3H & _CCP2MX_ON_3H
__CONFIG _CONFIG4L, _STVREN_ON_4L & _LVP_OFF_4L & _ICPRT_OFF_4L & _XINST_OFF_4L & _DEBUG_OFF_4L
endasm
DEFINE OSC 48
TRISA.4 = 1 ' RA4/T0CKI = input to TMR0 counter
TRISA.0 = 0 ' RA0 = output for LED
TRISB.0 = 0 ' RB0 = output for LED
CMCON = 7 ' All digital
i var byte
i=0
' Assign prescaler to WDT for 1:1 prescale on TMR0
' TMR0 clock will be from your external input on RA4/T0CKI
' Increment on high-to-low transitions
' If you prefer, then increment on low-to-high transitions
T0CON = 11111000 'T0CON = TMR0ON T08BIT T0CS T0SE PSA T0PS2 T0PS1 T0PS0
'
Lcdout $fe, 128, "Counter: ", #i
pause 100
Main:
TMR0L = 0 ' Clear TMR0 count before start
Loop1:
WHILE TMR0L = 0 ' Wait for high-to-low transition
WEND ' on RA4/T0CKI
pause 100
PORTB.0 = 1 ' LED on to indicate transition seen
i=i+1 ' Clear screen
Lcdout $fe, 128, "Counter: ", #i
PAUSE 100
PORTB.0 = 0 ' LED off
GOTO Main ' Start over
END
What did i miss?
regards,
tacbanon
-
Re: Counting led blinks..
Hi,
Not sure but the usual thing to check:
Does the pin you're trying to use have other functions mutliplexed to it, like ADC, Comparator, USB etc and does any of these peripherals need to be turned off for the pin to work in the mode you want. I see you've got the comparator covered but how about the ADC?
What do you mean by there is no display? Do you mean it doesn't the display the result or do you mean it doesn't display anything?
Again, check each pin against the datasheet, does have anything that may need to be turned off?
/Henrik.
-
Re: Counting led blinks..
hi,
Quote:
What do you mean by there is no display? Do you mean it doesn't the display the result or do you mean it doesn't display anything?
No display on the Lcd
Quote:
I see you've got the comparator covered but how about the ADC?
I dont think I'm gonna need ADC so I will need this...
ADCON0 = 000000 ' A/D converter off
ADCON1 = 15 ' make it digital
ucfg = 010100 ' I'm planning later on to use the usb
I'm not really sure if I'm getting it right, I'm struggling with the datasheet. The above added code has no effect..
tacbanon
-
Re: Counting led blinks..
Hi,
I got it, I have to remove ADCON0, just use ADCON1 = 15.
Thanks for your precious time, and "Thank GOD for PBP forum" :)
Next stop is to make this chip as usb cdc to pass the data to pc...
regards,
tacbanon
-
Re: Counting led blinks..
Hi, now I'm trying to create a usb cdc together with the reading pulse code.
Code:
asm ;__CONFIG _CONFIG1L, _PLLDIV_5_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L
__CONFIG _CONFIG1L, _PLLDIV_2_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L
__CONFIG _CONFIG1H, _FOSC_XTPLL_XT_1H & _FCMEN_OFF_1H & _IESO_OFF_1H
; ; ; Oscillator Switchover mode disabled
; ; Fail-Safe Clock Monitor disabled
; XT oscillator, PLL enabled, XT used by USB
__CONFIG _CONFIG2L, _PWRT_ON_2L & _BOR_ON_2L & _BORV_2_2L & _VREGEN_ON_2L
__CONFIG _CONFIG2H, _WDT_OFF_2H
__CONFIG _CONFIG3H, _MCLRE_ON_3H & _LPT1OSC_OFF_3H & _PBADEN_OFF_3H & _CCP2MX_ON_3H
__CONFIG _CONFIG4L, _STVREN_ON_4L & _LVP_OFF_4L & _ICPRT_OFF_4L & _XINST_OFF_4L & _DEBUG_OFF_4L
endasm
DEFINE OSC 48
DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 0
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 5
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 4
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 2000
DEFINE LCD_DATAUS 50
PAUSE 100
Include "cdc_desc.bas" ' Include the HID descriptors
buffer Var Byte[16]
Cnt VAR BYTE
Cnt = 16
TRISA.4 = 1 ' RA4/T0CKI = input to TMR0 counter
TRISA.0 = 0 ' RA0 = output for LED
CMCON = 7 ' All digital
ADCON1 = 001111 ' A/D converter off
' increment on low-to-high transitions
T0CON = 111000
USBInit ' Initialize USART
i var byte
i=0
'
Lcdout $fe, 128, "Counters: ", #i
pause 20
Main:
TMR0L = 0 ' Clear TMR0 count before start
USBService ' Service USB regularly
Loop1:
WHILE TMR0L = 0 ' Wait for high-to-low transition
WEND ' on RA4/T0CKI
pause 10
PORTB.0 = 1 ' LED on to indicate transition seen
i=i+1 ' Clear screen
buffer = i
Lcdout $fe, 128, "Counter: ", #i
'PAUSE 30
PORTB.0 = 0 ' LED off
USBService
USBOut 3, Buffer, cnt, Main
END
But I got this message "USB device not recognize". What could be causing this problem?
regards,
tacbanon
-
Re: Counting led blinks..
Hi,
I hope someone else will chime in and try to help you because I've never used USB and don't know what the usual culprits are. Only advice I can give is to look at other examples and compare. Perhaps start with a working example and then add your counting code in "on top".
/Henrik.
-
Re: Counting led blinks..
Okay thanks for the advice Henrik
regards,
tacbanon
-
Re: Counting led blinks..
Hi everyone, now the usb device is recognized and its in Port COM2. My only problem is that my pulse counter variable i is reseting back to zero when a pulse(acctually I'm using a button on RA4 to simulate the pulse) is detected. In the code I did not yet insert the command "USBOut 3, buffer, cnt, Main" to send to pc.
Code:
asm ;__CONFIG _CONFIG1L, _PLLDIV_5_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L
__CONFIG _CONFIG1L, _PLLDIV_2_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L
__CONFIG _CONFIG1H, _FOSC_XTPLL_XT_1H & _FCMEN_OFF_1H & _IESO_OFF_1H
; ; ; Oscillator Switchover mode disabled
; ; Fail-Safe Clock Monitor disabled
; XT oscillator, PLL enabled, XT used by USB
__CONFIG _CONFIG2L, _PWRT_ON_2L & _BOR_ON_2L & _BORV_2_2L & _VREGEN_ON_2L
__CONFIG _CONFIG2H, _WDT_OFF_2H
__CONFIG _CONFIG3H, _MCLRE_ON_3H & _LPT1OSC_OFF_3H & _PBADEN_OFF_3H & _CCP2MX_ON_3H
__CONFIG _CONFIG4L, _STVREN_ON_4L & _LVP_OFF_4L & _ICPRT_OFF_4L & _XINST_OFF_4L & _DEBUG_OFF_4L
endasm
DEFINE OSC 48
DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 0
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 5
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 4
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 2000
DEFINE LCD_DATAUS 50
PAUSE 100
Include "cdc_desc.bas" ' Include the HID descriptors
buffer Var Byte[16]
Cnt VAR BYTE
Cnt = 2
TRISA.4 = 1 ' RA4/T0CKI = input to TMR0 counter
TRISA.0 = 0 ' RA0 = output for LED
CMCON = 7 ' All digital
ADCON1 = 001111 ' A/D converter off
'If you prefer, then increment on low-to-high transitions
T0CON = 111000
USBInit ' Initialize USART
i var byte
i=0
' Assign prescaler to WDT for 1:1 prescale on TMR0
' TMR0 clock will be from your external input on RA4/T0CKI
' Increment on high-to-low transitions
'
Lcdout $fe, 128, "Counter: ", #i
'pause 20
Main:
USBService ' Must service USB regularly
TMR0L = 0 ' Clear TMR0 count before start
Loop1:
WHILE TMR0L = 0 ' Wait for high-to-low transition
USBService
WEND ' on RA4/T0CKI
pause 5
PORTB.0 = 1 ' LED on to indicate transition seen
i=i+1 ' increment i
Lcdout $fe, 128, "Counter: ", #i
USBService
PORTB.0 = 0 ' LED off
I appreciate any help...
thanks in advance,
tacbanon
-
Re: Counting led blinks..
When you enter the Loop1 routine you sit at the WHILE-WEND loop waiting for a pulse. When a pulse comes along you run thru the rest of the routine and finally pull PortB.0 low....then what happens?
There's no GOTO or END or anything after the Loop1 routine so the program will continue and continue and continue thru the (empty) codespace untill it reaches the end, then it'll wrap around and start over at the beginning and what happens there? Yep - you reset the count (i = 0) ;-)
By the way, you're now incrementing and displaying the i variable and not the TMR0 count but I guess that's intentional for now?
/Henrik.
-
Re: Counting led blinks..
Hi, yes your'e right Henrik "Goto Main" was all it need. :)
Quote:
By the way, you're now incrementing and displaying the i variable and not the TMR0 count but I guess that's intentional for now?
I think TMR0 and variable i are the same but only not reseting to zero, and I need it for visual.
I hope they can allow me here to continue, because I'm planning to incorporate an SD card module to hold the number of coins. :o
regards,
tacbanon
-
1 Attachment(s)
Re: Counting led blinks..
Hi, I would like to incorporate an sdcard to the project and record the number of coins, only when pressing a button (e.g RB7) , but first I want to make a seperate test program using Pic18F4550. As I understood the connection should be simple enough but just to make sure I attached an image of my connections(Please correct me if it's wrong). I found a source code but it's in C.
Code:
// example writing to SD card, sford
#include "mbed.h"
#include "SDFileSystem.h"
SDFileSystem sd(p5, p6, p7, p8, "sd"); // the pinout on the mbed Cool Components workshop board
int main() {
printf("Hello World!\n");
mkdir("/sd/mydir", 0777);
FILE *fp = fopen("/sd/mydir/sdtest.txt", "w");
if(fp == NULL) {
error("Could not open file for write\n");
}
fprintf(fp, "Hello fun SD Card World!");
fclose(fp);
printf("Goodbye World!\n");
}
The code creates a folder and writes "Hello fun SD Card World" to file name "sdtest.txt".
Hope anyone can help...
thanks in advance,
tacbanon
-
Re: Counting led blinks..
Hi,
That C-example does nothing for or with PBP, the C-compiler used in the example (which ever it is) has a built in library function to support a SD-card. There is no such function built into PBP. HOWEVER there is a SD-card example on (who would've thought) the examples page at MELABS (SDFS3.pbp).
With that said do you really need a SD-card? How much info do you need to store? The 4550 has 256bytes of EEPROM, can't you use that? Not that having a SD-card is "impossible" but using the EEPROM is going to be MUCH (I mean MUCH) easier than - which I think you'll see once you look at the example code.
/Henrik.
-
Re: Counting led blinks..
Hi Henrik, thanks for the responce. To be honest I already saw the link, but I'm skeptical because I dont really understand how it works(not simple for me). But I'm willing to try it out. I need to incorporate the sdcard because I'm trying to create a "coin operated computer rental app" I want later to save the number of coins and date/time per transaction. I also want to learn the EEPROM stuff but I was thinking about the capacity and since SDCARD can be quite cool (if I manage to incorporate it). I will try the link and post the results.
regards,
tacbanon
-
Re: Counting led blinks..
-
Re: Counting led blinks..
@mackrackit
very nice thanks for the link.
-
Re: Counting led blinks..
@mackrackit
Hi, I was able to run the example from melabs...but I'm interested how you made it as usb cdc and incorporating DT's interrupt, I tried to copy and paste your codes to see if it will compile, but unfortunately compiler errors occured on my setup. I have some questions that will help me understand using your code.
1. I use pic18F4550 instead of pic18F2550.
2. I dont have "SDFS.BAS" only "SDFS.PBP"
I dont have an rtc and temp sensor right now, only the sdcard. I commented out the functions that regards to the rtc and temp sensor. My goal at the meantime is to read/write to an sdcard and display its content to the hyperterminal.
thanks in advance,
tacbanon
-
Re: Counting led blinks..
The 4550 and 2550 are pretty much the same, just more or less I/Os.
SDFS.bas is the same as SDFS.pbp. Just different extensions. Way back when it was .bas.
What are the errors?
What version of PBP are you using?
Do you have DTs instant interrupt routines downloaded?
-
Re: Counting led blinks..
Hi, I was able to compile it without any error...and usb device is on port com2. I was expecting something will display on the communication terminal but I dont see any output. Probably I miss something on the conditions that needed to show some text.
Code:
'<FL_PIC18F2550>' '<FL_PBPL>'
DEFINE OSC 48
@ __CONFIG _CONFIG1L, _PLLDIV_5_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L ' I Change this, using 20Mhz crystal
@ __CONFIG _CONFIG1H, _FOSC_HSPLL_HS_1H
@ __CONFIG _CONFIG2H, _WDT_OFF_2H & _WDTPS_512_2H
@ __CONFIG _CONFIG2L, _PWRT_ON_2L & _VREGEN_ON_2L
@ __CONFIG _CONFIG3H, _PBADEN_OFF_3H & _MCLRE_OFF_3H
@ __CONFIG _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L
' Alias PIC pins and registers for SD/MMC card ' I follow this connections
SD_WE VAR PORTA.4 ' SD card write protect
SD_WE_TRIS VAR TRISA.4 ' SD card write protect direction
SDI VAR PORTA.5 ' SPI data in SD #7
SDI_TRIS VAR TRISA.5 ' SPI data in direction
SCL VAR PORTA.3 ' SPI clock SD #5
SCL_TRIS VAR TRISA.3 ' SPI clock direction
SD_CS VAR PORTC.2 ' SD card chip select SD #1
SD_CS_TRIS VAR TRISC.2 ' SD card chip select direction
SD_CD VAR PORTC.0 ' SD card detect
SD_CD_TRIS VAR TRISC.0 ' SD card detect direction
SDO VAR PORTC.1 ' SPI data out SD #2
SDO_TRIS VAR TRISC.1 ' SPI data out direction
INCLUDE "SDFS.PBP" ' Change extension to PBP
SDC_UseHardSPI = FALSE ' Use hardware SSP port for SPI.
INCLUDE "cdc_desc.bas" ' I have CDC_Desc, DT_INTS-18 and ReEnterPBP.BAS in the same folder
INCLUDE "DT_INTS-18.bas"
INCLUDE "ReEnterPBP-18.bas"
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT_INT, _CNT_PLUS, PBP, yes
INT_Handler USB_INT, _SERVICE_USB, ASM, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
'#########
'START USB AND INTERRUPTS
PAUSE 100 'TIME TO SETTLE
USBINIT 'INITIALIZE USB
USBSERVICE 'SERVICE USB
UIE = $7F 'ENABLE USB INTERRUPTS
UEIE = $9F 'ENABLE USB ERROR INTERRUPTS
PAUSE 500 'MORE TIME
USBINIT
USBSERVICE
@ INT_ENABLE USB_INT
USBSERVICE
@ INT_ENABLE INT_INT
'#########
'VARs AND DEFINEs
ADCON1 = 001110
LED VAR PORTA.2
TEXT_TIME VAR BYTE[6]
TEXT_DATE VAR BYTE[6]
TEXT_TEMP VAR BYTE[8]
TEXT_NO_CARD VAR BYTE[9]
MAC_FileName VAR BYTE[11]
B0 VAR BYTE
B1 VAR BYTE
CNT VAR WORD
CIU VAR BYTE 'CARD IN USE
CRON VAR BYTE[11]
CRON_D VAR BYTE[11]
SPACE VAR BYTE[2]
T_BUFFER VAR BYTE[8]
T_ONES VAR BYTE
T_TENS VAR BYTE
T_HUNS VAR BYTE
OUT_TEMP VAR BYTE
ADC_TEMP VAR WORD
S_TEMP VAR BYTE
X_TEMP VAR BYTE
'RTC DEFINES
DS_SCL VAR PORTB.1 'CLOCK
DS_SDA VAR PORTB.2 'DATA
RTC CON 010000
SEC_REG CON $00
CONT_REG CON $0E
CNTRL CON 000000
'RTC VARS
sec VAR BYTE: mins VAR BYTE: hr VAR BYTE: day VAR BYTE
date VAR BYTE: mon VAR BYTE: yr VAR BYTE
'RTC DEC VARS
SEC_O VAR BYTE: SEC_T VAR BYTE: MIN_O VAR BYTE: MIN_T VAR BYTE
HR_O VAR BYTE: HR_T VAR BYTE: MON_O VAR BYTE: MON_T VAR BYTE
DATE_O VAR BYTE: DATE_T VAR BYTE: YR_O VAR BYTE: YR_T VAR BYTE
'SD CARD FILE
FILE_seconds VAR BYTE: FILE_minutes VAR BYTE: FILE_hours VAR BYTE
FILE_day VAR BYTE: FILE_month VAR BYTE: FILE_year VAR BYTE
'#########
'SETS THE RTC TO PULSE OUT AT 1HZ
I2CWRITE DS_SDA, DS_SCL, RTC, CONT_REG, [CNTRL]
'SETS FILE NAME TO THE TIME BOARD IS POWERED
'GOSUB READ_RTC
MAC_FileName[0] = "1" '$30+HR_T 'Just made some dummy filename
MAC_FileName[1] = "0" '$30+HR_O
MAC_FileName[2] = "3" '$30+MIN_T
MAC_FileName[3] = "0" '$30+MIN_O
MAC_FileName[4] = "1" '$30+SEC_T
MAC_FileName[5] = "0" '$30+SEC_O
MAC_FileName[6] = " "
MAC_FileName[7] = " "
MAC_FileName[8] = "T"
MAC_FileName[9] = "X"
MAC_FileName[10] = "T"
'BUILD SOME USB TEXT
FOR B0 = 0 TO 5
LOOKUP B0,[" TIME "],B1
TEXT_TIME(B0) = B1
NEXT B0
FOR B0 = 0 TO 5
LOOKUP B0,[" DATE "],B1
TEXT_DATE(B0) = B1
NEXT B0
FOR B0 = 0 TO 7
LOOKUP B0,[" TEMP F "],B1
TEXT_TEMP(B0) = B1
NEXT B0
SPACE[0] = $d
SPACE[1] = $a
FOR B0 = 0 TO 9
LOOKUP B0,[" NO CARD",$d,$a],B1
TEXT_NO_CARD(B0) = B1
NEXT B0
CNT = 60 'I set CNT to 60 for test
'#########
'IF THE RTC NEEDS SET GOTO THE SET_RTC ROUTINE AND
'ENTER THE TIME AND DATE. RUN THE CODE ONCE THEN RE-COMMENT.
'GOSUB SET_RTC
'#########
'MAIN PROGRAM
CHECK:
IF CNT >= 60 THEN 'NUMBER OF SECONDS
CNT = 0
'GOSUB GET_T ' I disable this line, not read temperature
'GOSUB READ_RTC ' I disable this line, not read rtc
GOSUB USB_DISPLAY
IF (SD_WE = 0) AND (SD_CD = 0) THEN
GOTO SD_WRITE
ELSE
PWM LED,25,250
USBOUT 3, TEXT_NO_CARD, 10, CHECK
PAUSE 500
ENDIF
ENDIF
GOTO CHECK
'#########
'#########
'ISRs
CNT_PLUS:
IF CIU = 1 THEN
PWM LED,75,250
ELSE
IF (SD_WE = 0) AND (SD_CD = 0) THEN
TOGGLE LED
ELSE
LOW LED
ENDIF
ENDIF
CNT = CNT + 1
@ INT_RETURN
SERVICE_USB:
USBSERVICE
@ INT_RETURN
'#########
SET_RTC:
yr = $10
mon = $10
date = $09
sec = $00
mins = $52
hr = $02
I2CWRITE DS_SDA, DS_SCL, RTC, SEC_REG, [sec,mins,hr,day,date,mon,yr]
RETURN
'#########
READ_RTC:
I2CREAD DS_SDA, DS_SCL, RTC, SEC_REG, [sec,mins,hr,day,date,mon,yr]
SEC_T = sec & $70
SEC_T = SEC_T>>4
SEC_O = sec & $0F
MIN_T = mins & $70
MIN_T = MIN_T>>4
MIN_O = MINs & $0F
HR_T = hr & $70
HR_T = HR_T>>4
HR_O = hr & $0F
MON_T = mon & $70
MON_T = MON_T>>4
MON_O = mon & $0F
DATE_T = date & $70
DATE_T = DATE_T>>4
DATE_O = date & $0F
YR_T = yr & $70
YR_T = YR_T>>4
YR_O = yr & $0F
CRON[0] = " "
CRON[1] = $30+HR_T
CRON[2] = $30+HR_O
CRON[3] = ":"
CRON[4] = $30+MIN_T
CRON[5] = $30+MIN_O
CRON[6] = ":"
CRON[7] = $30+SEC_T
CRON[8] = $30+SEC_O
CRON[9] = $d
CRON[10] = $a
CRON_D[0] = " "
CRON_D[1] = $30+MON_T
CRON_D[2] = $30+MON_O
CRON_D[3] = "/"
CRON_D[4] = $30+DATE_T
CRON_D[5] = $30+DATE_O
CRON_D[6] = "/"
CRON_D[7] = $30+YR_T
CRON_D[8] = $30+YR_O
CRON_D[9] = $d
CRON_D[10] = $a
FILE_seconds = (SEC_T*10)+SEC_O
FILE_minutes = (MIN_T*10)+MIN_O
FILE_hours = (HR_T*10)+HR_O
FILE_day = (DATE_T*10)+DATE_O
FILE_month = (MON_T*10)+MON_O
FILE_year = (YR_T*10)+YR_O
RETURN
'#########
GET_T:
ADC_TEMP = 0
FOR X_TEMP = 1 TO 20
ADCON0=00000001
GOSUB READ_AD
S_TEMP = ADRESH
ADC_TEMP = ADC_TEMP + S_TEMP
PAUSE 250
NEXT X_TEMP
OUT_TEMP = ADC_TEMP / 20
OUT_TEMP = OUT_TEMP * 13/10
T_HUNS = OUT_TEMP/100
T_TENS = (OUT_TEMP - T_HUNS * 100)/10
T_ONES = OUT_TEMP-((T_HUNS*100)+(T_TENS*10))
T_BUFFER[0] = $30+T_HUNS
T_BUFFER[1] = $30+T_TENS
T_BUFFER[2] = $30+T_ONES
T_BUFFER[3] = " "
T_BUFFER[4] = " "
T_BUFFER[5] = " "
T_BUFFER[6] = $d
T_BUFFER[7] = $a
RETURN
READ_AD:
PAUSE 50
ADCON0.1=1
WHILE ADCON0.2=1:WEND
RETURN
'#########
USB_DISPLAY:
PAUSE 1
USBOUT 3, SPACE, 2, CHECK
PAUSE 1
USBOUT 3, TEXT_TIME, 6, CHECK
PAUSE 1
USBOUT 3, CRON, 11, CHECK
PAUSE 1
USBOUT 3, TEXT_DATE, 6, CHECK
PAUSE 1
USBOUT 3, CRON_D, 11, CHECK
PAUSE 1
USBOUT 3, TEXT_TEMP, 8, CHECK
PAUSE 1
USBOUT 3, T_BUFFER, 8, CHECK
PAUSE 1
RETURN
'#########
'SD CARD ROUTINES
SD_WRITE:
CIU = 1
SDINIT:
' FSInit initializes the card and reads all the preliminary information from it
GOSUB FSInit
IF (FAT_error != 0) THEN STOP
' Display card directory
GOSUB FINDfirst ' Find first file on card
WHILE (FAT_error = 0)
GOSUB FINDnext ' Find next file on card
WEND
SDFILENAME:
' This section defines a specific short (8.3) filename
' Note that spaces are use in empty elements and must be upper case for Windows
FAT_FileName[0] = MAC_FileName[0]
FAT_FileName[1] = MAC_FileName[1]
FAT_FileName[2] = MAC_FileName[2]
FAT_FileName[3] = MAC_FileName[3]
FAT_FileName[4] = MAC_FileName[4]
FAT_FileName[5] = MAC_FileName[5]
FAT_FileName[6] = MAC_FileName[6]
FAT_FileName[7] = MAC_FileName[7]
FAT_FileName[8] = MAC_FileName[8]
FAT_FileName[9] = MAC_FileName[9]
FAT_FileName[10] = MAC_FileName[10]
FAT_seconds = FILE_seconds
FAT_minutes = FILE_minutes
FAT_hours = FILE_hours
FAT_day = FILE_day
FAT_month = FILE_month
FAT_year = FILE_year+20
SDOPEN_W:
' Open a file for write
FAT_mode = "A" ' Write mode APPEND
GOSUB FSfopen ' Open file pointed to by Byte array FAT_FileName
IF (FAT_error = 10) THEN STOP
SD_WRITE_FILE:
' Write to file
FAT_src[0] = "T"
FAT_src[1] = "I"
FAT_src[2] = "M"
FAT_src[3] = "E"
FAT_src[4] = $d
FAT_src[5] = $a
FAT_src[6] = $30+HR_T
FAT_src[7] = $30+HR_O
FAT_src[8] = ":"
FAT_src[9] = $30+MIN_T
FAT_src[10] = $30+MIN_O
FAT_src[11] = ":"
FAT_src[12] = $30+SEC_T
FAT_src[13] = $30+SEC_O
FAT_src[14] = $d
FAT_src[15] = $a
FAT_src[16] = "D"
FAT_src[17] = "A"
FAT_src[18] = "T"
FAT_src[19] = "E"
FAT_src[20] = $d
FAT_src[21] = $a
FAT_src[22] = $30+MON_T
FAT_src[23] = $30+MON_O
FAT_src[24] = ":"
FAT_src[25] = $30+DATE_T
FAT_src[26] = $30+DATE_O
FAT_src[27] = ":"
FAT_src[28] = $30+YR_T
FAT_src[29] = $30+YR_O
FAT_src[30] = $d
FAT_src[31] = $a
FAT_src[32] = " "
FAT_src[33] = $30+T_HUNS
FAT_src[34] = $30+T_TENS
FAT_src[35] = $30+T_ONES
FAT_src[36] = " "
FAT_src[37] = "F"
FAT_src[38] = $d
FAT_src[39] = $a
FAT_src[40] = $d
FAT_src[41] = $a
FAT_count = 42
GOSUB FSfwrite
IF (FAT_error = 10) THEN STOP
IF (FAT_error != 0) THEN STOP
SDCLOSE:
' Close file
GOSUB FSfclose
IF (FAT_error != 0) THEN STOP
PAUSE 5000
CIU = 0
GOTO CHECK
What do you think I'm missing?
thanks,
tacbanon
-
Re: Counting led blinks..
Lets test the USB.
Go here and grab "USB_ASM_Service.pbp"
Then try this.
Code:
INCLUDE "cdc_desc.bas" ' Include the HID descriptors
INCLUDE "USB_ASM_Service.pbp" ' Base Interrupt System
BUFFER VAR BYTE[14]
LED VAR PORTA.2
ADCON1 = %00001111
CMCON = 7
buffer[0] = "H"
buffer[1] = "e"
buffer[2] = "l"
buffer[3] = "l"
buffer[4] = "o"
buffer[5] = " "
buffer[6] = "W"
buffer[7] = "o"
buffer[8] = "r"
buffer[9] = "l"
buffer[10] = "d"
buffer[11] = 13
buffer[12] = 10
buffer[13] = 0
Loop1:
USBOUT 3, buffer, 14, loop1
pause 500
TOGGLE LED
GOTO loop1
END
What version of PBP are you using?
-
1 Attachment(s)
Re: Counting led blinks..
Hi, I did test your code and its running without no problem.
I'm using PBP2.60
regards,
tacbanon
-
Re: Counting led blinks..
Ok, now we know your USB hardware is working. Have you been able to write anything to the SD card? Try a small SD card program without USB to make sure the SD card stuff works.