Read and write to Modbus RTU - python-3.x

I'm using minimalmodbus for reading and writing. I have USB to Rs485 connection.
I'm trying to write this "02 05 0000 ff11" to RTU register in python but i'm getting error. Here is my code.
Device address: 02
Function code: 05
Register Address: 0000
Value: ff00
import minimalmodbus
instrument = minimalmodbus.Instrument('COM4', 1)
instrument.write_register(02, 05, 0000, ff00)
I need the same functionality in the above code using python!

You are mixing up some settings.
The Modbus slave address (2 in your case) should be included in the instantiation of the instrument:
instrument = minimalmodbus.Instrument('COM4', 2)
And the arguments you are using for the write_register function are wrong as well, they should be:
instrument.write_register(0, 0xff00)
As you can see write_register only takes two arguments: the register number and the value you want to read in it.
It might be a good idea to take a look at the code and/or some examples.
EDIT: I realized you actually want to use function code 05 (write coils). To do that you should use write_bit function instead:
instrument.write_bit(0, 1)
That means write True on coil 0.

Related

Component that can create a hex value?

TLDR:
Is there a way to create a hex value between 0x20 and 0x7E with 5 volts? Is there a cheap component on the market or circuit logic that can achieve this?
I'm not sure what the proper terminology for this is, but here's what I'm trying to do:
I have a bluetooth module connected to my pico via UART0 TX and UART0 RX. The use for this is a bit long to explain, but essentially, I want the bluetooth module to work without my pico attached to it. I have a device that outputs a signal, the pico reads the signal, then it tells the bluetooth module to transmit to the receiver. However, since the data to transmit isn't actually important, it makes sense to cut out the pico and simply have the bluetooth module read the signal directly then transmit.
I have the device that outputs exactly when I want, but it outputs the equivalent of 00 in hex. My computer is connected via bluetooth and can read it just fine. However, the pico, reading the input through RX, can't. I've found no way for micropython using UART to read 00 - UART.any() and UART.read() want a character, and 00 only corresponds to NULL.
So essentially, I need some way to transmit a hex value between 0x20 and 0x7E without using the raspberry pi pico. Is there some kind of component that is able to do this? In practice, the bluetooth module will be connected to 5V power with up to 5 amps.
Any idea on how to get the Pico to read 00 in hex through the RX pin is welcomed too. The purpose of this is to not need multiple Picos, since the receiver and the transmitter will be a good distance from each other.
I found the issue. The pico actually can accept 0 through the UART RX pin. The issue was me having a wire misplaced. My computer saw the 0 input which made me think the pico couldn't handle it, but in fact it was never receiving it. Thanks for the help Kotzjan. Would have been interesting to fake a value into the port though!

BLE temperature characteristic conversion

I have a BLE app running on nrf51822 on Zephyr. Application is reading data from humidity and temperature sensor and exposes environmental sensing characteristic.
Main exposed value is temperature (uuid:2A6E).
I have trouble reading this data via Bluez on linux. With nrfConnect app everything works no problem - I connect to the device and can see temperature reading - somewhere
between 20 and 26 degrees (assigned to said uuid).
Via Bluez I can connect and read characteristic handle but the values does not make any sense to me. Here is my workflow:
$ sudo gatttool -t random -b <ADDR> -I
$ [<ADDR>][LE]> connect
$ Attempting to connect to <ADDR>
$ Connection successful
$ [<ADDR>][LE]> char-desc
# there are a lot of other chars here, I list the one that interests me
$ handle: 0x0017, uuid: 00002a6e-0000-1000-8000-00805f9b34fb
$ [<ADDR>][LE]> char-read-hnd 0x17
$ Characteristic value/descriptor: 2e 09
So I get this value, and I cannot convert this in any way I know of to something that would make sense. I am familiar with this document:
temperature xml
but I cannot figure out how this might help me. Somehow Nordic's app can make sense out of it, and I would like to do that too.
The temperature measurement follows the following rules:
it’s in little endian format so you first need to switch it to read as 0x092e
you convert that to decimal and you get (9x256+2x16+14) = 2350
then the value has an implied decimal exponent of -2, which means you take the value and divide by 100
This means the value read in this case is 23.50 Celsius

Reading from USB device through HIDAPI on Linux sometimes results in missing data

I am currently porting code that uses a USB device from Windows to Linux.
I've thoroughly tested the original application and I'm pretty sure that the device works well. I implemented the USB interface on Linux using hidapi-libusb and there are times when the returned data from the device is missing at least a byte.
Once it happens, all the returned values are missing that much data. I more or less have to disconnect and reconnect the USB device in order to make the USB device read data correct. I'm starting to think that maybe the first byte is sometimes returned as 00 and Linux ignores it. It usual occurs on successive reads.
For example:
I send get register state and I expect 10 data available for USB read. Byte 5 is the number of the data.
Expected:
00 00 01 02 00 08 42 (Data 8)
00 00 01 02 00 09 42 (Data 9)
Actual:
00 00 01 02 00 08 42 (Data 8)
00 00 02 00 09 42 ab (Data 9)
Data 9's packet number becomes wrong because it is missing a byte. I've tried changing to hidapi-hidraw, and it happens significantly less. I've checked the hexdump of the hidraw of the device (/dev/hidraw0), and it is consistent with the data I am getting in my application. I've tried using memory leak detection tools and no leaks/corruption is detected.
Is this a Linux problem (3.2.0-4-amd64) or is it possibly the device?
The pseudo code of my application is just:
Initialize HIDAPI and device related
Connect to device using HIDAPI
Write USB command
Read USB command (done multiple times if write expects multiple data)
Parse data
Repeat 3 and 4 until all commands are performed
Free memory and close HIDAPI.
Things I've tried:
Ensure no delay is between read and writes
Add flushing of read data before writing (sometimes catches stray data)
Add a really long timeout (five seconds) on flushing of read data - significantly reduces the problem at a big cost.

Talking to ACR1252U NFC Card Reader via Node.js

I am trying to communicate with an ACR1252U NFC card reader (http://www.acs.com.hk/en/products/342/acr1252u-usb-nfc-reader-iii-nfc-forum-certified-reader/) using Node.js and the https://github.com/nonolith/node-usb NPM module.
I have created a simple script to get the reader USB device and listen for events.
When an NFC card comes in contact with the reader I receive a buffer:
<Buffer 50 03>
When the NFC card is taken away from the read I receive a buffer:
<Buffer 50 02>
This indicates that I am at least able to get some basic communication with the reader working.
My problem now is I am trying to get information about the NFC card when it comes in contact with the reader. I have tried to send data to the reader but cannot get a consistent response (sometimes I get a buffer response and sometimes I don't, running the same command over and over).
I decided to simplify the command I was sending to just turn on and off the reader's internal buzzer so I looked at the API documentation (http://www.acs.com.hk/download-manual/6402/API-ACR1252U-A1-1.07.pdf) which says that to activate the buzzer you send through:
E0h 00h 00h 28h 01h + 1 byte to determine duration of buzzer activation
With that in mind I created a buffer:
var buf = new Buffer(6);
buf.write('e00000280108', 'hex');
Then used the USB module's out endpoint to send the data:
outEndpoint.transfer(buf, function (err) {
console.log('out transfer', err);
});
The console logs "out transfer" with no error but nothing is received from the "in" endpoint.
If I create a 64 byte buffer instead:
var buf = new Buffer(64);
buf.write('e00000280108', 'hex');
outEndpoint.transfer(buf, function (err) {
console.log('out transfer', err);
});
I receive a response from the "in" endpoint:
<Buffer e0 00 00 00 00 01 00 42 ff 00>
This doesn't seem to correspond to what is expect from the manual and doesn't activate the buzzer at all.
I'm very new to directly communicating with USB devices like this and my last experience of this type was sending AT commands to modems back in the day :)
Could anyone shed any light on what I am doing wrong? I figure that sending 64 bytes instead of 6 has something to do with the USB standard requiring a set length or something like that?!? Has anyone else had experience communicating with an NFC reader (non-HID) with Node.js? Ultimately all I want to do is be able to write some data to an NFC tag and read it back later on when the tag is presented.
I thought it would be a pretty simple process but I'm stumped! Maybe I should be encoded the data differently? Maybe I'm not terminating the data properly? I just don't know!
I tried increasing the buffer size by 1 and adding a \0 terminator to the buffer via:
buf.write('\0', 6, 'utf-8');
But that didn't make any difference at all.
Thanks!
The commands described in the API specification are (pseudo) APDU commands to be exchange with the reader over PC/SC. When you access the reader directly through USB without a PS/SC abstraction layer (see http://www.pcscworkgroup.com/specifications/overview.php), you have to implement that abstraction yourself. Therefore, you have to implement the USB CCID (chip card interface device) class interface yourself. Essentially, this means that you have to encapsulate APDU commands in the CCID protocol. You can fin the specification here: http://www.usb.org/developers/docs/devclass_docs/

How to calculate my GPIO port address

I have a Jetway NF81-T56 motherboard which has a header providing 8 I/O lines labeled GPIO30-GPIO37. There is no GPIO driver in my CentOS6 install, and I am attemptiing to write a driver. A Fintek F71869 Super IO chip provides the GPIO and other I/O functions. I can access and modify the GPIO3 registers through the 0x2e/0x2f ports, but haven't been able to access the data port using the GPIO BASE_ADDR set in the F71869 GPIO registers. I have read those registers, and the GPIO BASE_ADDR is set to 0x0a00. The manual page for the chip states:
The index port is BASE_ADDR[15:2] + 5 and the data port is BASE_ADDR[15:2] + 6
I have set the data port to 0x0f (as displayed by connected LEDs) and tried reading ports 0x0a00-0x0a7f. All returned 0xff, and not 0x0f. Does anyone know how to interpret the "BASE_ADDR[15:2]" notation syntax? I have tried searching the Internet and tried contacting the manufacturer, to no avail.
This is hardware-style vector (bitfield) notation, basically you right shift two places.
0x0a00 becomes 0x0280 if I'm doing it right in my head.
To draw it out here are the bits [15:0]
0x0a00 = 0000 1010 0000 0000
now select bits [15:2]
0000 1010 0000 00
which we re-format as [13:0] of a new vector
00 0010 1000 0000 = 0x0280
So it looks like you should be accessing at 0x0285 and 0x0286. However, you need to be sure you've got the board configured correctly, and more important you need to be sure that nothing else is also located at those addresses.

Resources