Shop OBEX P1 Docs P2 Docs Learn Events
PropBASIC Simple terminal I/O — Parallax Forums

PropBASIC Simple terminal I/O

RsadeikaRsadeika Posts: 3,837
edited 2012-10-19 09:56 in Propeller 1
Below is my version of showing a key press on a terminal screen. What I would like to do is expand this so it can respond to some simple commands, maybe ledon(16), ledoff(16), and quit. I am having a hard time trying to figure out how to do string input, and output, TX and RX of course.

The way I have my board setup is, I have an RS232 breakout board, and I use Tera Term as the terminal program. You could use pins 31, and 30, but its a pain because you cannot start the terminal program until PropBASIC has released the com port.

Thanks

Ray
'**********
'**** Master.pbas
'**** Simple terminal I/O
'**** Enter a keypress, and it displays on terminal screen
'**********
'** Device Settings
'**********

DEVICE	P8X32A, XTAL1, PLL16X
XIN		5_000_000

'**********
'** Constants
'**********
Baud	CON "T115200"

'**********
'** I/O Pins
'**********
TX	PIN 24 high
RX  PIN 25 input

'***********
'** Variables
'***********

alpha VAR long

'**********
'** Subroutine / Fuction Declarations
'**********
TX_BYTE	SUB 2
RX_BYTE FUNC 1
DELAY_MS	SUB 1

'**********
PROGRAM Start
'**********

Start:
  DELAY_MS 10

  
Main:
	TX_BYTE TX, "A"   'Print A on startup
	TX_BYTE TX, 10    'Newline
	TX_BYTE TX, 13    'CR
'Do simple console I/O
    'Start an endless loop 
	do
	  alpha = RX_BYTE RX  'Get keypress
	  IF alpha = 13 THEN  'Check if CR was pressed
	    TX_BYTE TX, 10    'Newline
	    TX_BYTE TX, 13    'CR
	  ELSE
	    TX_BYTE TX, alpha 'Print the keypress
	  ENDIF
	loop
'Stops program,just in case it ever breaks out of loop
  END

'**********
'** Subroutine / Function Code
'**********
SUB TX_BYTE
  SEROUT __param1, Baud, __param2
  ENDSUB
  
SUB DELAY_MS
  PAUSE __param1
  ENDSUB

FUNC RX_BYTE
	__param2 = __param1
	SERIN __param2, Baud, __param1
	return __param1
ENDFUNC

Comments

  • VonSzarvasVonSzarvas Posts: 3,451
    edited 2012-10-17 05:05
    @Ray

    Fairly sure Bean had an example included in the PropBasic demo files (probably in the first post of the original Propbasic thread if not in the more recent PropBasic zip).
    From memory it echo'd back stuff typed in the terminal... it might explain what you need.
  • pmrobertpmrobert Posts: 675
    edited 2012-10-17 05:50
    Jonnymac contributed pst_serial.lib some time ago. The control characters are specific for PST but there are nice examples of routines for reading strings, decs, hex, etc., from/to serial devices.

    -Mike
  • BeanBean Posts: 8,129
    edited 2012-10-17 06:14
    To actually implement commands, you need to parse the input string.
    It is MUCH easy to use single letter commands like:

    H# = Make pin "#" high
    L# = Make pin "#" low
    I# = Make pin "#" an input

    And so on...
    DEVICE P8X32A, XTAL1, PLL16X
    FREQ 80_000_000
    
    TX          CON 30
    RX          CON 31
    Baud        CON "T115200"
    
    temp        VAR LONG
    char        VAR LONG
    value       VAR LONG
    
    
    GetChar     FUNC 0
    GetValue    FUNC 0
    
    PROGRAM Start
    
    Start:
      DO
        char = GetChar
        IF char = "H" THEN
          value = GetValue
          HIGH value
        ELSEIF char = "L" THEN
          value = GetValue
          LOW value
        ELSEIF char = "I" THEN
          value = GetValue
          INPUT value
        ENDIF
      LOOP
    END
    
    
    FUNC GetValue
      value = 0
      DO
        temp = GetChar
        IF temp >= "0" AND
         temp <= "9" THEN
          temp = temp - "0"
          ' value = value * 10 + temp
          value = value * 2
          temp = temp + value
          value = value * 4
          value = value + temp
        ENDIF
      LOOP UNTIL temp = 13
      RETURN value
    ENDFUNC
    
    
    FUNC GetChar
      SERIN RX, Baud, temp
      IF temp >= "a" AND
       temp <= "z" THEN
        DEC temp,32
      ENDIF
      SEROUT TX, Baud, temp
      RETURN temp
    ENDFUNC
    
    

    Bean
  • MicksterMickster Posts: 2,694
    edited 2012-10-18 05:57
    Hey Bean,

    If I used this as the basis for Prop-to-Prop comms, I assume I can crank-up the Baud to multiples of what you have above, right?

    I love this compiler and hope you never abandon further development....Great Job!!!

    Regards,

    Mickster
  • BeanBean Posts: 8,129
    edited 2012-10-18 07:36
    You would want to use a buffered recieve task for that...
    DEVICE P8X32A, XTAL1, PLL16X
    FREQ 80_000_000
    
    TX          CON 30
    RX          CON 31
    Baud        CON "T115200"
    
    temp        VAR LONG
    char        VAR LONG
    value       VAR LONG
    
    bufferTail  VAR LONG = 0
    bufferHead  VAR LONG = 0
    
    recvBuffer  HUB BYTE(1024)
    latestHead  HUB LONG
    
    GetChar     FUNC 0
    GetValue    FUNC 0
    
    CogReceive  TASK AUTO
    
    PROGRAM Start
    
    Start:
      DO
        char = GetChar
        IF char = "H" THEN
          value = GetValue
          HIGH value
        ELSEIF char = "L" THEN
          value = GetValue
          LOW value
        ELSEIF char = "I" THEN
          value = GetValue
          INPUT value
        ENDIF
      LOOP
    END
    
    
    
    FUNC GetValue
      value = 0
      DO
        temp = GetChar
        IF temp >= "0" AND
         temp <= "9" THEN
          temp = temp - "0"
          ' value = value * 10 + temp
          value = value * 2
          temp = temp + value
          value = value * 4
          value = value + temp
        ENDIF
      LOOP UNTIL temp = 13
      RETURN value
    ENDFUNC
    
    
    FUNC GetChar
      ' Wait for character
      DO
        RDLONG latestHead, bufferHead
      LOOP UNTIL bufferTail <> bufferHead
    
      ' Get character from buffer
      RDBYTE recvBuffer(bufferTail), temp
      INC bufferTail
      bufferTail = bufferTail AND 1023
    
      ' Convert to uppercase
      IF temp >= "a" AND
       temp <= "z" THEN
        DEC temp,32
      ENDIF
    
      ' Echo character back
      SEROUT TX, Baud, temp
    
      ' Return character
      RETURN temp
    ENDFUNC
    
    ' ------------------------------------------
    
    TASK CogReceive
    char VAR LONG
    head VAR LONG = 0
    
      DO
        SERIN RX, Baud, char
        WRBYTE RecvBuffer(head), char
        INC head
        head = head AND 1023
        WRLONG latestHead, head
      LOOP
    
    ENDTASK
     
    

    Bean
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-10-18 07:58
    I need further explanation for this:
    help HUB "Just anything",0
    
    SEROUT TX, Baud, help
    
    this throws up an ERROR 6 Syntax Error ; help HUB "Just anything", 0
    If I change it to, help DATA "Just anything",0, then it works without an error. In your documentation I got the impression that using the HUB is the preferred way, but that does not to work for me, or how/when to use HUB maybe needs some more explanation. So, if you could set me straight ...


    Ray
  • BeanBean Posts: 8,129
    edited 2012-10-18 08:12
    Ray,
    I'll check into it.
    It looks like it should work.
    I use DATA instead of HUB for static strings.

    Bean

    P.S. I check it, you can't declare strings with HUB. DATA does what you want.
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-10-18 09:25
    P.S. I check it, you can't declare strings with HUB. DATA does what you want.
    If I use a lot of string data, it will use up a lot of COG RAM. Is the solution to use LMM mode?
     help DATA "Just anything",0
    
      TX_STR TX, help
    
    SUB TX_STR
      SEROUT TX, Baud, __param1 
      ENDSUB
    
    In the above snippet, when it runs, TX_STR TX, help, all I get is a blank line. Do I have to use something other than __param1, to deal with the string?

    Ray
  • BeanBean Posts: 8,129
    edited 2012-10-18 10:27
    DATA is stored in HUB RAM not COG RAM.

    I assume you are trying to do this...
    DEVICE P8X32A, XTAL1, PLL16X
    FREQ 80_000_000
    
    TX          CON 30
    RX          CON 31
    Baud        CON "T115200"
    
    help DATA "This is a string", 0
    
    TX_STR SUB 2
    
    PROGRAM Start
    
    Start:
      DO
        TX_STR TX, help
        PAUSE 1000
      LOOP
    END
    
    SUB TX_STR
      SEROUT __param1, Baud, __STRING(__param2)
    ENDSUB
    
    

    When you pass a HUB string as a parameter it is passed as the ADDRESS of the string in HUB ram.
    The SEROUT command "assumes" that __param2 is a character value that you want to send. To let it know that it is a string address you need to use the virtual __STRING() array.

    I hope this helps...

    Bean
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-10-18 12:18
    I improved the program some what, now at least you get a slight feel of a console IO. So, for the new people, if you want a quick and dirty way of turning on that LED you just placed on the breadboard, this might help out.

    Right now the program uses GetChar FUNC, I would still like to figure out how to do a GetString FUNC, so I could have a larger Command choice than just the letters of the alphabet. I guess I could try implementing an XBee driver, a very stripped down driver, and try to do something with one letter commands. Any suggestions for improvements or short cuts will be greatly appreciated.

    Ray
    '**********
    '**** Master.pbas
    '**** Simple terminal I/O
    '**** Improved stIO
    
    '**********
    '** Device Settings
    '**********
    
    DEVICE	P8X32A, XTAL1, PLL16X
    XIN		5_000_000
    
    '**********
    '** Constants
    '**********
    
    TX          CON 24  '30
    RX          CON 25  '31
    Baud        CON "T115200"
    
    '***********
    '** Variables
    '***********
    temp        VAR LONG
    char        VAR LONG
    value       VAR LONG
    
    '**********
    '** Subroutine / Fuction Declarations
    '**********
    GetChar     FUNC 0
    GetValue    FUNC 0
    TX_BYTE     SUB  2                       
    DELAY_MS	SUB 1
    TX_STR      SUB 2
    CR          SUB 0
    
    '**********
    '** String Data
    '**********
    help1 DATA "(h) help, (H)xx - Pin # HIGH, (L)xx - Pin # LOW",0
    help2 DATA "  (Q) Quit ",0
    Schar DATA "> ",0
    Sstop DATA "System Stop!",0
    
    '**********
    PROGRAM Start
    '**********
    
    Start:
    
      TX_STR TX, Schar
      TX_STR TX,  help1
      CR
      TX_STR TX, help2
      CR
      TX_STR TX, Schar
      
      DO
        char = GetChar
        IF char = "H" THEN
          value = GetValue
          HIGH value
        ELSEIF char = "L" THEN
          value = GetValue
          LOW value
        ELSEIF char = "I" THEN
          value = GetValue
          INPUT value
        ELSEIF char = "h" THEN
          TX_STR TX,  help1
          CR
          TX_STR TX, help2      
        ELSEIF char = "Q" THEN
          CR
          TX_STR TX, Sstop
          CR
          EXIT
        ENDIF
        CR
        TX_STR TX, Schar
      LOOP
    END
    
    ' End of program
    
    '**********
    '** Subroutine / Function Code
    '**********
    FUNC GetValue
      value = 0
      DO
        temp = GetChar
        IF temp >= "0" AND
         temp <= "9" THEN
          temp = temp - "0"
          ' value = value * 10 + temp
          value = value * 2
          temp = temp + value
          value = value * 4
          value = value + temp
        ENDIF
      LOOP UNTIL temp = 13
      RETURN value
    ENDFUNC
    
    
    FUNC GetChar
      SERIN RX, Baud, temp
      IF temp >= "a" AND
       temp <= "z" THEN
    '    DEC temp,32    'Makes all screen chars upper case
      ENDIF
      SEROUT TX, Baud, temp
      RETURN temp
    ENDFUNC
    
    SUB TX_BYTE
      SEROUT __param1, Baud, __param2
    ENDSUB
      
    SUB DELAY_MS
      PAUSE __param1
    ENDSUB
    
    SUB TX_STR
      SEROUT __param1, Baud, __STRING(__param2)
    ENDSUB
    
    SUB CR
      TX_BYTE TX, 10
      TX_BYTE TX, 13
    ENDSUB
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-10-19 04:16
    I am trying to get a GetStr function to work, with no success. The biggest problem is, IF strg = "help" THEN, for some reason strg, which is an array? is not compatible with "help". I figure that "help" is an array so, strg should be able to deal with it. The other question is, how do you deal with getting values into an array.

    Ray
    temp1       var long(40)
    strg        VAR LONG(40)
    
    GetStr      FUNC 0
    
      DO
         strg = GetStr
         IF strg = "help" THEN
           TX_STR TX,  help1
           CR
         ENDIF
        CR
        TX_STR TX, Schar
      LOOP
    
    FUNC GetStr
      
      DO
        char = GetChar
        IF temp = 13 THEN
          EXIT
        ELSE
          temp = temp1(temp)
          inc temp1
        ENDIF
      LOOP
    
      TX_STR TX, temp1
      RETURN temp1
    ENDFUNC
    
  • BeanBean Posts: 8,129
    edited 2012-10-19 06:09
    Ray,
    You cannot compare strings with "=", strings are special HUB byte arrays.

    I almost never use VAR arrays, because they require self-modifying-code on the propeller. I just use HUB arrays, which save COG space too.

    Are you trying to do something like this...
    DEVICE P8X32A, XTAL1, PLL16X
    FREQ 80_000_000
    
    TX          PIN 30 HIGH
    RX          PIN 31 INPUT
    Baud        CON "T115200"
    
    
    temp        VAR LONG
    char        VAR LONG
    char2       VAR LONG
    strStart    VAR LONG
    strPlace    VAR LONG
    
    temp1       HUB STRING(40)
    strg        HUB STRING(40)
    
    GetStr      SUB 1  ' String parameter
    CompStr     FUNC 2 ' Two string parameters; Returns 1 if they match, 0 otherwise
    GetChar     FUNC 0 ' Return char received
    TX_STR      SUB  2 ' Pin, String parameter
    TX_Char     SUB 2  ' Pin, char
    
    
    helpMsg     DATA "God helps those that help themselves...", 13, 0
    helloMsg    DATA "Well, hello to you too...", 13, 0
    unknownMsg  DATA "I don't understand that...", 13, 0
    
    
    PROGRAM Start
    
    Start:
      DO
        GetStr strg
        temp = CompStr strg, "help"
        IF temp = 1 THEN
          TX_STR TX,  helpMsg
        ELSE
          temp = CompStr strg, "hello"
          IF temp = 1 THEN
            TX_STR TX, helloMsg
          ELSE
            TX_STR TX, unknownMsg
          ENDIF
        ENDIF
      LOOP
    END
    
    
    SUB GetStr
      strStart = __param1
      strPlace = strStart
      DO
        char = GetChar
        IF char = 13 THEN
          WRBYTE strPlace, 0
        ELSE
          WRBYTE strPlace, char
        ENDIF
        INC strPlace
      LOOP UNTIL char = 13
      TX_STR TX, strStart
      TX_Char TX, 13
    ENDSUB
    
    
    FUNC CompStr
      strStart = __param1
      strPlace = __param2
      temp = 0 ' Assume NOT a match
      DO
        RDBYTE strStart, char
        RDBYTE strPlace, char2
        INC strStart
        INC strPlace
        IF char = 0 OR
         char2 = 0 THEN EXIT
      LOOP UNTIL char <> char2
      IF char = 0 AND
       char2 = 0 THEN
        temp = 1 'They match
      ENDIF
      RETURN temp
    ENDFUNC
    
    
    FUNC GetChar
      SERIN RX, Baud, temp
      RETURN temp
    ENDFUNC
    
    
    SUB TX_STR
      SEROUT __param1, Baud, __STRING(__param2)
    ENDSUB
    
    
    SUB TX_Char
      SEROUT __param1, Baud, __param2
    ENDSUB
    
    

    Bean
  • RsadeikaRsadeika Posts: 3,837
    edited 2012-10-19 06:49
    Thanks bean, that is what I was after. That should keep me from asking anymore questions.

    Ray
  • BeanBean Posts: 8,129
    edited 2012-10-19 09:56
    LOL No problem Ray. I'm happy to help.

    Bean
Sign In or Register to comment.