formatting data sent to port
Guys, one further thing... when there is no sensor connected the value for say Temperatures(0) will be 0. When present it sends the temperature as a three digit value, eg 25.7c would be sent as 257. I really need to send a zero value as 000 and not a single 0,
any ideas ?
Banging head against wall !
This is really doing my head in... My friends application simply sends Q on launch, and the S+three digits representing the new value for just one variable followed by Q. Yet I keep getting incorrect values in the receive variable.
Here's the test code. For testing purpose all the values for each variable is fixed to populate his PC application. The only variable that is updated is the Target Temperature for Unit 1.
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
alarmhigh VAR WORD[4] ' used to store the desired high temp alarm values
alarmhigh1 VAR alarmhigh[0]
alarmhigh2 VAR alarmhigh[1]
alarmhigh3 VAR alarmhigh[2]
alarmhigh4 VAR alarmhigh[3]
alarmlow VAR WORD[4] ' used to store the desired low temp alarm values
alarmlow1 VAR alarmlow[0]
alarmlow2 VAR alarmlow[1]
alarmlow3 VAR alarmlow[2]
alarmlow4 VAR alarmlow[3]
lightsetHR VAR WORD[4] ' user to set light on hour
lightsetHR1 VAR lightsetHR[0]
lightsetHR2 VAR lightsetHR[1]
lightsetHR3 VAR lightsetHR[2]
lightsetHR4 VAR lightsetHR[3]
lightsetMN VAR WORD[4]
lightsetMN1 VAR lightsetMN[0]
lightsetMN2 VAR lightsetMN[1]
lightsetMN3 VAR lightsetMN[2]
lightsetMN4 VAR lightsetMN[3]
lightoffHR VAR WORD[4]
lightoffHR1 VAR lightoffHR[0]
lightoffHR2 VAR lightoffHR[1]
lightoffHR3 VAR lightoffHR[2]
lightoffHR4 VAR lightoffHR[3]
lightoffMN VAR WORD[4]
lightoffMN1 VAR lightoffMN[0]
lightoffMN2 VAR lightoffMN[1]
lightoffMN3 VAR lightoffMN[2]
lightoffMN4 VAR lightoffMN[3]
StartHour VAR WORD[4]
StartHour1 VAR StartHour[0]
StartHour2 VAR StartHour[1]
StartHour3 VAR StartHour[2]
StartHour4 VAR StartHour[3]
StartMin VAR WORD[4]
StartMin1 VAR StartMin[0]
StartMin2 VAR StartMin[1]
StartMin3 VAR StartMin[2]
StartMin4 VAR StartMin[3]
StopHour VAR WORD[4]
StopHour1 VAR StopHour[0]
StopHour2 VAR StopHour[1]
StopHour3 VAR StopHour[2]
StopHour4 VAR StopHour[3]
StopMin VAR WORD[4]
StopMin1 VAR StopMin[0]
StopMin2 VAR StopMin[1]
StopMin3 VAR StopMin[2]
StopMin4 VAR StopMin[3]
Droptemp VAR WORD[4]
droptemp1 var Droptemp[0]
droptemp2 var Droptemp[1]
droptemp3 var Droptemp[2]
droptemp4 var Droptemp[3] ; these will be set via pots
Temperatures VAR WORD[4]
Temp1 VAR Temperatures[0]
Temp2 VAR Temperatures[1]
Temp3 VAR Temperatures[2]
Temp4 VAR Temperatures[3]
spModes VAR BYTE[4] ' controls how set point is adjusted PC or POT
spMode1 VAR spModes[0]
spMode2 VAR spModes[1]
spMode3 VAR spModes[2]
spMode4 VAR spModes[3]
SetPoints VAR WORD[4] ' used to store the desired temperature setting
SetPoint1 VAR SetPoints[0]
SetPoint2 VAR SetPoints[1]
SetPoint3 VAR SetPoints[2]
SetPoint4 VAR SetPoints[3]
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]
FlashStar VAR BIT
nTest var byte
temphold var byte
temp var byte
;---------------------------------------------------------------------
;set test values
Temperatures[0]=230
Temperatures[1]=240
Temperatures[2]=250
Temperatures[3]=260
normtemp[0]=240
normtemp[1]=250
normtemp[2]=260
normtemp[3]=270
alarmlow[0]=180
alarmlow[1]=180
alarmlow[2]=180
alarmlow[3]=180
alarmhigh[0]=360
alarmhigh[1]=360
alarmhigh[2]=360
alarmhigh[3]=360
StartHour1=00
StartHour2=00
StartHour3=00
StartHour4=00
StartMin1=00
StartMin2=00
StartMin3=00
StartMin4=00
StopHour1=00
StopHour2=00
StopHour3=00
StopHour4=00
StopMin1=00
StopMin2=00
StopMin3=00
StopMin4=00
Droptemp[0]=180
Droptemp[1]=180
Droptemp[2]=180
Droptemp[3]=180
lightsetHR1=00
lightsetHR2=00
lightsetMN1=00
lightsetMN2=00
lightoffHR1=00
lightoffHR2=00
lightoffMN1=00
lightoffMN2=00
;______________________________________________________________
main:
FOR TempWD = 0 TO 1000
IF RCIF=1 THEN GOSUB Term_RX
PAUSE 2
NEXT TempWD
setpoints(0)=normtemp(0)
LCDOut $FE,$D4,#setpoints(0)dig 2,#setpoints(0)dig 1,#setpoints(0)dig 0
FlashStar = !FlashStar
pause 200
goto main
send:
Hserout [DEC3 Temperatures[0]]
Hserout [DEC3 Temperatures[1]]
Hserout [DEC3 Temperatures[2]]
Hserout [DEC3 Temperatures[3]]
HSEROUT [dec3 normtemp[0]]
HSEROUT [dec3 normtemp[1]]
HSEROUT [dec3 normtemp[2]]
HSEROUT [dec3 normtemp[3]]
Hserout [dec3 alarmlow[0]]
Hserout [dec3 alarmlow[1]]
Hserout [dec alarmlow[2]]
Hserout [dec alarmlow[3]]
Hserout [dec3 alarmhigh[0]]
Hserout [dec3 alarmhigh[1]]
Hserout [dec3 alarmhigh[2]]
Hserout [dec3 alarmhigh[3]]
hserout [#StartHour[0] DIG 1,#StartHour[0] DIG 0,#StartMin[0] DIG 1,#StartMin[0] DIG 0]
hserout [#StartHour[1] DIG 1,#StartHour[1] DIG 0,#StartMin[1] DIG 1,#StartMin[1] DIG 0]
hserout [#StartHour[2] DIG 1,#StartHour[2] DIG 0,#StartMin[2] DIG 1,#StartMin[2] DIG 0]
hserout [#StartHour[3] DIG 1,#StartHour[3] DIG 0,#StartMin[3] DIG 1,#StartMin[3] DIG 0]
hserout [#StopHour[0] DIG 1,#StopHour[0] DIG 0,#StopMin[0] DIG 1,#StopMin[0] DIG 0]
hserout [#StopHour[1] DIG 1,#StopHour[1] DIG 0,#StopMin[1] DIG 1,#StopMin[1] DIG 0]
hserout [#StopHour[2] DIG 1,#StopHour[2] DIG 0,#StopMin[2] DIG 1,#StopMin[2] DIG 0]
hserout [#StopHour[3] DIG 1,#StopHour[3] DIG 0,#StopMin[3] DIG 1,#StopMin[3] DIG 0]
Hserout [dec3 Droptemp[0]]
Hserout [dec3 Droptemp[1]]
Hserout [dec3 Droptemp[2]]
Hserout [dec3 Droptemp[3]]
hserout [#lightsetHR[0] DIG 1,#lightsetHR[0] DIG 0,#lightsetMN[0] DIG 1,#lightsetMN[0] DIG 0]
hserout [#lightsetHR[1] DIG 1,#lightsetHR[1] DIG 0,#lightsetMN[1] DIG 1,#lightsetMN[1] DIG 0]
hserout [#lightoffHR[0] DIG 1,#lightoffHR[0] DIG 0,#lightoffMN[0] DIG 1,#lightOFFMN[0] DIG 0]
hserout [#lightoffHR[1] DIG 1,#lightoffHR[1] DIG 0,#lightoffMN[1] DIG 1,#lightOFFMN[1] DIG 0]
return
Term_RX:
HSERIN[nTest]
SELECT CASE nTest
CASE "S"
HSERIN [normtemp[0]]
setpoints(0)=normtemp[0]
END SELECT
gosub send
return
On booting the PIC it displays the value of normtemp[0] as 240 on the LCD. I've used a serial port monitor and when the application is launched the port sniffer confirms that Q was sent and the PIC dumped the string of values to the port, which the application pics up and populates the text boxes correctly.
http://micro-heli.co.uk/Applaunch.jpg
The application has been written to allow the user to enter the desired target temperature directly in the associated text box as required such as 45.2 and then click on the UPDATE button. This then sends S followed by the new value as a three digit number in the same format as the PBP code. This can be confirmed by the port sniffer
http://micro-heli.co.uk/apperror.jpg
However, the LCD display then reads 052, and this is then sent back to the PC application (as can be seen if you follow through the digits in the com sniffer top window.
http://micro-heli.co.uk/RHC.jpg
I think by fluke I did manage to get it to work once where the normtemp[0] variable was correctly updated, but that was after a restart of both the windows application and the PIC. What's been suggested is that I need the PBP code to check that the PICs buffer is empty, but I'm not sure on how to best do that.
Eventually we need to be able to update all the values in the rest of the boxes, and it my understanding my friends application will simply send all the values back in one data stream that will match the same as that transmitted (less the first 12 digits as it doesn't need to update the current temperatures - this is a one way transmission from the PIC). Thus the RX section will have HSERIN for each variables as per the HSEROUT section - will this compound the problem or can someone suggest a better way of doing this.
Now we're getting somewhere
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 :eek:
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 ?