I am using Go for a project and am transmitting data to an embedded device via the serial port (ttyusb). During fast and "large" transfers I've noticed that the transmitted data did not match the values I'd wanted to send.
I've tried various available libraries, in the end they all read and write using syscalls. So I've attached a Logic Analyzer to see what's going on.
Then I noticed that the data mismatch in the output had a clear pattern: Instead of sending my data the serial port would interleave my data with the following values:
0x55, 0x53, 0x42, 0x53, 0x70, 0x02
Followed by zeros (0x00). In total 22 Bytes. The total number of bytes transmitted via the serial line did match the number of bytes I wanted to write > so essentially my data was masked with these 22 Byte-Blocks. The weird thing is that I can translate those bytes to ASCII
0x55, 0x53, 0x42, 0x53, 0x70 = "USBSp"
Now my Question is: Can't I send arbitrary data (HEX values) over the serial port or are there some control characters that I should be aware of that would make the serial port send out Identity information or the like?
[EDIT]: Additional Information:
Host is MacOS running Go v1.10; tried with go.bug.st/serial.v1 and github.com/tarm/serial, various communication settings (bitrate etc.)
Target is nRF52840 preview development kit, using Nordic nRF5 SDK v12.3.0_d7731ad (not the newest, I know, but the only one supporting other boards too). Using app_uart_x API
you have to configure the serial port. the settings for both devices for baud rate, start/stop bits, ... have to match. then there are libraries in go like https://github.com/jacobsa/go-serial that enable standard serial port communication with that you can also use any hex values.
i can not say why the USBSp is sent because you did not post any code and gave no information what libraries you use. very likely this is not generated by the kernel module and instead by higher layer software because the kernel module used is usb-serial and USBSp does not appear in the source code :
https://elixir.bootlin.com/linux/v4.0/source/drivers/usb/serial/usb-serial.c
also not in kernel module ftdi-sio ( if you use ftdi chip )
https://elixir.bootlin.com/linux/v4.0/source/drivers/usb/serial/ftdi_sio.c
and also not in https://elixir.bootlin.com/linux/v3.3/source/drivers/usb/core/urb.c
Related
I am currently working on a script in docklight v2.0.
My setup is the following:
I have a splitter connected in the USB port of my PC.
That splitter is connected on a wire on which a communication is made between 2 devices.
Docklight is connected on the USB port and receives all the information transmited through that wire.
I have a script on docklight set up to put every byte in a buffer once docklight sniffs them.
My script is coded using the functions in Docklight and VBScript.
The problem I have is the following:
I put all the bytes in the same buffer, that mixes up the messages from both devices and it becomes impossible to analyse them.
What I need to do:
I need to know which byte comes from which device, Docklight is already able to do so, but I need to do that in my script so I can put the bytes in 2 different buffers to treat the data properly.
Using the fonction DL.OnReceive_GetChannel() solved my problem.
I am using Arduino Leonardo to transmit an string to a wifi module. The format of command that wifi module can recognize is:
AT60,1,content to a server
I am using an virtual server(TCP/IP Builder) to test the content I can received.
Here is the content I want to send:
smart/device/deviceCmd?userId=1010002003&deviceId=A00019999990002&cmd=ON
Since I try to send it again and again, I use a loop to send it. In the virtual server side, the content I got is:
smart/device/deviceCmd?userId=1010002003&devceId=A00019999990002&cmd=ON
smart/device/deviceCmd?userId=1010002003&devceId=A00019999990002&cmd=ON
smart/device/deviceCmd?userId=1010002003&dviceId=A00019999990002&cmd=ON
smart/device/deviceCmd?userId=1010002003&eviceId=A00019999990002&cmd=ON
smart/device/deviceCmd?userId=1010002003&devieId=A00019999990002&cmd=ON
smart/device/deviceCmd?userId=1010002003deviceId=A00019999990002&cmd=ON
smart/device/deviceCmd?userId=1010002003&dviceId=A00019999990002&cmd=ON
smart/device/deviceCmd?userId=1010002003&dviceId=A00019999990002&cmd=ON
smart/device/deviceCmd?userId=1010002003&deiceId=A00019999990002&cmd=ON
smart/device/deviceCmd?userId=1010002003&dviceId=A00019999990002&cmd=ON
This is the QUESTION: There exist one terrible mistake in the content I received, which is the deviceId part never correct. It's so weird.
Here is part of related code:
//In Uart.cpp
//These three lines can sent a formatted string as "AT60,1,content"
Serial1.write("AT60,");
Serial1.write(channelID); //channel ID = 1 here
Serial1.write(reportIsFire, 76);
//In Uart.h
//Definition of the string I need to send, which has 76 characters.
char reportIsFire[76] = ",smart/device/deviceCmd?userId=1010002003&deviceId=A00019999990002&cmd=ON \n";
Here is few background of this application:
I am using Arduino 1.5.8 IDE with VisualStudio
Since the serial buffer of Arduino is only 64 Bytes, I have already
change the buffer size to 128 Bytes in "HardwareSerial.h" to send
out this large string.
The baud rate is 115200 and I am using Serial 1. I have used Serial 1
to transmit few other characters and it works fine.
I will appreciate that If you have any idea about this question.
I am betting that the serial baud rate of the Arduino is not 100% correct. Increasing the buffer size will not matter if the data is being lost due to a timing issue in the physical link.
I'd recommend double-checking the code that initializes the serial baud rate generator. It may be possible to get a closer rate to 115,200 by either adjusting the available settings, altering the main clock speed (if possible), implementing some form of flow control, or all of the above.
In extreme cases, you may consider using a special-frequency oscillator. Many Microchip PICs use an internal or external 4MHz or 8MHz crystal, but this can produce far too much timing error for lengthy serial transmissions at high speed. In that case, something special, like a 7.3728MHz crystal can be used, bringing the accuracy to exactly 100% (at least on some PIC devices.)
Lastly, another consideration is if any pre-emptive code is running on the device, such as interrupts or timers which could inadvertently interfere with the serial output.
I don't have an answer, but I suspect the most likely problem is that the Wifi card can't read characters at a sustained 115200 baud rate. If possible, set the Wifi baud rate and the Arduino Serial.begin() to a lower rate, such as 57600 or 19200.
If the Arduino baud rate was simply inaccurate, I'd expect to see the problem appearing at random locations in the string, rather than about 40 characters in.
I have a modbus device I am trying to communicate with using an ethernet to RS485 device. I'm not sure whether the device uses modbus ASCII or RTU.
I am trying to format a request to a device with address 1. The command code is 11h. I'm not sure I'm formatting the request properly
Here is the string I am using for ASCII - ":010B000000000C\x0D\x0A"
Here is the hex I'm using for RTU: "\x01\x0B\x00\x00\x00\x00\x0B\xA4"
When I send this command it is echoed back but I'm not getting responses. I've been through the modbus documentation and I think I have the correct byte structure. I'm wondering if I'm encoding it right for ruby?
It turned out my ethernet to RS485 device wasn't capable of the correct timing for modbus. Once I purchased a new unit the ascii strings worked.
Are you sure the checksum should be written in pure bytes, not in ASCII? I mean, try to send :010B000000000C0D0A instead of :010B000000000C\x0D\x0A.
Also, you wrote that the command is 11h - for my understanding it is 0x11 (hex), and you are sending 0x0B. Or the command is 11 (dec)?
Am trying to get the manufacturer serial number (not volume number) of usb external harddrives or disk?
[EDIT]
i don't know or have any code yet on how to do this. the previous method i tried only returned the volume serial number
You can use WMI to retrieve this information. Hard drive serial numbers are in Win32_PhysicalMedia. I'm not going to take the time to write the code here; if you have any experience querying WMI in VB 6, you should be able to do it without much trouble. Otherwise, search for sample code online. You won't find much of anything specifically about hard drive serial numbers, but you'll find lots of WMI examples.
Be weary of the fact that you won't always get the serial number in the format you're expecting. For example, comments to this article indicate you might get something like:
Serial No. : 4a3532544e464137202020202020202020202020
in which case, you will have to decode the serial number:
By converting to hexdecimal bytes, we get the following (0x20 is blank character and is trimmed out):
0x4a, 0x35, 0x32, 0x54, 0x4e, 0x46, 0x41, 0x37
Swapping the odd and even bytes gets the following:
0x35, 0x4a, 0x54, 0x32, 0x46, 0x4e, 0x37, 0x41
The above ASCII codes are equal to the serial number string:
"5JT2FN7A"
I'm also not positive that all external/removable hard drives provide this information. Your mileage may vary, but the suggested method does work fine on internal hard drives.
Alternatively, it appears that you can do this using low-level Windows APIs like DeviceIOControl. You'll need to add declarations for the necessary functions to a module in your VB 6 app. This article on Code Project should help get you started; the code is written in native C++ and it's geared for consumption by .NET languages like C#, but I see no difficulty in adapting the code to VB 6.
I need to send data to a hardware device over serial port. I'm using a program called serial port tool for os x.
After I connect to the device there is a form box where I can type data to send. I have no idea how to format the data.
Here is an excerpt from the manual for the device.
"The Net Manager Command structure consists of one start byte, one command byte, five bytes of data, and a one byte checksum. Each message packet is formatted as follows:"
an example command is:
Byte0=30 Byte1=7 Byte2=5 Byte3=1 Byte4=2 Byte5=0 Byte6=245
How do I type that into the form box in serial port tool?
Thanks,
Seth
Does the "serial port tool" you're using come with any documentation?
Assuming the "form box" is expecting printable characters, what you're looking for is a way to input an arbitrary byte value. For example, there might be a mechanism that lets you use an octal or hexadecimal escape sequence (such as \036 or \24).