PDA

View Full Version : Serin timeout not working properly!



Megahertz
- 31st December 2009, 12:54
Happy New Year To everyone.
I am facing a small problem of Serin command. The timeout function is not working correctly. (Using 12F635 with WDT_OFF)


Main:
high led : pause 50 : low led
Serin FromRx,N2400,200,["pp3"],code
.....rest fo the code here

My led should blink 50mS ON & appx 200mS OFF when no data is comming from my RF Receiver. But this is not happening. Can someone help please? Thanks

Nicmus
- 31st December 2009, 13:28
Hi Megahertz,

If you want the LED to blink while waiting for input you must jump to your “Main” label after the timeout. Read the Serin command for more information.

HTH

Nick

Megahertz
- 31st December 2009, 14:43
Hi Megahertz,

If you want the LED to blink while waiting for input you must jump to your “Main” label after the timeout. Read the Serin command for more information.

HTH

Nick

Hello Nick, that is the problem. The serin command is not working as expected.

Bruce
- 31st December 2009, 14:56
It only jumps to a timeout label if you tell it where the label is.

Main:
high led : pause 50 : low led
Serin FromRx,N2400,200,Main,["pp3"],code
.....rest fo the code here

Megahertz
- 31st December 2009, 15:07
Sorry for the code, I have missed the *Main* while writing the question. It actually is there in my code.
I will correct my code statements to the following:


Main:
high led : pause 50 : low led
Serin FromRx,N2400,200,Main,["pp3"],code
.....rest of the code here
goto Main

The code enters main label and led blinks, but then it stops. I expect it to blink after every 200mS which is not happening.

Couple of times this happened as well that program entered main label, led blinked few times lets say 5 or 6 after every 200mS but then it stopped again.

I cannot understand this erratic behaviour of my PIC.

Bruce
- 31st December 2009, 15:13
The timeout period gets continuously reset if there's noise on the serial input pin. If you're trying to use this option with a noisy RF receiver, the timeout/label approach isn't going to work.

Megahertz
- 31st December 2009, 15:18
The timeout period gets continuously reset if there's noise on the serial input pin. If you're trying to use this option with a noisy RF receiver, the timeout/label approach isn't going to work.

Are there any other options?
I tried removing timeout period and use DT Interrupts, but it gave list of following errors.

Executing: "C:\PBP\PBPW.EXE" -ampasmwin -oq -z -p12F635 "TxRx.bas"
PICBASIC PRO(TM) Compiler 2.50b, (c) 1998, 2008 microEngineering Labs, Inc.
All Rights Reserved.

ERROR: Variable wsave3 position request 416 beyond RAM_END 127.
ERROR: Variable wsave2 position request 288 beyond RAM_END 127.
ERROR: Variable wsave1 position request 160 beyond RAM_END 127.
ERROR: Unable to fit variable wsave
ERROR: Unable to fit variable RS1_Save
ERROR: Unable to fit variable RS2_SaveHalting build on first failure as requested.
BUILD FAILED: Thu Dec 31 14:13:38 2009

Bruce
- 31st December 2009, 15:25
Open DT_INTS-14.bas and read the first few lines about the wsave errors.

Megahertz
- 31st December 2009, 15:34
Thanks for showing the starting point. I have fired a bullet in the dark as I do not know much about ASM, banks and stuff. BUT it has reduced the errors.

I still have few errors left.
My DT_IN... .bas looks like this now:


;wsave var byte $20 SYSTEM ' location for W if in bank0
wsave var byte $70 SYSTEM ' alternate save location for W
' if using $70, comment out wsave1-3
'
' --- IF any of these three lines cause an error ?? ----------------------------
' Comment them out to fix the problem ----
' -- It depends on which Chip you are using, as to which variables are needed --
;wsave1 var byte $A0 SYSTEM ' location for W if in bank1
;wsave2 var byte $120 SYSTEM ' location for W if in bank2
;wsave3 var byte $1A0 SYSTEM ' location for W if in bank3

And the errors are following:

Executing: "C:\PBP\PBPW.EXE" -ampasmwin -oq -z -p12F635 "TxRx.bas"
PICBASIC PRO(TM) Compiler 2.50b, (c) 1998, 2008 microEngineering Labs, Inc.
All Rights Reserved.

ERROR: Unable to fit variable RR2_Save
ERROR: Unable to fit variable RS1_Save
ERROR: Unable to fit variable RS2_SaveHalting build on first failure as requested.
BUILD FAILED: Thu Dec 31 16:29:42 2009

Thanks

Megahertz
- 31st December 2009, 15:43
OK, did some lookaround for the problem.
I have also commented in ReEnterPBP.bas the following


' T3_Save VAR WORD
' T4_Save VAR WORD

Now it seems that I am quiet near but one warning message is there still :


Executing: ........"TxRx.bas"
PICBASIC PRO(TM) Compiler 2.50b, (c) 1998, 2008 microEngineering Labs, Inc.
All Rights Reserved.
Warning[206] D:\BACKUP.........TXRX.ASM 752 : Found call to macro in column 1. (INT_CREATE)
Loaded D:\Backup..................TxRx.COD.
BUILD SUCCEEDED: Thu Dec 31 16:39:22 2009

Any advise if I should be bothered about the warning message?

Bruce
- 31st December 2009, 15:43
The 12F635 only has 64 bytes SRAM so if you're using DT ints with a PBP int handler you may need to free up some SRAM, and keep your int handler as simple as possible.

Hard to say without seeing what you're doing.

Megahertz
- 31st December 2009, 15:51
Hi Bruce, it seems we jumped across each others post at the same time. I have succeeded in building the project but a warning is there.

Warning[206] D:\BACKUP.........TXRX.ASM 752 : Found call to macro in column 1. (INT_CREATE)

Should I worry about it? Thanks for all the help.


P.S. Is there any online calculator around which can easily advise me when to expect the interrupt with TMR1 with 1:8 prescaler (4MHz) and also if DT Interrupts work with TMR0 in 12F635?

Bruce
- 31st December 2009, 15:55
Have you tried moving INT_CREATE out of column 1?

Edit: Look for a copy of Mister Es' calculator. Should be a link in a thread around here somewhere.

I don't think the calculator is going to help with what works & doesn't with DT ints, but Darrel already
answered part of your question back in this thread: http://www.picbasic.co.uk/forum/showthread.php?t=12354

Megahertz
- 31st December 2009, 16:06
Have you tried moving INT_CREATE out of column 1?

Column 1 ? What does it mean? Is it putting the ASM code somewhere in the middle of the code? Sorry for my ignorance on this topic.

Bruce
- 31st December 2009, 16:18
INT_CREATE in Column 1


ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RX_INT, _DoIntStuff, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor

INT_ENABLE RX_INT ; enable external UART RX interrupts
ENDASM

INT_CREATE not in Column 1


ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RX_INT, _DoIntStuff, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor

INT_ENABLE RX_INT ; enable external UART RX interrupts
ENDASM

Megahertz
- 31st December 2009, 16:22
Thank you Bruce. I learned something today that what a single press on the tab key can do for your code.

You are truly a master.
Thanks again.

Archangel
- 31st December 2009, 16:24
Column 1 ? What does it mean? Is it putting the ASM code somewhere in the middle of the code? Sorry for my ignorance on this topic.
Column 1: leftmost column of each line. Asm is picky about where you put things, just start the line with several spaces.

Megahertz
- 31st December 2009, 17:22
Hi, I am back again with a problem. This time it looks like the interrupt is serviced but only once and code does not move forward. Can you please have a look at my code and advise me if I am doing it right ?



Define OSC 4 ' OSCCON defaults to 4MHz on reset

INCLUDE "DT_INTS-14.bas" ; Base Interrupt System
INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts
Include "modedefs.bas"

@ __CONFIG _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_ON & _MCLRE_OFF & _CP_ON & _BOD_ON & _CPD_ON & _IESO_OFF & _FCMEN_ON & _WUREN_OFF

' Pin Definations are here
ToTx var GPIO.2
ToRx var GPIO.3
Monitor var GPIO.4
T1CON=49
main:
' Initialize the processor
TRISIO = %011000
CMCON0 = 7
GPIO=0
OPTION_REG = %00000111
WDA.4=1 : WPUDA.4=1
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _Setval, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

start0:
gpio.0=1 ' LED1

start:
gpio.1=1 ' LED 2
@ INT_ENABLE TMR1_INT
Serin ToRx, N2400,["pp3"],code
@ INT_DISABLE TMR1_INT
if code=0 then goto start0
' ELSE CHECK OTHER VALUES FOR THE RECEIVED CODE
goto start0

Setval:
code=0
gpio.0=0 : pause 200
@ INT_RETURN


When power is applied this is what happens:
1) Both LED1 & LED2 glow
2) LED 1 (gpio.0) goes off
and system stays like this though LED should turn ON after 200mS. Please help me know what am I doing wrong?

Bruce
- 31st December 2009, 19:43
Sounds like it's working exactly like it should be.

1. TMR1 interrupts while it's sitting in your SERIN routine waiting for 3 ASCII characters
followed by the byte that gets placed in code (which by the way hasn't been declared).

2. Once the interrupt service routine executes, it returns right back to your SERIN
routine with the LED off.

Insert a toggle command in your int handler for a quick visual indication of the int handler
executing. That would tell you it's working or not.

And -as-is, it's never going to execute any code below your SERIN routine unless all 3 ASCII
characters + the byte that goes into your undeclared code VAR are received.

Megahertz
- 31st December 2009, 20:24
Hi Bruce, I did that and yes you are right (as always) about it. I Learnt a bit more about interrupts as well while dealing with this problem.

Can you please advise/explain me how can I make the code jump and move to the next line of Serin with help of Interrupts. I really appreciate your help.
Thanks


P.S: This is not the full code, all variables are declared in my code. I just tried to highlight the problem to you with minimum code here.

Darrel Taylor
- 1st January 2010, 07:25
I don't know if this is what you had in mind,
but it could be a possibility for your Timeout wishes.

With the extra features of the 12F635, you should be able to to create a WDT based timeout for the SERIN or other command(s).

Starting with the WDT turned off, and DEFINE NO_CLRWDT 1
And this un-tested code ... (don't have a 12F635)

DEFINE OSC 4 ' OSCCON defaults to 4MHz on reset
DEFINE NO_CLRWDT 1 ' stop kicking the DOG

ASM
CFG = _INTRC_OSC_NOCLKOUT ; Oscillator
CFG=CFG& _WDT_OFF ; Watch Dog Timer <-- Very Important
CFG=CFG& _PWRTE_ON ; Power-on Timer
CFG=CFG& _MCLRE_OFF ; Master Clear Reset
CFG=CFG& _BOD_OFF ; Brown-out Detect
CFG=CFG& _IESO_OFF ; Internal External Switchover
CFG=CFG& _FCMEN_ON ; Fail-Safe Clock Monitor
CFG=CFG& _WUREN_OFF ; Wake-up and Reset
CFG=CFG& _CP_OFF ; Code Protect
CFG=CFG& _CPD_OFF ; EEPROM Data Protect
__CONFIG CFG
ENDASM

INCLUDE "modedefs.bas"

'----[Pin Definations]------------------------------------------------------
LED1 VAR GPIO.0
LED2 VAR GPIO.1
ToTx VAR GPIO.2
ToRx VAR GPIO.3
Monitor VAR GPIO.4

;----[Variables/Aliases]----------------------------------------------------
TOaddr VAR WORD BANK0 SYSTEM
code VAR BYTE

WDTO VAR STATUS.4 ; WatchDog Timer Timeout bit
SWDTEN VAR WDTCON.0 ; Software WDT Enable
BAUD CON N2400

'----[Initialize]-----------------------------------------------------------
Init:
IF !WDTO THEN ; If the WDT timed out
TOGGLE LED2
ASM
movf TOaddr + 1, W ; Goto Timeout Address
movwf PCLATH
movf TOaddr, W
movwf PCL
ENDASM
ELSE ; Power-on, or other Reset
CMCON0 = 7
GPIO=0
OPTION_REG = %00000111
WDA.4=1 : WPUDA.4=1
WDTCON = %00010110 ; 1:65536, WDT off
ENDIF

;----[Main Program Loop]----------------------------------------------------
Main:
TOGGLE LED1
ASM
movlw LOW(_TimeOut1) ; Set the Timeout jump Address
movwf TOaddr
movlw HIGH(_TimeOut1)
movwf TOaddr + 1
CLRWDT ; kick the DOG first
ENDASM

SWDTEN = 1 ' enable the WDT
Serin ToRx, BAUD,["pp3"],code
SWDTEN = 0 ' disable the WDT

SELECT CASE code ' CHECK VALUES FOR THE RECEIVED CODE
CASE 0 ' Null code, no action

CASE 1
; do code 1

CASE ELSE ' Unknown Code
; don't know the code. Ignore or Warn
END SELECT
GOTO Main

TimeOut1: ' Timeout occured
SWDTEN = 0 ' disable the WTD
; notify user of timeout
; or do timeout cleanup
GOTO Main
Prior to starting a SERIN command, it saves an address to the Timeout1 Label and starts the WDT.

If the WDT times out during the SERIN command, the processor will RESET.

At the top of the program, it checks to see if the reset was from power-up, or the WDT. If it was from the WDT, it was a Timeout, so it jumps to the timeout label that was saved prior to starting the SERIN command.

All previous Stack levels are discarded. So the label that it jumps to MUST be in the Main loop.

Timeout period can be adjusted by changing the WDTCON prescaler.

Food for thought while drinking Champaigne.
Happy New Year!

Megahertz
- 1st January 2010, 10:39
Thanks Darell, it is very interesting how you can go around things in programming.
Is it possible you can provide PBP statements for the following lines of the code:


1) TOaddr VAR WORD BANK0 SYSTEM

2) ASM
movf TOaddr + 1, W ; Goto Timeout Address
movwf PCLATH
movf TOaddr, W
movwf PCL
ENDASM

3) ASM
movlw LOW(_TimeOut1) ; Set the Timeout jump Address
movwf TOaddr
movlw HIGH(_TimeOut1)
movwf TOaddr + 1
CLRWDT ; kick the DOG first
ENDASM

Also I wonder if similar way of using WDT can be adopted for 12c671/12F508/16F676 as I have few little projects pending involving these and all of them will have one thing common - A noisy RF receiver attached to one pin

Thanks

P.S - No problem if you have not tested the code. I will try to my best to do it first, just after I know the PBP equivalent of the above statements.

Darrel Taylor
- 1st January 2010, 19:48
1) is already a PBP statement.

2) If you really must ... could be changed to ...
PCLATH = TOaddr.HighByte
PCL = TOaddr.LowByte

3) Must stay exactly like it is in ASM.

With the 12c671/12F508/16F676's, the WDT can not be turned on and off in software.
So this approach will not work with those chips.
<br>

Megahertz
- 1st January 2010, 20:13
So this approach will not work with those chips.
<br>

Thanks for the info, please advise me as to what other possible techniques there are for solving this problem with these other chips?
Thanks

Darrel Taylor
- 1st January 2010, 20:29
The best way is to use PIC's that fit your task.
Don't try to make your task work in a PIC that doesn't have the features you need.

Buy more 12F635's, they're only a buck apiece.
_____________
DT
http://www.pbpgroup.com/files/SIGIMG/Pick_PIC.gif

Megahertz
- 1st January 2010, 20:41
Buy more 12F635's, they're only a buck apiece.

No problem with the price, but sometimes I need more pins and also I have more of 508 than 635, so I asked if there is any other possible solution as I have quiet a few 16f676 & 508 lying around.

Darrel Taylor
- 1st January 2010, 20:56
Then don't use a WAIT qualifier in your SERIN.

If the problem is a noisy receiver, then you will get data from the SERIN if you read every byte without Waiting, although most of it will be garbage.

Compare the "pp3" sequence manually, and once received, grab the next byte.
In the compare loop, do the timeout manually too.

Also, put a timeout in the SERIN statement, in case there isn't any noise at that time.

If the problem is that it locks up due to opposite IDLE state. That will not help at all.