Two Serial Ports
mynet43
Posts: 644
Would someone please post some code showing how to use two serial ports at the same time?
I have one port with Rx, Tx on pins P12 and P13.
The other port has Rx, Tx on pins P14 and P15.
I'm familiar with using the serial routines like FullDuplexSerialPlus, etc. I've just never done two ports at once.
Thank you for your help.
Jim
I have one port with Rx, Tx on pins P12 and P13.
The other port has Rx, Tx on pins P14 and P15.
I'm familiar with using the serial routines like FullDuplexSerialPlus, etc. I've just never done two ports at once.
Thank you for your help.
Jim

Comments
I'll check that out.
It sounds like it's just what I'm looking for.
Jim
I often have a serial connection monitored in a separate cog.· This isn't the most efficient way to do this but it's easy for me to understand what is going on.
There are several refinements I left out for clarity.· In this example I left the names of the devices I use (barcode & balance).· This object only receives data from the serial connections and assumes data terminates with a carriage return.· You'd want to use a different solution if you also want to send data over the lines(such as FullDuplexSerial).
I'm using simpleSerial since I am "watching" the serial line a separate dedicated cog.
If you use FullDuplexSerial you wouldn't need to start new cogs to watch the serial ports since FullDuplexSerial·runs in·its own cog anyway.· Just use rxcheck in the main loop to check for new received bytes.
Hopefully·some of this will be useful to you.
{ Balance and Barcode Read and Display Object by Duane Degn August 1, 2010 This is a simplified version of a datalogging object I use. I removed the datalogging, wireless communication, and lots of other stuff. This objets assumes data from both serial connections send data terminating with a carriage return (ASCII 13). } CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 _balanceBaud = 4800 _barcodeBaud = 2400 ' Pin assignments _barcodeData = 8 ' through 10KΩ resistor (My barcode reader is 5V device) _balanceData = 10 _LargeBufferSize = 64 VAR long barcodeStack[noparse][[/noparse]32], balanceStack[noparse][[/noparse]32] byte barcodeFlag, balanceFlag byte balanceBuffer[noparse][[/noparse]_LargeBufferSize], barcodeBuffer[noparse][[/noparse]_LargeBufferSize] OBJ Balance : "Simple_Serial" Barcode : "Simple_Serial" Tv : "tv_terminal" PUB Main | temp barcodeFlag := 0 balanceFlag := 0 Tv.Start(12) Tv.str(@title) Tv.out(13) temp := cognew(WatchBarcode, @barcodeStack) waitcnt(clkfreq/10 + cnt) Tv.str(string("Barcode cog = ")) Tv.dec(temp) Tv.out(13) temp := cognew(WatchBalance, @balanceStack) waitcnt(clkfreq/10 + cnt) Tv.str(string("Balance cog = ")) Tv.dec(temp) Tv.out(13) ' **** Main Program Loop **** repeat if barcodeFlag == 1 Tv.str(string("Barcode = ")) Tv.str(@barcodeBuffer) barcodeFlag := 0 'Tv.out(13) ' in this case the barcodeBuffer has a carriage return at the end its line already. if balanceFlag == 1 Tv.str(string("Balance = ")) Tv.str(@balanceBuffer) 'Tv.out(13) balanceFlag := 0 ' Do other stuff PUB WatchBarcode | localCharacter, localIndex Barcode.init( _barcodeData, -1, _barcodeBaud) repeat barcodeBuffer[noparse][[/noparse]localIndex++] := Barcode.rx if barcodeBuffer[noparse][[/noparse]localIndex - 1] == 13 barcodeFlag := 1 localIndex := 0 repeat while (barcodeFlag == 1) ' wait for string to be displayed by main loop bytefill(@barcodeBuffer, 0, _LargeBufferSize) PUB WatchBalance | localCharacter, localIndex Balance.init( _balanceData, -1, _balanceBaud) repeat balanceBuffer[noparse][[/noparse]localIndex++] := Balance.rx if balanceBuffer[noparse][[/noparse]localIndex - 1] == 13 balanceFlag := 1 localIndex := 0 repeat while (balanceFlag == 1) ' wait for string to be displayed by RecordData loop bytefill(@balanceBuffer, 0, _LargeBufferSize) DAT title byte "Balance and Barcode Read and Display Object",0I haven't been able to get the 4 port serial object to work for me.· I think one of the methods I was using wasn't behaving well and keep the 4 port object from working.
Duane
Thank you for the example and your note about the 4-port serial interface.
I've downloaded the 4-port serial code and I plan to test it in the next couple of days.
I plan to run a loopback test, something like his sertest.spin. If this works, I think I'll be OK.
Thanks again for your help.
Jim
Duane, what was the problem you had? I do have an updated version but it adds a couple of advanced features rather than fixing any bugs.
Thanks for checking in on this.
A couple of questions, since I haven't tried it yet.
1. In your sertest.spin program, you use the constant NOMODE for the input mode parameter. Is this the correct constant to use for standard serial output?
2. In the same program you're using pcFullDuplexSerial as the debug serial program. This isn't included in your zip file. It looks like a single port version because the calls only have one argument. I'm using FullDuplexSerialPlus for the debug routine. Is there an advantage to using the 'pc' version?
3. Do you have a routine like 'getstr' in FullDuplexSerialPlus, or do I need to supply my own?
My goal is to support two standard RS-232 I/O ports for both input and output. It looks like this should work fine.
Am I on the right track?
Thank you for your help.
Jim
Thanks for the great answers. I think I'm off and running.
Do you plan to put the getstr( ) routine in the code? If not, I'll probably stick it in my copy of your program. Or it wouldn't be much trickier to put it in the calling program.
I also noticed you have a getc( ) entry that does the same thing as 'rxcheck', so I may use that.
Final question. In the sertest routines, I noticed you use a second object for the debug port. Would it also work to use one of your multi-ports and just assign it pins 31 and 30 in the AddPort call?
Thanks again for all your help. You've made it much easier to get started.
Jim
I doubt my problems were do to your object.· I was using an early version of Kye's SD card object (Kye has since stated it was full of bugs) and I'm guessing it didn't play nice with your object.· I had other troubles with the early SD object but I got it to work (I had to move some of my variables declared in a DAT section to the VAR section).· I plan on trying the four port serial object again with Kye's updated object.· It would save me several cogs (I'm always running out of cogs).
Duane
Re
PUB getstr(port, stringptr) | index '' Gets zero terminated string and stores it, starting at the stringptr memory address index~ repeat until ((byte[noparse][[/noparse]stringptr][noparse][[/noparse]index++] := rx(port)) == 13) byte[noparse][[/noparse]stringptr][noparse][[/noparse]--index]~shoud that be "== 0" if you are looking for a zero terminated string? Or are you looking for a zero terminated string that ends in 0,13?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
www.smarthome.viviti.com/propeller
I've been playing with it.
I added the code for getstr( ) to the driver and it works perfectly with the PST.
I wrote a test case to input from and output to the PST, using port 2.
I've attached the modified pcFullDulplexSerial4FC with the getstr( ) routine. I may remove this and put it in the calling routine.
Anyway, here's the test case. I'm running it on a demo board with a mouse attached. Everything works great!
Thanks for all the help.
Jim
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 DisplayPort = 0 ' Uart Port Number for Display Interface Display_RX = 12 ' Display RX Pin Display_TX = 13 ' Display TX Pin Serial_Port = 1 ' Uart Port Number for 2nd Serial Port for Comm Interface Serial_RX = 14 ' Serial RX Pin Serial_TX = 15 ' Serial TX Pin Debug_Port = 2 ' Uart Port Number for debug port to Prop Plug Debug_RX = 31 ' Debug RX Pin Debug_TX = 30 ' Debug TX Pin OBJ mouse : "mouse" ' Mouse Control Routine uart : "pcFullDuplexSerial4FC-getstr" '1 COG for 4 serial ports VAR long mouse_x, mouse_y byte strinp[noparse][[/noparse]128] PUB start ' start serial I/O routine uart.Init uart.AddPort(DisplayPort,Display_RX,Display_TX,UART#PINNOTUSED,UART#PINNOTUSED,UART#DEFAULTTHRESHOLD, { } UART#NOMODE,UART#BAUD115200) uart.AddPort(Serial_Port,Serial_RX, Serial_TX, UART#PINNOTUSED,UART#PINNOTUSED,UART#DEFAULTTHRESHOLD, { } UART#NOMODE,UART#BAUD115200) uart.AddPort(Debug_Port, Debug_RX, Debug_TX, UART#PINNOTUSED,UART#PINNOTUSED,UART#DEFAULTTHRESHOLD, { } UART#NOMODE,UART#BAUD115200) uart.Start 'Start the ports waitcnt(clkfreq/4 + cnt) ' wait to start up ' start mouse and set bound parameters mouse.start(24, 25) waitcnt(clkfreq/4 + cnt) ' wait to start up mouse.bound_limits(0, 0, 0, 239, 319, 0) mouse.bound_scales(8, 8, 0) ' 1,1,0 is default, 8,8,0 slows down mouse movement mouse.bound_preset(119, 159, 0) waitcnt(clkfreq*4 + cnt) ' wait to start debug screen cls ' clear the screen repeat 2 cursloc(10,10) str(string("Enter text: ")) getstr(@strinp) cursloc(10,12) str(string("Print text: ")) str(@strinp) tx(13) waitcnt(clkfreq*2 + cnt) cls ' now test the mouse movement cursloc(20,17) str(string("Mouse Position")) cursloc(20,19) str(string("X-Loc")) cursloc(30,19) str(string("Y_Loc")) repeat mouse_x := mouse.bound_x mouse_y := mouse.bound_y cursloc(20,20) dec(mouse_x) str(string(" ")) ' clear left over digits from last display cursloc(30,20) dec(mouse_y) str(string(" ")) '' Display Output Routines PRI cls ' clear the debug screen tx(16) PRI cursloc(x, y) ' position cursor to x, y location uart.tx(Debug_Port, 14) ' position the cursor on X (indent from left) uart.tx(Debug_Port, x) uart.tx(Debug_Port, 15) ' position the cursor on Y (down from top) uart.tx(Debug_Port, y) PRI dec(data) ' send decimal formatted data uart.dec(Debug_Port, data) PUB getstr(strptr) uart.getstr(Debug_Port,strptr) PRI hex(data,dig) ' send hex data uart.hex(Debug_Port, data, dig) PRI str(strptr) ' send string data uart.str(Debug_Port, strptr) PRI rx uart.rx(Debug_Port) PRI tx(dbyte) uart.tx(Debug_Port, dbyte)