I'm writing a simple program to transmit data from the MCU to the PC.
I'm using FTDI cable to achieve that.
Data that I'm sending is string digits from 0 to 9 (0x30 to 0x39 as ascii codes).
Both the MCU and the PC terminal are configured to 9600 kbps, 8 bits, no parity, no flow control, one stop bit.
When the data transferred from the MCU to the PC - symbols are wrong.
When TX and RX lines of the MCU are both connected to each other - I can see, that all symbols that were sent, were received by the MCU.
When TX and RX lines of the FTDI cable (connected to the PC) are connected to each other - all symbols that were sent from the PC terminal were received by the PC.
I cannot understand what can be wrong in sending data from the MCU to the PC.
Please, help!
The symptoms you describe suggest a timing mismatch between the PC and the MCU. UART serial comms can tolerate a baud rate mismatch of <5% at either end. In practice because teh PC is certainly accurate, you might get away with up to 10% in the embedded target - but that is extreme. Either the baud rate divisor for your part is incorrectly programmed, or your system clock is inaccurate or simply not the frequency you believe it to be. RC oscillators on some MCUs used to reduce costs can be off-nominal as bad as +/-10%.
You should verify the clock and the baud rate directly with an oscilloscope, or laboriously verify every clock setting from the PLL to the UART baud-rate generator.
The solution is more simple than I thought.
For my previous applications I used the ATC-810 cable (USB-to-UART, FT232BL chip).
At the past it worked, but now for some reason it doesn't works. New drivers from FTDI, may be...
When I took the TTL-232R-3V3 cable - all data that I'm sending from the MCU I'm receiving on the PC!
Thanks a lot for trying to help!!
Related
I've been working with a Siemens PLC to send data using RS232. The communication itself is working perfectly, I can monitor it if I connect the PLC to my PC (via a serial comm port).
Now, I wanted to make this communication wireless. I found out about the HC-05 modules and decided to get a few. I set 2 of them up with my arduino (one as master, one as slave, both paired and using the UART 9600,1,0 which is the same that my PLC uses).
I made the following connections:
PC Connection (with a serial comm adapter)
PLC Connection
Let's say I want to send this string:
<SoH>1RZ<CR>
If I check my serial monitor, I get weird stuff. Like:
##NULL©#NUL
The weird thing is that if I just remove the bluetooth modules and connect the PLC's Rx and Tx to the PC's Tx and Rx, respectively, the data is sent flawlessly. So I know that I have everything sorted out on the PLC/PC side.
Has anyone been through this, or does anyone have a suggestion that I can try?
RS232 typically uses ±12V. Negative voltages between -3V and -15V is logic high and positive voltages +3V till +15V is logic low.
Your bluetooth module on the other hand uses TTL logic. With a voltage range of 0-5V.
0-0.8V is low, 2-5V is high.
So
a) you cannot create the necessary voltage levels
b) you risk to destroy your 5V hardware by connecting it to ±12V.
c) you might run into problems as RS232 also has optional mechanisms for flow control. So Rx and Tx might not be enough.
You'll at least need a TTL-> RS232 level shifter for the PLC side and a USB to TTL serial adapter for the PC
Expected first printf line of software to serial output to Windows7 PC is:
main() ************************** SW START Project 2016-10-30 x1
Actual serial output (at TeraTerm or PuTTY);
▒▒▒▒()j**j*j**j*j**j*j**j*j**j*j ▒▒Ӕ▒Ҕ ▒▒▒▒▒▒▒ r01v-q0-30▒q
Serial worked great from mbed or VisualGDB to NUCLEO evaluation board.
ie.:
Serial pc(USBTX, USBRX);
Now, I'm running VisualGDB to the actual target board with a STM32F091RC.
ie.:
Serial pc(SERIAL_TX, SERIAL_RX);
At 9600, some chars are correct, most are garbage.
I've tried alternate target and cables, same problem. PC's Terminal program (TeraTerm or PuTTY) set at 8,n,1.
Looked in mbed library; default config is 8 data, no parity, 1 stop.
USB/serial converter cable is: FTDIChip TTL-232R-RPi (normally for Raspberry Pi).
It could be clock mismatch between eval board and target board. Assuming, you have correct grounding.
Another issue could be number of data bits in configs is off.
I guess it is not relevant anymore, but you have to pay attention to this points.
The Signal level is 3.3v and not 5v, not all USB Uart adapters work correctly with is
The polarity is the inverted to the standard, i.e. start bit is 1.5bit low like here
Ensure you have correct parity and bits. Most people (and Arduino) use 8N1 by default, but STM32 sample code uses 7O1 by default. See here: https://community.st.com/thread/40340-stm32cubefwf2v140projectsstm32f207zg-nucleoexamplesuartuartprintf-printing-garbage-data-over-the-terminal
I am trying connect multiple Arduino Mega Boards via their Serial pins to allow communication between the boards. I want to be able to connect an arbitrary amount of arduinos by daisy-chaning them and I want one board to be the master, taking control over the actions of the other boards. The master should be determined dynamically by the boards. I am aware that the daisy chaining method introduces delays to the communication due to the forwarding of packets, but so far I am planning on connection 4 boards at most. In the future this might increase to maybe 10 boards. My boards all have a separate power source, since they are connected to some other hardware which has its own power source.
My idea was to connect the boards in such a way, that the master would be determined by the wireing of the boards. I thought about having the "Serial" port as 'To-Master' serial port and the "Serial1" port as "To-Child" serial port. The boards send hello messages on the "To-Master" serial port and the master replies if it received such a message on the "To-Child" serial port. If no answer is received after some seconds, the board determines itself to be the master.
I wired the boards up by connecting the ground pins, and wiring RX1 of the master to TX0 of the child and TX1 of the master to RX0 of the child:
Basically my setup is working, since the boards do detect each other and exchange hello messages and replies. There is however a significant amount of packet loss or corruption which I would like to eliminate.
As a simple measure of packet verification, I begin each packet with a "magic number". The receiving board looks for this byte and only tries to read a packet after receiving this byte. Any other bytes received are simply discarded.
As it seems, it happens quite often that something is received on either serial port that does not start with the magic number and is therefore discarded. The timestamps of these events are however consistent with the timestamps of sending of the other board meaning that the packet was at least partially transmitted but somehow the magic byte got corrupted or discarded.
Is this a known problem with the arduinos serial ports?
Can it be related to my wiring?
Are there any measures I can take to ensure a save delivery of the packets?
Can it be a problem of the boards not reading the signal at the correct time (I used a baud rate of 9600)?
I also looked into I2C communication, but I did not find any resource or information if it is possible to dynamically choose the master for this type of communication. Also in the documentation it stated, that it is important that all devices share a common power source which is not possible in my scenario. However, the basic master-slave principle of this I2C conforms with my requirements, as I have a master that sends commands to all other boards. Could I2C be utilized in my case?
Thank you for your thoughts!
Here is a discussion about multi-master I2C topology of Arduinos, seems that it is supported (haven't tested it myself). - http://forum.arduino.cc/index.php/topic,13579.0.html
You can test SPI as well, here is a comparison between the two - http://components.about.com/od/Theory/a/Selecting-Between-I2c-And-Spi.htm.
Slave might be selected with generic GPIOs
I don't know any known implementation of multi-clients on top of Serial bus (usually it is intended for peer2peer communication only) - even though, your configuration seems reasonable, I would be considering other options.
BTW, from your comment about different power sources, I assume your boards are away from each-other. Have you considered very cheap ($2) RF modules, such as nRF24L01+ (http://maniacbug.wordpress.com/2011/11/02/getting-started-rf24/). THere is a library for networking those in multi-node network
Might be better off with I2C or SPI like people have suggested here.
However, to address your question directly, it is most likely wiring. I am assuming you are using cheap jumper wires to plug directly into the Arduino Headers. Noise on this connection is the most likely problem or garbled serial messages. Try implementing with twisted pair cables and connecting directly to the board.
SPI or I2C might have better error correction than your customer serial protocol. I would see the other answers for that.
I had a PC connected to a PLC (Mitsubishi Q Series) via a USB2RS232 cable. The cable was plugged into the PC side, which was then plugged into a Serial cable and then into the PLC. I hade the baud rate set to 19200 and everything worked fine.
My problem was that every now and then the PC would blue screen on me. When I checked through the dump files the problem seemed to be related to the driver for the USB2RS232 cable (ftdi). I update to the latest driver but still bluescreening (Pc was running Windows 7).
Anyway I replaced the PC with another which had a dedicated RS232 port. Now I keep getting communication issues which is indicated by the response by the PLC. Just by chance I lowered the baud rate down to 9600 on both the PC and PLC. The issue seems to have gone away.
My question is why would removing the USB2RS232 cable cause me to have to slow down the communication? Both devices can communicate at speeds greater than 19200 and I would have thought going from serial port (PC) to serial port (PLC) with a serial cable would be better.
EDIT: Problem maybe solved - still testing
Thanks to some of the input from you guys, I may have solved the problem. Here are the following points I went by to get the speed back up to 19200 when using straight RS232 to RS232.
Even though no noise was detected on the equipment, a shielded cable was used.
The PC program would wait 100ms between sending data to the PLC. I read somewehere that 100ms is a good approx for PLC scan time.
RS232 Communication between modern PLCs and modern computers is often a hassle. These are some things I look at what it's not working:
The cable. Lots of cables are nonstandard, and have nonstandard internal jumpers and whatnot that can increase error rates and lower throughput. It is possible that your USB converter is more advanced and is autodetecting something with your cable and compensating for it.
The OS on the PC. Windows versions newer than Windows 98 don't seem to have the best support for serial communications.
Interference. Be especially careful of drives near the comm line. If you are using unshielded cables, a drive that runs intermittently can cause exactly the problem you describe, where you get an intermittent failure, but no noise at all whe the equipment is idle and you go check.
From your description I would guess that you have your equipment in a "noisy" environment - judging from the previous blue screens and now the issues with a regular RS232.
Have you tried to run the setup elsewhere with same hardware but other environment?
See if you can get a better isolated serial cable and/or use an EMF-meter to measure electric/magnetic fields around your setup.
Also worth to check out would be to put in another RS232 card in the PC to see if you have issues there, it could be that you had bad luck and the RS232 has broken.
Edit
Are you sure the speed is higher than 9600 with the USB converter? maybe it has negotiated down the speed? (disclaimer: not sure what brand you are using and how intelligent it is).
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.