Shop OBEX P1 Docs P2 Docs Learn Events
Simple Serial question — Parallax Forums

Simple Serial question

s1ss1s Posts: 4
edited 2006-10-16 14:20 in BASIC Stamp
I am trying to rec'v serial commands from an external device. This device can't be changed.
What I am trying to do is control a LCD projector.
There are only four commands:
On
Off
RGB input
Video input

The On and Off commands are six bytes long and the RGB and Video are 8 bytes long.

All that is being done is the input to the BS2 is reading what button was pressed.

The baud is 38400.

With the Serin command I have setup an array of 8 bytes so when you press the 8 byte button it works great but when a 6 byte button is pressed the last two bytes don't get filled so the command waits. If I put a timeout in the command then some data may be missed completely when the code exits the Serin.

Just to explain this another way!

My input string is:
02 00 00 00 00 02 'On cmd'
02 01 00 00 00 03 'Off cmd'
02 03 00 00 02 01 01 09 'RGB input'
02 03 00 00 02 01 06 0E 'Video input'

These come in at 38400 baud.
A user can press any button at any time.
I need to see the string and determine what button was pressed then do my task according to the button pressed.

The problem I can't seem to get around is the fact that one string is 6 bytes and the other is eight.

The code I wrote so far is short:

bytearray var byte(8)

Main:
SERIN 14, 6, [noparse][[/noparse]STR bytearray\8]

DEBUG ? bytearray(0)
DEBUG ? bytearray(1)
DEBUG ? bytearray(2)
DEBUG ? bytearray(3)
DEBUG ? bytearray(4)
DEBUG ? bytearray(5)
DEBUG ? bytearray(6)
DEBUG ? bytearray(7),CR
goto Main

end

Any help would be appreciated.
Thank you,
Steve

Comments

  • BeanBean Posts: 8,129
    edited 2006-10-13 17:22
    I don't understand why codes are missed if you use a SERIN timeout ?
    Maybe your timeout is too long or too short.
    Are the codes repeated as long as the user holds the button ?

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheap used 4-digit LED display with driver IC·www.hc4led.com

    Low power SD Data Logger www.sddatalogger.com
    SX-Video Display Modules www.sxvm.com

    Don't mistake experience for intelligence. And vis-vera.
    ·
  • allanlane5allanlane5 Posts: 3,815
    edited 2006-10-13 18:01
    Yeah, I've seen this.

    The problem is, if you put in a timeout, the person could 'press the button' just before the timeout expires. So the SERIN gets one or two bytes, then times-out.

    If you don't put in a timeout, the SERIN can sit there FOREVER waiting for the bytes -- it never leaves the SERIN, so never misses any bytes.

    Sounds like it's time for a nice, small serial-recieve coprocessor like the:
    http://www.rhombus-tek.com/co-processors.html

    Use the "Simple Multi-Tasking" module -- gives you a serial input buffer.· Not bad for $12 plus shipping.
  • allanlane5allanlane5 Posts: 3,815
    edited 2006-10-13 18:05
    You COULD try to recieve 6 bytes, then read one byte more. The problem is, the second SERIN only has 260 uSec to start up (almost doable) before it misses the start bit of the EIGHTH byte. Depends on how much 'dead' time there is between bytes. I don't think it would work very well.
  • stamptrolstamptrol Posts: 1,731
    edited 2006-10-13 18:06
    s1s,
    Do the strings end with either a CR or LF? If they do, you can tell the SERIN command to watch for the CR or LF. That way, you set up your SERIN to always want 8 bytes, but if the the CR or LF is seen, it fills the last two bytes with nuls.

    I think the process is described in the helpfile related to SERIN.

    Cheers

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tom Sisk

    http://www.siskconsult.com
    ·
  • s1ss1s Posts: 4
    edited 2006-10-13 20:25
    I tried to put a Serin with 6 bytes and then run the serin again to catch the last byte but it always reads zero.

    There are no CR's or LF's at the end of the string.

    Does anyone think the faster Stamp would correct this issue?

    Just for FYI I will post the code that I just tried.
    **********************************************************************
    bytearray6 VAR Byte(6)
    bytearray1 VAR Byte

    DEBUG "Started", CR

    Main:
    SERIN 14, 6, [noparse][[/noparse]STR bytearray6\6]
    SERIN 14, 6, 1000, debugit, [noparse][[/noparse]bytearray1]



    debugit:
    DEBUG ? bytearray6(0)
    DEBUG ? bytearray6(1)
    DEBUG ? bytearray6(2)
    DEBUG ? bytearray6(3)
    DEBUG ? bytearray6(4)
    DEBUG ? bytearray6(5)
    DEBUG ? bytearray1
    'DEBUG ? bytearray(7),CR

    GOTO Main
    ***********************************************************************
  • John AbshierJohn Abshier Posts: 1,116
    edited 2006-10-14 00:23
    Jon Williams wrote a program in SX/B that did some limited checking between characters. It was a Nuts & Volts article about using the SX to read the Playstation controller and report back to the BASIC Stamp. I think it was Jan 2006. It used a serial baud rate of 38400. I found the code:
    Main: ' wait for header
    char = RX_BYTE
    IF char <> "!" THEN Main
    char = RX_BYTE
    IF char <> "P" THEN Main
    char = RX_BYTE
    IF char <> "S" THEN Main
    char = RX_BYTE
    IF char <> "X" THEN Main
    Instead of going back to main you could bail out if you id a 6 byte command and keep going for 8.
  • UnsoundcodeUnsoundcode Posts: 1,532
    edited 2006-10-14 22:26
    Steve, I looked at what you needed and tried a different approach. Instead of an array I used a byte for SERIN. The byte (mydata) will contain only the last transmitted byte. Because the last byte for each command is different this is all you need to differentiate between them.

    mydata VAR Byte

    main:

    SERIN 16,16468,[noparse][[/noparse]HEX mydata]

    SELECT mydata
    CASE 2
    ·· 'CODE FOR THE "ON" COMMAND
    CASE 3
    ·· 'CODE FOR THE "OFF" COMMAND
    CASE 9
    ·· 'CODE FOR THE "RGB" COMMAND
    CASE 14
    ·· 'CODE FOR THE VIDEO COMMAND
    ENDSELECT

    GOTO main

    I have to say I couldn't configure 38400 baud but·I captured the last byte everytime at 9600 on a BasicStamp OEM2

    Jeff T.
  • TechnoRobboTechnoRobbo Posts: 323
    edited 2006-10-15 01:54
    Are these the code below?
    It appears that the first 2 byte give you the an indication of the number of bytes to follow and 2 bytes of 00 that·you can ignore.

    Read the first 2 byte and with a little trial and error, an if statement and a pause statement you might be able to time the input and restart at·the 5th byte ··After all that's what bit-serialis all about.


    POWER ON: 02 00 00 00 00 02
    POWER OFF: 02 01 00 00 00 03
    Input 1 RGB 1: 02 03 00 00 02 01 01 09
    Input 2 RGB 2: 02 03 00 00 02 01 02 0A
    Input 3 RGB 3: 02 03 00 00 02 01 03 0B
    Input 4 COMPONENT: 02 03 00 00 02 01 12 1A
    Input 5 VIDEO 1: 02 03 00 00 02 01 06 0E
    Input 6 VIDEO 2: 02 03 00 00 02 01 07 0F
    Input 7 S-VIDEO 1: 02 03 00 00 02 01 0B 13
    Input 8 S-VIDEO 2: 02 03 00 00 02 01 0C 14
    Input 9 RGB DIGITAL: 02 03 00 00 02 01 1A 22
    Input 0 SDI: 02 03 00 00 02 01 1B 23
    PICTURE MUTE ON: 02 10 00 00 00 12
    PICTURE MUTE OFF: 02 11 00 00 00 13
    DISPLAY MUTE ON: 02 14 00 00 00 16
    DISPLAY MUTE OFF: 02 15 00 00 00 17
    LENS SHUTTER ON: 02 16 00 00 00 18
    LENS SHUTTER OFF: 02 17 00 00 00 19

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Have Fun


    TR
  • s1ss1s Posts: 4
    edited 2006-10-16 14:20
    Thank you to everyone who responded to this post. The code I used was a combination the responses.
    What I did was Serin the first two bytes then put the next four bytes into another array. As long as I get the last byte I can determine what button was pushed. The second byte would always tell me what direction to go whether it was an On/Off or input. With a few If/Then's it worked great. The code ran all weekend with no trouble.
    You all were a great help, thanks again,
    Steve
Sign In or Register to comment.