Broken code


Closed Thread
Results 1 to 23 of 23

Thread: Broken code

  1. #1
    sinoteq's Avatar
    sinoteq Guest

    Default Broken code

    Hi,
    I am using a 18F4620 and now I have some really strange things going on. I have a sub that is shifiting data to a external chip. If the code is smaller than 5A7F this works perfectly, but if I change anything in the code so it becomes larger the sub stops to work. The sub is in the middle of my program and the things I change are not related at all with this sub. Any ideas??

    Mike

  2. #2
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    i elaredy something like that but... it never happen to me. What you need to do is to move your sub somewhere else.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  3. #3
    sinoteq's Avatar
    sinoteq Guest


    Did you find this post helpful? Yes | No

    Default But...

    If I move the sub won't another sub take it's place? And then that one will not work. I need all my subs working There must be a reason for these stange things, I just need someone to figure it out or point me in the right direction.

    Mike

  4. #4
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by sinoteq View Post
    If I move the sub won't another sub take it's place? And then that one will not work. I need all my subs working There must be a reason for these stange things, I just need someone to figure it out or point me in the right direction.

    Mike
    Which version of PBP are you using?

  5. #5
    sinoteq's Avatar
    sinoteq Guest


    Did you find this post helpful? Yes | No

    Default

    I am using MPLAB 7.10 and PicBasic Pro 2.46

  6. #6
    skimask's Avatar
    skimask Guest


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by sinoteq View Post
    I am using MPLAB 7.10 and PicBasic Pro 2.46
    Got some source code for us to look at?

    On another note - you said you are using the 4620 to shift code out to another chip. Are you using the hardware SPI? If so, I've had nothing but trouble with that (nothing in the errata from Microchip). But I gave up on the hardware SPI and just wrote some code to 'bit-bang' the shifting for me. Fixed all my problems...
    Last edited by skimask; - 7th February 2007 at 14:18.

  7. #7
    sinoteq's Avatar
    sinoteq Guest


    Did you find this post helpful? Yes | No

    Default

    I am using a bit bang shift out so that part is no problem. I have done some more investigation and this is what things looks like:

    I have a working program and I add ONE new variable (Fire_Rate Var Byte), this code compiles to 5A7F and is working.

    I change the variable to Word size (Fire_Rate Var Word) this code compiles to 5ABF. This is 64 bytes larger but that can be explained with the 64 bytes blocks used in the 18F flash. This code does not work.

    If I change back to Byte size variable and use Define Reset ORG to trick the PIC into "making my program bigger" by adding 64 empty bytes in the begining the code compiles to 5ABF. This code is working.

    I take it from this that the problem is not related to the program size but to the allocation of RAM. The Fire_Rate variable is not used at all in the sub that has the problem, but obviously it is related in some way, most likely because it is changing the RAM allocation and bank select.

    I will look at the list file and see if I can come up with why and where things stops to work.

    Mike

  8. #8
    Join Date
    Feb 2003
    Posts
    432


    Did you find this post helpful? Yes | No

    Default

    Do you have any BRANCH instructions which may need to be changed to BRANCHL ?
    Keith

    www.diyha.co.uk
    www.kat5.tv

  9. #9
    sinoteq's Avatar
    sinoteq Guest


    Did you find this post helpful? Yes | No

    Default

    Nope. Only old useful Goto and GOSUB. By the way I can't see anything strange with the LST file.

    Mike

  10. #10
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    Check to see if you have a GOSUB to any routine that doesn't issue a
    RETURN to get back.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  11. #11
    sinoteq's Avatar
    sinoteq Guest


    Did you find this post helpful? Yes | No

    Default

    Thank you for all ideas but still no luck in fixing the problem. The program jumps to the sub but the sub makes some really strange things before it jumps back to where should. If I just remove the new variable or make it a Byte size things are working. I will see what happenes if I make 2 new byte size variables, that should be similar to making one word variable and using a word variable becomes crap.

    Later.....
    Mike

  12. #12
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Since we have to play 20 questions here...

    Do you have any Assembly instructions in your code?

    Adding a variable might move something to a different bank than the program is expecting.
    <br>
    DT

  13. #13
    sinoteq's Avatar
    sinoteq Guest


    Did you find this post helpful? Yes | No

    Default Update

    Sorry for playing "20 questions". I could not post the code because the code should not be public knowledge. Anyway the problem is solved and here is an update.

    The problem is with RAM allocation, PBP has a problem when assigning RAM space to variables. In this case one byte of a WORD size variable was assigned to the last adress in BANKA and the other byte of the same Word variable to the first adress in BANK0. Variables can not span 2 banks and this is why strange things happend. Melabs helped me to find this and they are working on a fix for this. There is a workaround, assign any BYTE size variable to the last adress of each bank you are using. Check the .ASM file and you can see how many variables you are using. This problem can happen between all RAM banks not only BANKA and BANK0. For 18F4620 that I use I added

    n Var Byte $7F

    This prevents a WORD to be assigned to the last adress of BANKA and also solved the problem.

    If you have a program with many variables this is something you would like to check. This problem is ALSO in current versions of 2.47!

    Mike
    Last edited by sinoteq; - 17th February 2007 at 05:34.

  14. #14
    Join Date
    Nov 2014
    Posts
    16


    Did you find this post helpful? Yes | No

    Default Re: Broken code

    It is the day after Thanksgiving. This sound like a problem I am having with a PIC18F46K22. Certain subs that I call make the program go into outer space. I have even tried GOSUB to a subroutine that only contains a RETURN statement and it never returns. ONLY subs after what seems to be a sizable program exhibit this problem and it is every one of them.. Will check variables on the boundary on Monday.

  15. #15


    Did you find this post helpful? Yes | No

    Default Re: Broken code

    Have you overflowed (or is that overflown?) the stack? Don't know 18F46K22 but some 18F's have option to reset on stack overflow.

    George

  16. #16
    Join Date
    May 2004
    Location
    NW France
    Posts
    3,611


    Did you find this post helpful? Yes | No

    Default Re: Broken code

    no code to look at = no serious answer ....

    MIGHT be a stack overflow ...

    Alain
    ************************************************** ***********************
    Why insist on using 32 Bits when you're not even able to deal with the first 8 ones ??? ehhhhhh ...
    ************************************************** ***********************
    IF there is the word "Problem" in your question ...
    certainly the answer is " RTFM " or " RTFDataSheet " !!!
    *****************************************

  17. #17
    Join Date
    Nov 2014
    Posts
    16


    Did you find this post helpful? Yes | No

    Default Re: Broken code

    Watchdog timer is off, I do use an Assembly interrupt routine to create a time base using TIMER2. AT 16 MHZ I can make a 1/100th second interrupt.
    I do not think I am overflowing the stack (or maybe I am?) as there is one GOSUB to one subroutine at a time in a Mainloop which contains nothing but a RETURN statement. If I move the subroutine further up in the code, it works fine. It seems like once it is further down enough, no subroutine will RETURN back.
    The PIC has 64K of code space, I should be nowhere near that. I wonder if I am crossing some 2K boundary or something like that or if the interrupt routine
    screws up a bank select register. I use MOVFF in the assembly interrupt routine to save W, STATUS, BSR, PCLATH upon entering, and restore upon exiting then RETFIE.

  18. #18


    Did you find this post helpful? Yes | No

    Default Re: Broken code

    JOOQ I looked at 18F46K22 datasheet. You can read the stack pointer, STKPTR. Just before your call test the stack pointer. At least you know whether your about to overflow. And of course make sure you have STVREN on.

    George
    Last edited by towlerg; - 28th November 2014 at 20:41. Reason: old and stupid

  19. #19
    Join Date
    Jan 2009
    Location
    Miami, Florida USA
    Posts
    637


    Did you find this post helpful? Yes | No

    Default Re: Broken code

    Mark, most people here, including myself, won't be able to help you with assembly language. Only a few here have gone to the dark side and know assembly .

    You said that the RETURN command in your subroutine doesn't seem to be working. It is very important to know the line where the program isn't working anymore. What I ussually do is to write a line of code to turn on an LED for 5 seconds. Then, I move that line toward the end of the program until the LED doesn't turn on anymore. Put this line before entering the subroutine and then inside the subroutine and let us know what you find out.
    "No one is completely worthless. They can always serve as a bad example."

    Anonymous

  20. #20
    Join Date
    Nov 2014
    Posts
    16


    Did you find this post helpful? Yes | No

    Default Re: Broken code

    OK I am using MPLAB 8.92 with PICBASIC 3 Gold

    GOSUB TEST1 works fine
    GOSUB TEST2 (or ANY subroutine after it) does not
    Here is my code, all comments are welcome

    ; Tell PBP the expected system-clock frequency

    INCLUDE "PIC18F46K22.INC"

    DEFINE OSC 16

    'Define interrupt handler
    DEFINE INTHAND TIMERINT

    'Don’t insert CLRWDTs
    DEFINE NO_CLRWDT 1

    'Set receive register to receiver enabled
    DEFINE HSER_RCSTA 90h
    ' RCSTA

    'Set transmit register to transmitter enabled
    DEFINE HSER_TXSTA 20h

    'Set baud rate
    DEFINE HSER_BAUD 19200

    'Clear overrun error upon execution of every HSERIN command
    DEFINE HSER_CLROERR 1

    'disable intrs during EEPROM writes
    DEFINE WRITE_INT 1

    GOTO START
    '------------------------------------------------------------------------------------------------------------------------
    'interrupt handler

    ASM
    TIMERINT

    ;interrupt service routine

    ;MOVFF source, destination = move source reg to dest reg
    ;either register can be in ram 000 to FFF

    ;save critical registers
    MOVFF W,_PreISR_W ;save W register contents
    MOVFF STATUS,_PreISR_STATUS ;save contents of STATUS register
    MOVFF PCLATH,_PreISR_PCLATH ;save contents of PCLATH register
    MOVFF PCLATU,_PreISR_PCLATU ;save contents of PCLATU register
    MOVFF BSR,_PreISR_BSR ;save contents of BSR register
    MOVFF FSR0L,_PreISR_FSR0L ;ind addr pointer lo
    MOVFF FSR0H,_PreISR_FSR0H ;ind addr pointer hi

    CLRF PCLATH
    CLRF STATUS
    CLRF BSR

    ;look for the timer2 interrupt
    NextIfCLR PIR1,TMR2IF ;check if timer2 int flag is set
    GOTO NotTimer2INT ;no
    BCF PIR1,TMR2IF ;yes,reset timer2 int flag

    MOVLB H'A' ;select ram bank A

    ;increment interrupt counters
    INCF _INTRCOUNT,File_reg
    ;................................................. .................................................. .....................
    NotTimer2INT

    CHECKRS232

    ;If an overrun occurred, clear the OERR flag by clearing the CREN receiver enable bit.
    BANKSEL RCSTA1
    NextIfSET RCSTA1,1 ;check for overrun by testing the OERR flag
    GOTO OverRUN

    BANKSEL PIR1
    NextIfSET PIR1,RCIF ;check for any received data
    GOTO GOTchar

    MOVLB H'A' ;select ram bank A
    CLRF _RS232RECD
    GOTO FinishISR

    GOTchar
    BANKSEL RCREG1
    MOVF RCREG1,W_reg
    MOVLB H'A' ;select ram bank A
    MOVWF _RS232RECD
    GOTO FinishISR

    OverRUN
    BCF RCSTA1,1
    BCF RCSTA1,4
    NOP
    BSF RCSTA1,4

    FinishISR
    MOVFF _PreISR_PCLATH,PCLATH ;restore pre-isr PCLATH register
    MOVFF _PreISR_PCLATU,PCLATU ;restore pre-isr PCLATU register
    MOVFF _PreISR_STATUS,STATUS ;restore pre-isr STATUS register
    MOVFF _PreISR_BSR,BSR ;restore pre-isr BSR register
    MOVFF _PreISR_FSR0L,FSR0L ;ind addr pointer lo
    MOVFF _PreISR_FSR0H,FSR0H ;ind addr pointer hi
    MOVFF _PreISR_W,W

    RETFIE ;return from interrupt

    ENDASM
    '------------------------------------------------------------------------------------------------------------------------
    START:


    'setup the oscillator

    OSCCON = %01111100
    ' 0 IDLEN Device enters Sleep mode on SLEEP instruction
    ' .111 IRCF<2:0> = HFINTOSC – (16 MHz)
    ' ....1 Device is running from the clock defined by FOSC<3:0> of the CONFIG1H register
    ' .....1 HFINTOSC frequency is stable
    ' ......00 Primary clock (determined by FOSC<3:0> in CONFIG1H)

    OSCCON2 = %10000111
    ' 1 System clock comes from 4xPLL
    ' .0 System clock comes from an oscillator, other than SOSC
    ' ..0 Unimplemented: Read as ‘0’
    ' ...0 MFINTOSC is not used
    ' ....0 Secondary oscillator is shut off if no other sources are requesting it.
    ' .....1 PRISD: Primary Oscillator Drive Circuit Shutdown = Oscillator drive circuit on
    ' ......1 MFINTOSC is stable
    ' .......1 LFINTOSC is stable
    '------------------------------------------------------------------------------------------------------------------------
    'setup I/O pins

    'PORTA...................

    ANSELA = %00000111
    ' 0 Unimplemented: Read as ‘0’
    ' .0 Unimplemented: Read as ‘0’
    ' ..0 RA5 is digital
    ' ...0 Unimplemented: Read as ‘0’
    ' ....1 RA3 is analog AN3 = BUFFERED LIGHT SIG4
    ' .....1 RA2 is analog AN2 = BUFFERED LIGHT SIG3
    ' ......1 RA1 is analog AN1 = BUFFERED LIGHT SIG2
    ' .......1 RA0 is analog AN0 = BUFFERED LIGHT SIG1

    TRISA = %00111111
    ' 0 RA7 output = SELECT1
    ' .0 RA6 output = SELECT2
    ' ..1 RA5 input = MOTION INPUT STATUS
    ' ...1 RA4 input = SWITCH STATUS
    ' ....1 RA3 input = BUFFERED LIGHT SIG4
    ' .....1 RA2 input = BUFFERED LIGHT SIG3
    ' ......1 RA1 input = BUFFERED LIGHT SIG2
    ' .......1 RA0 input = BUFFERED LIGHT SIG1

    LATA.7 = 1
    LATA.6 = 1

    'PORTB...................

    ANSELB = %00000000
    ' 0 RB7 is digital = PGD
    ' .0 RB6 is digital = PGC
    ' ..0 RB5 is digital
    ' ...0 RB4 is digital
    ' ....0 RB3 is digital
    ' .....0 RB2 is digital
    ' ......0 RB1 is digital
    ' .......0 RB0 is digital

    TRISB = %11111111
    ' 1 RB7 input = PGD
    ' .1 RB6 input = PGC
    ' ..1 RB5 input = DIP3
    ' ...1 RB4 input = DIP2
    ' ....1 RB3 input = DIP1
    ' .....1 RB2 input = TEST CH4 button
    ' ......1 RB1 input = TEST CH3 button
    ' .......1 RB0 input = TEST CH2 button

    WPUB = %00111111
    ' 0 RB7 weak pullup disabled = PGD
    ' .0 RB6 weak pullup disabled = PGC
    ' ..1 RB5 weak pullup enabled
    ' ...1 RB4 weak pullup enabled
    ' ....1 RB3 weak pullup enabled
    ' .....1 RB2 weak pullup enabled
    ' ......1 RB1 weak pullup enabled
    ' .......1 RB0 weak pullup enabled

    IOCB = 0 'disable interrupt on change


    'PORTC...................

    ANSELC = %00000000
    ' 0 RC7 is digital
    ' .0 RC6 is digital
    ' ..0 RC5 is digital
    ' ...0 RC4 is digital
    ' ....0 RC3 is digital
    ' .....0 RC2 is digital
    ' ......0 RC1 is digital
    ' .......0 RC0 is digital

    TRISC = %10010000
    ' 1 RC7 input = RX1
    ' .0 RC6 output = TX1
    ' ..0 RC5 output = SDO
    ' ...1 RC4 input = SDI
    ' ....0 RC3 output = SCK
    ' .....0 RC2 output = LED
    ' ......0 RC1 output = CSDAC2
    ' .......0 RC0 output = CSDAC1

    LATC.2 = 1
    LATC.1 = 1
    LATC.0 = 1

    'PORTD...................

    ANSELD = %00000000
    ' 0 RD7 is digital
    ' .0 RD6 is digital
    ' ..1 RD5 is analog AN25 = MAX4 POT
    ' ...1 RD4 is analog AN24 = MAX3 POT
    ' ....1 RD3 is analog AN23 = MAX2 POT
    ' .....1 RD2 is analog AN22 = MAX1 POT
    ' ......1 RD1 is analog AN21 = MIN4 POT
    ' .......1 RD0 is analog AN20 = MIN3 POT

    TRISD = %10111111
    ' 1 RD7 input = RX2
    ' .0 RD6 output = TX2
    ' ..1 RD5 input = AN25 = MAX4 POT
    ' ...1 RD4 input = AN24 = MAX3 POT
    ' ....1 RD3 input = AN23 = MAX2 POT
    ' .....1 RD2 input = AN22 = MAX1 POT
    ' ......1 RD1 input = AN21 = MIN4 POT
    ' .......1 RD0 input = AN20 = MIN3 POT


    'PORTE...................

    ANSELE = %00000011
    ' ....0 RE3 is digital = TEST CH1 button
    ' .....0 RE2 is digital = interrupt output
    ' ......1 RE1 is analog AN6 = MIN2 POT
    ' .......1 RE0 is analog AN5 = MIN1 POT

    TRISE = %10001011
    ' 1 weak pullup enabled on RE3
    ' ....1 RE3 input = digital = TEST CH1
    ' .....0 RE2 output = for test purposes
    ' ......1 RE1 input = AN6 = MIN2 POT
    ' .......1 RE0 input = AN5 = MIN1 POT
    '------------------------------------------------------------------------------------------------------------------------
    'setup A/D converter

    ADCON1 = %00000000
    ' 0 Selects the special trigger from CCP5
    ' .000 bit 6-4 Unimplemented: Read as ‘0’
    ' ....00 A/D VREF+ connected to internal signal, AVDD
    ' ......00 A/D VREF- connected to internal signal, AVSS

    ADCON2 = %10111101
    ' 1 ADFM=right justified, ADRESH contains the 2 most significant bits ADRESL contains the 8 least significant bits
    ' .0 Unimplemented
    ' ..111 A/D Acquisition time = 20 TAD
    ' .....101 A/D Conversion Clock = FOSC/16

    ADCON0 = %0000001 'a/d is enabled
    '------------------------------------------------------------------------------------------------------------------------
    'setup timer0 (UNUSED)
    '
    ' T0CON = %XXXXXXXX
    ' 1 TMR0ON Enable Timer0
    ' .0 T08BIT Timer0 is configured as an 16-bit timer/counter
    ' ..0 T0CS Internal instruction cycle clock (CLKOUT)
    ' ...1 T0SE Increment on high-to-low transition on T0CKI pin
    ' ....0 PSA Timer0 prescaler is assigned. Timer0 clock input comes from prescaler output.
    ' 1 = TImer0 prescaler is NOT assigned. Timer0 clock input bypasses prescaler.
    ' 0 = Timer0 prescaler is assigned. Timer0 clock input comes from prescaler output.
    ' .....xxx T0PS<2:0> 111 = 1:256 prescale value'
    ' 110 = 1:128 prescale value
    ' 101 = 1:64 prescale value
    ' 100 = 1:32 prescale value
    ' 011 = 1:16 prescale value
    ' 010 = 1:8 prescale value
    ' 001 = 1:4 prescale value
    ' 000 = 1:2 prescale value
    '------------------------------------------------------------------------------------------------------------------------
    'setup timer2
    'Fosc/4 with prescaler=16 AND postscaler of 10 yields 25,000 Hz, count of 250 gives interrupt every hundreth of a second

    PR2 = 249 'Timer2 Period Register
    T2CON = %01001110
    '
    ' bit 7 Unimplemented: Read as ‘0’
    ' bit 6-3 T2OUTPS<3:0>: TimerX Output Postscaler Select bits
    ' 0000 = 1:1 Postscaler
    ' 0001 = 1:2 Postscaler
    ' 0010 = 1:3 Postscaler
    ' 0011 = 1:4 Postscaler
    ' 0100 = 1:5 Postscaler
    ' 0101 = 1:6 Postscaler
    ' 0110 = 1:7 Postscaler
    ' 0111 = 1:8 Postscaler
    ' 1000 = 1:9 Postscaler
    ' 1001 = 1:10 Postscaler
    ' 1010 = 1:11 Postscaler
    ' 1011 = 1:12 Postscaler
    ' 1100 = 1:13 Postscaler
    ' 1101 = 1:14 Postscaler
    ' 1110 = 1:15 Postscaler
    ' 1111 = 1:16 Postscaler
    ' bit 2 TMR2ON: Timer2 On bit
    ' 1 = Timer2 is on
    ' 0 = Timer2 is off
    ' bit 1-0 T2xCKPS<1:0>: Timer2-type Clock Prescale Select bits
    ' 00 = Prescaler is 1
    ' 01 = Prescaler is 4
    ' 1x = Prescaler is 16
    '------------------------------------------------------------------------------------------------------------------------
    ;setup registers for MSSP1..........................
    SSP1CON1 = %00100010
    ; 0....... WCOL: Write Collision Detect bit 0=No collision
    ; 0...... SSPOV: Receive Overflow Indicator bit 0 = No overflow
    ; 1..... SSPEN: Master Synchronous Serial Port Enable bit
    ; 1 = Enables serial port and configures SCK1, SDO1, SDI1 and SS1 as serial port pins
    ; 0.... CKP: Clock Polarity Select 0 = Idle state for clock is a low level
    ; 0010 SSPM<3:0>: Master Synchronous Serial Port Mode Select bits
    ; 0010 = SPI Master mode, clock = FOSC/64

    SSP1STAT = %01000000
    ; 0....... SMP: Sample bit 0 = Input data sampled at middle of data output time
    ; 1...... CKE: SPI Clock Select bit
    ; 1 = Transmit occurs on transition from active to Idle clock state
    ; 0 = Transmit occurs on transition from Idle to active clock state
    ; NOTE: found that 0 or 1 seems to work if using MSSP1
    ; but only 1 works with re-mapped MSSP2
    ; 0..... Used in I2C™ mode only.
    ; 0.... Used in I2C™ mode only.
    ; 0... Used in I2C™ mode only.
    ; 0.. Used in I2C™ mode only.
    ; 0 BF: Buffer Full Status bit 0 = Receive not complete, SSPxBUF is empty
    '------------------------------------------------------------------------------------------------------------------------
    ;initialize parameters



    ;*********************************
    ;TEST FOR CALLING SUBROUTINES

    GOSUB TEST1
    ;GOSUB TEST2

    ;*********************************


    RS232RECD = 0
    EXITCAL = 0
    ANALOG = 0

    TIMERFLAGS = 0
    TIMECTR0 = 0
    TIMECTR1 = 0
    TIMECTR2 = 0
    TIMECTR3 = 0
    TIMECTR4 = 0
    TIMECTR5 = 0
    TIMECTR6 = 0
    TIMECTR7 = 0

    TIMECTR0 = 1000 : TIMERFLAGS.0 = 1
    TIMECTR1 = 1000 : TIMERFLAGS.1 = 1
    TIMECTR2 = 1000 : TIMERFLAGS.2 = 1
    TIMECTR3 = 1000 : TIMERFLAGS.3 = 1
    TIMECTR4 = 1000 : TIMERFLAGS.4 = 1
    TIMECTR5 = 1000 : TIMERFLAGS.5 = 1
    TIMECTR6 = 1000 : TIMERFLAGS.6 = 1
    TIMECTR7 = 1000 : TIMERFLAGS.7 = 1

    POTMIN1 = 0
    POTMIN2 = 0
    POTMIN3 = 0
    POTMIN4 = 0

    POTMAX1 = 0
    POTMAX2 = 0
    POTMAX3 = 0
    POTMAX4 = 0

    LIGHT1 = 0
    LIGHT2 = 0
    LIGHT3 = 0
    LIGHT4 = 0

    ANALOGCAL1 = 65535
    ANALOGCAL2 = 65535
    ANALOGCAL3 = 65535
    ANALOGCAL4 = 65535

    CALBYTE = 0

    ANALOGOUT1 = 0
    ANALOGOUT2 = 0
    ANALOGOUT3 = 0
    ANALOGOUT4 = 0
    ;GOSUB SETANALOG1
    ;GOSUB SETANALOG2
    ;GOSUB SETANALOG3
    ;GOSUB SETANALOG4

    INPUTS.9 = 0
    INPUTS.10 = 0
    INPUTS.11 = 0
    INPUTS.12 = 0
    INPUTS.13 = 0
    INPUTS.14 = 0
    INPUTS.15 = 0

    ZONE1 = 20
    ZONE2 = 40
    ZONE3 = 60

    TIMEHYS = 10

    SSPEN = 0 ' disable/enable SSP to reset MSSP port
    PAUSE 2
    SSPEN = 1

    'check EEPROM for cal values dac_a
    READ 0, EEPROMCODE
    IF EEPROMCODE = $55AA THEN
    READ 2, EEPROMCAL
    IF EEPROMCAL > 1000 AND EEPROMCAL < 1500 THEN
    CALBYTE.0 = 1
    ANALOGCAL1 = EEPROMCAL
    ENDIF
    ENDIF

    'check EEPROM for cal values dac_b
    READ 10, EEPROMCODE
    IF EEPROMCODE = $55AA THEN
    READ 12, EEPROMCAL
    IF EEPROMCAL > 1000 AND EEPROMCAL < 1500 THEN
    CALBYTE.1 = 1
    ANALOGCAL2 = EEPROMCAL
    ENDIF
    ENDIF

    'check EEPROM for cal values dac_c
    READ 20, EEPROMCODE
    IF EEPROMCODE = $55AA THEN
    READ 22, EEPROMCAL
    IF EEPROMCAL > 1000 AND EEPROMCAL < 1500 THEN
    CALBYTE.2 = 1
    ANALOGCAL3 = EEPROMCAL
    ENDIF
    ENDIF

    'check EEPROM for cal values dac_d
    READ 30, EEPROMCODE
    IF EEPROMCODE = $55AA THEN
    READ 32, EEPROMCAL
    IF EEPROMCAL > 1000 AND EEPROMCAL < 1500 THEN
    CALBYTE.3 = 1
    ANALOGCAL4 = EEPROMCAL
    ENDIF
    ENDIF
    '------------------------------------------------------------------------------------------------------------------------
    'enable necessary interrupts

    'PIE1: PERIPHERAL INTERRUPT ENABLE (FLAG) REGISTER 1
    PIE1 = %00000010
    ' 0 Unimplemented: Read as ‘0’.
    ' .0 A/D Converter Interrupt disabled
    ' ..0 Enables the EUSART1 receive interrupt
    ' ...0 Disables the EUSART1 transmit interrupt
    ' ....0 Disables the MSSP1 interrupt
    ' .....0 Disables the CCP1 interrupt
    ' ......1 Enables the TMR2 to PR2 match interrupt
    ' .......0 Disables the TMR1 overflow interrupt

    'PIE2: PERIPHERAL INTERRUPT ENABLE (FLAG) REGISTER 2
    PIE2 = 0 'all of these interrupts disabled

    'PIE3: PERIPHERAL INTERRUPT ENABLE (FLAG) REGISTER 3
    PIE3 = 0 'all of these interrupts disabled

    'PIE4: PERIPHERAL INTERRUPT ENABLE (FLAG) REGISTER 4
    PIE3 = 0 'all of these interrupts disabled

    INTCON = %11000000
    'bit 7 GIE/GIEH: Global Interrupt Enable bit 1 = Enables all unmasked interrupts
    'bit 6 PEIE/GIEL: Peripheral Interrupt Enable bit (including timer2)
    'bit 5 TMR0IE: TMR0 Overflow Interrupt Enable bit 1 = Enables the TMR0 overflow interrupt
    'bit 4 INT0IE: INT0 External Interrupt Enable bit
    'bit 3 RBIE: Port B Interrupt-On-Change (IOCx) Interrupt Enable bit
    'bit 2 TMR0IF: TMR0 Overflow Interrupt Flag bit
    'bit 1 INT0IF: INT0 External Interrupt Flag bit
    'bit 0 RBIF: Port B Interrupt-On-Change (IOCx) Interrupt Flag bit

    INTCON2 = %00000100
    'bit 7 RBPU: PORTB Pull-up Enable bit 0 = PORTB pull-ups are enabled
    'bit 6 INTEDG0: External Interrupt 0 Edge Select bit
    'bit 5 INTEDG1: External Interrupt 1 Edge Select bit
    'bit 4 INTEDG2: External Interrupt 2 Edge Select bit
    'bit 3 Unimplemented: Read as ‘0’
    'bit 2 TMR0IP: TMR0 Overflow Interrupt Priority bit 1 =High priority
    'bit 1 Unimplemented: Read as ‘0’
    'bit 0 RBIP: RB Port Change Interrupt Priority bit

    INTCON3 = %00000000
    'bit 7 INT2IP: INT2 External Interrupt Priority bit
    'bit 6 INT1IP: INT1 External Interrupt Priority bit
    'bit 5 Unimplemented: Read as ‘0’
    'bit 4 INT2IE: INT2 External Interrupt Enable bit
    'bit 3 INT1IE: INT1 External Interrupt Enable bit
    'bit 2 Unimplemented: Read as ‘0’
    'bit 1 INT2IF: INT2 External Interrupt Flag bit
    'bit 0 INT1IF: INT1 External Interrupt Flag bit
    '------------------------------------------------------------------------------------------------------------------------

    ;***************************************
    ;********** M A I N L O O P **********
    ;***************************************

    MAINLOOP:

    GOSUB CHARRECEIVED

    'when INTRCOUNT = 100 we are at the one second boundary
    IF INTRCOUNT < 100 THEN GOTO MAINLOOP

    INTRCOUNT = 0

    IF CALBYTE < 15 THEN
    IF PORTC.2 = 0 THEN
    LATC.2 = 1
    GOTO MAIN2
    ELSE
    LATC.2 = 0
    GOTO MAIN2
    ENDIF
    ENDIF

    MAIN2:
    IF TIMECTR0 > 0 THEN TIMECTR0 = TIMECTR0 - 1
    IF TIMECTR1 > 0 THEN TIMECTR1 = TIMECTR1 - 1
    IF TIMECTR2 > 0 THEN TIMECTR2 = TIMECTR2 - 1
    IF TIMECTR3 > 0 THEN TIMECTR3 = TIMECTR3 - 1
    IF TIMECTR4 > 0 THEN TIMECTR4 = TIMECTR4 - 1
    IF TIMECTR5 > 0 THEN TIMECTR5 = TIMECTR5 - 1
    IF TIMECTR6 > 0 THEN TIMECTR6 = TIMECTR6 - 1
    IF TIMECTR7 > 0 THEN TIMECTR7 = TIMECTR7 - 1
    ;................................................. .................................................. .....................
    LATE.2 = 1

    'send data
    ;................................................. .................................................. .....................
    'send timer0
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["A"] : PAUSE 2
    HSEROUT [TIMECTR0.LOWBYTE] : PAUSE 2
    HSEROUT [TIMECTR0.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send timer1
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["B"] : PAUSE 2
    HSEROUT [TIMECTR1.LOWBYTE] : PAUSE 2
    HSEROUT [TIMECTR1.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send timer2
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["C"] : PAUSE 2
    HSEROUT [TIMECTR2.LOWBYTE] : PAUSE 2
    HSEROUT [TIMECTR2.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send timer3
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["D"] : PAUSE 2
    HSEROUT [TIMECTR3.LOWBYTE] : PAUSE 2
    HSEROUT [TIMECTR3.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send timer4
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["E"] : PAUSE 2
    HSEROUT [TIMECTR4.LOWBYTE] : PAUSE 2
    HSEROUT [TIMECTR4.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send timer5
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["F"] : PAUSE 2
    HSEROUT [TIMECTR5.LOWBYTE] : PAUSE 2
    HSEROUT [TIMECTR5.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send timer6
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["G"] : PAUSE 2
    HSEROUT [TIMECTR6.LOWBYTE] : PAUSE 2
    HSEROUT [TIMECTR6.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send timer7
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["H"] : PAUSE 2
    HSEROUT [TIMECTR7.LOWBYTE] : PAUSE 2
    HSEROUT [TIMECTR7.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send timerflags
    GOSUB CHARRECEIVED
    TEMP = RS232RECD
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["I"] : PAUSE 2
    HSEROUT [TEMP.LOWBYTE] : PAUSE 2
    HSEROUT [TEMP.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send light sensor1
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["J"] : PAUSE 2
    HSEROUT [LIGHT1.LOWBYTE] : PAUSE 2
    HSEROUT [LIGHT1.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send light sensor2
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["K"] : PAUSE 2
    HSEROUT [LIGHT2.LOWBYTE] : PAUSE 2
    HSEROUT [LIGHT2.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send light sensor3
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["L"] : PAUSE 2
    HSEROUT [LIGHT3.LOWBYTE] : PAUSE 2
    HSEROUT [LIGHT3.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send light sensor4
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["M"] : PAUSE 2
    HSEROUT [LIGHT4.LOWBYTE] : PAUSE 2
    HSEROUT [LIGHT4.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send potmin1
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["N"] : PAUSE 2
    HSEROUT [POTMIN1.LOWBYTE] : PAUSE 2
    HSEROUT [POTMIN1.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send potmin2
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["O"] : PAUSE 2
    HSEROUT [POTMIN2.LOWBYTE] : PAUSE 2
    HSEROUT [POTMIN2.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send potmin3
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["P"] : PAUSE 2
    HSEROUT [POTMIN3.LOWBYTE] : PAUSE 2
    HSEROUT [POTMIN3.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send potmin4
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["Q"] : PAUSE 2
    HSEROUT [POTMIN4.LOWBYTE] : PAUSE 2
    HSEROUT [POTMIN4.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send potmax1
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["R"] : PAUSE 2
    HSEROUT [POTMAX1.LOWBYTE] : PAUSE 2
    HSEROUT [POTMAX1.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send potmax2
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["S"] : PAUSE 2
    HSEROUT [POTMAX2.LOWBYTE] : PAUSE 2
    HSEROUT [POTMAX2.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send potmax3
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["T"] : PAUSE 2
    HSEROUT [POTMAX3.LOWBYTE] : PAUSE 2
    HSEROUT [POTMAX3.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send potmax4
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["U"] : PAUSE 2
    HSEROUT [POTMAX4.LOWBYTE] : PAUSE 2
    HSEROUT [POTMAX4.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send analogout1
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["V"] : PAUSE 2
    HSEROUT [ANALOGOUT1.LOWBYTE] : PAUSE 2
    HSEROUT [ANALOGOUT1.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send analogout2
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["W"] : PAUSE 2
    HSEROUT [ANALOGOUT2.LOWBYTE] : PAUSE 2
    HSEROUT [ANALOGOUT2.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send analogout3
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["X"] : PAUSE 2
    HSEROUT [ANALOGOUT3.LOWBYTE] : PAUSE 2
    HSEROUT [ANALOGOUT3.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send analogout4
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["Y"] : PAUSE 2
    HSEROUT [ANALOGOUT4.LOWBYTE] : PAUSE 2
    HSEROUT [ANALOGOUT4.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send analogoutcal1
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["Z"] : PAUSE 2
    HSEROUT [ANALOGCAL1.LOWBYTE] : PAUSE 2
    HSEROUT [ANALOGCAL1.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send analogoutcal2
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["a"] : PAUSE 2
    HSEROUT [ANALOGCAL2.LOWBYTE] : PAUSE 2
    HSEROUT [ANALOGCAL2.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send analogoutcal3
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["b"] : PAUSE 2
    HSEROUT [ANALOGCAL3.LOWBYTE] : PAUSE 2
    HSEROUT [ANALOGCAL3.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send analogoutcal4
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["c"] : PAUSE 2
    HSEROUT [ANALOGCAL4.LOWBYTE] : PAUSE 2
    HSEROUT [ANALOGCAL4.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send inputs
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["d"] : PAUSE 2
    HSEROUT [INPUTS.LOWBYTE] : PAUSE 2
    HSEROUT [INPUTS.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send zone1
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["e"] : PAUSE 2
    HSEROUT [ZONE1.LOWBYTE] : PAUSE 2
    HSEROUT [ZONE1.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send zone2
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["f"] : PAUSE 2
    HSEROUT [ZONE2.LOWBYTE] : PAUSE 2
    HSEROUT [ZONE2.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send zone3
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["g"] : PAUSE 2
    HSEROUT [ZONE3.LOWBYTE] : PAUSE 2
    HSEROUT [ZONE3.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'send time hysteresis
    GOSUB CHARRECEIVED
    HSEROUT [":"] : PAUSE 2
    HSEROUT ["h"] : PAUSE 2
    HSEROUT [TIMEHYS.LOWBYTE] : PAUSE 2
    HSEROUT [TIMEHYS.HIGHBYTE] : PAUSE 2
    HSEROUT ["!"] : PAUSE 2
    ;................................................. .................................................. .....................
    'read inputs..........
    ' BIT 0 = CH1 TEST PB = RE3 on when = 0
    ' BIT 1 = CH2 TEST PB = RB0 on when = 0
    ' BIT 2 = CH3 TEST PB = RB1 on when = 0
    ' BIT 3 = CH4 TEST PB = RB2 on when = 0
    ' BIT 4 = DIP1 = RB3 on when = 0
    ' BIT 5 = DIP2 = RB4 on when = 0
    ' BIT 6 = DIP3 = RB5 on when = 0
    ' BIT 7 = AUX SW INPUT = RA4 on when = 1
    ' BIT 8 = MOTION INPUT = RA5 on when = 1
    ; BIT 9 = SYSTEM MODE 0= normal 1= cal (set by external RS232 command)

    INPUTS.0 = PORTE.3
    INPUTS.1 = PORTB.0
    INPUTS.2 = PORTB.1
    INPUTS.3 = PORTB.2
    INPUTS.4 = PORTB.3
    INPUTS.5 = PORTB.4
    INPUTS.6 = PORTB.5
    INPUTS.7 = PORTA.4
    INPUTS.8 = PORTA.5
    ;................................................. .................................................. .....................
    'read light sensor 1 on AN0 = RA0 pin 2
    ADCON0 = %00000011
    ' 0 bit 7 Unimplemented: Read as ‘0’
    ' .00000 = AN0
    ' ......1 bit 1 GO/DONE: A/D Conversion Status bit
    ' 1 = A/D conversion cycle in progress
    ' Setting this bit starts an A/D conversion cycle.
    ' This bit is automatically cleared by hardware when
    ' the A/D conversion has completed.
    ' 0 = A/D conversion completed/not in progress
    ' .......1 bit 0 ADON: ADC Enable bit
    ' 1 = ADC is enabled
    ' 0 = ADC is disabled and consumes no operating current

    ADLOOP1:
    PAUSE 5
    If ADCON0.1 = 1 Then GOTO ADLOOP1 'Wait for low on bit-1 of ADCON0, conversion finished

    ANALOG.HIGHBYTE = ADRESH 'HIGH byte of result
    ANALOG.LOWBYTE = ADRESL 'LOW byte of result
    TEMPLONG1=ANALOG*100
    TEMPLONG2=TEMPLONG1/1023
    LIGHT1 = TEMPLONG2
    ;................................................. .................................................. .....................
    'read light sensor 2 on AN1 = RA1 pin 3
    ADCON0 = %00000111
    ' 0 bit 7 Unimplemented: Read as ‘0’
    ' .00001 = AN1
    ' ......1 bit 1 GO/DONE: A/D Conversion Status bit
    ' 1 = A/D conversion cycle in progress
    ' Setting this bit starts an A/D conversion cycle.
    ' This bit is automatically cleared by hardware when
    ' the A/D conversion has completed.
    ' 0 = A/D conversion completed/not in progress
    ' .......1 bit 0 ADON: ADC Enable bit
    ' 1 = ADC is enabled
    ' 0 = ADC is disabled and consumes no operating current

    ADLOOP2:
    PAUSE 5
    If ADCON0.1 = 1 Then GOTO ADLOOP2 'Wait for low on bit-1 of ADCON0, conversion finished

    ANALOG.HIGHBYTE = ADRESH 'HIGH byte of result
    ANALOG.LOWBYTE = ADRESL 'LOW byte of result
    TEMPLONG1=ANALOG*100
    TEMPLONG2=TEMPLONG1/1023
    LIGHT2 = TEMPLONG2
    ;................................................. .................................................. .....................
    'read light sensor 3 on AN2 = RA2 pin 4
    ADCON0 = %00001011
    ' 0 bit 7 Unimplemented: Read as ‘0’
    ' .00010 = AN2
    ' ......1 bit 1 GO/DONE: A/D Conversion Status bit
    ' 1 = A/D conversion cycle in progress
    ' Setting this bit starts an A/D conversion cycle.
    ' This bit is automatically cleared by hardware when
    ' the A/D conversion has completed.
    ' 0 = A/D conversion completed/not in progress
    ' .......1 bit 0 ADON: ADC Enable bit
    ' 1 = ADC is enabled
    ' 0 = ADC is disabled and consumes no operating current

    ADLOOP3:
    PAUSE 5
    If ADCON0.1 = 1 Then GOTO ADLOOP3 'Wait for low on bit-1 of ADCON0, conversion finished

    ANALOG.HIGHBYTE = ADRESH 'HIGH byte of result
    ANALOG.LOWBYTE = ADRESL 'LOW byte of result
    TEMPLONG1=ANALOG*100
    TEMPLONG2=TEMPLONG1/1023
    LIGHT3 = TEMPLONG2

    GOSUB CHARRECEIVED
    ;................................................. .................................................. .....................
    'read light sensor 4 on AN3 = RA3 pin 5
    ADCON0 = %00001111
    ' 0 bit 7 Unimplemented: Read as ‘0’
    ' .00011 = AN3
    ' ......1 bit 1 GO/DONE: A/D Conversion Status bit
    ' 1 = A/D conversion cycle in progress
    ' Setting this bit starts an A/D conversion cycle.
    ' This bit is automatically cleared by hardware when
    ' the A/D conversion has completed.
    ' 0 = A/D conversion completed/not in progress
    ' .......1 bit 0 ADON: ADC Enable bit
    ' 1 = ADC is enabled
    ' 0 = ADC is disabled and consumes no operating current

    ADLOOP4:
    PAUSE 5
    If ADCON0.1 = 1 Then GOTO ADLOOP4 'Wait for low on bit-1 of ADCON0, conversion finished

    ANALOG.HIGHBYTE = ADRESH 'HIGH byte of result
    ANALOG.LOWBYTE = ADRESL 'LOW byte of result
    TEMPLONG1=ANALOG*100
    TEMPLONG2=TEMPLONG1/1023
    LIGHT4 = TEMPLONG2
    ;................................................. .................................................. .....................
    'read POTMIN1 on AN5 = RE0 pin 8
    ADCON0 = %00010111
    ' 0 bit 7 Unimplemented: Read as ‘0’
    ' .00101 = AN5
    ' ......1 bit 1 GO/DONE: A/D Conversion Status bit
    ' 1 = A/D conversion cycle in progress
    ' Setting this bit starts an A/D conversion cycle.
    ' This bit is automatically cleared by hardware when
    ' the A/D conversion has completed.
    ' 0 = A/D conversion completed/not in progress
    ' .......1 bit 0 ADON: ADC Enable bit
    ' 1 = ADC is enabled
    ' 0 = ADC is disabled and consumes no operating current

    ADLOOP5:
    PAUSE 5
    If ADCON0.1 = 1 Then GOTO ADLOOP5 'Wait for low on bit-1 of ADCON0, conversion finished

    ANALOG.HIGHBYTE = ADRESH 'HIGH byte of result
    ANALOG.LOWBYTE = ADRESL 'LOW byte of result
    TEMPLONG1=ANALOG*100
    TEMPLONG2=TEMPLONG1/1023
    POTMIN1 = TEMPLONG2
    ;................................................. .................................................. .....................
    'read POTMIN2 on AN6 = RE1 pin 9
    ADCON0 = %00011011
    ' 0 bit 7 Unimplemented: Read as ‘0’
    ' .00110 = AN6
    ' ......1 bit 1 GO/DONE: A/D Conversion Status bit
    ' 1 = A/D conversion cycle in progress
    ' Setting this bit starts an A/D conversion cycle.
    ' This bit is automatically cleared by hardware when
    ' the A/D conversion has completed.
    ' 0 = A/D conversion completed/not in progress
    ' .......1 bit 0 ADON: ADC Enable bit
    ' 1 = ADC is enabled
    ' 0 = ADC is disabled and consumes no operating current

    ADLOOP6:
    PAUSE 5
    If ADCON0.1 = 1 Then GOTO ADLOOP6 'Wait for low on bit-1 of ADCON0, conversion finished

    ANALOG.HIGHBYTE = ADRESH 'HIGH byte of result
    ANALOG.LOWBYTE = ADRESL 'LOW byte of result
    TEMPLONG1=ANALOG*100
    TEMPLONG2=TEMPLONG1/1023
    POTMIN2 = TEMPLONG2

    GOSUB CHARRECEIVED
    ;................................................. .................................................. .....................
    'read POTMIN3 on AN20 = RD0 pin 19
    ADCON0 = %01010011
    ' 0 bit 7 Unimplemented: Read as ‘0’
    ' .10100 = AN20
    ' ......1 bit 1 GO/DONE: A/D Conversion Status bit
    ' 1 = A/D conversion cycle in progress
    ' Setting this bit starts an A/D conversion cycle.
    ' This bit is automatically cleared by hardware when
    ' the A/D conversion has completed.
    ' 0 = A/D conversion completed/not in progress
    ' .......1 bit 0 ADON: ADC Enable bit
    ' 1 = ADC is enabled
    ' 0 = ADC is disabled and consumes no operating current

    ADLOOP7:
    PAUSE 5
    If ADCON0.1 = 1 Then GOTO ADLOOP7 'Wait for low on bit-1 of ADCON0, conversion finished

    ANALOG.HIGHBYTE = ADRESH 'HIGH byte of result
    ANALOG.LOWBYTE = ADRESL 'LOW byte of result
    TEMPLONG1=ANALOG*100
    TEMPLONG2=TEMPLONG1/1023
    POTMIN3 = TEMPLONG2
    ;................................................. .................................................. .....................
    'read POTMIN4 on AN21 = RD1 pin 20
    ADCON0 = %01010111
    ' 0 bit 7 Unimplemented: Read as ‘0’
    ' .10101 = AN21
    ' ......1 bit 1 GO/DONE: A/D Conversion Status bit
    ' 1 = A/D conversion cycle in progress
    ' Setting this bit starts an A/D conversion cycle.
    ' This bit is automatically cleared by hardware when
    ' the A/D conversion has completed.
    ' 0 = A/D conversion completed/not in progress
    ' .......1 bit 0 ADON: ADC Enable bit
    ' 1 = ADC is enabled
    ' 0 = ADC is disabled and consumes no operating current

    ADLOOP8:
    PAUSE 5
    If ADCON0.1 = 1 Then GOTO ADLOOP8 'Wait for low on bit-1 of ADCON0, conversion finished

    ANALOG.HIGHBYTE = ADRESH 'HIGH byte of result
    ANALOG.LOWBYTE = ADRESL 'LOW byte of result
    TEMPLONG1=ANALOG*100
    TEMPLONG2=TEMPLONG1/1023
    POTMIN4 = TEMPLONG2
    ;................................................. .................................................. .....................
    'read POTMAX1 on AN22 = RD2 pin 21
    ADCON0 = %01011011
    ' 0 bit 7 Unimplemented: Read as ‘0’
    ' .10110 = AN22
    ' ......1 bit 1 GO/DONE: A/D Conversion Status bit
    ' 1 = A/D conversion cycle in progress
    ' Setting this bit starts an A/D conversion cycle.
    ' This bit is automatically cleared by hardware when
    ' the A/D conversion has completed.
    ' 0 = A/D conversion completed/not in progress
    ' .......1 bit 0 ADON: ADC Enable bit
    ' 1 = ADC is enabled
    ' 0 = ADC is disabled and consumes no operating current

    ADLOOP9:
    PAUSE 5
    If ADCON0.1 = 1 Then GOTO ADLOOP9 'Wait for low on bit-1 of ADCON0, conversion finished

    ANALOG.HIGHBYTE = ADRESH 'HIGH byte of result
    ANALOG.LOWBYTE = ADRESL 'LOW byte of result
    TEMPLONG1=ANALOG*100
    TEMPLONG2=TEMPLONG1/1023
    POTMAX1 = TEMPLONG2

    GOSUB CHARRECEIVED
    ;................................................. .................................................. .....................
    'read POTMAX2 on AN23 = RD3 pin 22
    ADCON0 = %01011111
    ' 0 bit 7 Unimplemented: Read as ‘0’
    ' .10111 = AN23
    ' ......1 bit 1 GO/DONE: A/D Conversion Status bit
    ' 1 = A/D conversion cycle in progress
    ' Setting this bit starts an A/D conversion cycle.
    ' This bit is automatically cleared by hardware when
    ' the A/D conversion has completed.
    ' 0 = A/D conversion completed/not in progress
    ' .......1 bit 0 ADON: ADC Enable bit
    ' 1 = ADC is enabled
    ' 0 = ADC is disabled and consumes no operating current

    ADLOOP10:
    PAUSE 5
    If ADCON0.1 = 1 Then GOTO ADLOOP10 'Wait for low on bit-1 of ADCON0, conversion finished

    ANALOG.HIGHBYTE = ADRESH 'HIGH byte of result
    ANALOG.LOWBYTE = ADRESL 'LOW byte of result
    TEMPLONG1=ANALOG*100
    TEMPLONG2=TEMPLONG1/1023
    POTMAX2 = TEMPLONG2
    ;................................................. .................................................. .....................
    'read POTMAX3 on AN24 = RD4 pin 27
    ADCON0 = %01100011
    ' 0 bit 7 Unimplemented: Read as ‘0’
    ' .11000 = AN24
    ' ......1 bit 1 GO/DONE: A/D Conversion Status bit
    ' 1 = A/D conversion cycle in progress
    ' Setting this bit starts an A/D conversion cycle.
    ' This bit is automatically cleared by hardware when
    ' the A/D conversion has completed.
    ' 0 = A/D conversion completed/not in progress
    ' .......1 bit 0 ADON: ADC Enable bit
    ' 1 = ADC is enabled
    ' 0 = ADC is disabled and consumes no operating current

    ADLOOP11:
    PAUSE 5
    If ADCON0.1 = 1 Then GOTO ADLOOP11 'Wait for low on bit-1 of ADCON0, conversion finished

    ANALOG.HIGHBYTE = ADRESH 'HIGH byte of result
    ANALOG.LOWBYTE = ADRESL 'LOW byte of result
    TEMPLONG1=ANALOG*100
    TEMPLONG2=TEMPLONG1/1023
    POTMAX3 = TEMPLONG2
    ;................................................. .................................................. .....................
    'read POTMAX4 on AN25 = RD5 pin 28
    ADCON0 = %01100111
    ' 0 bit 7 Unimplemented: Read as ‘0’
    ' .11001 = AN25
    ' ......1 bit 1 GO/DONE: A/D Conversion Status bit
    ' 1 = A/D conversion cycle in progress
    ' Setting this bit starts an A/D conversion cycle.
    ' This bit is automatically cleared by hardware when
    ' the A/D conversion has completed.
    ' 0 = A/D conversion completed/not in progress
    ' .......1 bit 0 ADON: ADC Enable bit
    ' 1 = ADC is enabled
    ' 0 = ADC is disabled and consumes no operating current

    ADLOOP12:
    PAUSE 5
    If ADCON0.1 = 1 Then GOTO ADLOOP12 'Wait for low on bit-1 of ADCON0, conversion finished

    ANALOG.HIGHBYTE = ADRESH 'HIGH byte of result
    ANALOG.LOWBYTE = ADRESL 'LOW byte of result
    TEMPLONG1=ANALOG*100
    TEMPLONG2=TEMPLONG1/1023
    POTMAX4 = TEMPLONG2

    LATE.2 = 0

    GOTO MAINLOOP
    '------------------------------------------------------------------------------------------------------------------------
    TEST1:
    RETURN
    '------------------------------------------------------------------------------------------------------------------------
    ;here a character was received via RS232
    CHARRECEIVED:
    IF RS232RECD = 0 THEN RETURN

    'enter CAL mode?
    IF RS232RECD = "A" THEN

    INPUTS.9 = 1 'set flag to in cal mode

    EXITCAL = 0

    If CALBYTE.0 = 1 THEN
    ANALOGOUT1 = ANALOGCAL1
    ELSE
    ANALOGOUT1 = 2540
    ENDIF

    If CALBYTE.1 = 1 THEN
    ANALOGOUT2 = ANALOGCAL2
    ELSE
    ANALOGOUT2 = 2540
    ENDIF

    If CALBYTE.2 = 1 THEN
    ANALOGOUT3 = ANALOGCAL3
    ELSE
    ANALOGOUT3 = 2540
    ENDIF

    If CALBYTE.3 = 1 THEN
    ANALOGOUT4 = ANALOGCAL4
    ELSE
    ANALOGOUT4 = 2540
    ENDIF

    RETURN
    ENDIF

    'increment analogout1 in cal mode?
    IF RS232RECD = "B" AND INPUTS.9 = 1 THEN
    ANALOGOUT1 = ANALOGOUT1 + 1
    IF ANALOGOUT1 > 2740 THEN ANALOGOUT1 = 2740
    IF ANALOGOUT1 < 2340 THEN ANALOGOUT1 = 2340
    RETURN
    ENDIF

    'decrement analogout1 in cal mode?
    IF RS232RECD = "b" AND INPUTS.9 = 1 THEN
    ANALOGOUT1 = ANALOGOUT1 - 1
    IF ANALOGOUT1 > 2740 THEN ANALOGOUT1 = 2740
    IF ANALOGOUT1 < 2340 THEN ANALOGOUT1 = 2340
    RETURN
    ENDIF

    'increment analogout2 in cal mode?
    IF RS232RECD = "C" AND INPUTS.9 = 1 THEN
    ANALOGOUT2 = ANALOGOUT2 + 1
    IF ANALOGOUT2 > 2740 THEN ANALOGOUT2 = 2740
    IF ANALOGOUT2 < 2340 THEN ANALOGOUT2 = 2340
    RETURN
    ENDIF

    'decrement analogout2 in cal mode?
    IF RS232RECD = "c" AND INPUTS.9 = 1 THEN
    ANALOGOUT2 = ANALOGOUT2 - 1
    IF ANALOGOUT2 > 2740 THEN ANALOGOUT2 = 2740
    IF ANALOGOUT2 < 2340 THEN ANALOGOUT2 = 2340
    RETURN
    ENDIF

    'increment analogout3 in cal mode?
    IF RS232RECD = "D" AND INPUTS.9 = 1 THEN
    ANALOGOUT3 = ANALOGOUT3 + 1
    IF ANALOGOUT3 > 2740 THEN ANALOGOUT3 = 2740
    IF ANALOGOUT3 < 2340 THEN ANALOGOUT3 = 2340
    RETURN
    ENDIF

    'decrement analogout3 in cal mode?
    IF RS232RECD = "d" AND INPUTS.9 = 1 THEN
    ANALOGOUT3 = ANALOGOUT3 - 1
    IF ANALOGOUT3 > 2740 THEN ANALOGOUT3 = 2740
    IF ANALOGOUT3 < 2340 THEN ANALOGOUT3 = 2340
    RETURN
    ENDIF

    'increment analogout4 in cal mode?
    IF RS232RECD = "E" AND INPUTS.9 = 1 THEN
    ANALOGOUT4 = ANALOGOUT4 + 1
    IF ANALOGOUT4 > 2740 THEN ANALOGOUT4 = 2740
    IF ANALOGOUT4 < 2340 THEN ANALOGOUT4 = 2340
    RETURN
    ENDIF

    'decrement analogout4 in cal mode?
    IF RS232RECD = "e" AND INPUTS.9 = 1 THEN
    ANALOGOUT4 = ANALOGOUT4 - 1
    IF ANALOGOUT4 > 2740 THEN ANALOGOUT4 = 2740
    IF ANALOGOUT4 < 2340 THEN ANALOGOUT4 = 2340
    RETURN
    ENDIF

    'increment zone3 in cal mode?
    IF RS232RECD = "F" AND INPUTS.9 = 1 THEN
    ZONE3 = ZONE3 + 1
    IF ZONE3 > 100 THEN ZONE3 = 100
    IF ZONE3 < ZONE2+5 THEN ZONE3 = ZONE2+5
    RETURN
    ENDIF

    'decrement zone3 in cal mode?
    IF RS232RECD = "f" AND INPUTS.9 = 1 THEN
    ZONE3 = ZONE3 - 1
    IF ZONE3 > 100 THEN ZONE3 = 100
    IF ZONE3 < ZONE2+5 THEN ZONE3 = ZONE2+5
    RETURN
    ENDIF

    'increment zone2 in cal mode?
    IF RS232RECD = "G" AND INPUTS.9 = 1 THEN
    ZONE2 = ZONE2 + 1
    IF ZONE2 > ZONE3-5 THEN ZONE2 = ZONE3-5
    IF ZONE2 < ZONE1+5 THEN ZONE2 = ZONE1+5
    RETURN
    ENDIF

    'decrement zone2 in cal mode?
    IF RS232RECD = "g" AND INPUTS.9 = 1 THEN
    ZONE2 = ZONE2 - 1
    IF ZONE2 > ZONE3-5 THEN ZONE2 = ZONE3-5
    IF ZONE2 < ZONE1+5 THEN ZONE2 = ZONE1+5
    RETURN
    ENDIF

    'increment zone1 in cal mode?
    IF RS232RECD = "H" AND INPUTS.9 = 1 THEN
    ZONE1 = ZONE1 + 1
    IF ZONE1 > ZONE2-5 THEN ZONE1 = ZONE2-5
    IF ZONE1 < 5 THEN ZONE1 = 5
    RETURN
    ENDIF

    'decrement zone1 in cal mode?
    IF RS232RECD = "h" AND INPUTS.9 = 1 THEN
    ZONE1 = ZONE1 - 1
    IF ZONE1 > ZONE2-5 THEN ZONE1 = ZONE2-5
    IF ZONE1 < 5 THEN ZONE1 = 5
    RETURN
    ENDIF

    'increment time hysteresis in cal mode?
    IF RS232RECD = "I" AND INPUTS.9 = 1 THEN
    TIMEHYS = TIMEHYS + 1
    IF TIMEHYS > 300 THEN TIMEHYS = 300
    IF TIMEHYS < 1 THEN TIMEHYS = 1
    RETURN
    ENDIF

    'decrement time hysteresis in cal mode?
    IF RS232RECD = "i" AND INPUTS.9 = 1 THEN
    TIMEHYS = TIMEHYS - 1
    IF TIMEHYS > 300 THEN TIMEHYS = 300
    IF TIMEHYS < 1 THEN TIMEHYS = 1
    RETURN
    ENDIF

    'exit cal mode?
    IF RS232RECD = "Z" AND INPUTS.9 = 1 THEN
    EXITCAL = 1
    RETURN
    ENDIF

    RETURN
    '------------------------------------------------------------------------------------------------------------------------
    TEST2:
    RETURN
    '------------------------------------------------------------------------------------------------------------------------
    'analog output 1 DAC1-A
    SETANALOG1:

    CSDAC1 = 0

    DACBUFFER= ANALOGOUT1
    DACBUFFER.15 = 0 'bit 15 1=Write to DACb 0=Write to DACa
    DACBUFFER.14 = 0 'bit 14 VREF Input Buffer Control bit 1=Buffered 0=Unbuffered
    DACBUFFER.13 = 1 'bit 13 GA: Output Gain Selection bit 1=1x 0=2x
    DACBUFFER.12 = 1 'bit 12 SHDN: Output Shutdown Control bit 1=VOUT is available 0=Shutdown

    SPI_BUFFER = DACBUFFER.HIGHBYTE
    SP_INT_FLAG = 0
    WHILE SP_INT_FLAG = 0 : WEND

    SPI_BUFFER = DACBUFFER.LOWBYTE
    SP_INT_FLAG = 0
    WHILE SP_INT_FLAG = 0 : WEND

    CSDAC1 = 1 ;disable DAC0

    RETURN
    '------------------------------------------------------------------------------------------------------------------------
    'analog output 2 DAC1-B
    SETANALOG2:

    CSDAC1 = 0 'enable DAC chip1

    DACBUFFER= ANALOGOUT2
    DACBUFFER.15 = 1 'bit 15 1=Write to DACb 0=Write to DACa
    DACBUFFER.14 = 0 'bit 14 VREF Input Buffer Control bit 1=Buffered 0=Unbuffered
    DACBUFFER.13 = 1 'bit 13 GA: Output Gain Selection bit 1=1x 0=2x
    DACBUFFER.12 = 1 'bit 12 SHDN: Output Shutdown Control bit 1=VOUT is available 0=Shutdown

    SPI_BUFFER = DACBUFFER.HIGHBYTE
    SP_INT_FLAG = 0
    WHILE SP_INT_FLAG = 0 : WEND

    SPI_BUFFER = DACBUFFER.LOWBYTE
    SP_INT_FLAG = 0
    WHILE SP_INT_FLAG = 0 : WEND

    CSDAC1 = 1 ;disable DAC chip1

    RETURN

    END

  21. #21
    Join Date
    Nov 2014
    Posts
    16


    Did you find this post helpful? Yes | No

    Default Re: Broken code

    OK Without changing any code I got the program to work. All I did was rearrange the subroutines. Is it possible that one of the subroutines was at a code page boundary?

  22. #22
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,588


    Did you find this post helpful? Yes | No

    Default Re: Broken code

    I'm not familiar with this routine at the bottom, but won't this run forever or does an interrupt engage?

    Code:
    SP_INT_FLAG = 0 
    WHILE SP_INT_FLAG = 0 : WEND
    Robert

  23. #23
    Join Date
    Nov 2014
    Posts
    16


    Did you find this post helpful? Yes | No

    Default Re: Broken code

    That code is writing to a Microchip MCP4922 DAC on the SPI bus.
    SP_INT_FLAG VAR PIR1.3 which is SSP1IF indicating the SPI write was completed by the micro.

    I suppose it could be an infinite loop if the micro fails to write to the SPI bus, but unlikely.

Similar Threads

  1. Reading in Manchester code
    By brid0030 in forum Code Examples
    Replies: 0
    Last Post: - 10th March 2009, 22:55
  2. How much code space do PBP statements use.
    By Darrel Taylor in forum Code Examples
    Replies: 5
    Last Post: - 13th February 2009, 22:31
  3. Loop with two motor and 2 sensors
    By MrRoboto in forum mel PIC BASIC
    Replies: 4
    Last Post: - 9th December 2008, 00:40
  4. Making Program Code Space your playground...
    By Melanie in forum Code Examples
    Replies: 15
    Last Post: - 19th July 2008, 09:26
  5. Melanies RTC code has broken
    By keithdoxey in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 6th October 2006, 16:22

Members who have read this thread : 3

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts