Pyserial and QUERY Issues - pyserial

I have a MKS pressure transducer with a 9 pin DB connector. The user interface is through RS-232 or RS-485 serial communications. I am currently developing code using pyserial and python to query the transducer via a plugable RS-232 to usb adaptor. I'm sure the adaptor works because I have used it for communicating with another instrument via pyserial.
The relevant pins for the transducer are:
3 - POWER +
4 - POWER -
6 - RELAY COMMON
7 - RS485 - / RS232 TXD
9 - RS485 + / RS232 RXD
My adaptor is connected to /dev/ttyUSB1.
The transducer has a factory default baud rate = 9600, the data format is 8 data bits, no parity and one stop bit. Based on the manual the query and command syntax are the same for RS485 and RS232.
The problem that I am having is querying the transducer.
The syntax required for a query is:
#<device address><query>?;FF
For example to Query current baud rate: #253BR?;FF
Where:
# <attention charector>
253 <default address>
BR? <query for baud rate>
;FF <terminator>
My python code is:
import serial
Piezo = serial.Serial(port ='/dev/ttyUSB1',
baudrate=9600,parity =serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,bytesize=serial.EIGHTBITS,
timeout =1)
print Piezo.isOpen()
Piezo.write('#253BR?;FF')
print Piezo.readall()
Piezo.close()
With my response:
%run /home/vivekd/Desktop/Software/Pressure/Piezon.py
True
unfortunately I do not get a response back, I am assuming it has to do with the write sequence and the non-traditional terminator. I have tried other write combo's but I get no response. Any and all suggestion would be helpful.
Thanks.
-V

Solved, the issue was the rs232 sent and received pin wiring were backwards.

Related

How to read Analog Output Holding Registers on Advantech ADAM 6717 through ModBus TCP

I've been exploring the ADAM 6717 from Advantech.
This is the ModBus address table for said device:
At first I wanted to modify the value of the Digital output channel 0(DO0), so, as can be seen from the picture above, such address is the 0x0017.
I succeed at this by using a ModBus tool and the following settings:
Sending either "On" or "Off", turns On and off a LED connected to that output. Everything runs smoothly according to my expectation up to this point.
The problem arises when I want to read the Analog Input channel 6 or equivalently, address 400431~40044.
Since that address lies on the Analog Output Holding Registers part of the address table, I though that the following settings would accomplish the job:
However, as can be seen above, the reading shows 0.0 when there is actually 6V connected to that input (a potentiometer)
It is worth mentioning that I've made sure to enable the AI6 channel as well as setting it to Voltage mode instead of current. Also, the web utility for the device shows the AI6 reading correctly as I change the potentiometer's resistance value.
So the problem doesn't lie in the connection from the potentiometer to the AI6 but somewhere else.
Out of nothing and leaving aside what I think I know on this topic, I though of changing the function from 0x03 to 0x04
However, the response is exactly the same.
It bugs me that I can read and write values to the output coils but not the Analog output holding registers.
Is there any configuration that I might be missing over here?
Thanks in advance.
Device settings:
IP address: 10.0.0.1
Port in which the ModBus service is running: 5020

Raspberry Pi 4: Python3 smbus2 prepends 0x00 to all I2C data writes

I have working C & Python3 code, based upon simple examples from the internet, where I can correctly send data from my Raspberry Pi4 to an Atmel SAM-E70 dev kit board. I've got a logic analyzer connected to look at the data being sent, and for every i2c_write_data_block() from my Python3 code, the smbus2 code sends the 7-bit address, followed by 0x00, followed by the byte stream that I want to send. My C code, sending the same byte streams, doesn't have the 0x00 between the address and the data. Finally, sending the byte stream using i2ctransfer() from the shell also works as expected: no extra byte.
Hypothetically, it could be that the smbus2 package is trying to use a 10-bit address, but I cannot find any documentation supporting this supposition. In fact, what I've found indicates that the I2C bus configuration is performed via config file(s) which would lead me to the believe that the language used to communicate on the I2C bus shouldn't matter - it would have the same configuration.
Has anyone else encountered this?
I noticed the same thing using the smbus2 i2c_write_data_block() function.
To avoid sending the 0x00 start byte, use the i2c_rdwr() function.
Example:
bus = SMBus(1)
address = 4
data = 'Some message'.encode()
msg = i2c_msg.write(address, data)
bus.i2c_rdwr(msg)

Can't receive from USB bulk endpoint despite Windows enumerates and libusb reads descriptor of STM32 custom device class

For a fast ADC sampling USB device, I am using the USB 2.0 High Speed capable STM32F733 with the embedded USB-HS PHY. In USBView, I can see that the device is enumerated, the libusb code opens the device and claims interface, but when I try to receive data with libusb_bulk_transfer, the operation times out (return code -12). Things I have tried: I have confirmed than when I request data with libusb_bulk_transfer, the device is interrupted. Note: I have DMA enabled in my class configuration C file and it is not clear to me how that is triggered. I have verified that the transfersize and packet count registers are being set correctly by the LL library function, and that when I request data from
Any tips on debugging such problems will be much appreciated - this board is my undergrad thesis due in under two months!
Desktop sequence:
libusb_get_device_list, libusb_get_device_descriptor, libusb_open, libusb_get_string_descriptor_ascii, libusb_free_device_list, libusb_bulk_transfer(devh, fat_EPIN_ADDR, inframe, fat_EPIN_SIZE, &gotBytes, 100). Where gotBytes is integer, and inframe is a large array.
Device firmware:
MX_USB_DEVICE_Init();
uint8_t txBuffer[10*fat_EPIN_SIZE];
while (1)
{
USBD_LL_Transmit(&hUsbDeviceHS, Custom_fat_EPIN_ADDR, txBuffer, Custom_fat_EPIN_SIZE);
HAL_Delay(1);
}
Custom_fat_EPIN_SIZE is 0x200 and the endpoint address is 0x81 (EP IN 1)
Installed driver for device is WinUSB (verified in Device Manger to be winusb.sys), and I am linking libusb-1.0 into my desktop program. You can find my source code at https://gitlab.com/tywonemi-school-stuff/silicon-radar-fun, the firmware is My SW/v1 and the desktop software is a Qt Creator project in My SW/Viewer, of note is usb.cpp. You can also compare with testing project/HIDTest, which is code that I tested with STM32F303 nucleo dev board where I was able to read an array through IN bulk endpoint with the Viewer application. However, F3 has the USB peripheral, while F7 has OTG_USB, and I am now attempting USB 2.0 compliant HS so there may be more protocol-based pitfalls. You can also find the output of the device descriptor etc from USBView in my SW/USBView_broken.txt
EDIT 1: I have found finally some concrete error in the STM32 behavior. The DMAADDR is set for EPIN 0x81, and never increments, despite the DMA being enabled. I have went through literally every occurrence of the word "DMA" in the USB_OTG periphery.
I thought it might be that my linker script makes my array be stored in DTCM or similar, and the OTG DMA can't access it, but the address of txBuffer is 0x2003EBEC which is in SRAM2. The AHB matrix in the reference manual clearly shows, that the USB OTG HS DMA is master for a bus that SRAM2 is a slave of. And DTCM is connected too. I will look for application notes for USB OTG HS DMA - it just seems to be refusing to copy data!
I have fixed my issue by disabling the DMA setting. I have re-read the relevant portions of the reference manual and still don't know how exactly the values propagate into the Tx FIFOs. It is possible that DMA-less operation will be a major bottleneck in my project, I might return to this later.

Baud rate limits in software and serial communication with an external device

I am using a USB port port operating as a virtual COM port to achieve serial communication with an external device using MATLAB or Visual Basic 6. I am facing baud rate limitations depending on the software I use to communicate with the device. MATLAB (2018a) has no problems because it can set high baud rates. Visual Basic 6 on the other hand faces limitations on the baud rates that can be set in the software. In terms of solutions, I have looked into this to set a higher baud rate in Visual Basic 6: https://www.mev.co.uk/pages/Support/VB-Baud.html
The drivers for the virtual COM port are made by FTDI and can be found here: http://www.ftdichip.com/Drivers/VCP.htm . After configuration in the Device Manger, the device I am communicating with appears under 'Ports (COM & LPT)' as 'USB Serial Port (COM4)' in the Device Manager.
The device requires a baud rate of 1000000 and 2 stop bits for successful communication (if you need any more information, please let me know). As far as I am aware, the baud rate set in the software to communicate via the serial port has to be 1000000 to match that of the external device I am using. I think my problem might require a bit an explanation of how serial communication works when a USB port is acting as a virtual COM port because I worry that it differs from communication using a 'real' serial port, if possible. The FTDI driver appears to be very flexible so I do not understand why Visual Basic cannot tap into this flexibility. Is it impossible to set a baud rate of 1000000 in Visual Basic 6? If it is impossible, are there any methods to overcome this limitation?
The VB6 code for baud rate setting is found below, where 'Port' is the address of COM port e.g. COM4, COM3:
MainForm.MSComm1.CommPort = Port
MainForm.MSComm1.Settings = "9600,N,8,1"
If anyone can help me understand how serial communication works in this setting and if I can overcome the constraints of Visual Basic 6, I would be very grateful.
It seems that you are using MSComm32.ocx, not VB6 directly.
The maximum speed you can set for this is 256,000 bps.
How to send to the serial port by using Mscomm32.ocx
The following baud rate values are valid: 110, 300, 600, 1200, 2400, 4800, 9600 (default), 14400, 19200, 28800, 38400, 56000, 57600, 115200, 128000, 256000.
If you want more speed, please use Win32 API directly with the following library etc.
Serial port programming VB6 via Win32 API
Serial Port Communication
Serial port programming on Visual Basic with Windows API
grricks/vb6SerialAPI
Or, can it be used if the library provided by FTDI is defined by Declare Function like the above library?
D2XX Programmer's Guide
6.9 FT_W32_SetCommState
Example
FT_HANDLE ftHandle; // setup by FT_W32_CreateFile
FTDCB ftDCB;
if (FT_W32_GetCommState(ftHandle,&ftDCB)) {
// FT_W32_GetCommState ok, device state is in ftDCB
ftDCB.BaudRate = 921600; // Change the baud rate
if (FT_W32_SetCommState(ftHandle,&ftDCB))
; // FT_W32_SetCommState ok
else
; // FT_W32_SetCommState failed
}
else
; // FT_W32_GetCommState failed

packets lost xbee series 1

I have two xbee's series 1. I have them as endpoint devices working in API mode and talking to each other. The first xbee is attached at a raspberry pi, while the other is on my pc where I see the terminal tab of XCTU program. The baud rate I use is 125000.
From raspberry pi I try to send a jpg image which is 30Kbytes. I send data frames 100 byte long (the biggest as it is said in the xbee documentation). Inside a loop I create and send the packets, I have also a cout statement that prints the loop number. Everything is fine and all bytes are sent. When I comment out the cout statement not all bytes are sent.
From what I have understood the cout statement works as a delay between packets, but I still cannot understand why is this happening as it is supposed that I use the half speed ...
I hope I was clear and look forward for a reply.
UPDATE
Just to summarize, i changed baud rate to 250000 where there is the same behavior as in 125000. I also implemented hardware flow control by checking cts signal. When xbees are in transparent mode I need a delay between sending characters at around 150us. The same goes for api mode too. The difference with 125000 baud rate in api mode was that the delay needed, was enough to be betwween each data packet, but in 250000 the delay is needed between each byte that i send. If i do the above everything goes well.
The next thing i did was to plug both xbees in my pc in transparent mode. I went to terminal tab of xctu software where i chose assemble packet and sent at around 3000 bytes to the other xbee. The result was the same. The second xbee received at about 1500 bytes and then each time that i was sending one byte from the first to the second, the "lost bytes" were being received at packets of 1000. :/
So could anyone know what am I doing wrong?
You should connect the /CTS pin from the XBee module into the Raspberry Pi, and have your routine stop sending data when the XBee de-asserts it.
At higher baud rates, it's possible to stream data into the XBee module faster than it can send to the remote module. The local XBee module uses the /CTS pin to notify the host when its buffers are almost full and the host should stop sending. People refer to this as hardware flow control.
It may be necessary to modify the serial driver on the Raspberry Pi to make use of that signal -- it should pause the transmit buffer when de-asserted, and automatically resume sending when re-asserted.