Page 1 of 1
Wait for char question
Posted: 15 June 2009, 10:16 AM
by hakha4
Hi everybody
Asking for advice how to implement a 'wait for char' routine. I have a 128x64 touch display (Simmetry CS-2B)with built in templates etc hooked up to a ZX1291e. The display sends a '>'when it's ready for next command. It also have a pin that is pulled up to 1 when ready. I have tried several approaches but none works 100 % ok. I'm not expecting people to write code for me but any advice would be appreciated. Whats the best way to check for the 'ready' pin ? The code below don't work in all scenarios. I've tried waitforinterrupt but that also didn't work good enough. What I'm really looking for is a Basic Stamp 'Serin-like' command or a routine that catches the ">" from the display before I send any commands/text to the display. I have googled on this but not much to find
Code: Select all
'******************************************
' called before sending anything to the display
'******************************************
Public Function Ready_TouchLCD()As Boolean
Dim Cmd_Status as byte
Cmd_Status= GetPin(CmdPin)'Pin 7
debug.print Cstr(Cmd_status)
If Cmd_Status = 1 then' command finished. Display ready
Ready_TouchLCD = True
Else ' command not finished
Ready_TouchLCD = False
End If
End Function
[admin edit: added code tags]
Regards Hucke
Re: Wait for char question
Posted: 15 June 2009, 10:40 AM
by dkinzer
hakha4 wrote:Whats the best way to check for the 'ready' pin ?
I was able to download some specifications on the device but they are not very detailed. I suspect that the high level on J4-5 is too short to be detected with a wait loop. Using WaitForInterrupt() should work but it would need to be done carefully. I suspect that it will be necessary to use a dedicated task for detect the "ready" condition and set a flag indicating that it has been seen. The main task would then clear the flag, send a command and watch for the flag to be set again before proceeding.
An alternate method would be to check the input queue for the ready character. Assuming that the device doesn't send any other data, you could clear the input queue, send a command and then wait for the ready character to appear in the queue.
One potential problem is that the device can operate at 9600, 19.2K and 38.4K baud but the software UART channels (3-6) cannot be operated above 19.2K. If the device defaults to 9600 and you never change the baud, however, there shouldn't be a problem.
Posted: 15 June 2009, 12:28 PM
by hakha4
Thank's a lot for quick answer! A Task with waitforinterrupt fixed the problem
Regards Hucke
Posted: 15 June 2009, 17:48 PM
by dkinzer
hakha4 wrote:A Task with waitforinterrupt fixed the problem
Would you care to post the code that is now working? Perhaps it would be helpful to other readers.
By the way, did you understand the edit that was made to your original post regarding "code tags"?
Posted: 16 June 2009, 14:15 PM
by hakha4
Hi!
Now getting the touch display to work stable and as intended so far. Below is the relevant parts for how I am sending commands/text and the Tasks dealing with interrupt/checking for touched Display. I'm not a proffesional programmer so there are probably more elegant ways to do it but it works!
The size of Stack buffers are guesstimates but when reducing the 'Private taskCheckReady(1 to 100) to 50 it stopped working. Are there some rules for size or just try ?
CODE FROM Pool.bas and Touch.bas
Code: Select all
'****************** Project to deal with my pool,reading temps etc *******
Option Explicit
Option ExtRamConfig On
Public COM3 As Boolean = False'Touch LCD
Public COM4 As Boolean = False'LCD Plus
Public COM5 As Boolean = False'#142- temp/relay
Public COM6 As Boolean = False'reserve
Private taskCheckTouch(1 to 100) as Byte 'stack for Sub CheckLCDTouch_TouchResponse
Private tmpCommand as String ' for sending commands/text to Display
Public Sub Main()
'Reset LCDTouch
tmpCommand="R"
Call PrintText_TouchLCD(tmpCommand)
tmpCommand=":#"
Call PrintText_TouchLCD(tmpCommand)
'**************************************'
'set 4 SW serial channels
Call ComChannels(4,9600)
'Load Main Menu
Call Main_LCDTouch_Menu
Do
'this routine not ready,just for testing respons on touch Display
CallTask CheckLCDTouch_TouchResponse,taskCheckTouch
call delay(0.1)
Loop
End Sub
Code below from Touch.bas
'***** Touch LCD uses Pin 14,8,9 ***************************
Private Const Tx_TouchLCD As Byte = 9
Private Const Rx_TouchLCD As Byte = 8
Private Const CmdPin As Byte = 14'Pin 14 interrupt 6
Private Cmd_status As Boolean ' True means Display ready for new command
'**********************************************************
Dim OutBuffer(0 To 128) As Byte
Dim InBuffer(0 To 128) As Byte
Private taskCheckReady(1 to 100) as Byte ' Checks if Display are ready for new command
'***********************************************************
'** must be called first before communicate with COM 3
'***********************************************************
Public Sub Init_TouchLCD()
'open buffers for COM-port
Call OpenQueue(OutBuffer, 127)
Call OpenQueue(InBuffer, 127)
' Open COM3 port:noninverted 8-bit 1 stop bit
Call DefineCom(3,Rx_TouchLCD, Tx_TouchLCD, bx0000_1000,1)'Pin 8 = grey Pin 9 = brown
Call OpenCom(3,9600,InBuffer, OutBuffer)
COM3 = True
End sub
'******************************** MAIN MENU ************************************
Public Sub Main_LCDTouch_Menu()
Dim tmpCommand As String
tmpCommand = "*"'just to make sure the Display is ready if 'coldstarted'
Call PrintText_TouchLCD(tmpCommand)
tmpCommand = "C"'clear sreen
Call PrintText_TouchLCD(tmpCommand)
'print text on line 1 to 4
tmpCommand="tm12,Installningar"
Call PrintText_TouchLCD(tmpCommand)
tmpCommand="tm32,Temperaturer"
Call PrintText_TouchLCD(tmpCommand)
tmpCommand="tm52,Relastatus"
Call PrintText_TouchLCD(tmpCommand)
tmpCommand="tm72,Lampstatus"
Call PrintText_TouchLCD(tmpCommand)
'overlay with built in touchsreen, four lines, respons 1 to 4 when touched
tmpCommand = "BA"
Call PrintText_TouchLCD(tmpCommand)
End Sub
'*********************************************************************************
' Main Display routine for sending commands/text *********************************
'*********************************************************************************
Public Sub PrintText_TouchLCD(tmpText As String)
' Open com3 port for TouchLCD if closed
If COM3 = False Then
Call Init_TouchLCD
End if
'if '*' skip Check if Ready to recieve, just to wake Display up
If tmpText = "*" Then
Call PutQueueStr(OutBuffer,tmpText & Chr(13))
End If
'Check if Ready to recieve
CallTask CheckLCDTouch_Ready,taskCheckReady
If Cmd_Status Then
Call PutQueueStr(OutBuffer,tmpText & Chr(13))
'reset Cmd_Status
Cmd_Status = False
End if
Call delay(0.1) 'pause to give Display time to catch up
End Sub
'**********************************************
'****** Task called from PrintText_TouchLCD ***
'****** High on Pin 14 means Display ready for command
'**********************************************
Public Sub CheckLCDTouch_Ready()
Call WaitForInterrupt(zxPinRisingEdge,6)'Pin 14, int 6 on ZX 1281e
Cmd_Status = True
End Sub
'**********************************************
'****** Task called from Sub Main ***
'****** to check if touch screen pressed ******
'**********************************************
Public Sub CheckLCDTouch_TouchResponse()
Dim tmpResponse As String
Dim tmpCommand As String
Dim TouchRespons As String
Call ClearQueue(InBuffer)'empty buffer to make sure respons char is 4-th char (# or response char)
tmpCommand="K"
Call PrintText_TouchLCD(tmpCommand)' sending a 'K' tells Display to response on touch
tmpResponse = GetQueueStr(InBuffer)
TouchRespons = mid(tmpResponse,4,1) '# or number according to touched button
Select Case TouchRespons
Case "#"'do nothing
Call PutPin(6,zxOutPutHigh)
Case Else 'check button touched and open relevant menu or whatever
Call PutPin(6,zxOutPutLow)'just visualize rutine is responding to touch (maybe a Beep to)
Call Delay(0.05)
Call PutPin(6,zxOutPutHigh)
End Select
debug.print "Touched = " & TouchRespons
End Sub
Regards Hucke
Posted: 16 June 2009, 14:29 PM
by dkinzer
hakha4 wrote:Are there some rules for size or just try ?
The compiler is supposed to generate a warning if the task stack size is smaller than it calculates as the minimum. You can also look at the .map file in which there is a list of tasks and the minimum task stack size for each. Generally speaking, you'll find the .map file in the same directory as your .pjt file.
If you have code that does not execute correctly unless the stack size is significantly larger than the minimum, I would like to take a look at it.
Posted: 16 June 2009, 14:57 PM
by dkinzer
hakha4 wrote:[T]here are probably more elegant ways to do it but it works!
Although there are exceptions, tasks are generally structured as some initialization code followed by an infinite loop. I think that this structure would work well for the task that monitors the ready signal from the LCD. It might look something like this:
Code: Select all
Public LCD_Ready as Boolean
Public Sub CheckLCDTouch_Ready()
Do
LCD_Ready = True
Call WaitForInterrupt(zxPinRisingEdge, 6) 'Pin 14, int 6 on ZX 1281e
Loop
End Sub
You would invoke this task only once, probably in Main() after the serial port for the LCD has been initialized.
The routine for writing commands to the LCD might look like this:
Code: Select all
Public Sub PrintText_TouchLCD(tmpText As String)
'if '*' skip Check if Ready to recieve, just to wake Display up
If (tmpText <> "*") Then
' wait for the LCD to be ready
Do While Not LCD_Ready
Call Sleep(0)
Loop
End If
' reset the ready flag
LCD_Ready = False
' send the command string
Call PutQueueStr(OutBuffer, tmpText)
' append a carriage return
Call PutQueueByte(OutBuffer, 13)
End Sub
Posted: 17 June 2009, 4:14 AM
by hakha4
Thanks Don for the tips. A rewrite my code and test. I'm still thinking 'Visual Basic' when programming but with people like You spending time helping others I'm improving. I've played with other microcomputers earlier but the Zbasic and hardware are just super and I'm thinking programming all a'round the clock
Regards Hucke