Shop OBEX P1 Docs P2 Docs Learn Events
SX to SX communication SX/B — Parallax Forums

SX to SX communication SX/B

RsadeikaRsadeika Posts: 3,837
edited 2006-01-04 17:41 in General Discussion
I am trying, as learning experience, to get two SX's talking to each other using the basics. I would like to attempt this in SX/B before resorting to asm. Here is what I have so far.

SX#1- SX52, 4MHz, has an interrupt going.
.
.
.
rDATA var byte
temp var byte
.
.
.
·rDATA = "A"
temp = 50
tx_again:
serout re.7, T9600, rDATA
djnz temp, tx_again
.
.
.

SX#2- SX28, 4MHz, plain jane
.
.
.
rDATA var byte
.
.
.
·do
·· serin rc.7, T9600, rDATA
·loop until rDATA = "A"
.
.
.

In this form I do not get anything going, but if I change, for SX#2, loop until rDATA ="A" to loop until rDATA > 0, then I get some activity. It breaks out of the loop, and goes on to do something else. I replaced this with a 65, but that did not work.

I guess I can not figure out why, on SX#2, it is not able to recognize "A" , or any other character as a valid one. Befor I move onto SPI or I2C, I want to try this in plain serial mode.

Any suggestions are appreciated
Thanks
Ray

Comments

  • Jon WilliamsJon Williams Posts: 6,491
    edited 2006-01-01 23:41
    Remember that with True mode the idle state of the serial line is high -- you may want to change to Inverted mode (idle state is low). If you want to stick with True mode then pull the serial line high; this will prevent a low-floating serial line from looking like false bits to the receiver side.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
  • RsadeikaRsadeika Posts: 3,837
    edited 2006-01-02 16:12
    I tried changing the value from T(true) to N(inverted), on both boards, it still did not work. If I put in < 255, when the setting was N,·then I got some activity. I guess more detail is needed , on both boards I have the pullups activated, both are set for internal RC at 4MHz,·and I have one wire to the respective pins. One board sends the data, and the other board is in a loop, waiting for the data to arrive.

    Since, in the setup that I have, when I change the conditions from '=' to '<' or '>' it breaks out of the loop, meaning something has arrived. When I use "A" or 65·as the value, on the receiving end, I am not getting anything, is this a baud problem, or something else. In one of the other posts there was some mention about using serin/serout while using the internal RC, could that be the problem. Since I only have one 4MHz resonator, I can not have both at oschs2 setting.

    Just to·make sure that my thinking is correct, T(true) = msb|lsb, and N(inverted) = lsb|msb. Anything else of significance that I should know about these baud modes.·I am not certain as to how this would have any impact on an SX to SX communication. Now I am stumped.

    Any help would be appreciated.

    Thanks

    Ray
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2006-01-02 16:30
    Simple question: Do you have a common ground between the SXes?

    Serial comms is always LSB first. A "True" signal has the serial idle state high with the start and any "1" bits going low, an "Inverted" signal has the idle state low, with the start and "1" bits going high.

    There's no reason you shouldn't be able to make this work -- I have many projects that use a BASIC Stamp and the SX, and both are simply microcontrollers. Perhaps if you post both programs (not just fragments) then something will be detected by one of us.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2006-01-02 16:34
    D'oh! I just looked up again and noticed that one of your SX chips has an interrupt running -- this with screw up your baud rate. What you should do is switch to an interrupt-driven UART on this side. Or -- and only if your interrupt timing is constant -- you could "tweak" the baud setting on that side to accommodate the time spent in the interrupt. This is a bit tricky, but has been done (Bean did a servo driver using interrupts with a modified baud value -- it's in the Projects forum).

    Sorry I didn't catch the interrupt thing earlier; I'm still exhausted from my move from Dallas to SoCal.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
  • RsadeikaRsadeika Posts: 3,837
    edited 2006-01-02 17:21
    A common ground between them, hmmm. Does that mean another wire that connects at the ground connector on each board, no. When I do this stuff nothing turns out to be a simple matter. I have a direct cut and paste of the two programs. I am hoping it's some obvious that I overlooked.

    Thanks

    Ray



    *******CODE

    The slave
    '
    ' Program Description
    '


    '
    ' Device Settings
    '

    DEVICE········· SX28, OSC4MHZ, TURBO, STACKX, OPTIONX
    FREQ··········· 4_000_000


    '
    ' IO Pins
    '
    ·led1 var rc.0
    ·led2 var rc.1

    '
    ' Constants
    '


    '
    ' Variables
    '
    ·rDATA var byte
    ·temp1 var byte


    ····························


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




    '
    ' Subroutine Declarations
    '
    ·ledon1 sub
    ·ledon2 sub


    '
    ' Program Code
    '

    Start:
    · PLP_A = %00000000
    · PLP_B = %00000000
    · PLP_C = %00000000

    main:
    ·do
    ·· serin rc.7, N9600, rDATA
    ·loop until rDATA = "A"
    · ledon1
    · ledon2
    goto main
    end

    'subs
    ledon1:
    · low led1
    · pause 1000
    · high led1
    return

    ledon2:
    · low led2
    · pause 1000
    · high led2
    return

    'data

    **************************

    The master
    '
    ' Program Description
    '


    '
    ' Device Settings
    '

    DEVICE·SX52,OSC4MHZ

    'IRC_CAL IRC_4MHZ
    FREQ·4_000_000


    '
    ' IO Pins
    '

    IRpin·VAR·RE.0·' IR input
    LED1·VAR·RD.0·' LED


    '
    ' Constants
    '
    ChUp·con 16· 'GoFore
    ChDn··· con 17· 'GoBack
    Power·· con 21· 'Power (red Button)


    '
    ' Variables
    '

    cmdCode··VAR·Byte·' IR command code (7 bits)
    cmdWork··VAR·Byte·' work space for cmd byte
    bitCount·VAR·Byte·' track bits received
    bitWidth·VAR·Byte·' measure bit width
    flags··VAR·Byte
    rxCmd··VAR·flags.0·' receiving command
    rxBit··VAR·flags.1·' measuring bit width?
    hasCmd··VAR·flags.2·' command code available

    temp1··VAR·Byte·' subroutine work vars
    temp2··VAR·Byte
    temp3··VAR·Byte

    temp·var Byte

    rDATA var Byte


    '
    · INTERRUPT NOPRESERVE
    '

    ISR_Start:
    · ASM
    ··· JB··· hasCmd, ISR_Exit·' exit if holding command
    ··· JB··· rxCmd, Check_Bit·' receiving now?
    ··· JB··· IRpin, ISR_Exit··' exit if IR line idle

    Start_Packet:
    ··· SETB· rxCmd···' set rx flags
    ··· SETB· rxBit
    ··· CLR·· cmdWork··' clear work vars
    ··· CLR·· bitWidth
    ··· CLR·· bitCount
    ··· JMP·· ISR_Exit

    Check_Bit:
    ··· JNB·· IRpin, Update_BitWidth·' still in bit?
    ··· JNB·· rxBit, ISR_Exit·' in idle period?
    ··· CLRB· rxBit···' no, clear bit flag
    ··· CJA·· bitCount, #0, Test_DBit ' start or data bit?

    Test_SBit:
    ··· CJA·· bitWidth, #74, Next_Bit ' proper start bit?
    ··· CLR·· rxCmd···' no, reset
    ··· JMP·· ISR_Exit

    Test_DBit:
    ··· CLC
    ··· RR··· cmdWork··' prep for next bit
    ··· CJB·· bitWidth, #34, Next_Bit ' "1" bit?
    ··· SETB· cmdWork.6··' yes, set it

    Next_Bit:
    ··· CLR·· bitWidth··' clear for next bit
    ··· INC·· bitCount··' update count
    ··· CJB·· bitCount, #8, ISR_Exit ' done?
    ··· SETB· hasCmd··' set available flag
    ··· MOV·· cmdCode, cmdWork·' copy work to output
    ··· CLRB· rxCmd···' clear rx flag
    ··· JMP·· ISR_Exit

    Update_BitWidth:
    ··· INC·· bitWidth··' else inc width
    ··· SETB· rxBit···' refresh in bit flag
    · ENDASM

    ISR_Exit:
    · RETURNINT 104···' 26 uS @ 4 MHz


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


    '
    ' Subroutine Declarations
    '
    processCode sub

    gofore sub
    goback sub
    robotStop sub

    ledon sub

    '
    ' Program Code
    '

    Start:

    ·PLP_A = %00000000········· ' pull-up unused pins
    ·PLP_B = %00000000
    ·PLP_C = %00000000
    ·PLP_D = %00000000
    ·PLP_E = %00000000

    · OPTION = $88·············· ' interrupt, no prescaler

    Main:
    · IF hasCmd = 0 THEN Main··· ' wait for new code
    · processCode··········· ' put new code on LEDs
    · hasCmd = 0················ ' clear flag
    · GOTO Main

    end
    '
    ' Subroutine Code
    '
    processCode:
    · if cmdCode = ChUp then
    · gofore
    · endif
    · if cmdCode = ChDn then
    · goback
    · endif
    · if cmdCode = Power then
    · robotStop
    · endif

    '*******************
    rDATA = "A"
    temp = 255
    tx_again:
    serout re.7, N9600, rDATA
    djnz temp, tx_again

    '*********************
    return

    gofore:
    · ledon
    return

    goback:
    · ledon
    return

    robotStop:
    · ledon
    return

    ledon:
    · low LED1
    · pause 1000
    · high LED1
    return
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2006-01-02 18:14
    It's the interrupt in the second program that's causing the problem -- you'll need to change to an ISR-driven UART to work around this.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
  • RsadeikaRsadeika Posts: 3,837
    edited 2006-01-02 18:46
    Thanks Jon,

    I was affraid of that. I guess I will try to implement, a UART that is in asm code, into the ISR. That sounds like it should keep me busy for awhile. I remember for the SIRCS_ISR program that you came up with, you mentioned that the RETURNINT 104 (26 uS @ 4 MHz) was setup to also handle 9600 baud. So, I guess the 104 rate would be a good place to start at.

    Thanks

    Ray
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2006-01-02 18:54
    You don't have to do everything from scratch -- download Al Williams's SX book for ISR code that you can adapt; that's what I've done for my MIDI and LED multiplexer projects (though I was using the receiver portion).

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
  • Jon WilliamsJon Williams Posts: 6,491
    edited 2006-01-02 18:56
    Question: Is there a reason you have to use an ISR for the IR detection? You could use the other version I wrote for you and when the subroutine returns the master could send the code serially -- all of this in high-level SX/B. I understand that my question may be bogus, but at this point I don't know what your overall is.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
  • RsadeikaRsadeika Posts: 3,837
    edited 2006-01-02 21:40
    Here we go again. I have some new code, the master essentially sends, and slave is supposed to respond when it receives the character. It does not work, I must of overlooked something.

    The reason I was using the SIRCS_ISR version is because I had the IR detector hooked up to my SX52 board, since the pulsin command has a bug, I could not use the plain SIRCS on the SX52 board. I guess I will have to reconnect things, but first I want to get a plain serin/serout to work between the two boards.

    Thanks

    Ray



    ********CODE

    This is the master

    '
    ' Program Description
    '


    '
    ' Device Settings
    '

    DEVICE· SX52, OSCHS2
    FREQ· 4_000_000


    '
    ' IO Pins
    '

    TXpin·VAR·RE.7···· ' Transmit


    '
    ' Constants
    '



    '
    ' Variables
    '
    · rDATA var byte
    · temp1 var byte





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


    '
    ' Subroutine Declarations
    '


    '
    ' Program Code
    '

    Start:
    · PLP_A = %00000000······· ' pull-up unused pins
    · PLP_B = %00000000
    · PLP_C = %00000000
    · PLP_D = %00000000
    · PLP_E = %00000000

    ·rDATA = "A"
    ·temp1 = 20
    Main:
    tx_again:
    · serout TXpin, N9600, rDATA
    · djnz temp1, tx_again

    · pause 5000
    goto Main

    END


    '
    ' Subroutine Code
    '


    ' =========================================================================
    ' User Data
    ' =========================================================================



    ******************************

    This is the slave

    '
    ' Program Description
    '


    '
    ' Device Settings
    '

    DEVICE········· SX28, OSCXT2, TURBO, STACKX, OPTIONX
    FREQ··········· 4_000_000


    '
    ' IO Pins
    '
    ·led1 var rc.0
    ·led2 var rc.1

    '
    ' Constants
    '


    '
    ' Variables
    '
    ·rDATA var byte
    ·temp1 var byte


    ····························


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




    '
    ' Subroutine Declarations
    '
    ·ledon1 sub
    ·ledon2 sub


    '
    ' Program Code
    '

    Start:
    · PLP_A = %00000000
    · PLP_B = %00000000
    · PLP_C = %00000000

    main:
    ·do
    ·· serin rc.7, N9600, rDATA
    ·loop until rDATA = "A"
    · ledon1
    · ledon2
    goto main

    end

    'subs
    ledon1:
    · low led1
    · pause 1000
    · high led1
    return

    ledon2:
    · low led2
    · pause 1000
    · high led2
    return
  • RsadeikaRsadeika Posts: 3,837
    edited 2006-01-03 13:22
    After some tinkering I got this to work, sort of. I had to add a common ground wire between the two boards. If somebody has an explanation as to how this magic works, I would appreciate it. And if I add another slave board, do I have to continue the common ground theme, in essence connecting all the boards with a common ground. In all the examples of SPI or I2C, it does not show a common ground between multiple slaves.

    The sort of part, the way it is supposed to work is the master is in a do while loop for a 255 count, sending the character. Breaks out of the loop, takes a three second pause, goes to main, top of the loop, and does it again.

    For the slave it is in a do while loop also, until it gets the character, then does the LED on thing, and goes back to the top of the loop, and does it again.

    The problem is, it cycles through one time, gets the character and turns on the LED's, then nothing. What I am expecting is a constant flashing of the LED's. I did notice that when I hit the reset button on the master, it would cycle through again.

    Did I miss something crucial in my code.

    Thanks

    Ray







    ***********CODE

    This is the master
    '
    ' Device Settings
    '

    DEVICE· SX52, OSCHS2
    FREQ· 4_000_000


    '
    ' IO Pins
    '

    TXpin·VAR·RE.7···· ' Transmit


    '
    ' Constants
    '



    '
    ' Variables
    '
    · rDATA var byte
    · temp1 var byte





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


    '
    ' Subroutine Declarations
    '


    '
    ' Program Code
    '

    Start:
    · PLP_A = %00000000······· ' pull-up unused pins
    · PLP_B = %00000000
    · PLP_C = %00000000
    · PLP_D = %00000000
    · PLP_E = %00000000

    ·rDATA = "A"
    ·temp1 = 255
    Main:

    ·DO WHILE temp1 > 0
    ··· SEROUT TXpin, T9600, rDATA··· ' send the byte
    ··· DEC temp1················· ' update count
    · LOOP

    'tx_again:
    ·' serout TXpin, N9600, rDATA
    '· djnz temp1, tx_again

    · pause 3000
    goto Main

    END


    '
    ' Subroutine Code
    '


    ' =========================================================================
    ' User Data
    ' =========================================================================



    This is the slave
    '
    ' Device Settings
    '
    DEVICE········· SX28, OSCXT2, TURBO, STACKX, OPTIONX
    FREQ··········· 4_000_000

    '
    ' IO Pins
    '
    ·led1 var rc.0
    ·led2 var rc.1
    '
    ' Constants
    '

    '
    ' Variables
    '
    ·rDATA var byte
    ·temp1 var byte

    ····························

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


    '
    ' Subroutine Declarations
    '
    ·ledon1 sub
    ·ledon2 sub

    '
    ' Program Code
    '
    Start:
    · PLP_A = %00000000
    · PLP_B = %00000000
    · PLP_C = %00000000
    main:
    ·do
    ·· serin rc.7, T9600, rDATA
    ·loop until rDATA = "A"
    · ledon1
    · ledon2
    goto main
    end
    'subs
    ledon1:
    · low led1
    · pause 1000
    · high led1
    return
    ledon2:
    · low led2
    · pause 1000
    · high led2
    return
    'data
  • SawmillerSawmiller Posts: 276
    edited 2006-01-03 14:54
    im prolly wrong but it looks like in the master code it will count down once then when it goes back to main its already temp1 = 0...

    i think hop.gif

    dan
  • RsadeikaRsadeika Posts: 3,837
    edited 2006-01-03 15:26
    Yes, you are right on. After looking·at the code for awhile, that is·what I finally noticed. So, in the master, after the loop I put in a temp1=255, and now it works as expected. So, that tells me that the transmit loop has to be in a loop for a certain amount of cycles in order for the slave to get the message.

    The other thing that I noticed is on the slave board when I remove the power and the SX-Key, and then turn on the master, the power LED on the slave board goes on. I did not think that the pins put out that much power so it would turn on the board power LED on the the slave board.

    I am still trying to figure out whats with the common ground thing. My guess would be that since you have a common ground between the boards, you also have a common Vdd between the boards when the Tx/Rx pins are connected. But, what does that have to do with anything.

    Now I can see that I will have to create a UART VP to put into an interrupt within the SX/B program. That way I could have a task, Tx/Rx, running in the background, while I come up with commands that I would use to turn on one LED and then the other, under certain conditions.

    Thanks

    Ray
  • Michael ChadwickMichael Chadwick Posts: 80
    edited 2006-01-03 19:33
    Hi Ray,

    Whenever you want to get a signal from some place to another place, you have to also provide a return path for the signal current.· That is what the ground does for you.·· Assuming you have two separate power supplies like wall warts running the two boards, there is no common connection between them until you deliberately make the connection.

    Without the common, your serial signal is just lifting the whole receiving SX circuit up and down, so the receiving SX never saw the signal change.· Been there, done that!

    The SX also has input protection diodes which will couple the signal power from an input to the power pin on the SX when the receiving SX is off.· That is why your power light lights on the receiver even with power removed.· Generally there is not enough supplied by the transmitting SX to power the receiver, just enough to light the LED.

    MRC
  • RsadeikaRsadeika Posts: 3,837
    edited 2006-01-04 13:42
    Thanks MRC and everybody who helped out. I got the two boards, networked, and I use that term very loosesly (wire and code). This little experiment gave me·some insight as to what it takes to get two uC to talk to each other.

    The problem that I have with serin/serout, is that you can not use an interrupt when implementing those commands. In my project I am still leaning towards having a multi tasking scenario within an SX/B framework; I am still looking at Peter's (pjv) RTOS code for more insight. If I go with SPI, I2C, ..., etc, all of that code is in asm, which means I would have to convert the VP's to SX/B format, and there are no real examples as to how I would implement a command(s) to make it work. I already tried doing an asm UART, within SX/B, resulting in, not working. I am thinking that I might present that code in another thread, with lots of people looking at it, maybe I could get it to work. That could be the second VP within an SX/B framework, the first VP·being Jon's SIRCS_ISR, of course.

    The next area of investigation would be virtual ciruits. I can see down the road that I will need some devices that require an ADC, and I believe that the SX can do this within code. I could be mistaken about this, if I am correct, that means one less chip on my board.

    Thanks

    Ray
  • pjvpjv Posts: 1,903
    edited 2006-01-04 17:20
    Hi Ray;

    You are absolutely correct about the A/D being implemented in software; that is, with the addition of two resistors and one small non-critical capacitor. Works a "treat". In fact if need be, you can dynamically vary the resolution of the Virtual A/D from 2 bits (or less, but then it's hardly an A/D) through 14 bits. At that extreme the SX's noise starts to get to you. At 8 bits you resolve 20 milliVolts in a 5 Volt range very nicely. The trade-off is a linear speed-for-bits relationship.

    Works great for doing DFT's and FFT's in the SX for audio, tone detection etc.

    I'm curious which of the two RTOS's you are pursuing. The non-preemptive is very simple, and of course simple minded. The pre-emptive is fairly tricky, and takes some experience to get the full gist.

    Keep on pluggin' !

    Cheers,

    Peter (pjv)
  • RsadeikaRsadeika Posts: 3,837
    edited 2006-01-04 17:41
    Peter,

    I am looking at the non-preemptive code, your SX contest submissiom for last year. I want to get a general feel for how you are implementing the RTOS. I must stress at this point that I want to implement this within SX/B, no easy task I am sure. That is why I want to study the easier code; I like to get some small stuff working before I take on more difficult stuff.

    I am also thinking along the lines of having the backbone of the system my Real Time Tasking System (RTTS), if you will.·As a working model I would like to have VP's written as subroutines, and with an RTTS command, have the VP's or other pieces of code,·run continously in the background, or a one time run in the background.

    I know I have a long way to go with this.

    Thanks

    Ray
Sign In or Register to comment.