Hi,
That's weird.... As long as I send Snnn here I can't seem to make it fail. If I send Snn[CR] then it shows nn because apparently HSERIN terminates the reception when it sees the [CR], however if I just send Snn it times out properly. If I then return to properly sending Snnn it works fine again.
Try calling this:At start up and from the timeout routine, it should flush the receive buffer.Code:FlushBuffer: While PIR1.5 HSERIN [TempWd] WEND TempWd=0 LCDOUT $FE,1,"Buffer flushed" RETURN
/Henrik.
Well I have no idea what's happening. I added the sub routine at the end of the code and then called it thus
And the subroutine gets called as part of the initialization before it checks the port in the main program loop. The results when using the serial coms util in MCS were again random. I managed three changes in a row before the LCD reported 0 received. I tried the application written in LB and that too had similar results. I've also tried this application from my Son's PC and got the same result, so that would rule out my PC's port as the issue.Code:Term_RX: TempWD = 0 HSERIN[nTest] SELECT CASE nTest CASE "S" TempWD = 0 HSERIN 1000,RX_Bombed,[DEC3 TempWD] normtemp[0] = TempWD gosub send end select RETURN RX_Bombed: gosub FlushBuffer LCDOUT $FE,$80 lcdOUT $FE,$D4,"all we got was", dec TempWD LCDOUT $FE,$80 return FlushBuffer: While PIR1.5 HSERIN [TempWd] WEND TempWd=0 LCDOUT $FE,1,"Buffer flushed" RETURN
I've re-loaded one of the versions which included code written by DT which uses hyperterm to display data and allow variables to be changed one at a time and that functions just fine so that would suggest the coms on the EasyPIC5 board and the PIC don't have an issues.
One thing I have noticed, When I simplify the code to simply read the variable
and send say S789 from the serial communicator the LCD changes but displays 007 as if it's picked up the 1st byte and then ignored the rest. If I change the HSERIN line by removing DEC statement the LCD displays 055 ???? - I was expecting at least 078 ???Code:Term_RX: HSERIN[nTest] SELECT CASE nTest CASE "Q" gosub send CASE "S" gosub update End select Return update: HSERIN [DEC normtemp[0]] setpoints(0)=normtemp[0] gosub flushbuffer: return
I would welcome any further suggestions
Hi,
Try running it a slower baud rate, just as a test - say 2400 baud.
It is because you just say HSERIN [DEC Normtemp[0]] so PBP grabs the first character which is 7 - change that to DEC3 to grab three digits and properly convert it to 789.One thing I have noticed, When I simplify the code to simply read the variable and send say S789 from the serial communicator the LCD changes but displays 007 as if it's picked up the 1st byte and then ignored the rest.
And this is because you removed the DEC modifier so PBP again grabs one character and 55 is the ASCII code for "7".If I change the HSERIN line by removing DEC statement the LCD displays 055 ???? - I was expecting at least 078 ???
You have to remember that the PC (in this case) doesn't send the "value" 789 it sends the the individual digits representing the number as text "S", "7", "8", "9" if you look at that transmision with your serial port monitor you'll see that what is sent is 83 55 56 57 which are the ASCII codes for S789.
The DEC modifier converts the text representation of the value into an actual value. If you remove it the value stored in the variable will be the value received - which is 55 when you send "7".
/Henrik.
Full Code:
Code:ASM __CONFIG _CONFIG1H, _OSC_HSPLL_1H __CONFIG _CONFIG2L, _PWRT_ON_2L __CONFIG _CONFIG2H, _WDT_ON_2H & _WDTPS_512_2H __CONFIG _CONFIG3H, _PBADEN_OFF_3H __CONFIG _CONFIG4L, _LVP_OFF_4L & _XINST_OFF_4L ENDASM DEFINE OSC 48 ; uses 12Mhz xtal ADCON1 = $0F clear DEFINE LCD_DREG PORTB ' LCD Data port DEFINE LCD_DBIT 0 ' starting Data bit (0 or 4) DEFINE LCD_EREG PORTB ' LCD Enable port DEFINE LCD_EBIT 5 ' Enable bit (on EasyPIC 5 LCD) DEFINE LCD_RSREG PORTB ' LCD Register Select port DEFINE LCD_RSBIT 4 ' Register Select bit (on EasyPIC 5 LCD) DEFINE LCD_BITS 4 ' LCD bus size (4 or 8 bits) DEFINE LCD_LINES 4 ' number of lines on LCD DEFINE LCD_COMMANDUS 2000 ' Command delay time in us DEFINE LCD_DATAUS 50 ' Data delay time in us ;----[Port settings]---------------------------------------------------- TRISA = %11001111 TRISB = %00000000 TRISD = %00001111 CMCON = 7 ' disable Comparators ;----[USART defines]-------------------------------------------------------- DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 0 DEFINE HSER_CLROERR 1 ' Clear overflow automatically DEFINE HSER_SPBRG 25 ' 115200 Baud @ 48MHz, 0.16% SPBRGH = 0 BAUDCON.3 = 1 ' Enable 16 bit baudrate generator ColumnWidth CON 10 TempWD VAR WORD RCIF VAR PIR1.5 ' USART receive flag GIE VAR INTCON.7 tr var byte normtemp VAR WORD[4] ' used to store the desired temperature setting normtemp1 VAR normtemp[0] normtemp2 VAR normtemp[1] normtemp3 VAR normtemp[2] normtemp4 VAR normtemp[3] nTest var byte temphold var byte temp var byte TimeoutCount var byte ;--------------------------------------------------------------------- ;set test values normtemp[0]=240 normtemp[1]=250 normtemp[2]=260 normtemp[3]=270 ;______________________________________________________________ gosub FlushBuffer main: FOR TempWD = 0 TO 1000 IF RCIF=1 THEN GOsub Term_RX PAUSE 1 NEXT TempWD pause 200 goto main Term_RX: HSERIN[nTest] SELECT CASE nTest CASE "S" TempWD = 0 HSERIN 1000,RX_Bombed,[DEC3 TempWD] normtemp[0] = TempWD gosub send Goto Term_Rx RX_Bombed: TimeoutCount = TimeOutCount + 1 lcdOUT $FE,1,"all we got was", dec TempWD,", ", DEC TimeOutCount end select Goto Term_Rx Send: HSEROUT [DEC normtemp[0],10] setpoints(0)=normtemp[0] LCDOut $FE,$D4,#setpoints(0)dig 2,#setpoints(0)dig 1,#setpoints(0)dig 0 RETURN FlushBuffer: While PIR1.5 HSERIN [TempWd] WEND TempWd=0 LCDOUT $FE,1,"Buffer flushed" RETURN
I tried this at 2400 baud (having use PIC multicalc to get the Uart setting) and it gave one error and then echoed all the subsequent entry's correctly. I then changed it back to 115200 and it works a treat- even with my friends application.
Henrick thanks for taking the time out to assist me with this, and for explaining the serial function in laymens terms, I have learnt a lot from your posts.
Now just got to amend the code so that it does the same for all the other variables
I think Charles was going to have his application send one long string of all the variables, maybe I should ask him if he can make it user selected so it updates just the one ?
Uhmmm strange things.. I spoke too soon.
If I follow your example code
when the program 1st runs and detects somthing in the buffer it gosubs to Term_RX, but with the goto hi-lighted above the program then never returns to the main program... If I change this to go to main I'm back where I started from...Code:Term_RX: HSERIN[nTest] SELECT CASE nTest CASE "S" TempWD = 0 HSERIN 1000,RX_Bombed,[DEC3 TempWD] normtemp[0] = TempWD gosub send Goto Term_Rx RX_Bombed: TimeoutCount = TimeOutCount + 1 lcdOUT $FE,1,"all we got was", dec TempWD,", ", DEC TimeOutCount end select Goto Term_Rx FlushBuffer: While PIR1.5 HSERIN [TempWd] WEND TempWd=0 LCDOUT $FE,1,"Buffer flushed" RETURN
I guess I should ask Charles to design his application so that it opens a second window to do the updates, and when it opens that window it sends a Q or P or something which makes the PIC jump to the Term_RX section, and then sends another character when the updating window is closed (sort of click APPLY )
Hi,
That goto was needed in order to test it at my end (I said I modified it), it was never my intention for you to copy/paste that code back into your application - sorry about that.
With this code:You are looping around polling the RCIF flag 1000 times in one second (basically). But at 115200 baud you're sending ~11500 bytes or characters per second (one startbit, 8 databots, one stopbot = 10bits per character).Code:main: FOR TempWD = 0 TO 1000 IF RCIF=1 THEN GOsub Term_RX PAUSE 1 NEXT TempWD pause 200 goto main
This means you're sending ~11.5 characters every millisecond. The PICs hardware buffer is only 2 levels deep so you're very likely to overrun the buffer before the HSERIN command is able to grab the data.
At 2400baud you're only sending 240 characters per second so your polling loop will have no problem catching the RCIF flag and jump to the Term_Rx routine before the buffer overruns.
Does that make sense?
/Henrik.
Bookmarks