For fast communication from TCP to SPI on an Arduino Yun.

Dear all !

After perusing this forum I believe I have a pretty decent idea of how I'm going to achieve the following project. But before I start this lengthy process I'd like to submit it to you guys in case I'm headed to a major pitfall.

The end goal is this:
I need to communicate through the SPI port with a Direct Digital Synthethizer, through the Ethernet port of the Arduino Yun. The straightforward way would be to use the YunServer and YunClient libraries and listen on a port of my choice for TCP strings sent from my computer. However, this method is slow and is documented as such.

My plan of action is to use the OpenWrt distro. By using the socat command (needs to be compiled, but should not be a problem) I can redirect whatever strings come on the port of my choice and redirect on /dev/ttyATH0.

From there a Sketch reads the string, does its magic, and sends the proper instruction on the SPI port.

My first question is : are there pitfalls ?
Second question : I'm afraid the serial port I mentioned only communicates on USB and not to the Arduino chip itself, I can't seem to find documentation on that topic.

Thanks to all of you.

Matthias

You are quick to dismiss YunServer/YunClient, because you've heard it's slow. People reporting that things are slow is a relative term, and whether something is fast enough or too slow greatly depends on the needs of the application, and no two applications are truly alike. What bandwidth do you need? Have you tried it and found it to be too slow?

Mattse:
Second question : I'm afraid the serial port I mentioned only communicates on USB and not to the Arduino chip itself, I can't seem to find documentation on that topic.

/dev/ttyATH0 on the AR3391 side is directly connected to Serial1 on the '32U4 side, using shield connector pins 0 and 1. Serial on the '32U4 side is connected to the microUSB connector. They are two different serial channels and there should be no conflict.

The conflict comes in with the Bridge library. If you are talking directly to the serial port hardware as you propose, you will be commandeering the same serial port used by the Bridge library, so you will not be able to use that library or any of its features (file I/O, Console, bridge key/value data pairs, etc.)

The other danger with using the serial port directly is that your sketch code must be able to handle unexpected input from the port, and be able to distinguish it from the actual data. For reliability, you might need to implement a data packeting scheme with error detection so that unexpected input can be ignored. This might be difficult if you are simply streaming the network socket data to the serial port. The issue is that the port also acts as the Linux console. While you can easily disable the command line processor, you will still get system messages sent to that port when certain things happen (like SD cards, USB devices, and network cables being inserted/removed.) Furthermore, you need to be careful about not sending data from the sketch to the Linux side while booting up, as this can interrupt the boot process (there are two places where you can "press any key" to stop the boot process and enter a special command line. While it does a lot more than you want THIS POST discusses some of the things to watch for when using the serial port directly without the Bridge.

Another possibility might be to handle all of the SPI communications on the Linux side and bypass the sketch. HERE is a current discussion that mentions using the SPI interface from Linux, maybe it gives you some ideas.

Mattse:
...
My plan of action is to use the OpenWrt distro. By using the socat command (needs to be compiled, but should not be a problem) I can redirect whatever strings come on the port of my choice and redirect on /dev/ttyATH0.
...

No need compiled

opkg update
opkg install socat

http://www.ibuyopenwrt.com/index.php/8-yun-compatible/158-console-class

ShapeShifter:
You are quick to dismiss YunServer/YunClient, because you've heard it's slow. People reporting that things are slow is a relative term, and whether something is fast enough or too slow greatly depends on the needs of the application, and no two applications are truly alike. What bandwidth do you need? Have you tried it and found it to be too slow?

1+

Profile bridge class speed

If your application is required run faster than 1/4 second, then forget about bridge class.

Hello all.

First of all thank you very much for the thorough answers.

ShapeShifter:
You are quick to dismiss YunServer/YunClient, because you've heard it's slow. People reporting that things are slow is a relative term, and whether something is fast enough or too slow greatly depends on the needs of the application, and no two applications are truly alike. What bandwidth do you need? Have you tried it and found it to be too slow?

sonnyyu:
If your application is required run faster than 1/4 second, then forget about bridge class.

Actually I've seriously considered the Bridge class, even tested it out with a simple code echoing in the terminal the strings sent through a port of my choice. It works, but the time it takes is proportional to the string size. As my strings will be pretty long (at least 200 ascii characters), I'm afraid the Bridge class won't suffice. I need my DDS to be programmed in under 100ms. I would have loved to use the Bridge class. Its even the reason I bought the Yun in first place.

ShapeShifter:
/dev/ttyATH0 on the AR3391 side is directly connected to Serial1 on the '32U4 side, using shield connector pins 0 and 1. Serial on the '32U4 side is connected to the microUSB connector. They are two different serial channels and there should be no conflict.

The conflict comes in with the Bridge library. If you are talking directly to the serial port hardware as you propose, you will be commandeering the same serial port used by the Bridge library, so you will not be able to use that library or any of its features (file I/O, Console, bridge key/value data pairs, etc.)

That's great news. So I can send my strings to Serial1 from the Linux side with "socat" and debug on Serial. As far as the Bridge library goes, I can do without.

sonnyyu:
No need compiled

ibuyopenwrt.com - ibuyopenwrt Resources and Information.

Awesome! So i don't need a microSD to install GCC and compile socat ...etc.
I haven't tried using the console class yet. Does it have the same speed limitations as using the traditional YunServer/Client/Bridge class ? (ie time proportionnal to string size)

Regarding Shape's concerns about wrong packets being interpreted by the Arduino side, I'll cross that bridge when I get there. I don't have too many concerns though since the commands need to have very specific syntax to be interpreted such as "AD9852_1 MODE 2 FREF 300000000.0 F1 65456456456.2 F2 65987987987.2 PHASE1 100.000 PHASE 2 100.000" and possibly more stuff depending on the functionality I want out of my DDS. So i kinda doubt the Arduino side will misinterpret stuff from the Serial pile.

I'll keep you posted on the advancements of the project. Thanks again for the great answers, you've helped me more than you know.

Cheers from France.

Matthias

Mattse:
I haven't tried using the console class yet. Does it have the same speed limitations as using the traditional YunServer/Client/Bridge class ? (ie time proportionnal to string size)

I would assume it has the same performance, as it uses the same basic underlying transport mechanism. But it's a moot point because it uses the Bridge library, so it will not be available to you if you bypass the Bridge and use the serial port directly. Remember, it's everything in the Bridge LIBRARY that won't be available, not just the Bridge CLASS. (It's unfortunate that both the library and one of the classes/mechanisms share the same name, as it can cause confusion.)

So i kinda doubt the Arduino side will misinterpret stuff from the Serial pile.

So your code will gracefully ignore system log messages, even if they show up in the middle of, or interleaved into, the characters of your expected message? Using the Bridge, you are gaining a lot of reliability, which is one of the reasons it's slower. Without the bridge, you lose those protections, so your code had better be able to deal with unexpected data, and with the occasional lost packet if a console message comes in during the middle of one of those long command strings.

Hey all.

Indeed, I've said my farewells to the Bridge library.

As for you concerns about stray packets, the risk is greatly reduced since the Arduino is on a local closed network, and is only listening on a very specific port. So in my specific case, I doubt this to be a pitfall.

The solution would be to replace the socat command by a Python or C program that validates the packets before sending them through serial port to the ATMega. I have no idea how to do that...

The project is actually moving at great pace. I was wondering, since you guys helped me out, how could i do my share ? making a tutorial ? documenting the project ? Basically: where and what.

Cheers to all.

Matthias

Mattse:
As for you concerns about stray packets, the risk is greatly reduced since the Arduino is on a local closed network, and is only listening on a very specific port. So in my specific case, I doubt this to be a pitfall.

The solution would be to replace the socat command by a Python or C program that validates the packets before sending them through serial port to the ATMega. I have no idea how to do that...

No, you are missing the point. The issue is not stray data coming over the network port, the TCP protocol will do that for you, therefore there is no need for a Python or C program to validate the data.

The issue is that Linux uses that same port as its console, and that's where it logs certain diagnostic and activity messages. For example, it can generate a message on that port every time an Ethernet cable is attached or removed, or an SD card or USB device is inserted or removed, or myriad other system events occur. Those messages will be asynchronous from your socat data, and could occur at any time, perhaps even inside a packet being forwarded by socat.

It's the Arduino sketch that could see the bad data, not the Linux side, although the solution would be a Linux side program to read packets from the network, and encapsulate them into your own protocol with start/end packet markers and some sort of error detection checksum or CRC. The sketch would then have to validate packets and throw out bad ones. Note that in this case the packets are not just the network packets, they are an extra layer wrapped around the received network packets.

ShapeShifter:
...
The issue is that Linux uses that same port as its console, and that's where it logs certain diagnostic and activity messages. For example, it can generate a message on that port every time an Ethernet cable is attached or removed, or an SD card or USB device is inserted or removed, or myriad other system events occur. Those messages will be asynchronous from your socat data, and could occur at any time, perhaps even inside a packet being forwarded by socat.
...

Permanently remove such limit is upgrading CPU with more than one UART port?

sonnyyu:
Plan B:

Bypass Arduino. Run everything at Linux side.

AR9331 (Yun) one UART
AR9341 One low-speed UART (115 Kbps), one highspeed UART (3 Mbps)
AR9344 One low-speed UART (115 Kbps), one highspeed UART (3 Mbps)
QCA9558 One low-speed UART (115 Kbps), one highspeed UART (3 Mbps)
MT7628 two UART
MT7688 three UART

I have accessed all of above and will start to testing multiple UART function once I have time.