Seite 1 von 1

Library QSerialDevice v 0.2.0 released!

Verfasst: 2. März 2010 17:45
von kuzulis
Hi!
Sorry my English.

So, announces release: QSerialDevice v 0.2.0

Many amendments, write makes no sense, therefore, give a brief clipping annotations:

QSerialDevice - a cross-platform library for serial devices, which uses framework Qt4 (see http://qt.nokia.com/).

Requirements:

OC: Win2K/WinXP/WinVista/Win7 or any GNU / Linux distribution
Qt4:>=4.5.0
Processor: any (which is supported by Qt4)
Compiler: any (which is supported by Qt4)

Notes:

Due to the fact that I (the author) do not have the opportunity to test the library at all possible operating systems, all compilers, processors, etc. - It is possible that the library in some cases will not work: (.
Library tested only on:
OC: Windows XP Pro Sp3 (win32) and GNU ArchLinux x86_64
Qt4: from 4.5.3 to 4.6.2
Processor: AMD Athlon 4400 + 64x2 Socket AM2
Compiler: gcc, MinGw
Theoretically (with minor fixes source code) can ensure that the library has worked on other platforms.

QSerialDevice Library contains the following classes:

* AbstractSerial
* SerialDeviceWatcher
* SerialDeviceInfo

AbstractSerial

Class AbstractSerial - provides a self-contained set of methods and properties for light and easy to work with serial devices (serial port) of your PC (or other device).

The class supports the following features:
- to set the speed of data exchange
- to set the number of bits of data
- to set the number of stop bit
- set modes parity
- to establish regimes of control flow
- set timeout symbol
- write data to the serial device
- read data from serial device
- manage such lines as a port: DTR, RTS
- reading of such lines as a port: CTS, DSR, DCD, RI, RTS, DTR, ST, SR
- automatically receive notification when:
- receiving at least one byte (character) in the input buffer
- writing the last byte in the output buffer
- change of status of the serial device (for errors, etc.)
- to get the current value of the number of bytes in the receiving buffer
- set timeout joining at least one byte (character) in the input buffer

(see further description AbstractSerial and source code)

SerialDeviceWatcher

Class SerialDeviceWatcher - is a helper class for the monitoring of serial devices.

Class provides the following features:
- to obtain a list of names of all serial devices that are available in the system
- automatically receive notification when adding / removing of any serial device

(see further description SerialDeviceWatcher and source code)

SerialDeviceInfo

Class SerialDeviceInfo - also is a helper class to obtain information about the serial device.

Class provides the following features:
- to get "friendly" name interesuyushego us serial device
- to obtain the "description" interesuyushego us serial device
- to get VID and PID interesuyushego us serial device (experimental)
- we are interested to check the serial device to the existence of
- we are interested to check the serial device on employment (lock)
-, etc.

(see further description SerialDeviceInfo and source code)

Download Releases can be the home page of the project: http://fireforge.net/frs/?group_id=199
Download the latest cuts SVN: http://fireforge.net/snapshots.php?group_id=199

Verfasst: 2. März 2010 20:43
von bronko
Hi kuzulis,

I am very interested to use your lib. I played around today with qextserialport to send a LIN bus header-> no success. I don't know if you are familiar with LIN: It is a widely used automotive bus, which has a header consisting of a syncBreak, syncField and an IDfield, usualy at 19.2kbit/s and ONE wire (RX and TX are coupled via a circuit). The problem is to generate this syncBreak, because it consists of 13Tbit dominant level. Qextserialport doesn't have a setBreak (as python's pyserial has) to put TX to 0. Switching to 14400bit/s for the syncBreak isn't possible, too (because there is a header timeout of 140% nominal time).

I know a implementation on Windows, where TX is put to 0 and then a delay (complex for-loop) is executed, and afterwards TX to 1. This is not a perfect solution, because the delay has different timings (CPU frequency scaling, ...).
Do you think there is a way with QT (and QSerialDevice) to do this?
Unfortunately my C++/Windows API/QT skills aren't the very best :-)

Bronko

Verfasst: 3. März 2010 07:03
von kuzulis
I am not familiar with the Local Interconnect Network (LIN) Bus.
As I understand from your words, and read the description of the protocol here: http://zone.ni.com/devzone/cda/tut/p/id/9733
the main problem lies in the fact that the field break must contain 13 bits of dominant 1 recessive?

ie break = 11111111111110 bin?

The fact that the serial ports are working with "standard" drivers, which provide: 5,6,7,8 data bits combination of start bit, stop bits, parity bits.
ie the physical layer mode: 8M2 = 1 start + 8 data + 1 parity + 2 stop = 12 bits and can not get LIN Break = 13 bits + 1 bit.

In this case, perhaps you can "cheat" and to obtain Lin Break use a combination of modes 5N1 + 5N1, etc.? And when you create other fields (Sysc, ID, etc.) and use is normal (standard) mode of the port.
PS: IMHO
PSPS: IMHO, protocol LIN bus supported only on microcontrollers levels or specials UART chips

Verfasst: 3. März 2010 07:35
von kuzulis
ups, i see source pyserial , and tonight will add similar sendBreak (), setBreak () [/ b] methods in QSerialDevice

Verfasst: 3. März 2010 08:38
von bronko
"Dominant" means low (0x00).
It would be really gread if you could implement setBreak().
Some background (using 19200bit/s):
13*Tbit = 676us
If you switch for the sync break to 14400bit/s and send 0x00 you get:
1startbit+8databits=9*Tbit=625us (which is ok for most cases). But switching the baudrate unfortunately takes too long (Qextserialport), because there is a delay of >1ms till the baudrate is switched back to 19.2kbit. (This is maybe a Windows constraint). I don't know (yet) how to implement a delay of 650us...800us on windows. Any suggestions are welcome...

P.S. The headertimeout (13bit dominant, 1bit space(delimiter), 10 bit syncFiled, 10bitIDfiled)=34bit(incl. start,stopbits) is 140%*33bits=47,6bit

Verfasst: 3. März 2010 16:48
von kuzulis
I added the same library pyserial Methods: sendBreak(int) and setBreak(bool).
Try from SVN here: http://fireforge.net/snapshots.php?group_id=199

Verfasst: 3. März 2010 19:49
von bronko
I downloaded it, but could not find a method called setBreak or sentBreak. "grep"ing for it in the qserialdevice folder wasn't succesful, too?!

Verfasst: 3. März 2010 20:43
von kuzulis
Oops, yes, there are no changes. Perhaps the server is not yet crawled. : (
Then go to: http://fireforge.net/scm/?group_id=199
and do as it says (svn checkout svn://scm.fireforge.net/svnroot/qserialdevice)

PS: just in case, if you do not succeed, then attaching here By joining with the archive.

Verfasst: 4. März 2010 08:28
von kuzulis
oops...

Last night, hastened to add methods and they made mistakes.

Edit the file: nativeserialengine_win.cpp change:

Code: Alles auswählen

bool NativeSerialEnginePrivate:: nativeSetBreak (bool set)
(
....
        if (:: SetCommBreak (hd) == 0) (
....
    if (:: ClearCommBreak (hd) == 0) (
....
)
to

Code: Alles auswählen

bool NativeSerialEnginePrivate:: nativeSetBreak (bool set)
(
....
        if (:: SetCommBreak (hd)) (
....
    if (:: ClearCommBreak (hd)) (
....
)
:)

Verfasst: 4. März 2010 16:42
von bronko
I checked out your code (rev.69), made your modifications:

Code: Alles auswählen

Index: K:/work/qserialdevice/qserialdevice/qserialdevice.pro
===================================================================
--- K:/work/qserialdevice/qserialdevice/qserialdevice.pro	(revision 69)
+++ K:/work/qserialdevice/qserialdevice/qserialdevice.pro	(working copy)
@@ -3,6 +3,7 @@
 TEMPLATE        = lib
 
 CONFIG          += staticlib
+#CONFIG          += dll
 CONFIG          -= debug_and_release debug
 QT              -= gui
 
Index: K:/work/qserialdevice/qserialdevice/nativeserialengine_win.cpp
===================================================================
--- K:/work/qserialdevice/qserialdevice/nativeserialengine_win.cpp	(revision 69)
+++ K:/work/qserialdevice/qserialdevice/nativeserialengine_win.cpp	(working copy)
@@ -310,7 +310,7 @@
         return false;
     }
 
-    /* тут нужно задатѼ настѤойки для АСИНХРиННиГи Ѥежима! нужно пѤовеѤитѼ!
+    /* тут нужно задатѼ настѤойки для АСИНХРиННиГи Ѥежима! нужно пѤовеѤитѼ!
     (here you need to specify the settings for the asynchronous mode! to check!) */
     ct.ReadIntervalTimeout = MAXDWORD;
     ct.ReadTotalTimeoutMultiplier = 0;
@@ -608,7 +608,7 @@
     }
     
     if (set) {
-        if (::SetCommBreak(hd) == 0) {
+        if (:: SetCommBreak (hd)) {
 #if defined (NATIVESERIALENGINE_WIN_DEBUG)
     qDebug("Windows: NativeSerialEnginePrivate::nativeSetBreak(bool set) \n"
             " -> function: ::SetCommBreak(hd) returned: 0. Error! \n");
@@ -617,7 +617,7 @@
         }
         return true;
     }
-    if (::ClearCommBreak(hd) == 0) {
+    if (:: ClearCommBreak (hd))  {
 #if defined (NATIVESERIALENGINE_WIN_DEBUG)
     qDebug("Windows: NativeSerialEnginePrivate::nativeSetBreak(bool set) \n"
             " -> function: ::ClearCommBreak(hd) returned: 0. Error! \n");
Index: K:/work/qserialdevice/examples/writer/writer.pro
===================================================================
--- K:/work/qserialdevice/examples/writer/writer.pro	(revision 69)
+++ K:/work/qserialdevice/examples/writer/writer.pro	(working copy)
@@ -15,7 +15,7 @@
 DEPENDPATH      += .
 INCLUDEPATH     += ../../qserialdevice
 
-QMAKE_LIBDIR    += ../../build/lib/qintegratedserialdevice/release
+QMAKE_LIBDIR    += ../../build/lib/qserialdevice/release
 
 SOURCES         = main.cpp 
, build your writer example, had to change the path of path QMAKE_LIBDIR in writer.pro

Running the example, I get this output:

Code: Alles auswählen

Please enter serial device name, specific by OS,
 example: in Windows -> COMn, in GNU/Linux -> /dev/ttyXYZn: COM1
Windows: NativeSerialEnginePrivate::nativeOpen(QIODevice::OpenMode mode)
 -> trying to open device:  "COM1"

Windows: NativeSerialEnginePrivate::nativeSetBreak(bool set)
 -> function: ::ClearCommBreak(hd) returned: 0. Error!

Windows: NativeSerialEnginePrivate::nativeOpen(QIODevice::OpenMode mode)
 -> function: nativeReset() returned: false. Error!

Error opened serial device  "COM1"
Serial device  "COM1"  is closed
Windows: NativeSerialEnginePrivate::nativeClose()
 -> hd == INVALID_HANDLE_VALUE. Error!


Verfasst: 5. März 2010 07:26
von kuzulis
Try not to remove the zeros from SetCommBreak and ClearCommBreak, ie write:

Code: Alles auswählen

bool NativeSerialEnginePrivate:: nativeSetBreak (bool set)
(
....
        if (:: SetCommBreak (hd) == 0) (
....
    if (:: ClearCommBreak (hd) == 0) (
....
) 
Different sources have different describes the values returned by these functions. Horror! :)

Verfasst: 11. März 2010 08:46
von bronko
I used your example "Writer" as basis an put something like this
to the main loop:

Code: Alles auswählen

while (1)
    {
#if 1
      MyDevice->setBreak(true);
      for(x = 0; x < 99999; x++)
       for(y = 0; y < 99999999; y++);
      MyDevice->setBreak(false);

      bw = MyDevice->write(syncField);

      cout << "\n" << "sent header" << "\n";
      cin >> dummy;
#else
      MyDevice->sendBreak(1);
      cout << "\n" << "sent header" << "\n";
      cin >> dummy;
#endif
    }
It works as it should, but my problem is not solved completly, because both versions (setBreak sendBreak) have of course a very big span when it comes to <1ms Breaks.
Maybe anybody solved this. Maybe measuring the time of a long duration loop (100ms?) and CPU speed and then calculate it down for a shorter loop (700us) could solve the problem of CPU frequency scaling?
Any ideas are welcome

Bronko

Verfasst: 12. März 2010 06:43
von kuzulis
IMHO, impossible to reckon time. The whole "problem" in the multi-tasking Windows / GNU Linux + system is not real time. And if we can take it "ticks" the CPU - all-time is not exactly equal measures off and different loads on the OS interval of time will always be different.
As an option - you can create a thread and set it the highest priority.
Another option - use a microcontroller as a master device. ie microcontroller will poll your devices on the LIN Bus, and you'll have to question myself microcontroller via RS-232 on some "normal" protocol.

PS; maybe I am mistaken.