View previous topic :: View next topic |
Author |
Message |
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Thu Mar 12, 2020 10:56 am Post subject: Problems with Print and Bytematch |
|
|
I am having a problem using serial ports and byetmatch.
If I try to receive data on com1 when data had just been sent I get garbage added.
Also when the bytematch interrupt is triggered serial transmission continues and bytematch fails
so should serial transmission stop on the port
This code works ok
Note there is a CRLF at the end of transmission from Nextion
Code: |
'Interface between MPP solar products and PC terminal
$regfile = "m644pdef.dat" ' specify the used micro
Const Xtal = 8000000
$crystal = Xtal ' used crystal frequency
'$baud = 9600 ' use baud rate
$hwstack = 300
$swstack = 300
$framesize = 300
Dim Crc_16 As String * 2
Dim Work2 As Word At Crc_16 Overlay
Dim Work(35) As String * 40
Dim Thecrc As Word
Dim Rs232 As Byte
Dim Uart_command_in As String * 50
Dim Uart_command As String * 254
Dim Aruart_command(253) As Byte At Uart_command Overlay
Dim Send_command As String * 50
Dim Send_bytes(49) As Byte At Send_command Overlay
Dim Crcstr As String * 2
Dim Crcwrd As Word At Crcstr Overlay
Dim Z As Byte
Dim Task As Byte
Dim Temp1 As String * 20
Dim Temp2 As Word
Dim Temp3 As Byte
Dim Dog As String * 20
Dim V As Byte
Dim Crc As Byte
Dim Page As Byte
Dim Bres As Long '--This is the timer value
Declare Sub Chopup
Declare Sub Find_command
Declare Sub Cal_crc16
Declare Sub Nextion
$lib "glcdKS108.lbx"
'Config Graphlcd = 240x64 , Dataport = Portc , Controlport = Porta , Ce = 5 , Cd = 6 , Wr = 3 , Rd = 4 , Reset = 7 , Fs = 0 , Mode = 6
Config Graphlcd = 128 * 64sed , Dataport = Porta , Controlport = Portc , Ce = 2 , Ce2 = 3 , Cd = 7 , Rd = 6 , Reset = 4 , Enable = 5
Setfont Font8x8
Config Com1 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Com2 = 2400 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Serialin0 = Buffered , Size = 20 , Bytematch = 10
Config Serialin1 = Buffered , Size = 150
'Config Timer0 = Timer , Prescale = 1024 'configure the timer
'On Ovf0 Tim0_isr 'Define ISR handler for clock
' Enable Timer0 'Enable timer 0 interrupt
Enable Interrupts
Open "com2:" For Binary As #2
Open "com1:" For Binary As #1
V = 0
Temp1 = "Booting"
'Print #2 , "get page"
'Call Nextion
Wait 1
'Call Get_chr
Print #1 , "gridvolts.txt=" ; Chr(34) ; "Booting" ; Chr(34);
Call Nextion
Wait 2
'Print #2 , "status.gridvolts.txt=" + Chr(34) + Work(1) + Chr(34);
'Call Nextion
Cls
Setfont Font8x8
Lcdat 1 , 1 , "BOOTING"
Wait 3
Cls
Do
Wait 4
Loop
End 'end program
Sub Nextion
Printbin #1 , &HFF ; &HFF ; &HFF
Waitms 200
End Sub
Serial0charmatch:
While Ischarwaiting(#1) = 1
Rs232 = Inkey(#1) 'get a character from the buffer
If Rs232 = 13 Or Len(uart_command_in) > 20 Then 'uart_command full or enter key sent
'make uper case
Uart_command_in = Ucase(uart_command_in)
Select Case Uart_command_in
Case "STATUS"
Page = 1
Temp3 = 1
Case "STATUS2"
Page = 2
Temp3 = 1
Case "SETTINS"
Page = 3
Temp3 = 1
End Select
Uart_command_in = ""
Clear Serialin0
Else
Uart_command_in = Uart_command_in + Chr(rs232) 'add the character to the uart_command buffer
' Print Chr(rs232) ;
'Exit Do
End If
'End If
Wend
Lcdat 4 , 1 , "PAGE>" ; Page
Return
$include "font8x8.font"
|
But when I add the other port code which sends data to the Nextion display on com1 every 4 seconds
after getting data from com2 from my inverters it does not work unless I pick the time where its waiting
before continuing the loop to send a command to the inverters.
Code: |
'Interface between MPP solar products and PC terminal
$regfile = "m644pdef.dat" ' specify the used micro
Const Xtal = 8000000
$crystal = Xtal ' used crystal frequency
'$baud = 9600 ' use baud rate
$hwstack = 300
$swstack = 300
$framesize = 300
Dim Crc_16 As String * 2
Dim Work2 As Word At Crc_16 Overlay
Dim Work (35) As String * 40
Dim Thecrc As Word
Dim Rs232 As Byte
Dim Uart_command_in As String * 50
Dim Uart_command As String * 254
Dim Aruart_command (253) As Byte At Uart_command Overlay
Dim Send_command As String * 50
Dim Send_bytes (49) As Byte At Send_command Overlay
Dim Crcstr As String * 2
Dim Crcwrd As Word At Crcstr Overlay
Dim Z As Byte
Dim Task As Byte
Dim Temp1 As String * 20
Dim Temp2 As Word
Dim Temp3 As Byte
Dim Dog As String * 20
Dim V As Byte
Dim Crc As Byte
Dim Page As Byte
Dim Bres As Long '--This is the timer value
Dim R As Byte
Dim J As Byte
Declare Sub Chopup
Declare Sub Find_command
Declare Sub Cal_crc16
Declare Sub Nextion
$lib "glcdKS108.lbx"
'Config Graphlcd = 240x64 , Dataport = Portc , Controlport = Porta , Ce = 5 , Cd = 6 , Wr = 3 , Rd = 4 , Reset = 7 , Fs = 0 , Mode = 6
Config Graphlcd = 128 * 64sed , Dataport = Porta , Controlport = Portc , Ce = 2 , Ce2 = 3 , Cd = 7 , Rd = 6 , Reset = 4 , Enable = 5
Setfont Font8x8
Config Com1 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Com2 = 2400 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Serialin0 = Buffered , Size = 20 , Bytematch = 10
Config Serialin1 = Buffered , Size = 150
'Config Timer0 = Timer , Prescale = 1024 'configure the timer
'On Ovf0 Tim0_isr 'Define ISR handler for clock
' Enable Timer0 'Enable timer 0 interrupt
Enable Interrupts
Open "com2:" For Binary As # 2
Open "com1:" For Binary As # 1
V = 0
Temp1 = "Booting"
'Print #2 , "get page"
'Call Nextion
Wait 1
'Call Get_chr
Print # 1 , "gridvolts.txt=" ; Chr(34) ; "Booting" ; Chr(34);
Call Nextion
Wait 2
'Print #2 , "status.gridvolts.txt=" + Chr(34) + Work(1) + Chr(34);
'Call Nextion
Cls
Setfont Font8x8
Lcdat 1 , 1 , "BOOTING"
Wait 3
Cls
Do
' Select Case Uart_command_in
Select Case V
Case 0 'get the state of inverter
Uart_command_in = "QPIGS"
Task = 1
V = 1
Case 1
Uart_command_in = "QMOD" 'get mode inverter is in
Task = 3
V = 2
Case 2
Uart_command_in = "QPGS0" 'get inverter one state
Task = 4
V = 3
Case 3
Uart_command_in = "QPGS1" 'get inverter two state
Task = 4
V = 0
End Select
' End Select
Send_command = Uart_command_in
Uart_command_in = ""
Z = Len(send_command )
Thecrc = Crc16(send_bytes () , Z ) 'workout the CRC
Swap Thecrc
'Print Hex(thecrc)
Crcwrd = Thecrc
Wait 2
' If Pause > 2 Then
Print # 2 , Send_command ; Crcstr ; Chr(13) ;
' End If
Wait 2
' If Pause > 4 Then
While Ischarwaiting(# 2) = 1
Rs232 = Inkey(# 2) 'get a character from the buffer
If Rs232 = 13 Or Len(uart_command ) > 253 Then 'uart_command full or enter key sent
Temp2 = Instr(uart_command , "NAKss" )
If Temp2 > 0 Then 'inverter did not accept command
Uart_command = ""
Clear Serialin1
Print # 1 , "gridvolts.txt=" ; Chr(34) ; "NAKss" ; Chr(34);
Call Nextion
'Print #2 , ""
'Print #2 , "not accepted"
'Print #2 , ""
Else
Call Find_command
End If
Uart_command = ""
Clear Serialin1
Else
Uart_command = Uart_command + Chr(rs232 ) 'add the character to the uart_command buffer
End If
Wend
Loop
End 'end program
Sub Find_command
Local A As String * 3
Local B As String * 1
Local C As Byte
Local D As Byte
Local E As Long
C = &B00000111
Call Cal_crc16
If Crc = 1 Then
Disable Interrupts
Select Case Task
'Print "Status bits>" ; Work(17)
Case 1
Call Chopup
'get the state of inverter
Delchar Work (1) , 1 'remove the (
'work(17) staus bits
'Print ">>Inverter Stats<<"
' Print "Grid Volts=" ; Work(1)
Print # 1 , "gridvolts.txt=" ; Chr(34) ; Work (1) ; Chr(34);
Call Nextion
'Print "Grid Frequency=" ; Work(2)
Print # 1 , "gridfreq.txt=" ; Chr(34) ; Work (2) ; Chr(34);
Call Nextion
'Print "AC Output Volts=" ; Work(3)
Print # 1 , "outvolts.txt=" ; Chr(34) ; Work (3) ; Chr(34);
Call Nextion
'Print "AC Output Frequency" ; Work(4)
Print # 1 , "outfreq.txt=" ; Chr(34) ; Work (4) ; Chr(34);
Call Nextion
'Print "Apparent Power=" ; Work(5)
Temp2 = Val(work (5))
Temp1 = Str(temp2 )
Print # 1 , "outwatts.txt=" ; Chr(34) ; Temp1 ; Chr(34);
Call Nextion
'Print "Active Power=" ; Work(6)
'Print "Load=" ; Work(7) ; "%"
Temp2 = Val(work (7))
Temp1 = Str(temp2 )
Temp1 = Temp1 + "%"
Print # 1 , "load.txt=" ; Chr(34) ; Temp1 ; Chr(34);
Call Nextion
'Print "Buss Volts=" ; Work(
Print # 1 , "bussvolt.txt=" ; Chr(34) ; Work (8) ; Chr(34);
Call Nextion
'Print "Battery Volts=" ; Work(9)
Print # 1 , "battvolts.txt=" ; Chr(34) ; Work (9) ; Chr(34);
Call Nextion
'Print "Battery Discharge Current=" ; Work(16) ; "Amps"
'Print "Battery Current=" ; Work(10) ; "Amps"
'are we discharging
Temp2 = Val(work (10))
Print
Print "work10" ; Work (10)
Print
Temp2 = Val(work (10))
Select Case Temp2
Case Is > 0
'Temp2 = Val(work(10))
Work (10) = Str(temp2 )
'Work(10) = "+" + Work(10)
Print # 1 , "battamps.txt=" ; Chr(34) ; Work (10) ; Chr(34);
Call Nextion
Case 0
Temp2 = Val(work (16))
If Temp2 = 0 Then
Temp2 = 1
End If
Work (16) = Str(temp2 )
Work (16) = "-" + Work (16)
Print # 1 , "battamps.txt=" ; Chr(34) ; Work (16) ; Chr(34);
Call Nextion
End Select
'Print "Battery Capacity=" ; Work(11) ; "%"
Temp2 = Val(work (11))
Temp1 = Str(temp2 )
Temp1 = Temp1 + "%"
Print # 1 , "soc.txt=" ; Chr(34) ; Temp1 ; Chr(34);
Call Nextion
'Print "Inverter Heat Sink Temp=" ; Work(12) ; "C"
Temp2 = Val(work (12))
Temp1 = Str(temp2 )
Print # 1 , "inverttmp.txt=" ; Chr(34) ; Temp1 ; Chr(34);
Call Nextion
'Print "PV Current into Battery=" ; Work(13) ; "Amps"
'Print "PV Voltage=" ; Work(14) ; "Volts"
Temp2 = Val(work (14))
Temp1 = Str(temp2 )
Print # 1 , "panlvolts.txt=" ; Chr(34) ; Temp1 ; Chr(34);
Call Nextion
'Print "Solar Charger Battery Voltage=" ; Work(15) ; "Volts"
Temp2 = Val(work (13))
Temp1 = Str(temp2 )
Print # 1 , "panlamps.txt=" ; Chr(34) ; Temp1 ; Chr(34);
Call Nextion
A = Mid(work (17) , 1)
If A = "1" Then
'Print "SBU Priority=Yes"
Else
'Print "SBU Priority=No"
End If
A = Mid(work (17) , 2)
If A = "1" Then
'Print "Configuration Change"
Else
'Print "Configuration No Change"
End If
A = Mid(work (17) , 3)
If A = "1" Then
'Print "Solar Charger Firmware Updated"
Else
'Print "Solar Charger Firmware Not Updated"
End If
A = Mid(work (17) , 4)
If A = "1" Then
'Print "Load is On"
Else
'Print "Load is Off"
End If
A = Mid(work (17) , 6 , 3)
D = Binval(a )
'Select Case D
' Case 0
'Print "No charging On"
'Case 6
'Print "Solar charging On"
'Case 5
'Print "AC charging On"
'Case 7
'Print "Solar & AC Charging On"
'End Select
'QMOD device mode
Case 3
Work (1) = Mid(uart_command , 2 , 1 )
Select Case Work (1)
Case "P" 'POWER ON MODE
Work (4) = "POWER ON MODE"
Case "S" 'STANDBY MODE
Work (4) = "STANDBY MODE"
Case "L" 'LINE MODE
Work (4) = "LINE MODE"
Print # 1 , "va12.val=1" ;
Call Nextion
Case "B" 'BATTERY MODE
Work (4) = "BATTERY MODE"
Print # 1 , "va12.val=0" ;
Call Nextion
Case "F" 'FAULT MODE
Work (4) = "FAULT MODE"
Case "H" 'POWER SAVING MODE
Work (4) = "POWER SAVING MODE"
End Select
Print # 1 , "invmode.txt=" ; Chr(34) ; Work (4) ; Chr(34);
Call Nextion
Uart_command = ""
'inverter two state
Case 4
' V=0 QPGS1 V=1 QPGS0
If V = 0 Then
B = "2"
Else
B = ""
End If
Call Chopup
'the state of parallel inverter
'work() variable contents
'1 = parallel number 1 to 9 zero = not exist
'2 inverter serial number
'3 working mode
'4 fault code
Delchar Work (1) , 1 'remove the (
'work(17) staus bits
'Print ">>Inverter Stats<<"
' Print "Grid Volts=" ; Work(1)
If Work (1) = "1" Then 'yes have parra
'Print #2 , "yes have parra"
Print # 1 , "serial" ; B ; ".txt=" ; Chr(34) ; Work (2) ; Chr(34);
Call Nextion
Print # 1 , "gridvolts.txt=" ; Chr(34) ; Work (5) ; Chr(34);
Call Nextion
'Print "Grid Frequency=" ; Work(2)
Print # 1 , "gridfreq.txt=" ; Chr(34) ; Work (6) ; Chr(34);
Call Nextion
'Print "AC Output Volts=" ; Work(3)
Print # 1 , "outvolts.txt=" ; Chr(34) ; Work (7) ; Chr(34);
Call Nextion
'Print "AC Output Frequency" ; Work(4)
Print # 1 , "outfreq" ; B ; ".txt=" ; Chr(34) ; Work (8) ; Chr(34);
Call Nextion
'Print "Apparent Power=" ; Work(5)
Temp2 = Val(work (9))
Temp1 = Str(temp2 )
Print # 1 , "outwatts" ; B ; ".txt=" ; Chr(34) ; Temp1 ; Chr(34);
Call Nextion
'Print "Active Power=" ; Work(10)
'Print "Load=" ; Work(7) ; "%"
Temp2 = Val(work (11))
Temp1 = Str(temp2 )
Temp1 = Temp1 + "%"
Print # 1 , "load" ; B ; ".txt=" ; Chr(34) ; Temp1 ; Chr(34);
Call Nextion
'Print "Buss Volts=" ; Work(
' Print #2 , "status.bussvolts.txt=" + Chr(34) + Work() + Chr(34);
'Call Nextion
'Print "Battery Volts=" ; Work(9)
Print # 1 , "battvolts.txt=" ; Chr(34) ; Work (12) ; Chr(34);
Call Nextion
'Print "Battery Discharge Current=" ; Work(16) ; "Amps"
'Print "Battery Current=" ; Work(10) ; "Amps"
'are we discharging
Temp2 = Val(work (13)) Print
'Print "work13" ; Work(13)
' Print
Select Case Temp2
Case Is > 0
Work (13) = Str(temp2 )
'Work(13) = "+" + Work(13)
Print # 1 , "battamps" ; B ; ".txt=" ; Chr(34) ; Work (13) ; Chr(34);
Call Nextion
Case 0
Temp2 = Val(work (27))
If Temp2 = 0 Then
Temp2 = 1
End If
Work (27) = Str(temp2 )
Work (27) = "-" + Work (27)
Print # 1 , "battamps" ; B ; ".txt=" ; Chr(34) ; Work (27) ; Chr(34);
Call Nextion
End Select
'Print "Battery Capacity=" ; Work(11) ; "%"
Temp2 = Val(work (14))
Temp1 = Str(temp2 )
Temp1 = Temp1 + "%"
Print # 1 , "soc.txt=" ; Chr(34) ; Temp1 ; Chr(34);
Call Nextion
'Print "Inverter Heat Sink Temp=" ; Work(12) ; "C"
' Print #2 , "status.inverttmp.txt=" + Chr(34) + Work(12) + Chr(34);
'Call Nextion
'Print "PV Current into Battery=" ; Work(13) ; "Amps"
'Print "PV Voltage=" ; Work(14) ; "Volts"
Temp2 = Val(work (15))
Temp1 = Str(temp2 )
Print # 1 , "panvolts" ; B ; ".txt=" ; Chr(34) ; Temp1 ; Chr(34);
Call Nextion
'Print "Solar Charger Battery Voltage=" ; Work(15) ; "Volts"
Temp2 = Val(work (26))
Temp1 = Str(temp2 )
Print # 1 , "panlamps" ; B ; ".txt=" ; Chr(34) ; Temp1 ; Chr(34);
Call Nextion
'this section needs changes!!!!
' A = Mid(work(20) , 1)
' If A = "1" Then
'Print "SBU Priority=Yes"
' Else
'Print "SBU Priority=No"
' End If
'A = Mid(work(20) , 2)
' If A = "1" Then
'Print "Configuration Change"
' Else
'Print "Configuration No Change"
'End If
'A = Mid(work(20) , 3)
' If A = "1" Then
'Print "Solar Charger Firmware Updated"
'Else
'Print "Solar Charger Firmware Not Updated"
'End If
'A = Mid(work(20) , 4)
'If A = "1" Then
'Print "Load is On"
'Else
'Print "Load is Off"
'End If
'A = Mid(work(17) , 6 , 3)
'D = Val(work(21))
'Select Case D
'Case 0 'single machine
'Print "No charging On"
'Case 1
'Print "Solar charging On"
'Case 5
'Print "AC charging On"
'Case 7
'Print "Solar & AC Charging On"
'End Select
'Print ">>>>>>>>>>>" + Chr(34) + Work(3) + Chr(34)
Select Case Work (3)
Case "P" 'POWER ON MODE
Temp1 = "POWER ON MODE"
Case "S" 'STANDBY MODE
Temp1 = "STANDBY MODE"
Case "L" 'LINE MODE
Temp1 = "LINE MODE"
Case "B" 'BATTERY MODE
Temp1 = "BATTERY MODE"
Case "F" 'FAULT MODE
Temp1 = "FAULT MODE"
Case "H" 'POWER SAVING MODE
Temp1 = "POWER SAVING MODE"
End Select
'Work(4) = "status.invmode.txt=" + Work(4)
Print # 1 , "invmode.txt=" ; Chr(34) ; Temp1 ; Chr(34);
Call Nextion
End If
End Select
Else
Work (1) = "BAD CRC"
Print # 1 , "gridvolts.txt=" ; Chr(34) ; Work (1) ; Chr(34);
Call Nextion
Wait 2
End If
Enable Interrupts
End Sub
'get the individual parameters returned
Sub Chopup
Local Lx As Byte
Lx = Split(uart_command , Work (1) , " ")
'Print "we had " ; Lx ; " lots of data returned"
End Sub
Sub Cal_crc16
Local Z As Word
Local Rcrc As Word
Local Rcrc2 As Word
Z = Len(uart_command )
Z = Z - 2 'last two bytes are crc
'Print "Z is>" ; Z
Rcrc = Crc16(aruart_command () , Z ) 'calculate the CRC
Swap Rcrc 'bytes are in reverse order to what is sent to us
'Print "Cal CRC is>" ; Hex(rcrc)
Crc_16 = Right(uart_command , 2) 'get the last two bytes the crc
Rcrc2 = Work2 'this is a word variable overlayed on Crc_16
' Print "The sent crc>" ; Hex(rcrc2)
If Rcrc = Rcrc2 Then 'they match data good
' Print "CRC OK
Crc = 1
Else
' Print "CRC BAD"
Crc = 2
End If
End Sub
Sub Nextion
Printbin # 1 , &HFF ; &HFF ; &HFF
Waitms 200
End Sub
Serial0charmatch :
Wait 4
While Ischarwaiting(# 1) = 1
Rs232 = Inkey(# 1) 'get a character from the buffer
If Rs232 = 13 Or Len(uart_command_in ) > 20 Then 'uart_command full or enter key sent
'make uper case
Uart_command_in = Ucase(uart_command_in )
Select Case Uart_command_in
Case "STATUS"
Page = 1
Temp3 = 1
Case "STATUS2"
Page = 2
Temp3 = 1
Case "SETTINS"
Page = 3
Temp3 = 1
End Select
J = Len(uart_command_in )
Cls
Lcdat 4 , 1 , "PAGE>" ; Page
Lcdat 6 , 1 , Uart_command_in
Lcdat 7 , 1 , "LEN>" ; J
Uart_command_in = ""
Clear Serialin0
Else
Uart_command_in = Uart_command_in + Chr(rs232 ) 'add the character to the uart_command buffer
End If
Wend
Incr R
Lcdat 5 , 1 , "YES" ; R
Wait 1
Return
$include "font8x8.font"
|
Regards Paul
(BASCOM-AVR version : 2.0.8.2 ) |
|
Back to top |
|
|
hgrueneis
Joined: 04 Apr 2009 Posts: 902 Location: A-4786 Brunnenthal
|
Posted: Thu Mar 12, 2020 11:19 am Post subject: |
|
|
Paul,
I would first try to replace the wait 4 with a few nops.
"Do
Wait 4
Loop"
Best regards
Hubert |
|
Back to top |
|
|
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Thu Mar 12, 2020 12:12 pm Post subject: |
|
|
The wait in the Serial0charmatch was to see if it stopped the transmission on com1
which it did not. The wait in the loop was just to slow things down and that code works
its the second lot with com2 added that does not.
Regards Paul |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Thu Mar 12, 2020 4:52 pm Post subject: |
|
|
My suggestion is to skip the whole code and start new from scratch.
Alone the Serial0charmatch is a nightmare.
After charmatch-trigger the whole message exists already in the serial input buffer, while you copy it byte-per-byte with a while-loop in another string-variable.
This waste of time and processor cycles happens even more in an interrupt routine, where the topmost rule is: speed, speed and speed.
Serial0charmatch is part of an ISR and while it is executed, the controller does nothing else, which includes also that incoming data on Com1/2 are not buffered anymore and gets lost.
Such sort of code-writing sooner or later bites you in the back.
And it seems that happened already. |
|
Back to top |
|
|
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Fri Mar 13, 2020 9:08 am Post subject: |
|
|
I think you misunderstand MWS
" part of an ISR and while it is executed, the controller does nothing else"
this is exactly what I want to happen but it does not
data is still being transmitted on the com port
I put that incr R in to count the number of times the ISR runs
If data is being transmitted on com1 when data is received on com1 the ISR does not run.
Paul |
|
Back to top |
|
|
EDC
Joined: 26 Mar 2014 Posts: 971
|
Posted: Fri Mar 13, 2020 9:40 am Post subject: |
|
|
Do you saw how I handle communication with Nextion and Atmega? https://www.mcselec.com/index2.php?option=com_forum&Itemid=59&page=viewtopic&p=77756#77756
I handle it like that because Strings/Commands from Nextion are terminated with three FF`s, not CRLF
So for example Nextion in first two bytes inform me how long string will be, send it and always ends with three FF`s
So I leave Bytemach (it can be still handy for counting FF`s).
Now more important stuff. In Config serialin topic in the Help you can read that for Bytematch you must preserve registers that are altered in your routine. Its because for normal Buffered Serialin compiler know what registers will be used and save only them. It is for performance.
So if you dont know what registers you trash in that very long procedure you should use Saveall (or NoSave Tool ) but I advice to only set a small flag in that routine "We_got_LF" and return. Then handle received data in the main loop.
So everytime you get LF your main loop will be know of that but, like I wrote, Nextion sends three FF`s instead CRLF I think. |
|
Back to top |
|
|
Duval JP
Joined: 22 Jun 2004 Posts: 1161 Location: France
|
Posted: Fri Mar 13, 2020 11:18 am Post subject: |
|
|
Paul,
I'm currently working on a big project with Nextion displays.
-Sd card management
-serial/usb output
-keypad
I use the routines I have developed and publish here : https://www.mcselec.com/index2.php?option=com_forum&Itemid=59&page=viewtopic&t=14537
All the Nextion routines works well (I hope ) but nobody complain
and I have no problem at all with Nextion (14 pages !) and the M1284 is nearly full !
I use debug usb.... to follow my program following the work of EDC, thanks for him , but with inkey in place of waitkey
BUT the couple (nextion and bascom) is limited , I do a maximum with Bascom. For me Nextion is a tool for fast display. I use image, text and slider no more.
JP _________________ pleasure to learn, to teach, to create |
|
Back to top |
|
|
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Fri Mar 13, 2020 12:33 pm Post subject: |
|
|
Quote: | EDC wrote
I handle it like that because Strings/Commands from Nextion are terminated with three FF`s, not CRLF
|
I am not using defaults of the nextion displays you can make them send what you want
in my case loading the settings page sends "settinsCRLF"
I have made a lot of use of the nextion to do the graphics and animation and it is working very well.
The nextion starts and stops , changes sequence of animation due to values of text box number values
I have also got the nextion display converting text to numbers and adding these to get totals.
When I learn more of the nextion commands I think I may even be able to do away with the AVR
as there is a mode to handle the incoming serial to the nextion using your own programs on the nextion
but it is not documented or examples shown.
I have tried saving registers but it made no difference.
I am now going to get the nextion send an instruction to the AVR to get the data from the inverter
every 4 seconds this way I should be able to not have data going to the nextion while it is sending
JP I found use for the progress bar as an animation of direction of flow of power in my system
There is a lot more to the Nextion displays than just being dumb screens.
Regards Paul |
|
Back to top |
|
|
laborratte
Joined: 27 Jul 2005 Posts: 299 Location: Berlin
|
Posted: Fri Mar 13, 2020 12:38 pm Post subject: |
|
|
Paul,
viewed superficially I can see at least two problems:
- most of the time (during Find_command) INTs are disabled so you likely miss the matching character
- you have to save registers by yourself in serial0charmatch (pushall/popall - see help)
maybe you overthink your algorithm - for me it seems that a proper state machine is a better approach. |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Fri Mar 13, 2020 1:08 pm Post subject: |
|
|
Paulvk wrote: | data is still being transmitted on the com port |
You need to be more specific.
What Com-port does the transmission and what kind of data is sent? Garble or meaningful one, which you can attribute to certain parts of code?
If you receive only one byte from said com port, immediately after entry of the ISR, it would be ok, as the UART sends what it had in it's UDR-register.
The mcs.lib-routine where the USART0_RX-interrupt vector points to and which again calls Serial0Charmatch is called '_GOTCHAR0', contains nothing to re-enable interrupts, before it returns itself.
Thus if more than one byte is sent by the com port while executing Serial0CharMatch, there are two possibilities:
1) The controller accidentally reboots, therefor toggle a port/led at startup a few times to detect it.
2) One of the commands within Serial0Charmatch does not respect the disabled interrupts and accidentally re-enables them. This can be tested by disabling code within the ISR bit by bit, recompile and test. However consider also, that for interrupting another interrupt is required and sending of data seems not to be interrupt-driven. Makes this point more unlikely.
Simulation of your code is a bit difficult, thus the suggested methods will lead to the culprit more easily. |
|
Back to top |
|
|
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Fri Mar 13, 2020 11:12 pm Post subject: |
|
|
Sequence of events for program
AVR sends QPGS0 with CRC to inverter on com2
Inverter responds on com2 with
(243.4 50.0 230.3 50.0 0437 0432 010 404 50.50 000 083 0035 00 09 079.8 50.63 00000 00110110 00 00 00455 010CRLF
Note CRC at end of response
My code gets the values from the response then sends this to the nextion in Sub Find_command
sending to nextion on com1
example
(243.4 this is grid voltage 243.4 volts ac
Code: |
Print #1 , "gridvolts.txt=" ; Chr(34) ; Work(5) ; Chr(34);
Call Nextion
|
Quote: |
Thus if more than one byte is sent by the com port while executing Serial0CharMatch,
|
Yes a lot more than one byte, 4 seconds of transmission all those print lines in the Sub Find_command
I have a rs232 to 5V buffer board (max3232) it has RX & TX leds so I can see the transmission.
Note the print commands in Sub Find_command have to be running as there is no TX buffer
I tried using a TX buffer and this stopped all transmission on com1
I think to simulate program maybe if I get rid of Sub Find_command
and just put a bunch fixed of print commands to the nextion or a for next loop
This will also tell me if its some sort of problem using both com ports
Quote: |
1) The controller accidentally reboots, therefor toggle a port/led at startup a few times to detect it.
|
I have the MCS boot loader installed and a led flashes when it boots and the led does not flash
also the BOOTING would display on the lcd.
I would not think I would be the first to use duplex on a com port but maybe I am.
Also the code has been running all night the Serial0charmatch was run 12 times by me pressing buttons on nextion last night
this morning the sun comes up activating the solar chargers and the nextion is displaying data / running animation
in response to commands be sent from the AVR so other than the Serial0CharMatch ISR its all working ok.
Regards Paul |
|
Back to top |
|
|
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Sat Mar 14, 2020 2:33 am Post subject: |
|
|
I have made the test and the transmission pauses as would be expected
so why does it not stop in my program
Also added code to loop that activate com2 with inverter and transmission pauses as would be expected
Code: |
'ADDED TO LOOP
Uart_command_in = "QPGS1"
Send_command = Uart_command_in
Uart_command_in = ""
Z = Len(send_command)
Thecrc = Crc16(send_bytes() , Z) 'workout the CRC
Swap Thecrc
'Print Hex(thecrc)
Crcwrd = Thecrc
Wait 2
' If Pause > 2 Then
Print #2 , Send_command ; Crcstr ; Chr(13) ;
' End If
|
Code: |
$regfile = "m644pdef.dat" ' specify the used micro
Const Xtal = 8000000
$crystal = Xtal ' used crystal frequency
'$baud = 9600 ' use baud rate
$hwstack = 300
$swstack = 300
$framesize = 300
Dim Crc_16 As String * 2
Dim Work2 As Word At Crc_16 Overlay
Dim Work(35) As String * 40
Dim Thecrc As Word
Dim Rs232 As Byte
Dim Uart_command_in As String * 50
Dim Uart_command As String * 254
Dim Aruart_command(253) As Byte At Uart_command Overlay
Dim Send_command As String * 50
Dim Send_bytes(49) As Byte At Send_command Overlay
Dim Crcstr As String * 2
Dim Crcwrd As Word At Crcstr Overlay
Dim Z As Byte
Dim Task As Byte
Dim Temp1 As String * 20
Dim Temp2 As Word
Dim Temp3 As Byte
Dim Dog As String * 20
Dim V As Byte
Dim Crc As Byte
Dim Page As Byte
Dim Bres As Long '--This is the timer value
Declare Sub Chopup
Declare Sub Find_command
Declare Sub Cal_crc16
Declare Sub Nextion
Declare Sub Send_tst
$lib "glcdKS108.lbx"
'Config Graphlcd = 240x64 , Dataport = Portc , Controlport = Porta , Ce = 5 , Cd = 6 , Wr = 3 , Rd = 4 , Reset = 7 , Fs = 0 , Mode = 6
Config Graphlcd = 128 * 64sed , Dataport = Porta , Controlport = Portc , Ce = 2 , Ce2 = 3 , Cd = 7 , Rd = 6 , Reset = 4 , Enable = 5
Setfont Font8x8
Config Com1 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Com2 = 2400 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Serialin0 = Buffered , Size = 50 , Bytematch = 10
Config Serialin1 = Buffered , Size = 150
'Config Timer0 = Timer , Prescale = 1024 'configure the timer
'On Ovf0 Tim0_isr 'Define ISR handler for clock
' Enable Timer0 'Enable timer 0 interrupt
Enable Interrupts
Open "com2:" For Binary As #2
Open "com1:" For Binary As #1
V = 0
Temp1 = "Booting"
'Print #2 , "get page"
'Call Nextion
Wait 1
'Call Get_chr
Cls
Setfont Font8x8
Lcdat 1 , 1 , "BOOTING"
Wait 3
Cls
Do
Wait 4
Call Send_tst
Loop
End 'end program
Sub Send_tst
For Z = 1 To 20
Print #1 , "gridvolts.txt=" ; Chr(34) ; "245" ; Chr(34);
Call Nextion
'Print "Grid Frequency=" ; Work(2)
Print #1 , "gridfreq.txt=" ; Chr(34) ; "50.1" ; Chr(34);
Call Nextion
'Print "AC Output Volts=" ; Work(3)
Print #1 , "outvolts.txt=" ; Chr(34) ; "239" ; Chr(34);
Call Nextion
'Print "AC Output Frequency" ; Work(4)
Print #1 , "outfreq.txt=" ; Chr(34) ; "49.9" ; Chr(34);
Call Nextion
Next
End Sub
Sub Nextion
Printbin #1 , &HFF ; &HFF ; &HFF
Waitms 200
End Sub
Serial0charmatch:
While Ischarwaiting(#1) = 1
Rs232 = Inkey(#1) 'get a character from the buffer
If Rs232 = 13 Or Len(uart_command_in) > 20 Then 'uart_command full or enter key sent
'make uper case
Uart_command_in = Ucase(uart_command_in)
Select Case Uart_command_in
Case "STATUS"
Page = 1
Temp3 = 1
Case "STATUS2"
Page = 2
Temp3 = 1
Case "SETTINS"
Page = 3
Temp3 = 1
End Select
Uart_command_in = ""
Clear Serialin0
Else
Uart_command_in = Uart_command_in + Chr(rs232) 'add the character to the uart_command buffer
' Print Chr(rs232) ;
'Exit Do
End If
'End If
Wend
Incr Task
Lcdat 5 , 1 , "count" ; Task
Lcdat 4 , 1 , "PAGE>" ; Page
Wait 3
Return
$include "font8x8.font"
| [/code] |
|
Back to top |
|
|
Paulvk
Joined: 28 Jul 2006 Posts: 1257 Location: SYDNEY
|
Posted: Sat Mar 14, 2020 10:01 am Post subject: |
|
|
I have now changed the program so that the Nextion sends to the AVR every 20 secconds
this causes the AVR to send the commands to the inverter
the inverter sends back the data
the AVR parses the data and sends it to the Nextion text boxes
This now works as I want and data flows in each direction but not at the same time.
Regards Paul |
|
Back to top |
|
|
MWS
Joined: 22 Aug 2009 Posts: 2262
|
Posted: Sat Mar 14, 2020 10:30 am Post subject: |
|
|
Paulvk wrote: | so why does it not stop in my program |
That's hard to say, especially if one (me) would never ever write code this way, as it has huge conceptional flaws and this is not only my opinion.
Furthermore it does not make sense to waste efforts on messed up code, only to find out why a certain behavior is different than expected.
The only sense to work through some of this original code would be in case a bug is to assume within the compiler. In this case I don't think so.
About a flawed concept:
In a nuclear reactor the shut-down, means injection of the control rods would need the highest priority, as it must be fast.
Your code in contrary displays some information on a HID, aka display. It does not make any difference if the content to display appears 100 to 500ms later on the screen, as your reaction time is limited anyway.
Means: only two things need to be done in the serialcharmatch ISR, set a flag and copy the command string into a buffer, lock the buffer until the command is processed.
The main loop checks the flag, evaluates the buffered string and displays the result, after it clears the flag, thus unlocking the buffer.
If incoming commands rush in faster than the display routines can handle it, then some logic/concept is required for what to do with the inrush, i.e. save or loose it.
For the main loop to be able to react within said 100-500ms, it needs clean programming, no 'wait 4' or things like that.
Instead the loop has to run as fast as possible, if a certain timing is required, set up a timer which sets a flag, let's say every 100ms.
The required actions can then get executed at given time slots by setting soft-timers, that's counting a variable till it reaches 10 with the help of the timer flag, if 10 is reached, 1 second has passed, reset this soft-timer and execute certain code then.
If something is urgent there can be an override flag, which activates certain sub-functions immediately. The fastest possible reaction time depends on the slowest code.
Which should be the display routines.
Without proper concept you will further try to botch the code together and you either fail or get some instable construct.
Your choice, you're free of course to botch as much as you like, while others are free to ignore it. |
|
Back to top |
|
|
Duval JP
Joined: 22 Jun 2004 Posts: 1161 Location: France
|
Posted: Sat Mar 14, 2020 11:10 am Post subject: |
|
|
MWS wrote Code: | If incoming commands rush in faster than the display routines can handle it, then some logic/concept is required for what to do with the inrush, i.e. save or loose it. |
this shows a defect in the Nextion screens:
I have to display 30 calculation results in a page, including 4 with a large font (40). I realized that if I didn't make small poses (50ms) between the displays one of the four results was not displayed correctly, while the debug showed that they were well sent.
As we don't have the hand on the Nextion code, we have to deal with it.
JP _________________ pleasure to learn, to teach, to create |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|