Shop OBEX P1 Docs P2 Docs Learn Events
Sx Serial Comms problem — Parallax Forums

Sx Serial Comms problem

djh82ukdjh82uk Posts: 193
edited 2009-04-07 21:50 in General Discussion
Hi Guys

Im having trouble getting serial comms to work, I know it's my code thats messing it up.

I am sending out a 3 digit number from a propeller board, I know this works as I have an arduino that can receive the 3 bytes that make up the number.

However i cannot get this code to work on the SX, all I want to start with as a test, is for it to receive a number, and if that number matches 001, switch on pin 1, 002, switch on pin 2 etc.

But I think my problem is that the SX is only receiving one byte, and not the 3 bytes, ive never been any good with the SX so would appreciate some help.

Here is my code so far:

DEVICE sx48, OSC4MHZ
IRC_CAL IRC_SLOW
FREQ 4_000_000
PROGRAM Start

sData var Byte
leds var byte

Start:
'OUTPUT RA.2
'OUTPUT RA.3


Main:
DO
SERIN RA.1, N9600, sData
'001 = RA.2
'002 = RA.3
'LEDs = sData
if sdata = 001 then
toggle RA.2
endif

LOOP


DJH

Comments

  • JonnyMacJonnyMac Posts: 9,412
    edited 2009-04-03 14:44
    You need to use an external crystal or resonator -- the internal source is not accurate enough for serial comms. Use a 4MHz resonator and change your DEVICE line to OSCXT1.
  • djh82ukdjh82uk Posts: 193
    edited 2009-04-03 15:25
    hmm, i had an email to say Bean had replied to this thread, but there is no post here :S

    With regards the crystal, is that definatley needed for low speed comms?

    What about my code only wanting to receive 1 byte?

    Thanks

    DJH
  • JonnyMacJonnyMac Posts: 9,412
    edited 2009-04-03 15:51
    Use a resonator and the problems will go away -- the part costs less than $2 and will save you a lot of time (which is worth money).

    You only have one SERIN statement, and that works with bytes. If you search the forums you'll find several examples of SERIN wrapped in a function called RX_BYTE that allows you to call it multiple times without consuming code space.
  • djh82ukdjh82uk Posts: 193
    edited 2009-04-03 16:30
    Hiya

    I did find those posts, but I could not figure out how it was working, or how to get the received data into a variable with a format that I wanted.

    DJH
  • JonnyMacJonnyMac Posts: 9,412
    edited 2009-04-03 17:50
    You haven't been very clear about the format you want -- a few more details on your part could reduce this from 20 questions to 2.....

    For example: you say you're sending out a 3-digit number from the Propeller. Is that three ASCII characters? (e.g., "001") -- these are important details.

    If you are in fact sending ASCII characters these routines will give you an idea of how to put SERIN into a function and how to receive a value as an string -- up to three characters (any non-digit character will terminate the input).

    FUNC RX_BYTE
      SERIN RX, Baud, __PARAM1
      ENDFUNC
    
    ' -------------------------------------------------------------------------
    
    FUNC RX_DEC3
      rxDigit       VAR     tmpB1
      rxIdx         VAR     tmpB2
      rxResult      VAR     tmpB3
    
      rxResult = 0                                  ' clear result
      FOR rxIdx = 0 TO 2                            ' allow up to 3 digits
        rxDigit = RX_BYTE                           ' get a digit from stream
        IF rxDigit < "0" THEN EXIT                  ' abort on non-digit
        IF rxDigit > "9" THEN EXIT
        rxDigit = rxDigit - "0"                     ' convert from ASCII
        rxResult = rxResult * 10                    ' update result
        rxResult = rxResult + rxDigit               ' add new digit to result
      NEXT
      RETURN rxResult
      ENDFUNC
    
  • BeanBean Posts: 8,129
    edited 2009-04-03 18:16
    DJH,
    I had replied...But then Jon said exactly the same thing before I did. So I deleted the post.

    You MIGHT get away with using the internal oscillator and "IRC_CAL IRC_4MHZ" but it will be iffy. The slower the baud rate the better luck you will have.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    There is a fine line between arrogance and confidence. Make sure you don't cross it...

    ·
  • djh82ukdjh82uk Posts: 193
    edited 2009-04-03 18:48
    Thanks Jon, thats just what I needed, something laid out a bit more specifically for the problem I have. I am sending as bytes at the moment, so Im guessing they will come through as ascii, I will give the code a go and try and find a resonator also..

    Thanks

    DJH
  • pjvpjv Posts: 1,903
    edited 2009-04-03 19:35
    Hi All;

    I hate to be a spoiler in all of this, but I use the internal oscillator at 4 MHz for serial comms at 9600 frequently, and find it totally reliable provided one is able and prepared to "tune" the software timing to suit.

    Additionally, the stability with temperature is adequate.

    I normally run things at 50 MHz with a resonator, but for low cost and battery apps the internal 4Mhz works just peachy.

    All that said, for critical applications I would go to a resonator, but I have some applications where there just is no room for the leaded part.

    Cheers,

    Peter (pjv)
  • JonnyMacJonnyMac Posts: 9,412
    edited 2009-04-03 19:39
    You're not being a spoiler, Peter, yet may I suggest being unrealistic given the skills admitted to by the original poster -- he wants easy plug-and-play (i.e., using high-level SX/B) and will not do the kind of fine-tuning that comes very easily to you.
  • djh82ukdjh82uk Posts: 193
    edited 2009-04-03 20:08
    Ok, the below code compiles, but does not work, I have a 3-pin 4Mhz resonator in the X2 port on the project board, I have been taking it out when programming.

    I have the TX line pulled low on the propeller board, but it goes direct to the RX pin on the SX board and the 2 boards share the same ground.

    DEVICE sx48, OSCXT2
    IRC_CAL IRC_SLOW
    FREQ 4_000_000
    PROGRAM Start

    sData var Byte
    leds var byte
    tmpB1 var Byte
    tmpB2 var Byte
    tmpB3 var Byte
    rxDigit VAR tmpB1
    rxIdx VAR tmpB2
    rxResult VAR tmpB3


    RX_BYTE SUB 0
    RX_DEC3 SUB 0

    Start:


    Main:

    RX_Byte
    if rxResult = 001 then led

    led:
    output ra.2
    Pause 3000
    goto main

    FUNC RX_BYTE
    SERIN RA.1, N9600, __PARAM1
    ENDFUNC

    '

    FUNC RX_DEC3


    rxResult = 0 ' clear result
    FOR rxIdx = 0 TO 2 ' allow up to 3 digits
    rxDigit = RX_BYTE ' get a digit from stream
    IF rxDigit < "0" THEN EXIT ' abort on non-digit
    IF rxDigit > "9" THEN EXIT
    rxDigit = rxDigit - "0" ' convert from ASCII
    rxResult = rxResult * 10 ' update result
    rxResult = rxResult + rxDigit ' add new digit to result
    NEXT
    RETURN rxResult
    ENDFUNC
  • RobotWorkshopRobotWorkshop Posts: 2,307
    edited 2009-04-03 20:57
    How many different values are you going to send to the SX chip? If you control both sides (Propeller and SX) then why bother converting the number to ASCII before sending it?? That will just add overhead on both sides. I would just pattern your messages to the SX like those that are already standard for talking to many devices:

    http://forums.parallax.com/forums/default.aspx?f=15&m=258522&g=258661

    JonnyMac has published some excellent examples using the SX where it uses a protocol like this to send data. I believe Parallax has many on their site as a PDF download. I would try using those to start with and build from that. The ISR based serial receive code is nice since it can watch for stuff coming down the serial line in the background and you won't miss anything.

    You mention the two chips are sharing a common ground. Are you running both chips at 3.3V or is the SX running at 5V?
  • djh82ukdjh82uk Posts: 193
    edited 2009-04-03 21:04
    Hiya, I will be sending 3 digit numbers from 000 to 999 to the SX

    Prop is on 3.3V and the SX must be on 5V come to think of it as im using the project boards.

    It wasn't a problem with an arduino tho but that may have been luck.

    I am doing it this way as the Prop will be using the serial TX line as a sort of bus, I will have SX boards, Picaxe boards etc listenning in until they get a command that is meant for them.

    regards

    DJH
  • JonnyMacJonnyMac Posts: 9,412
    edited 2009-04-03 22:25
    Using TTL levels on the SX side you'll be fine. The attached program does what you want -- tested on a PDB using a terminal program.
  • djh82ukdjh82uk Posts: 193
    edited 2009-04-03 23:36
    Thank you Jon

    I can't thank you enough for spending the time writing that out.

    As soon as I get back I will give it a go.

    Thanks

    DJH
  • djh82ukdjh82uk Posts: 193
    edited 2009-04-04 22:51
    Hi Jon

    Ok

    I went to compile it, I changed the T9600 to N9600 as my prop does serial inverted (pulled low), also changed the chip to SX48. It failed to compile as the command that said "PUTBIT" came back as not being a command, I have never used the "PUT" command so I tried it as "PUT BIT" but still no compile, so i took out the bit and it compiled ok, but im presuming that breaks it now?

    Also I added in a line to try and make RA.2 high when the value 001 is recived (just as a test).

    Also I have a 3 pin resonator in X2 on the board, does that mean the osc setting needs to change?

    I have re-attatched the file so you can see my changes, and possibly where i broke it.

    Am I correct in thinking that it would make all of portC go low is "999" is received?

    Im trying to learn from your code.

    Thanks Again

    DJH
  • JonnyMacJonnyMac Posts: 9,412
    edited 2009-04-04 23:10
    You need to download and install the latest version of the compiler -- presently 2.00.19. Get it from a sticky at the top of this forum.
  • djh82ukdjh82uk Posts: 193
    edited 2009-04-06 13:57
    Ok, just installed the new compiler, failed to compile again, different error, it said that FUNC RX_BYTE could not have an ENDFUNC without a RETURN, so I added one just above the endfunc, now compiles ok.

    What should the OSC be set to, to use the X2 port on the dev board?

    DJH
  • JonnyMacJonnyMac Posts: 9,412
    edited 2009-04-06 14:14
    That is not a failure to compile, it's a warning that can be ignored. The RX_BYTE function moves the received byte into __PARAM1 (which is what RETURN does) so RETURN is not required. If you didn't use RETURN __PARAM1 then you have hosed up the function. As I indicated in my post with the code, that program has actually been tested (using HyperTerminal for input and LEDs on the PDB).
  • djh82ukdjh82uk Posts: 193
    edited 2009-04-06 16:37
    Hiya

    Ok, no luck, I have tried it a few different ways, so it must be my circuit?, so a checklist:

    RB.0 is being used as the RX on the SX board.
    Gnd on both boards is connected.
    I am using N9600 on the prop
    I am using N9600 as the baud on the SX, but I don't know if the hardware is, as if I put a multimeter between GND and the RX pin on the SX, I get 1.48V, when the pro Xmits it drops down to 1.32 for less than a second (obviosuly not accurate). If I disconnect the SX board, the voltage on the props TX pin is 0v, and rises to 0.3V when xmitting.

    Is that right? The only circuitry I have, is a 4.7k Pull-Down resistor on the prop board for the TX lead. no components on the SX side.

    Should I set the pin to NOPULLUP on the SX side as im using the serial inverted?

    Sorry to be a pain, must be getting on your nerves by now

    Thanks

    DJH
  • JonnyMacJonnyMac Posts: 9,412
    edited 2009-04-06 21:29
    Well, you're right about that last part....

    One of the simple facts that you seem to be ignoring is that the SX has a TTL threshold of 1.4 volts; this is why nothing is getting through (based on your measurements). A better solution, in my opinion, is to use Open-True (OT) mode with a pull-up on the line between the Propeller and the SX. The Propeller is 5v tolerant and the pull-up (4.7K to 5v) limits the current through the TX pin on the Propeller when it makes that pin an output-low (for start and zero bits). Using the pull-up keeps the signal on the SX side legal.

    I wrote a simple program for a Propeller demo board that spits out bytes in OT mode; on the receiving end is an SX28 in a PDB with a pull-up on its RX pin (to 5v) and the port C bits connected to LEDs. It works.
  • djh82ukdjh82uk Posts: 193
    edited 2009-04-07 16:19
    Hiya

    Do I not also need a pullup to 3.3v on the prop side?

    As thats what sets it's mode (True or inverted)

    Right now, I have changed it so there is a pullup on the prop to 3.3v (4.7K) and that goes straight into the SX RA.0 pin, the pin now reads around 3.3v and drops to 2.26V when xmitting (not accurate).

    Question is, is it dropping below 1.4V so fast that the multimeter does not register? Or do I still have the wrong voltages?

    If I pull it up to 5v, I presume that I don't pull it up to 3.3v on the prop side?

    Thanks

    Daniel
  • djh82ukdjh82uk Posts: 193
    edited 2009-04-07 16:27
    Ok

    I have tried it with just the 4.7k pullup to 5v on the SX side, and the voltages seem the same, around 3.6V dropping to 2.8 when xmitting.

    I had to change the code a little to test it, could you have a quick look for anything glaringly obvious?

    I changed it so that it puts 2 leds high when it received 999 via serial

    Thanks

    DJH
  • RobotWorkshopRobotWorkshop Posts: 2,307
    edited 2009-04-07 18:53
    It will be hard to tell that the prop is transmitting by just using a voltmeter. The fact that it does drop in voltage does imply that it probably is sending something and at least pulling the line low at some point for some duration. Just think PWM and averaging the voltage.... If you want to watch it on the line you should use a scope or something to analyze the serial signal.

    I haven't seen any mention of how you have the LED's connected. Are they connected to 5V with a current limiting resistor to each SX pin and setup to light when pulled low? Have you ever seen the LED's change state and light if you make a tiny program to flash the LED's?

    Before making any changes to Jon's code why not just temporally connect some LED's to port C on your SX chip to exactly replicate what Jon has working. If that works then build on that. If not then you have some other connection problem and more tweaks to the code will just waste time looking for a problem that may be somewhere else.
  • djh82ukdjh82uk Posts: 193
    edited 2009-04-07 21:50
    Hiya

    I know the prop xmits, as my arduino board receives the transmission fine.

    I have been checking PortC with a mulitmeter, but trying an led will not be a problem

    Yes I the leds on PortB with 180ohm resisitors

    DJH
Sign In or Register to comment.