LDR response is always slow and in addition, it gives a voltage out which is proportional to the amount of light, what you want is an abrupt voltage change when the light is interrupted. I suggest using a photo-transistor or photo-diode instead of the LDR. A better alternative, if you can mechanically mount it is to use a slotted opto-coupler. This has the light source and sensor inside a single package with a slot between them. If you can arrange for your propeller or something attached to it to pass through the slot and interrupt the light beam it should work fast enough and in any ambient light conditions.
Brian.
Your problem is caused by the TSOP1556. What you are trying to get is a logic level change as the light is interrupted, the TSOP doesn't do that. Inside the TSOP is a carrier filter so it rejects any signal that doesn't look like it comes from a real IR remote control unit. Basically, you don't get a steady light beam from a remote control, it sends a kind of Morse code pattern made by switching on and off very rapid bursts of light, usually around 38,000 per second. The IR receiver contains a filter that blocks anything that isn't at that frequency so it doesn't respond to room lights being switched on or even sunlight falling on it. Your LED is producing a steady light beam so the filter is rejecting it.
You have two options, you can pulse your LED at 38KHz so the TSOP accepts it, or you can change to a non-filtered IR receiver. Personally, I would go for the second option as it is simpler and will give more accurate results.
Brian.
errorlevel -302 ;
ORG 0x00
GOTO INIT
ORG 0x04 ; Interrupt vector
NOP
NOP
CALL IntRupt ; Interrupt routine
BCF INTCON, 1 ; Reset int flag
RETFIE
INIT:
Counter EQU 0x20; Delay counter
SaveW EQU 0x40 ; To save W register
DHexVal EQU 0x28 ; Hex value to display
Tens EQU 0x41 ; Dec value to display LCD
Ones EQU 0x42 ; Dec value to display LCD
Disp10 EQU 0x30 ; Displ 1:0
Disp11 EQU 0x31 ; Displ 1:1
BANKSEL TRISA
MOVLW b'00000000' ; Set 0 to input
MOVWF TRISA
BANKSEL 0x5 ;
CLRF 0x5 ; Set All B pins to 0
BANKSEL TRISB
MOVLW b'00000001' ; Set 0 to input
MOVWF TRISB
BANKSEL 0x6 ;
CLRF 0x6 ; Set All B pins to 0
BANKSEL TRISD
MOVLW b'00000000' ; Set output
MOVWF TRISD
BANKSEL PORTD ;
CLRF PORTD ; Set All B pins to 0
movlw 0x07 ; Turn comparators off and enable
movwf 0x1f ; pins for I/O functions
bsf INTCON, GIE, ACCESS
gie01:
bcf INTCON, GIE
btfsc INTCON, GIE
goto gie01
clrf PORTA
clrf PORTB
clrf PORTC
clrf PORTD
clrf PORTE
movlw b'00000111'
movwf ADCON1
BSF INTCON, GIE
BSF INTCON, PEIE
BSF INTCON, 4
MOVLW .8 ;
MOVWF Counter ; Counter = 8
CALL InitTmr1 ; Init timer1
START: ; Main loop
CALL CheckTmr1 ; Check if tmr1 is done
movwf 0x22 ; Move returnvalue to register
btfsc 0x22,0 ; Is it 0, jump next line.
CALL CheckCounter ; Is it 1, Check counter.
CALL DispLCD ; Display values on LCDs
goto START
CheckTmr1
BTFSS PIR1, TMR1IF ; Timer1 Overflow?
RETLW 0x0 ; Still going, return 0
RETLW 0x1 ; Time's up!
CheckCounter:
DECFSZ Counter, F ; Decrease CounterA * 500ms
GOTO Jump1 ; If not zero Jump1
GOTO Jump2 ; If zero Jump2
Jump1: CALL InitTmr1 ; Restart timer
RETURN ; Return
Jump2: MOVLW .8 ; Reset Counter = 4
MOVWF Counter ; Counter = 2
CALL TimesUp ; Do the thingy
CALL InitTmr1 ; Restart timer
RETURN ; Return
DispLCD
; Display part 0/1 on displ 1
MOVF Ones, W ; Put Ones into W
ADDWF Ones, W
CALL LCD10 ; Translate W into display10
MOVWF Disp10 ; Save
MOVF Ones, W
ADDWF Ones, W
CALL LCD20
IORWF Disp10, W ; Add together
BCF PORTA, 0
BSF PORTA, 1 ; Turn on part 0 for disp 1,2
MOVWF PORTB ; Display part 0 on disp 1,2
MOVF Ones, W ; Put Ones into W
ADDWF Ones, W
CALL LCD11 ; Translate W into display11
MOVWF Disp11 ; Save
MOVF Ones, W
ADDWF Ones, W
CALL LCD21
IORWF Disp11, W ; Add together
BCF PORTA, 1
BSF PORTA, 0 ; Turn on part 1 for disp 1,2
MOVWF PORTB ; Display part 1 on disp 1,2
RETURN ; Done
LCD10
ADDWF PCL, F
RETLW b'00010110' ; 0:0
RETLW b'00001100' ; 1:0
RETLW b'00011100' ; 2:0
RETLW b'00001100' ; 3:0
RETLW b'00001010' ; 4:0
RETLW b'00001110' ; 5:0
RETLW b'00011110' ; 6:0
RETLW b'00000000' ; 7:0
RETLW b'00011110' ; 8:0
RETLW b'00001010' ; 9:0
LCD11
ADDWF PCL, F
RETLW b'00001110' ; 0:1
RETLW b'00000000' ; 1:1
RETLW b'00001010' ; 2:1
RETLW b'00001110' ; 3:1
RETLW b'00001100' ; 4:1
RETLW b'00000110' ; 5:1
RETLW b'00000110' ; 6:1
RETLW b'00001110' ; 7:1
RETLW b'00001110' ; 8:1
RETLW b'00001110' ; 9:1
LCD20
ADDWF PCL, F
RETLW b'11100000' ; 0:0
RETLW b'01100000' ; 1:0
RETLW b'11000000' ; 2:0
RETLW b'11100000' ; 3:0
RETLW b'01100000' ; 4:0
RETLW b'10100000' ; 5:0
RETLW b'10100000' ; 6:0
RETLW b'11100000' ; 7:0
RETLW b'11100000' ; 8:0
RETLW b'11100000' ; 9:0
LCD21
ADDWF PCL, F
RETLW b'10110000' ; 0:1
RETLW b'00000000' ; 1:1
RETLW b'01110000' ; 2:1
RETLW b'01100000' ; 3:1
RETLW b'11000000' ; 4:1
RETLW b'11100000' ; 5:1
RETLW b'11110000' ; 6:1
RETLW b'00000000' ; 7:1
RETLW b'11110000' ; 8:1
RETLW b'11000000' ; 9:1
TimesUp
MOVLW b'00000001'
XORWF PORTD, F
MOVF 0x21, W ; RPM
MOVWF DHexVal ; Display value
CLRF 0x21 ; Clear out, start over
CALL HexToDec ; Convert Hex to Dec
RETURN
HexToDec ; Convert Hex to dec
CLRF Ones
CLRF Tens
movf DHexVal, W ; Get hex value to convert
movwf Ones
repeat: movlw .10
subwf Ones, W
btfss STATUS, C
RETURN ; Done converting
movwf Ones
incf Tens, f
goto repeat
InitTmr1
BCF T1CON, TMR1ON ; Stop Timer1
BCF PIR1, TMR1IF ; Clear Timer1 overflow flag
BCF T1CON, 4
BCF T1CON, 5
BSF T1CON, TMR1ON ; Start Timer1
RETURN
IntRupt
MOVWF SaveW ; Save what's in W
MOVLW b'00000010'
XORWF PORTD, F
INCF 0x21, f ; Increase RPM counter
MOVF SaveW, W ; Restore W
BCF INTCON, 1 ; Reset int flag
RETURN ; And return
end
Hi,
Will let Brian go into the code detail as he is more familiar with your project.
Would just say a few things about you using the 18F4550 chip - for a start why ..?
Are you thinking that because its a USB chip that you can use USB ..? - in short you can really only use its USB function if you are programming in C - have never seen any code for assembler.
Your 16F code needs to be updated to match the differences of the 18F chips which is rather different in many small ways - different locations for the two levels of interrupt , high and low at 0x008 and 0x018 etc.
The ram banking and memory paging is also different etc , etc.
You need to search for the 16F to 18F migration documents from Microchip which will help identify all the areas you should address.
As you have just started coding, moving to a different chip series is perhaps not a good move so soon.
You are right again, I'm not going to use USB just trying to teach myself more about the P18F at the same time. But, yes I must go back to the P16 again because it suites my project better.
/ Morgan
; ===================================================== *
; Processor Type
; ==============
LIST P=18F4520,r=hex,n=80,x=off,st=off
errorlevel -302 ; no bank warnings
#include <P18F4520.INC>
;******************************************************************************
;
; Configuration bits
; ==================
; specified here are changes to the .inc file defaults
CONFIG OSC=INTIO67, PWRT=ON, BOREN=OFF, WDT=OFF, MCLRE=OFF, LPT1OSC=OFF, PBADEN=OFF
CONFIG LVP=OFF, XINST=OFF, DEBUG=OFF
;******************************************************************************
;
; Variable definitions
; ====================
; Bank0 variables 0x000 to 0x07F access ram
; (4550 bank0 to 0x05F only)
cblock 0x000
WREG_TEMP ;variable used for context saving
STATUS_TEMP ;variable used for context saving
BSR_TEMP ;variable used for context saving
ENDC
; Bank1 variables 0x100 to 0x1FF
cblock 0x100 ; BANK1
pntr
offset
dval
WORK1
; last address entered max FF
endc
; *****************************************************************************
;
; EEPROM data
; ===========
; Data to be programmed into the Data EEPROM is defined here
;
org 0Xf00000
de 0X10,0X00,0X15,0X14,0x20,0X22,0X19,0X13 ;de00
de 0X30,0X00,0X10,0X20,0X22,0X15,0X10,0X30 ; 08
de 0X21,0X30,0X00,0X00,0X00,0X00,0X00,0X00 ; 10
de 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00 ; 18
de 0X00,0X00,0X15,0X15,0X00,0X00,0X00,0X00 ; 20
de 0X00,0X00,0X10,0X10,0X10,0X10,0X10,0X10 ; 28
de 0X10,0X10,0X10,0X10,0X10,0X10,0X10,0X10 ; 30
de 0X10,0X10,0X10,0X10,0X10,0X10,0X10,0X10 ; 38
de 0X10,0X10,0X10,0X10,0X10,0X10,0X00,0X00 ; 40
de 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00 ; 48
de 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00 ; 50
de 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00 ; 58
de 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00 ; 60
de 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00 ; 68
de 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00 ; 70
de 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00 ; 78
de 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00 ; 80
de 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00 ; 88
de 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00 ; 90
de 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00 ; 98
de 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00 ; A0
de 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00 ; A8
de 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00 ; B0
de 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00 ; B8
de 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00 ; C0
de 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00 ; C8
de 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00 ; D0
de 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00 ; D8
de 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00 ; E0
de 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00 ; E8
de 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00 ; F0
de 0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00 ; F8
;******************************************************************************
;
; Reset vector
; ============
ORG 0x0000
nop
bootup goto Main ;go to start of main code
;******************************************************************************
;
; High priority interrupt vector
; ==============================
; This code will start executing when a high priority interrupt occurs or
; when any interrupt occurs if interrupt priorities are not enabled.
ORG 0x0008
bra HighInt ;go to high priority interrupt routine
;******************************************************************************
;
; Low priority interrupt vector
; =============================
; This code will start executing when a low priority interrupt occurs.
; This code can be removed if low priority interrupts are not used.
ORG 0x0018
; movff STATUS,STATUS_TEMP ;save STATUS register
; movff WREG,WREG_TEMP ;save working register
; movff BSR,BSR_TEMP ;save BSR register
; *** low priority interrupt code goes here ***
; movff BSR_TEMP,BSR ;restore BSR register
; movff WREG_TEMP,WREG ;restore working register
; movff STATUS_TEMP,STATUS ;restore STATUS register
retfie
;******************************************************************************
;
; High priority interrupt routine
; ===============================
; The high priority interrupt code is placed here to avoid conflicting with
; the low priority interrupt vector.
HighInt nop
hisrend retfie FAST
;******************************************************************************
;******************************************************************************
;
; Start of main program
; =====================
; initialisation of system, clear RAM , setup i/o ports
Main movlw b'01100010' ; set internal osc to 4 mhz
movwf OSCCON
ramclr movlb D'1' ; define bank1, so it and bank 0/15 (access)
; can be addressed without banking
clrf INTCON ; clear interupts
clrf STATUS ; reset to bank 0
clrf FSR1H ; FSR routine to clear ram banks 0 -4 only
clrf FSR1L
clrram clrf POSTINC1 ; clear location and inc
movlw 0x05 ; now in bank5 ?
subwf FSR1H,W
bnz clrram ; carry on clearing if not at bank5
; ***************************************************************************
;
; LOOKUP TABLE 18F
; ==============
disptble movwf TABWORK ; sets system for 18F lookups - 2 byte calls
bcf STATUS,C
rlcf TABWORK,F
movlw HIGH(table1)
btfsc STATUS,C
incf WREG,W
movwf PCLATH
movlw LOW(table1)
addwf TABWORK,W
btfsc STATUS,C
incf PCLATH,F
movwf PCL
table1 retlw 0x30 ; 0
retlw 0x31 ; 1
retlw 0x32 ; 2
retlw 0x33 ; 3
retlw 0x34 ; 4
retlw 0x35 ; 5
retlw 0x36 ; 6
retlw 0x37 ; 7
retlw 0x38 ; 8
retlw 0x39 ; 9
retlw 0x41 ; a
retlw 0x42 ; b
retlw 0x43 ; c
retlw 0x44 ; d
retlw 0x45 ; e
retlw 0x46 ; f
I have to ask the question, why are you simulating in ISIS when you assemble the program in MPLAB which has it's own simulator?
I use the PICKit2, in fact have two of them and a Salae logic analyzer, all hooked up to one PC. I find them excellent, especially when I can hook them to two processors in different parts of circuits and watch the signals between them on the analyzer.
Can you clarify, when you see the table/page problem, is it in the 16F628 or in the 18F4550 you see the problem? I've gotten confused over the debugging and the migration issues.
Brian.
Hi,
Well good move about getting the Pickit2 - a great buy - just make sure you buy the genuine Microchip one.
This Zif board is great value and well made, though a little interface cable makes connection a lot easier. **broken link removed**
For the 18F chips there is no Paging to worry about and all the system registers are in just one Bank so no Banksel to bother with.
Also the Ram banks are so big you don't normally have to worry about changing banks - the example code I sent allows you to have access to 384 bytes of user ram, banks 0 Access and bank 1, before changing to another Bank.
When using tables use this bit of code with them all - was given it by the Microchip forum guys.
Code:; *************************************************************************** ; ; LOOKUP TABLE 18F ; ============== disptble movwf TABWORK ; sets system for 18F lookups - 2 byte calls bcf STATUS,C rlcf TABWORK,F movlw HIGH(table1) btfsc STATUS,C incf WREG,W movwf PCLATH movlw LOW(table1) addwf TABWORK,W btfsc STATUS,C incf PCLATH,F movwf PCL table1 retlw 0x30 ; 0 retlw 0x31 ; 1 retlw 0x32 ; 2 retlw 0x33 ; 3 retlw 0x34 ; 4 retlw 0x35 ; 5 retlw 0x36 ; 6 retlw 0x37 ; 7 retlw 0x38 ; 8 retlw 0x39 ; 9 retlw 0x41 ; a retlw 0x42 ; b retlw 0x43 ; c retlw 0x44 ; d retlw 0x45 ; e retlw 0x46 ; f
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?