LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.

Notices


Reply
  Search this Thread
Old 03-28-2013, 07:11 AM   #1
shanham67
LQ Newbie
 
Registered: Mar 2013
Posts: 7

Rep: Reputation: Disabled
Hyperterm works, minicom doesn't


I have a 1990 model cnc controller that imports/exports programs via a RS232 interface (9600,7,E,1). When I connect using a usb-serial converter, hyperterm and winxp I am able to download the text of a program from the cnc controller to my laptop with no problems.

When I connect to my linux box with the same usb-serial converter i get jibberish (foreign characters) in both minicom and from a small pySerial program that i snipped from the web.

Can anyone suggest what character translations hyperterm is automatically doing that minicom is not?

I suspect that I can mask a single bit of each character and clean it all. I also suspect that there is a setting for minicom and pySerial that will do the trick.
 
Old 03-28-2013, 12:16 PM   #2
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,724

Rep: Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918
I am not aware of any translation that hyperterm does but minicom does not. Have you verified that you have the same port settings between hyperterm and minicom?

Another alternative is cutecom which has the option to display raw data in addition to regular ASCII characters.
 
Old 03-28-2013, 02:05 PM   #3
shanham67
LQ Newbie
 
Registered: Mar 2013
Posts: 7

Original Poster
Rep: Reputation: Disabled
cutecom is a no-go. running on a headless server.
 
Old 03-28-2013, 02:30 PM   #4
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,724

Rep: Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918
How do you access the server?
 
Old 03-28-2013, 02:49 PM   #5
shanham67
LQ Newbie
 
Registered: Mar 2013
Posts: 7

Original Poster
Rep: Reputation: Disabled
ssh
 
Old 03-29-2013, 11:16 AM   #6
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,883
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
Whatever the serial resource as it shows up on Linux, /dev/ttySx or /dev/ttyUSBx. From a shell prompt you can view the settings and change them:

Code:
stty -F/dev/ttyUSB0 115200
will change the port to be 115,200, most ports will be N81.

You can also cat the output of that port if it happens to be always talking. For instance I work with embedded sensor boards which arrive via serial USB, so I would do
Code:
cat /dev/ttyUSB0
to view the output of that port.
 
Old 04-01-2013, 10:53 AM   #7
shanham67
LQ Newbie
 
Registered: Mar 2013
Posts: 7

Original Poster
Rep: Reputation: Disabled
Hyperterminal, minicom, more information...

Ok,
I think my machine is outputting binary data, perhaps some terminal protocol. Hyperterminal decodes and displays what I want to see from linux (minicom/python) (see the attached screen grab of hyperterminal). I have also posted a screen grab of the output from minicom when receiving the same RS232 stream. Addtionally, I have posted the output from my readserial.py python capture script program after piping it through xxd. Does anyone recognize this encoding scheme? If so, how do I setup something on my linux machine to perform the same translation that hyperterminal is doing automatically?

Code:
~$ sudo python readserial.py > readserial.py.out
CTRL-C (to stop the script)
~$ xxd readserial.py.out
0000000: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000010: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000020: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000030: 0000 8d0a 0a30 a042 c547 c94e a050 474d  .....0.B.G.N.PGM
0000040: a0b1 30a0 c94e c348 a08d 0a0a b1a0 d4cf  ..0..N.H........
0000050: cfcc a044 c5c6 a0b1 a0cc 2b30 a0d2 2b30  ...D......+0..+0
0000060: 2eb1 b235 a08d 0a0a b2a0 d4cf cfcc a0c3  ...5............
0000070: 41cc cca0 b1a0 5aa0 53a0 b430 3030 a08d  A.....Z.S..000..
0000080: 0a0a 33a0 c359 c3cc a044 c5c6 a035 2e30  ..3..Y...D...5.0
0000090: a0c3 c9d2 c355 cc41 d2a0 50cf c34b c5d4  .....U.A..P..K..
00000a0: a08d 0a0a b4a0 c359 c3cc a044 c5c6 a035  .......Y...D...5
00000b0: 2eb1 a053 c5d4 a055 502d 302e b2a0 8d0a  ...S...UP-0.....
00000c0: 0a35 a0c3 59c3 cca0 44c5 c6a0 352e b2a0  .5..Y...D...5...
00000d0: 44c5 50d4 48a0 2d30 2e33 a08d 0a0a 36a0  D.P.H.-0.3....6.
00000e0: c359 c3cc a044 c5c6 a035 2e33 a050 c5c3  .Y...D...5.3.P..
00000f0: 4b47 a02d 302e 3035 a0c6 b430 a08d 0a0a  KG.-0.05...0....
0000100: b7a0 c359 c3cc a044 c5c6 a035 2eb4 a0d2  ...Y...D...5....
0000110: 4144 c955 5330 2e33 35a0 8d0a 0ab8 a0c3  AD.US0.35.......
0000120: 59c3 cca0 44c5 c6a0 352e 35a0 c635 30a0  Y...D...5.5..50.
0000130: 44d2 2da0 8d0a 0a39 a0cc a0d8 2bb2 2eb2  D.-....9....+...
0000140: 35a0 592d b22e 35a0 d230 a0c6 a04d 41d8  5.Y-..5..0...MA.
0000150: a04d 3033 a08d 0a0a b130 a0cc a05a 2b30  .M03.....0...Z+0
0000160: 2eb2 a0d2 30a0 c6a0 4d41 d8a0 4d39 39a0  ....0...MA..M99.
0000170: 8d0a 0ab1 b1a0 cca0 d82b 30a0 592b 30a0  .........+0.Y+0.
0000180: 5a2b b1a0 d230 a0c6 a04d 41d8 a04d 30b2  Z+...0...MA..M0.
0000190: a08d 0a0a b1b2 a0c5 4e44 a050 474d a0b1  ........ND.PGM..
00001a0: 30a0 c94e c348 a08d 0a0a                 0..N.H....
~$ file readserial.py.out
readserial.py.out: data
Code:
~$ cat readserial.py
#!/usr/bin/python

import os, serial, time

s = serial.Serial('/dev/ttyUSB0', baudrate=9600, bytesize=7, parity='E', stopbits=1, timeout=None, xonxoff=0, rtscts=0)
while True:
    line = s.readline()
    if "clear\n" == line:
        os.system('clear')
    else:
        print line
Attached Thumbnails
Click image for larger version

Name:	hyperterm.JPG
Views:	112
Size:	66.3 KB
ID:	12181   Click image for larger version

Name:	minicom.JPG
Views:	115
Size:	35.9 KB
ID:	12182  
 
Old 04-01-2013, 12:41 PM   #8
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,724

Rep: Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918
Quote:
how do I setup something on my linux machine to perform the same translation that hyperterminal is doing automatically?
By using the same settings. From the hyperterm screen shot the port is configured as 8-N-1 vs 7-E-1 as posted in your python script and I assume how minicom is configured.
 
Old 04-01-2013, 03:45 PM   #9
shanham67
LQ Newbie
 
Registered: Mar 2013
Posts: 7

Original Poster
Rep: Reputation: Disabled
I wish...

When I first start hyperterm the status line that you pointed out says 'Auto detect' after reading the data it changes to '9600 8-N-1'.

I don't find the status line of hyperterm very trustworthy. I can disconnect, change port settings, and reconnect and I still get good data from hyperterm.

Attached below are screen grabs of hyperterm showing both 9600-7N1 and 9600-7E1 and the same clean text output. I have also attached a screen grab of the port setup from device manager. The device manager port settings have been 9600-7E1 all along. I have a configuration parameter on the machine that I am trying to interface to that indicates that it is output 9600-7E1 data.

By the way, I have tried all of these settings (9600-8-N-1, 9600-7-N-1, 9600-7-E-1) in minicom and readserial.py.
Attached Thumbnails
Click image for larger version

Name:	hyperterm_7E1.JPG
Views:	96
Size:	95.7 KB
ID:	12183   Click image for larger version

Name:	hyperterm-7N1.JPG
Views:	70
Size:	96.3 KB
ID:	12184   Click image for larger version

Name:	devmgr_7E1.JPG
Views:	73
Size:	94.0 KB
ID:	12185  
 
Old 04-01-2013, 09:06 PM   #10
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,724

Rep: Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918Reputation: 5918
Your right... The difference between 7e1 and 8n1 is negligible and would appear like dropped bits like the output of your python script. The gibberish output from minicom is puzzling.
 
Old 04-02-2013, 08:32 AM   #11
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,883
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
The original problem was to download a program to this computer via serial.

The two steps I'd do here if I could not get a specification on how to send the data would be:

1.) Write a program to run on Linux which would listen to the serial port and print out exactly what Hyperterm is sending when it sends a file the correct way in which it works. This way you'll be able to see exactly what Hyperterm is sending.

2.) Write a program which takes your program file and sends it over the serial port to your target in the same manner which Hyperterm is sending it to you.

Also you can configure the port between 7E1 and 8N1 to see which variation makes the data look correctly when you read it as Hyperterm sends it to your Linux program. 8N1 is the most common, but I have one case of 8-bit, Odd parity in my system.

Use open(2) and read(2) to accomplish this. Here also are some examples for configuring port rates and parity via a Linux C program.

Example to configure the rate, my set port rate function uses 115,200, 230,400, or defaults to 38,400, but you can use whichever rates are appropriate for you. Note also that my log mechanism is not common, is a macro, and uses that debug argument, nothing you need to worry about. I also have many includes because it's a utilities file, so I've checked a bit and shown the includes mainly required for the library calls from termios(3).

Code:
#include <termios.h>
#include <unistd.h>

int set_port_rate(char *port, char *rate, int debug)
{
    struct termios term_ios;
    speed_t new_rate;
    int fd;

    if(!strlen(port)) {
        dae_log("set_port_rate: Invalid(NULL) port\n");
        return -1;
    }
    if((fd = open(port, O_RDWR | O_NOCTTY)) < 0) {
        l_err = errno;
        sprintf(l_err_str, "%d:%s", errno, strerror(errno));
        dae_log("set_port_rate: Error opening %s. %d(%s)\n", port, errno, strerror(errno));
        return -1;
    }
    if(!strncmp(rate, SERIAL_115200_RATE, strlen(SERIAL_115200_RATE))) {
        new_rate = B115200;
    }
    else if(!strncmp(rate, SERIAL_230400_RATE, strlen(SERIAL_230400_RATE))) {
        new_rate = B230400;
    }
    else {
        new_rate = B38400;
    }

    memset(&term_ios, 0, sizeof(term_ios));
    tcgetattr(fd, &term_ios);
    cfmakeraw(&term_ios);
    cfsetspeed(&term_ios, new_rate);
    tcflush(fd, TCIFLUSH);
    tcsetattr(fd, TCSANOW, &term_ios);

    return 0;
}
Example to set port parity. This can be extended to set bits to be 7, (term_ios.c_flag |= CS7) would be the correct action here.

Code:
int set_port_parity(char *port, tcflag_t parity, int debug)
{
    struct termios term_ios;
    int fd;

    if(!strlen(port)) {
        dae_log("set_port_parity: Invalid(NULL) port\n");
        return -1;
    }
    if((fd = open(port, O_RDWR | O_NOCTTY)) < 0) {
        l_err = errno;
        sprintf(l_err_str, "%d:%s", errno, strerror(errno));
        dae_log("set_port_parity: Error opening %s. %d(%s)\n", port, errno, strerror(errno));
        return -1;
    }

    memset(&term_ios, 0, sizeof(term_ios));
    tcgetattr(fd, &term_ios);
    term_ios.c_cflag |= (PARENB | parity);
    tcflush(fd, TCIFLUSH);
    tcsetattr(fd, TCSANOW, &term_ios);

    return 0;
}
 
Old 04-02-2013, 10:52 AM   #12
shanham67
LQ Newbie
 
Registered: Mar 2013
Posts: 7

Original Poster
Rep: Reputation: Disabled
...making some progress

rtmistler, thanks for the time you spent replying. However, I am not sending from hyperterm. I am receiving.

I have made progress in determining that the problem seems to be with the parity bit on the linux side. In the attached screen grab you can see a hex dump of the stream I am trying to read. The back window is bray's terminal running on windows. The front window is the output of the following pyserial program running on linux.

Code:
#!/usr/bin/python

import os, serial, time, sys

s = serial.Serial('/dev/ttyUSB0', baudrate=9600, bytesize=7, parity=serial.PARITY_EVEN, stopbits=1, timeout=None, xonxoff=0, rtscts=0)
while True:
    x = s.read(1)
#    print x.encode('hex')
    sys.stdout.write(x.encode('hex')+' ')
NOTE: If I switch bray's terminal from hex mode to ascii mode it displays the correct output.

I have highlighted the differences between the output in the attached screen grab. Notice that all of the differences are for bytes which have odd parity in the lower seven bits. Next, I will mask off the MSB of each byte to see if it displays correctly. I suspect that this should not be necessary. Does anyone have any suggestions?
Attached Thumbnails
Click image for larger version

Name:	hex_diffs.jpg
Views:	98
Size:	134.6 KB
ID:	12192  
 
Old 04-02-2013, 11:41 AM   #13
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,883
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
You're trying to use this through Linux versus Windows right?

There are other port settings besides character size, parity, and stop bits.

stty shows you that and allows you to set the port up for things like RAW mode; which is really a combination of attribute settings in a certain way. Many times when writing a serial port application in Linux I have to configure the port to be raw mode. That's why I'm referring to the termios(3) utilities: tcgetattr(), tcsetattr(), and so forth.

There either are or are not equivalents which you can use via python; however the termios utilities are based on Linux and therefore based on C, so the best recommendation I could make would be to experiment with a C program to better view and control the entire termios structure. You get that structure by tcgetattr() and then you can examine all settings, many of which will likely be meaningless, but there is one which will probably resolve this so that you can talk to this system via Linux versus Windows utilities.
 
Old 04-02-2013, 01:14 PM   #14
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
You observe that the sender appears to be using ODD parity. The next thing to try, then, is to set ODD parity at the receiver, rather than masking the problem by masking the high bit.
If you need to use the serial port to do file transfers, may I suggest using one of the many serial file transfer protocols and/or applications that already exist for such purposes? Kermit or Z-modem would be good starting points.
--- rod.
 
Old 04-02-2013, 01:57 PM   #15
shanham67
LQ Newbie
 
Registered: Mar 2013
Posts: 7

Original Poster
Rep: Reputation: Disabled
Solved !

To answer my original question, hyperterminal is apparently stripping off the high bit. Linux is not. I switched from python to perl because I know perl, was just cutting and pasting the python stuff. I still haven't gone back to see how to set 'istrip' using minicom. But the following perl script solves my problem. Here is my perl reader:

Code:
#!/usr/bin/perl

use Device::SerialPort;

my $port = Device::SerialPort->new("/dev/ttyUSB0");
$port->databits(7);
$port->baudrate(9600);
$port->parity("even");
$port->stopbits(1);

$port->read_char_time(50);
$port->read_const_time(500);
$port->stty_istrip(1);

while(1) {
  my($count,$byte)=$port->read(1);
  if($count > 0 ){
   print "$byte";
  }
}
Note: this must be sudo'd to work
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Darn serial port doesn't work with minicom jblc Linux - Hardware 1 07-08-2010 01:59 AM
Minicom via ttyS0: Please help with $TERM, $MINICOM, colors, mouse/gpm. GrapefruiTgirl Linux - Software 2 07-19-2008 07:01 AM
usrobotics external serial sportster and courier modems works with minicom not wvdial msingerdo Linux - Hardware 3 01-15-2007 10:30 PM
Mounting works, playing music works, reading tags doesn't Celettu Linux - Newbie 7 08-23-2006 12:27 PM
Echo /devPrinting doesn't work, echo /usb/lp0 works, Testpage works, Printing doesn't Hegemon Linux - General 3 08-15-2002 01:13 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software

All times are GMT -5. The time now is 06:37 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration