|
|
Home » U++ Library support » U++ Library : Other (not classified elsewhere) » About RS232
|
|
|
|
|
|
Re: About RS232 [message #28176 is a reply to message #3788] |
Fri, 20 August 2010 13:58   |
jeremy_c
Messages: 175 Registered: August 2007 Location: Ohio, USA
|
Experienced Member |
|
|
Last night I grabbed a copy of libctb (https://iftools.com/opensource/ctb.en.php). I modified the source a bit and made a U++ package out of it. So now I just say Add Package, Ctb and my app has serial support.
I have not tested it yet under linux but will be doing so shortly. The only problem with what I did was I had to change several headers for the package. For example, the ctb package uses:
#include "ctb-0.15/abcdef.h"
I changed these to read:
So, with each update to libctb, that would have to be done. Is there a better way? I wanted to let U++ handle the building of the package.
I started with Serial.h/.cpp that I found here and it worked fine for some devices I was controlling but not for others. I needed the ability to set 2 stop bits, to raise the DTR and RTS states, etc...
I am not sure what is the best idea here. To keep my Ctb package or to browse it's source, learn how the Data Bits, Parity, Stop Bits and Line States are set/queried and port them to the Serial.h/Serial.cpp. I kind of liked the Serial.h/.cpp's function ReadDataWaiting(). w/Ctb you can read X number of bytes with a timeout but say you want 30 bytes, Readv(buf, 30); may result in a partial read, i.e. maybe 15 were available before the timeout occurs. You'll get the 15. With Serial.h/.cpp I could enter a loop and say:
tries = 0;
while (ReadDataWaiting() < 30) {
tries++;
if (tries > 3) do_fail_code();
Sleep(50);
}
Jeremy
|
|
|
|
Re: About RS232 [message #29834 is a reply to message #28178] |
Sun, 21 November 2010 02:17   |
nlneilson
Messages: 644 Registered: January 2010 Location: U.S. California. Mojave &...
|
Contributor |
|
|
What is the current status of what is included in Upp for:
RS232, serial port, COM port, or whatever the designation or how it is wrapped.
I am currently using 2827 but could update.
I am interested in the #include and the few lines of code required to hook up to serial port.
Python uses PySerial
Java uses rxtx (note that Oracle/Sun has dropped support for comm)
Win uses System::IO::Ports;
I have good results with all of these.
Since I am not that experienced with Upp a simple complete package with an example (like those in the "examples" folder included with Upp), if there is one, would be appreciated. Otherwise I spend several hours on something very basic before getting something to compile/link.
There is info in the thread like:
jerson's CommPak.zip
Pavel's 4.zip
Didier' SerialPort.tgz
Nick's Serial.cpp, Serial.h
As mentioned an example that works with what is included in the Upp install is what is preferred, or with least addition of header files or ??.
luzr wrote on Mon, 26 June 2006 20:05 | While there is no specific support, it is still regular C++, so everything you can do in C/Win32 API (or C/Posix/Linux API), you can do in U++ too...
Mirek
|
I try to use:
using namespace System::IO::Ports;
from my existing code that runs in MSVC that gives errors in Upp.
|
|
|
|
|
Re: About RS232 [message #29846 is a reply to message #3788] |
Sun, 21 November 2010 22:06   |
nlneilson
Messages: 644 Registered: January 2010 Location: U.S. California. Mojave &...
|
Contributor |
|
|
That was very useful!
Having an example that can be downloaded, unzipped, placed in MyApps, opened in TheIde, select execute, and have it compile/link/run is great.
For someone that is fairly new to Upp getting a few lines of code and trying to get it to run is very frustrating and takes time.
I did notice that the pull down menu in the Setup Comms box for baud rate does not include these.
115200
57600
38400
These cannot be seen/picked even though they are listed in Serial.h. I added them in main.cpp line 57:
int Port,Baud[]={1200,2400,4800,9600,19200,38400,57600,115200};
Whoever ported the code from C++ to be compatible in Upp in Serial.h and Serial.cpp did a good job.
Neil
[Updated on: Sun, 21 November 2010 22:51] Report message to a moderator
|
|
|
Re: About RS232 [message #29855 is a reply to message #3788] |
Tue, 23 November 2010 03:50   |
nlneilson
Messages: 644 Registered: January 2010 Location: U.S. California. Mojave &...
|
Contributor |
|
|
Looking at Serial.h and Serial.cpp they were not familiar to what I have previously used.
To help someone else this is what was done.
In my Python and Java code and the reason for doing it this way.
1. Loop through the ports from COM4 to COM20 (COM3 is the default for Win printer).
2. Loop through the ports to check the baud rate.
3. Open each port that returns the NMEA GPS GGA sentence that run concurrently, three is the most tried so far without threads, no problems.
Here is a snip of code to work with the Serial.h and Serial.cpp
Thread work;
void OpenAction() {
if (!CommPort.Open(6,57600)) Exclamation("Cannot open COM6");
Sleep(1000);
work.Run(THISBACK(Work));
}
void Work(){
char ch;
char buf1[1];
String St1;
while (CommPort.ReadDataWaiting() ) {
CommPort.ReadData(buf1, 1);
ch = buf1[0];
if(ch!='\n' || ch!='\r')St1 << ch;
if(ch=='\n'){
Data<<=St1;
...
Sleep(980);
The COM port and baud is hard coded here, the app will find and insert these parameters.
Note the Sleep(1000); before the work thread is run and Sleep(980);, otherwise the ReadDataWaiting() is empty.
This reads a char at a time but the parameter has to be a char buf, hence the necessity for char buf1[1];
This is very basic but shows how you can get data from a serial port you can work with. There is also a lot of try/catch, if(...), continue, break, parse(...), send(...), swear(), etc..
[Updated on: Tue, 23 November 2010 05:06] Report message to a moderator
|
|
|
Re: About RS232 [message #39393 is a reply to message #3788] |
Fri, 15 March 2013 14:40   |
 |
jibe
Messages: 294 Registered: February 2007 Location: France
|
Experienced Member |
|
|
Hi,
Is there something new about all that ?
There is already some good job done. If I don't forget anything, we have those works :
- Mindtraveller (Pavel) 4.ZIP Oct 12, 2008
- Didier SerialPort.tgz Feb 05, 2010
- nixnixnix (Nick) Serial.h and Serial.cpp Mar 07, 2010
- jerson CommPak.zip Aug 06, 2010
What about starting from all that to build a final package and add it to upp, at least in bazaar ?
If now PC have often no more COM ports, RS232 is still used a lot in industry. More : several USB devices have a driver allowing to use them as a COM device. Such a package would be very useful !
I could try to do it... Any help or suggestion will be appreciated, especially what is interresting or missing in every package above and how they could (or not...) be mixed together.
|
|
|
|
|
Re: About RS232 [message #39398 is a reply to message #39393] |
Fri, 15 March 2013 16:04   |
Zbych
Messages: 327 Registered: July 2009
|
Senior Member |
|
|
If you want I can help you with linux part of serial port implementation.
First you should tell me what interface you want.
My proposition:
1. Vector<String> ListPorts();
returns list of available ports. On windows you can use QueryDosDeviceW to get list of devices. On linux udev does similar thing.
2. bool Open(const char * port_name, enum speed, enum flow_control, enum parity)
3. void Close()
4. int Write(const void * data, int len, int timeout_ms = 5000);
5. int Write(String data, int timeout_ms = 5000);
6. String ReadUntil(int amount, int stop_byte = -1, int timeout_ms = 5000);
7. void FlushInput();
to clean input queue
8. void FlushOutput();
to clean output queue
I would like to have timeouts in every Write and Read functions, because they often depend on the command you send to device.
Things like stop_byte are useful for communication with modems.
Maybe we should also have Callbacks (when new data arrive, when usb serial device is (un)plugged)?
[Updated on: Fri, 15 March 2013 16:08] Report message to a moderator
|
|
|
Re: About RS232 [message #39409 is a reply to message #39397] |
Fri, 15 March 2013 22:45   |
 |
jibe
Messages: 294 Registered: February 2007 Location: France
|
Experienced Member |
|
|
Thanks for the replies 
jerson wrote on Fri, 15 March 2013 16:00 | I am not sure what kind of errors you get. I use only the windows platform and the code works well on it.
|
... And I'm almost sure that it can work with Linux as well : As I said, it's just that there is not the same methods ! I had just a quick try and did not study well all that, probably it's just different names...
I posted immediately before going further just to know if there is some good reason. If not, I'll just make so that the class is exactly the same for Linux or Windows, as far as possible.
jerson wrote on Fri, 15 March 2013 16:00 | I'd like to collaborate if there is any movement on this and may also add the modbus RTU feature if prodded. Right now, I am juggling too many things and time sharing is hard.
|
You do as you can according to your free time. If it's possible for you, I'll let you try and eventually debug the Windows part, as I'm working only under Linux.
Zbych wrote on Fri, 15 March 2013 16:04 | If you want I can help you with linux part of serial port implementation.
First you should tell me what interface you want.
|
Thanks
But for now, I'm just beginning to discover what has been already done. I think that it will be enough for what I have to do (just read the output of an A/D converter and display the signal like an oscilloscope).
I'll see later in more details your proposition, when I'll know better jerson's package. I think it's already good, but could be better with some enhancements or additions like a more complete Open function with flow control and parity as you propose : if we make a package to add to upp, it must be some more complete.
[Updated on: Fri, 15 March 2013 22:47] Report message to a moderator
|
|
|
|
Re: About RS232 [message #39460 is a reply to message #39450] |
Sun, 17 March 2013 08:56   |
Mindtraveller
Messages: 917 Registered: August 2007 Location: Russia, Moscow rgn.
|
Experienced Contributor |

|
|
Let me share some thoughts on serial port communication as industrial automation developer. Critics is welcome.
First of all, the main idea behind all this functionality is sending and receiving some actual data to/from PC. The most common scenario is to send request and receive answer (PC = master, device = slave). We also must understand highly asynchronous nature of all these tasks, because at no circiumstances serial port i/o must be done in common thread (especially when it handles GUI). The next idea is crossplatform code, because our great U++ framework is crossplatfrom too. The last requirement is the ease of tuning: most of time we need to tune some parameters of serial port "on the field", and we must me able to do it without recompiling our code.
These features put together really professional-grade serial library.
Let's recollect them, dividing by levels of abstraction:
1. Port handling and I/O (lowest level).
Crossplatform code handling system-dependent serial port code.
Done with tiny library called crossplatserial with my little modifications. It has Apache license (which is the same as BSD, AFAIK).
This level creates SerialPort objects from external file or code. So if you need to tune i.e. the baudrate, you just change external file and restart your app.
I attach crossplatserial to this message and you may use it, if it is all that you want.
2. Datagramms <-> values (protocol stuff).
Actually the main code should work with data. Not with actual bytes you send through serial port. I achieved it with my BNF library which is responsible for using protocols.
That is how it works:
You have external file defining a protocol. BNF takes plain bytes and returns Vector<Value> and back. For example: ***modbus (crc_start byte byte word_be word_be crc_end crc_modbus)
| (crc_start byte byte byte word_be crc_end crc_modbus);
***icp_din_clear_request "$" HEX:2 "C" "\0D";
***icp_din_clear_answer (("!" arg:1 HEX:2) | ("?" arg:0 HEX:2)) "\0D";
Ok. On this level we've left protocols behind and made possible for SerialPort to work with actual Vector<Value> (not with plain bytes). I repeat that protocol is defined in external file, so if you need to tune it, you just change protocol description in file and restart your app. Extremely useful in some cases "in the field".
3. Asynchrony (highest level).
IMO the ideal approach for asynchrony of serial i/o is using queued threads. This means each thread has it's queue and you put there this thread's callback with custom parameters. That is how threads interact, no syncronization objects needed.
This is done with bazaar/MtAlt package I wrote some time ago.
In spite of this frightening description, the actual use of this is simple. Let's look at real-world example: class SensorNB3000: public SerialPortNotify<CallbackQueue> {/*...*/}; //creates callback queue
void SensorNB3000::RequestMeasure()
{
Vector<Value> args;
args << ((int) addr.GetData()) << 6 << 50 << 1;
sensorPort->SendReceiveSleep_(PREPARE_TIMEOUT_NB3000);
sensorPort->SendReceive_
(
"modbus",
args,
"modbus",
RECEIVE_TIMEOUT_NB3000,
NULL,
Ptr<SiloSensorNB3000>(this),
&SensorNB3000::OnMeasure
);
}
void SensorNB3000::OnMeasure(bool result, Vector<Value> args, void *custom)
{
//...
}
This code means: SensorNB3000 class adds some timeout to sensorPort thread queue and then requests send/receive operation with modbus protocol. Send modbus args are {addr,6,50,1} and the handling routing is OnMeasure. The SensorNB3000::OnMeasure() routine is syncroneously called in the SensorNB3000 thread (no sync is needed in your code!).
Here are the most of the concepts I propose. If you find them too comlicated, you may just use attached library. If you consider using all these levels of abstraction in U++, we may discuss it further.
[Updated on: Sun, 17 March 2013 09:00] Report message to a moderator
|
|
|
Goto Forum:
Current Time: Sat Apr 26 18:25:03 CEST 2025
Total time taken to generate the page: 0.01376 seconds
|
|
|