I have a uncommon protocol, which requires 9600 baud, 9 bits and one stop bit. I can't find any driver, which can implement this sending/receiving.
Can I send something to /dev/tty* for emulating these queries? What should I send? How can I emulate a 9600 baud rate?
You can use sticky parity, which is also called MARK and SPACE parity. termios.h supports this. However, you need to change the parity settings before sending address or data bytes accordingly and depending on the hardware, this may introduce undesired delays between two types of bytes. I have experienced delays from 0.4 ms to 10 ms with FT232RL & FT232BL USB to serial converters. I'm not sure but I suspect that it's also affected by the motherboard and the USB port you use (USB2 or USB3). Also, you need to be sure that the transmit buffer is empty before attempting a parity mode change because it also affects the parity settings of the bytes that are already placed in the transmit buffer.
Related
I have a project using MDB (multi-drop bus) for vending machine (VDM).
The VDM has a MDB-RS232.
I'm not sure if it converts 9bit - 8bit (MDB-UART).
How do I read data from VDM in my computer?
Thanks all
MDB (multi-drop bus) is 9 bit, because after the standard 8 data bits (like in standard RS232 UART communication) there is a 9th bit called "mode".
(Wikipedia on MDB: "the mode bit differentiates between ADDRESS and DATA bytes.")
But you can read such data even with regular 8-bit RS232 interfaces, e.g. a plain standard USB-to-RS232 device for PC.
Here is how:
Use 9600 baud, 8 data bits, 1 stop bit, but RS232 parity setting "Space". Make sure you receive the original character value even in case of a Parity Error indication. Any MDB address byte from your VDM will be received with a Parity Error (but still be displayed correctly). Any data byte will be displayed without error.
For sending MDB ADDRESS and DATA bytes using a standard 8-bit RS232 port, you could apply temporary parity changes: Change the parity setting to "Mark" before sending an address byte, then change back to "Space" before sending data bytes.
On Windows, you can do such tricks with our Docklight software (see Docklight and MDB). It's free for basic testing and there is also a related 9-bit example project.
On Linux / Raspberry Pi other users have successfully implemented the parity trick, too, see this stackexchange post about a MDB + Pi.
But also with RealTerm, Teraterm, Termite, Bray, YAT or any other RS232 application you should be able to read the data, as long as it handles "Space" or "Mark" parity settings correctly.
You'll need an adapter which will do all convert operations on-the-fly and in real time. If you want to emulate VMC (master), you'll need MDB-UART master adapter. If you want to emulate MDB peripheral device (such as coin changer, bill validator etc), you'll need this. For two-way "sniffing" MDB bus you'll need a combination of these devices.
Direct connection PC's RS-232 to MDB will not work due to strict MDB timings (delay between VMC command and peripheral response must not exceed 5ms, delays between POLL requests are 50-300ms in general). I mean pretty reliable functioning available for commercial purposes.
I am using 2.6.32 OMAP based linux kernel. I have observed that at high speed data rate (Serial port set to 460800 baud rate) serial port HW fifo overflow happens.
The serial port is configured to generate interrupt at every 8 bytes in rx and tx both direction (i.e when the serial port HW fifo is 8 byte full serial interrupt is generated which reads the data from the serial port at once).
I am transmitting 114 bytes packet continuously (Serial driver has no clue about the packet mode, it receives data in raw mode). Based on calculations,
460800 bits/sec => 460800/10 = 46080 bytes/sec (Where 1 stop bit and 1 start bit) so in 1 second I can transmit under worst case 46080/114 => 404.21 packets without any issue.
But, I expect the serial port to handle at least 1000 packets per second as such I have configured serial driver to generate interrupt every 8 bytes.
I tried the same using windows XP and I am able to read upto 600 packets / second.
Do you think this is feasible on linux under above circumstances? or I am missing something? Let me know your comments.
could someone also, send some important configuration settings that needs to be configured in .config file. I am unable to attach .config file otherwise, I can share it.
There are two kind of overflows that can occur for a serial port. The first one is the one you are talking about, the driver not responding to the interrupt fast enough to empty the FIFO. They are typically around 16 bytes deep so getting a fifo overflow requires the interrupt handler to be unresponsive for 1 / (46080 / 16) = 347 microseconds. That's a really, really long time. You have to have a pretty drastically screwed up driver with a higher priority interrupt to trip that.
The second kind is the one you didn't consider and offers more hope for a logical explanation. The driver copies the bytes from the fifo into a receive buffer. Where they will sit until the user mode program calls read() to read them. Getting an overflow on that buffer will happen when don't configure any kind of handshaking with the device and the user mode program is not calling read() often enough. It looks exactly like a fifo buffer overflow, bytes just disappear. There are status bits to warn about these problems but not checking them is a frequent oversight. You didn't mention doing that either.
So start by improving the diagnostics, do check the overflow status bits to know what's going on. Then do consider enabling handshaking if you find out that it is actually a buffer overflow issue. Increasing the buffer size is possible but not a solution if this is a fire-hose problem. Getting the user mode program to call read() more often is a fix but not an easy one. Just lowering the baud rate, yeah, that always works.
I'm building a project that uses an HID OEM75 as the access point for a locking mechanism. We're doing our control through an Arduino Duemilanove (ATmega328). We're working with SPI for the security and (apparently) support. (I realize that any RFID chip has pretty weak security.)
I'm currently struggling with receiving bytes via SPI from the card reader.
The card reader is in autonomous read mode, meaning it reads a card, sends a signal to the Arduino (via a card present line, separate from SPI), which tells the Arduino to pull the Slave Select line high to activate the transfer cycle from the card reader. This is where I run into trouble, I can't understand how I can get the Arduino to simply read the bytes coming in from the card reader without sending any command bytes to the card reader?
The default command structure, SPI.transfer(0x00), sends a byte (in this case the dummy byte 0x00) and then accepts a byte from the source, but because our source is operating autonomously, it won't accept the dummy byte (and that will actually mess up its operation).
To word it simply: how can we accept a string of bytes from the slave source without sending bytes from the Master Source, using Arduino's SPI library?
If I am not wrong, using the SPI bus as a master is like shifting a dummy byte to the slave while reading the incoming byte in reverse.
USB HID Host driver for Windows from embedded24.net
Well it's a little late, but hey, it'll help someone out there.
First off:
which tells the Arduino to pull the Slave Select line high to activate
the transfer cycle from the card reader.
This is SPI, you pull the Slave Select low to activate the slave, not high. You put it high to tell it to shut up while others are talking.
I can't understand how I can get the Arduino to simply read the bytes
coming in from the card reader without sending any command bytes to
the card reader?
That's because you don't. In SPI, the master (which the arduino is set up as and the SPI.h library assumes) initiates communication. It sends out data on the MOSI line and the slave responds on the MISO line. If you have nothing to say to the slave, just send 0xFF or whatever dummy bytes and then check what came in on the MISO. On the arduino, I believe that gets stored in the SPDR, SPI data register. Or use whatever the spi library gives you.
but because our source is operating autonomously, it won't accept the
dummy byte (and that will actually mess up its operation).
If the case is that you really can't send data to the SPI slave device without it screwing up, then it's not actually implementing SPI, and the arduino SPI library won't help you. You'll have to hack out your own solution. The SPI standard is actually pretty loose and all sorts of people do it their own special way. Which is vastly annoying. I've seen devices use the SS line to initiate clock synching. Which means you can't just tie it to ground to have that slave always be on.
Before you write it off though, I'd suggest investigating why it won't accept the dummy byte. You might be using "3-wire" SPI which combine MOSI and MISO and turn it from full duplex into half duplex, and you'll have to get the timing right so you don't trample everything.
When getting into the nitty gritty of SPI, an oscilloscope works wonders for seeing what actually happened vs what you think should have happened.
I currently have an embedded device connected to a PC through a serial port. I am having trouble with receiving data on the PC. When I use my PCI serial port card I am able to receive data right away (no delays). When I use my USB-To-Serial plug or the motherboards built in serial port I have to delay reading data (40ms for 32byte packets).
The only difference I can find between the hardware is the UART. The PCI card uses a 16650 and the plug/motherboard uses a standard 16550A. The PCI card is set to interrupt at 28 bytes and the plug is set to interrupt at 14 bytes.
I am connected at 56700 Baud (if this helps).
The delay becomes the majority of the duty cycle and really increases transfer time. (10min transfer vs 1 hour transfer).
Does anyone have an explanation for why I have to use a delay with the plug/motherboard? Can anyone suggest a possible solution to minimizing or removing this delay?
Linux has an ASYNC_LOW_LATENCY flag for the serial driver that may help. Whatever driver you're using may have something similar.
However, latency shouldn't make a difference on a bulk transfer. It should add 40 ms at the very start of the transfer and that's it, which is why drivers don't worry about it in the first place. I would recommend refactoring your transfer protocol to use a sliding window protocol, with a window size of around 100 packets, if you are doing 32-byte packets at that baud rate and latency. In other words, you only want to stop transmitting if you haven't received an ACK for the packet you sent 100 packets ago.
You'll probably find that different USB-Serial converters produce different results. We've found that the FTDI ones work well for talking with embedded devices. Some converters seem to buffer the data for a long time and/or fragment it.
I've never seen a problem with a motherboard connection - not sure what is going on there! Can you change the interrupt point for the motherboard serial port?
I have a serial to usb converter. When I hook it up to my breakout box and create a loopback I am able to send / receive at close to 1Mbps without problems. The serial port sends binary data that may be translated into ascii data.
Using .Net I set my software to fire an event on every byte (ReceivedBytesThreshold=1), though that doesn't mean it will.
I am designing software around an existing hardware product. I have full control of the communication protocol but I'm not sure how to facilitate device detection.
A device could have a range of possible configurations (i.e. baud rate, data bits, parity bits, stop bits) that must be detected at runtime. What is the easiest, most reliable way for the software to figure out what configuration it is using? Again, I have full control of the communication protocol so I can define any mechanism I wish.
Is this a full-duplex or half-duplex device? Can you control request-to-send and monitor clear-to-send on both ends of the serial line? Is the serial line point-to-point (like RS-232) or multi-drop (like RS-485)? It will make a (albeit small) difference if you are going to interfere with other already connected devices while negotiating with a newly connected one.
If you think of the handshake process like a modem negotiating a link layer protocol, it uses a standard set of messages to describe the type of communications it would like to have and waits for an "ack" from the other end. In your case I recommend having a "let's talk" standard message that your head end generates with the range of bit rates and waits for the ack from the device.
I also recommend reducing the number of configuration options for the device. Forget about variable data bits, parity bits, and stop bits. The serial communications world is no longer as unstable as it was back in the 70's. Just use 8 data bits, no parity, one stop bit and vary the bit rate. A CRC on the end of messages provides plenty of error-checking.