Cannot read serial port data with Matlab R2010a

8 visualizzazioni (ultimi 30 giorni)
Mark
Mark il 27 Apr 2011
I am trying to write a Matlab script for sampling voltage data from an Agilent 34401A digital multimeter over the serial RS232 connection. I am able to open the connection, write the SCPI commands, but I cannot read any responses from the multimeter. There are never any available bytes, and fscanf, fread, etc. do not find any data. Interestingly, the only way I have been able to receive data is over the Agilent Connection Expert Interactive IO interface. I have also tried the same SCPI commands in Python to no avail, as well as CoolTerm. But since it works in the Agilent software, I know it cannot be the driver, cable, or USB-serial converter I am using.
Here is the setup:
Matlab version R2010a Agilent 34401A DMM Belkin F5U109 USB-serial converter (with driver installed) Windows Vista Basic Agilent IVI/VISA drivers installed for the DMM
Here is the code that I am using to debug this issue:
serialObject = serial('COM4');
set(serialObject, 'BaudRate', 9600);
set(serialObject, 'Parity', 'none');
set(serialObject, 'ReadASyncMode', 'continuous');
set(serialObject, 'StopBits', 1);
set(serialObject, 'Timeout', 10);
set(serialObject, 'RequestToSend', 'off');
set(serialObject, 'FlowControl', 'none');
set(serialObject, 'Terminator', 'LF');
fopen(serialObject);
fprintf(serialObject, '*RST\n');
fprintf(serialObject, '*CLS\n');
fprintf(serialObject, '*IDN?\n');
pause(1);
fscanf(serialObject)
fclose(serialObject);
delete(serialObject);
At the fscanf() part it always times out and never finds data. I have checked this manually using serialObject.bytesAvailable as well.
I googled this problem for hours, finding at least a dozen reports of this issue but as of yet, I have not found a single solution. Can anyone help me with this dilemma? =[[[[[[[[ Thank you in advance.

Risposte (8)

Mark
Mark il 27 Apr 2011
Okay, I believe I fixed it. I cannot explain why this works... here is the command history as well as the output. Basically I had to assert DTR low, open the connection, assert DTR high then begin. Any reason why this might be?
EDU>> serialObject = serial('COM4')
Serial Port Object : Serial-COM4
Communication Settings
Port: COM4
BaudRate: 9600
Terminator: 'LF'
Communication State
Status: closed
RecordStatus: off
Read/Write State
TransferStatus: idle
BytesAvailable: 0
ValuesReceived: 0
ValuesSent: 0
EDU>> set(serialObject, 'BaudRate', 9600);
set(serialObject, 'Parity', 'none');
set(serialObject, 'ReadASyncMode', 'continuous');
set(serialObject, 'StopBits', 2);
set(serialObject, 'Timeout', 5);
set(serialObject, 'RequestToSend', 'off');
set(serialObject, 'DataTerminalReady', 'off');
set(serialObject, 'FlowControl', 'none');
EDU>> get(serialObject)
ByteOrder = littleEndian
BytesAvailable = 0
BytesAvailableFcn =
BytesAvailableFcnCount = 48
BytesAvailableFcnMode = terminator
BytesToOutput = 0
ErrorFcn =
InputBufferSize = 512
Name = Serial-COM4
ObjectVisibility = on
OutputBufferSize = 512
OutputEmptyFcn =
RecordDetail = compact
RecordMode = overwrite
RecordName = record.txt
RecordStatus = off
Status = closed
Tag =
Timeout = 5
TimerFcn =
TimerPeriod = 1
TransferStatus = idle
Type = serial
UserData = []
ValuesReceived = 0
ValuesSent = 0
SERIAL specific properties:
BaudRate = 9600
BreakInterruptFcn =
DataBits = 8
DataTerminalReady = off
FlowControl = none
Parity = none
PinStatus = [1x1 struct]
PinStatusFcn =
Port = COM4
ReadAsyncMode = continuous
RequestToSend = off
StopBits = 2
Terminator = LF
EDU>> fopen(serialObject)
EDU>> get(serialObject)
ByteOrder = littleEndian
BytesAvailable = 0
BytesAvailableFcn =
BytesAvailableFcnCount = 48
BytesAvailableFcnMode = terminator
BytesToOutput = 0
ErrorFcn =
InputBufferSize = 512
Name = Serial-COM4
ObjectVisibility = on
OutputBufferSize = 512
OutputEmptyFcn =
RecordDetail = compact
RecordMode = overwrite
RecordName = record.txt
RecordStatus = off
Status = open
Tag =
Timeout = 5
TimerFcn =
TimerPeriod = 1
TransferStatus = idle
Type = serial
UserData = []
ValuesReceived = 0
ValuesSent = 0
SERIAL specific properties:
BaudRate = 9600
BreakInterruptFcn =
DataBits = 8
DataTerminalReady = off
FlowControl = none
Parity = none
PinStatus = [1x1 struct]
PinStatusFcn =
Port = COM4
ReadAsyncMode = continuous
RequestToSend = off
StopBits = 2
Terminator = LF
EDU>> set(serialObject, 'DataTerminalReady', 'on')
EDU>> fprintf(serialObject, '*IDN?')
EDU>> fscanf(serialObject)
ans =
HEWLETT-PACKARD,34401A,0,11-5-2
EDU>> fclose(serialObject)
EDU>> delete(serialObject)

Walter Roberson
Walter Roberson il 27 Apr 2011
stop bits should be 2
When you use fprintf like that, two newlines will be sent: the one you coded specifically and the one that is in the default format of '%s\n'
See also the debugging hints in the first document link.
You might need to turn on DTR.
You might need to change the *CLS to *CLR
  1 Commento
Mark
Mark il 27 Apr 2011
Thanks for the response Walter.
I changed the stopbits and newline usage, but that didn't fix my problem. I also asserted DTR using
set(serialObject, 'DataTerminalReady', 'on');
*CLS is the SCPI command for this instrument for clearing, instead of *CLR. I don't know why.
I still can't get any data received. Maybe I should assert DTR off instead? Before it was set default, which may have been on already.

Accedi per commentare.


Will Reeves
Will Reeves il 4 Lug 2014
Modificato: Will Reeves il 4 Lug 2014
I know this issue dates back from 2011 but I had the same problem yesterday and had to dig up the manual - might save someone else some time...
The issue is actually the "DSR" (Data Set Ready) pin (6). I'm not sure exactly what the problem is. It could be that the cable I used doesn't have this pin (and DTR) connected.
Alternatively, Matlab has an option for hardware flow control but only really mentions use of the RTS and CTS pins. The Meter doesn't use this protocol so querying serial_obj.Pinstatus yields all "off".
The Multimeter manual states:
"The multimeter monitors the DSR line to determine when the controller is ready to accept data over the interface. The multimeter monitors the DSR line (pin 6 on the RS-232 connector) before each character is sent. The output is suspended if the DSR line is FALSE. When the DSR line goes TRUE, transmission will resume."
So this is the cause. With no flow control you can send commands fine, but the Meter will never reply unless the DSR line is held "high". Matlab does not allow manual control over this so you'll have to hold it high yourself.
I worked around the problem by rewiring the serial cable so that the DTR (Data Terminal Ready), pin 4 was connected to pin 6 (DSR) and all was fine!
I also complied with the manual:
"To disable the DTR/DSR handshake, do not connect the DTR line and tie the DSR line to logic TRUE. If you disable the DTR/DSR handshake, also select a slower baud rate (300, 600, or 1200 baud) to ensure that the data is transmitted correctly."
by setting the baud rate to 1200...
It might be possible to do some more rewiring to get hardware flow control fully working, but I had what I needed for a quick experiment.

Anang sutawijaya
Anang sutawijaya il 6 Mar 2015
hallo my all friend i have problem with serial send this is " Error evaluating registered method 'Start' of MATLAB S-Function 'sserialsb' " please help me to solve this.

Anang sutawijaya
Anang sutawijaya il 6 Mar 2015
this is my plan

Anang sutawijaya
Anang sutawijaya il 6 Mar 2015

bellili mahjoub
bellili mahjoub il 3 Apr 2016
Hi , I have a problem : someone help me ; how to read the measured mass of an electronic scale and display on GUI (I did MATLAB ) , wearing the electronic scale is RS232 . I have a USB / RS232 which can connect with PC, ( algorithm ) , finally thank you. I made a graphic interface for MATLAB, and I want to automatically display the weighed value on laptop PC when weighing a product.

alican kara
alican kara il 17 Giu 2020

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by