Shop OBEX P1 Docs P2 Docs Learn Events
Reading bytes from PC via RS232 — Parallax Forums

Reading bytes from PC via RS232

Craig JacobsCraig Jacobs Posts: 9
edited 2008-09-21 18:40 in General Discussion
I am trying to send commands to the SX board from the COM port on my Linux box. The circuit I have is pin 3 from the DB9 -> 3.3KOhm Resistor -> RA.1. This pin is pulled up via a 4.7K Resistor. I also have port C wired up to a 7-segment display (This part has been tested and is working fine). Also I'm using the 50Mhz resonator.

When I send a character (0x9 for example) to the COM port (/dev/ttyS0) I get a response, but only seem to be getting hex 1s and 0s. I have done everything I can think of to try to ensure that the baud rates match (9600), etc.

I'm wondering if there is anyone that has experience trying to interface a linux system to the SX this way and has any suggestions. I actually thought this was going to be the "easy" part smile.gif

Unfortunately I don't have a windows machine with a com port [noparse]:([/noparse] to do any testing.

Any help would be greatly appreciated.

Here is my SX/B code (I started with the SERIN example in the SX/B Online Help PDF):


'
' Device Settings
'

DEVICE SX28, OSCHS1, TURBO, STACKX, OPTIONX
FREQ 50_000_000
ID "SERIAL"

'
' IO Pins
'
LED PIN RC OUTPUT '7-segment display
SIO PIN RA.1 INPUT 'pull-up via 4.7K
'
' Constants
'
kDash CON %00010000
kBaud CON "OT9600"

'
' Variables
'
serByte VAR Byte 'serial I/O byte
tmpB1 VAR Byte 'parameter

' =========================================================================
PROGRAM Start
' =========================================================================

Pgm_ID:
DATA "SERIAL", 0

'
' Subroutines / Jump Table
'
MAKE_DIGIT FUNC 1,1 ' make 7-segs digit
RX_BYTE FUNC 1 ' receive serial byte
'
' Program Code
'

Start:
PLP_A = %0010 ' pull up unused pins
PLP_B = %00000000

Testing:
LED = kDash ' clear display
serByte = RX_BYTE
IF serByte <= $F THEN
LED = MAKE_DIGIT serByte
ENDIF

'FOR serByte = $0 to $f '--- for testing the 7-seg display
' LED = MAKE_DIGIT serByte
PAUSE 150
'NEXT

GOTO Testing

'
' Subroutine Code
'

' Use: rxInput = RX_BYTE
' reads byte from serial input and places it in 'rxInput'
FUNC RX_BYTE
SERIN SIO, kBaud, tmpB1 ' receive a byte
RETURN tmpB1
ENDFUNC

'
' Use: destination = MAKE_DIGIT value
' converts number in 'value' to 7-segment digit pattern
' and places it in 'destination'
FUNC MAKE_DIGIT
tmpB1 = __PARAM1 ' copy value
IF tmpB1 <= $F THEN ' check range
READ SegMap + tmpB1, tmpB1 ' read table value
ELSE
tmpB1 = kDash ' display dash -- out of range
ENDIF
RETURN tmpB1
ENDFUNC


' =========================================================================
' User Data
' =========================================================================
SegMap:
' bafg.cde
DATA %11100111 ' 0
DATA %10000100 ' 1
DATA %11010011 ' 2
DATA %11010110 ' 3
DATA %10110100 ' 4
DATA %01110110 ' 5
DATA %01110111 ' 6
DATA %11000100 ' 7
DATA %11110111 ' 8
DATA %11110110 ' 9
DATA %11110101 ' A
DATA %00110111 ' b
DATA %01100011 ' C
DATA %10010111 ' d
DATA %01110011 ' E
DATA %01110001 ' F



Here is the script I run on the Linux box to send bytes to the serial port:

echo -n 0x0 >> /dev/ttyS0
sleep .2
echo -n 0x1 >> /dev/ttyS0
sleep .2
echo -n 0x2 >> /dev/ttyS0
sleep .2
echo -n 0x3 >> /dev/ttyS0
sleep .2
echo -n 0x4 >> /dev/ttyS0
sleep .2
echo -n 0x5 >> /dev/ttyS0
sleep .2
echo -n 0x6 >> /dev/ttyS0
sleep .2
echo -n 0x7 >> /dev/ttyS0
sleep .2
echo -n 0x8 >> /dev/ttyS0
sleep .2
echo -n 0x9 >> /dev/ttyS0
sleep .2
echo -n 0xA >> /dev/ttyS0
sleep .2
echo -n 0xB >> /dev/ttyS0
sleep .2
echo -n 0xC >> /dev/ttyS0
sleep .2
echo -n 0xD >> /dev/ttyS0
sleep .2
echo -n 0xE >> /dev/ttyS0
sleep .2
echo -n 0xF >> /dev/ttyS0

Comments

  • JonnyMacJonnyMac Posts: 9,214
    edited 2008-09-17 16:30
    Since you're not using an inverter circuit (e.g., MAX232) you need to specify inverted mode; change kBaud to "N9600"

    Also, change your series limiter to 20K and add a 50K pull-down after between the SX and the 20K (the pull-down is only needed for when the PC is disconnected). The 20K will limit the current into your SX should your PC be pumping out full RS-232 levels (+/-15 volts). The 20K/50K combination will form a bit of a divider for high-going bits but should put the input well about the TTL input threshold of 1.5v, even with non standard (i.e., low voltage) serial ports.
  • Craig JacobsCraig Jacobs Posts: 9
    edited 2008-09-18 02:56
    Thank you.

    I have implemented these changes, but I'm still getting garbage, although it seems a different sort. Do you have any suggestions for a setup that will let me test this? Preferably a Linux character based solution, but if I need to I'll get a Windows box with a com port for testing. Ultimately I do need to hook it up to a Linux box, but If I can get the serial stuff working reliable I can do the Linux stuff later: one problem at a time.

    On the Linux box I've run stty on the port, setting it to 9600 cs8 no parity, and have tried sending hex (per the above script) no dice.

    Generally speaking, does RS-232 communications with the SX have the capacity for being highly reliable? I have a programing background, but I'm very new to micro controllers, so I apologize in advance for any stupid questions.

    Another question is do I need to send Hex to the SX or should I be able to send ASCII? Phase 2 is creating a buffered serial interface so I can send some actual data, and ASCII will be easier to deal with.

    BTW I've been working my way through Practical SX/B and I have found it to be very helpful. I haven't done any assembly for over 20 years, and I'd like to keep it that way smile.gif

    -C
  • PJMontyPJMonty Posts: 983
    edited 2008-09-18 05:14
    Craig,

    Serial communications on the SX is rock solid as long as you have a good oscillator. Since you're using a resonator, you should be fine.

    You mentioned that you're getting a "different sort" of garbage. What exactly? Also, rather than sending the value 0 to 15 in hex, just try sending the same character over and over. you need some way to determine what you're sending and what you're getting. If you're sending a different value each time, it makes it hard to correlate what is coming from the Linux box with what is being received on the SX. You first need to make sure that you're getting a consistent value into the SX each time. Sending the same value over and over will let you find out if this is happening or not.

    Thanks,
    PeterM
  • Craig JacobsCraig Jacobs Posts: 9
    edited 2008-09-18 16:13
    Serial communications on the SX is rock solid as long as you have a good oscillator. Since you're using a resonator, you should be fine.
    I'm currently using a 50Mhz, but for 9600 baud, a 4Mhz (external) should be sufficient, right?

    You mentioned that you're getting a "different sort" of garbage. What exactly?
    I'm not sure. I'm getting a byte, but regardless of what I send (echo 0x7 > /dev/ttyS0, for example) whatever I'm getting is outside the $0 - $F range. I'm not sure how to tell specifically what I'm getting on the SX side.

    Also, rather than sending the value 0 to 15 in hex, just try sending the same character over and over. you need some way to determine what you're sending and what you're getting. If you're sending a different value each time, it makes it hard to correlate what is coming from the Linux box with what is being received on the SX. You first need to make sure that you're getting a consistent value into the SX each time. Sending the same value over and over will let you find out if this is happening or not.
    Agreed. I'm modifying the code to send a hex 7 every .2 seconds.

    I do have some questions about sending bytes. My understanding is that it doesn't really matter if the source is hex or ascii, right? For example, sending an "A" is equivalent to sending 0x41 - SERIN would see the same value, correct? So I could test for either $41 or "A" in the SX/B code?

    Thanks,

    -Craig
  • Craig JacobsCraig Jacobs Posts: 9
    edited 2008-09-19 03:47
    Success! roll.gif

    The basic problem was that I was trying to send hex values but the shell was treating them literally, so 0xf was '0xf', not $f. I rewrote my scripts to output ASCII, made the proper stty settings, and it works great. For those of you that want to send serial to a SX from a linux box, I have a sample PHP script that uses PHP Serial class by R
  • Craig JacobsCraig Jacobs Posts: 9
    edited 2008-09-19 16:36
    Also, I found this Nuts and Volts column this morning that I found really helpful. I probably should have done some more research before diving in.

    Column #125: Control from Your Favorite Terminal

    Thanks all for you help.
  • T'SaavikT'Saavik Posts: 60
    edited 2008-09-21 16:35
    "minicom" is usually the default terminal program for linux.

    ctrl-a then z will bring up the main menu.
  • Craig JacobsCraig Jacobs Posts: 9
    edited 2008-09-21 18:40
    Yeah. Once I got the whole HEX vs ASCII thing figured out that worked too.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    -Craig
Sign In or Register to comment.