SX to SX communication SX/B
Rsadeika
Posts: 3,837
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
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 Williams
Applications Engineer, Parallax
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
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
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
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 Williams
Applications Engineer, Parallax
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 Williams
Applications Engineer, Parallax
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
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
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
i think
dan
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
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
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
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)
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