Tty for serial port to Arduino from Linino

EDIT: please also see mwalimu's question in reply # 59.

I started a new thread for doing tty through the SPI bus, realizing afterwards that my questions were off topic.
http://forum.arduino.cc/index.php?topic=211823.0

New Problem!

I can't upload a sketch to the arduino over USB. I can over the Yun interface (192.168.1.140 on my network). I've tried uncommeting "ttyATH0::askfirst:/bin/ash --login" and rebooting, but nothing seems to be working.

I'm thinking I need to reflash the Yun image, but I'm afraid that i run the risk of bricking it since I can't program the arduino and there is no serial connection directly to the linux system.

Help?

I don't think this has anything to do with the /dev/ttyATH0<->Serial1 connection, the USB is Serial on the AVR side of things. What do you mean by

I can't upload a sketch to the arduino over USB.

? What prevents it? Do you get errors? Do you not see the Yun in the IDE? You don't have a USB cable?

This solved one person's problems but without more information than you gave it may not help you:
flash bootloader-

/usr/bin/run-avrdude    /etc/arduino/Caterina-Yun.hex

Going back to the beginning here, reading this and everything I can find has left me totally confused..

I managed to get firmata working through the usb connection, but when first reading this I thought it was for a wireless firmata, but on my third full read through I'm not sure, mostly because I'm not sure what some of this is or how to find actual information on it.
If someone could help me out that would be amazing.

Basically what I'm trying to do is get a wireless I/O into max. (I started a topic about it here but no love Yun with Max/Msp over wifi - Arduino Yún - Arduino Forum )
As I said in there, I have limited experience with arduino IDE (and to an extent Java, although I guess that's not helpful..) and no experience with python or linux.

Can anyone help me?

Also:

  1. What's pyfirmata for on the arduino, from what I can gather it's an interface for on a computer?
  2. When it's installed on the linino side, it's running linux, but installed with python?

I'm sorry about my ignorance here, I still think this is not that difficult, but I just can't get my head around it.
Thanks in advance!

Just got my first yun. The HW/wlan side is very promissing (in terms of stability and most of all latency), but the brige code brings in disapointing latency of around 300 ms per round trip. So I looked for alternatives and found this very interessting thread.

Now I want to throw in my 2 cent:

I am sure, the data coming in at 250000 is to fast for the arduino side, as violinuxer in reply #29 already suspected. But this is not (not only) due to the CPU beeing so slow, but due to arduino library for serial.

All you are probably not aware of some serial speed issues being investigated while writing an arduino lib to connect AX-12 digital servos at 1 Mbit/s. I quote from pablogindel.com

Be sure to go into the hardware/arduino/cores/HardwareSerial.cpp and make the following changes::

// modificación para usar la biblioteca AX12

/SIGNAL(SIG_USART1_RECV)
{
unsigned char c = UDR1;
store_char(c, &rx_buffer1);
}
/

^^ COMMENT THIS OUT!

To put it in one sentence: The ISR stuff in HardwareSerial.cpp just takes to long, so one needs to replace it to be able to use higher speed rates.

I am sure, this is the reason, why it is not working here with 250000. And why is it working during the boot, you may ask. I guess it is not working, but the incoming data is thrown away anyway (see reply #17), so nobody cares.

BTW: Federico Fissore in reply #58 is not quite right about where the 1.5 ms come from. It is not the process start, but just the WiFi delays (which are amazing short, to have that said). I know this, because i did some speed testing with a single threaded (=not threaded) python server on the linux side., and I got the same average 1.5 ms for one send-package-receive-package-cycle (on an already opened socket).

Hm, in my Arduino 1.5.6 HardwareSerial.cpp I can not find the given lines.

I also was just doing some speed intensive stuff and ran into terrible performance and latency issues with the bridge. In my case I had a lot of output being quickly generated by a process and an arduino sketch trying to consume that output. Not only was it very slow, but it was also dropping a lot of data. I think the various levels of buffering in the bridge library need to be investigated, perhaps there are underflows/overflows occuring when things get into tight loops of sending/receiving data. I also noticed the python process running the bridge would spike up to 99% CPU--might be interesting to see if there's a way to profile it and see where all the time is being spent.

In the end I disabled the bridge and had great luck just talking directly with Serial1. In my case I found I had to wait about 90 seconds in the setup of my sketch before trusting any input on Serial1, otherwise I was getting bootup noise. I tried the wait for 1 full second of no Serial1 traffic like in the bridge code and found it didn't actually work and bootup traffic was still getting spammed to my sketch.

Has anyone looked into using GPIO 19 on the Linino/MIPS processor, which appears in the schematic to be connected to ATmega INT6/AIN0/PE6 pin, as a means of signaling between the two processors? I'm thinking of perhaps modifying the bridge to look for a high or low signal on this line and completely disable itself if it finds it. For example in your sketch if you want to disable the bridge you would set PE6 high in the setup and sit waiting. On the Linino side when the bridge starts up it would look for a high signal on GPIO 19 and if it finds it set the line low and immediately abort/stop running. Then on the ATmega side it would be waiting for the line to go low as a signal that it's safe to start using Serial1 exclusively. There's still a race condition if the linino processor gets reset but the ATmega does not or vice versa, but maybe there's a way to work around that (or just live with resetting both at the same time). Consider this mod a 'draw bridge' that lets you disable and enable the bridge library from a sketch. :slight_smile:

tdicola:
Has anyone looked into using GPIO 19 on the Linino/MIPS processor, which appears in the schematic to be connected to ATmega INT6/AIN0/PE6 pin, as a means of signaling between the two processors?

Here is some basic code and documentation concerning the use of GPIO 19 as a kind of linux boot monitor.

Eberhard

Hm, in my Arduino 1.5.6 HardwareSerial.cpp I can not find the given lines.

Yes, you are right, it has changed a bit. I just checked it: The ISR code is now called"HardwareSerial::_rx_complete_irq" an can be found in the file HardwareSerial_private.h. Anyway, the arduino style serial receive ISR can be deactivated e.g. in HardwareSerial1.cpp, it is the whole block around the line

Serial1._rx_complete_irq();

Anyway, the principle remains: Probably the arduino style serial receive ISR is too slow, and must be replaced by an own (faster) ISR to be able to use more than 115200 bit/s.

========================

After thinking about all this, I made a theorie:
Why is there so much hassle in the bridge code with CRC and internal retries?? The "cable length" between the linino and the AVR side is so short, that there shouln't be any errors at all. Can it be, that the arduino people realized all these errors, but weren't aware off the problematic ISR timing, and then found a (bad) solution in doing CRC and retries?

As always, the problem with serial communications is the size of the receive buffer, not the speed of the link or the response of the interrupt service routine. A 250kbaud serial link can deliver slightly more than 2kBytes per second - that's about 500microseconds between bytes. However, it only takes about 4 microseconds for an interrupt service routine on a 16MHz Mega board to store that byte in the receiver buffer.

I had to write my own serial receiver for a project recently, with incoming data at close to 1Megabaud, with message lengths in the order of 500 bytes. That required 4K of sram devoted to one receive buffer - rather more than the library allocates. The main loop has to be very streamlined to process the messages, and any delay can cause a buffer overrun - that's bad news as the message must be sent again, or discarded.

And that's the problem - writing a library that probably supports four serial ports with receive and transmit buffers for each channel eats up sram - and that's not appreciated by users who use only one channel to output logging to a terminal.

@tdicola:- The reason for the 99% cpu usage mentioned previously is probably the serial transmit routine blocking when the transmit buffer becomes full.

GreyCon:
Happy to supply the code if anyone is interested.

Ooooh yes please :grin:

Hi!
I'm about to start a project in which I need to have pure serial com between linux and the AVR. And so, I ended up here...
In order to make serial port free to AVR, kernel messages and console needs to be disabled.
But as pointed out, by removing the inittab entry and removing kernel messages at boot, will leave you in a bad situation if linux side should end up in a bad state.
So, my solution so far is to change inittab as such:

::sysinit:/etc/init.d/rcS S boot
::shutdown:/etc/init.d/rcS K shutdown
#ttyATH0::askfirst:/bin/ash --login
ttyATH0::once:/bin/ash --login

This will start one shell at boot up, leaving the possibility to connect.
The sketch will have to wait for boot to pass in a similar manner as shown before, It will then have to connect
and send "echo 0 > /proc/sys/kernel/printk" to disable kernel output to serial, and finally an "exit" to kill the ash shell.
Now, the serial is free for use, without loosing the valuable boot messages and shell.
If anyone knows of any better solution, I'd very much appreciate if you share the info.

I gave brewmonkey's approach a whirl, all seems to work as expected.

The only observations I have is you can modify inittab like this to never even start the console on ttyATH0:

::sysinit:/etc/init.d/rcS S boot
::shutdown:/etc/init.d/rcS K shutdown
#ttyATH0::askfirst:/bin/ash --login

kill the kernel chatter in rc.local:

# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.
echo 0 > /proc/sys/kernel/printk
wifi-live-or-reset
exit 0

Now the sketch just needs to wait patiently until all is ready, if there are problems later the you can use failsafe to recover:

Press the [f] key and hit [enter] to enter failsafe mode
f
- failsafe -
/etc/preinit: line 1: telnetd: not found


BusyBox v1.19.4 (2013-08-07 16:16:02 CEST) built-in shell (ash)
Enter 'help' for a list of built-in commands.

      ___                   ___                       ___           ___     
     /\__\      ___        /\__\          ___        /\__\         /\  \    
    /:/  /     /\  \      /::|  |        /\  \      /::|  |       /::\  \   
   /:/  /      \:\  \    /:|:|  |        \:\  \    /:|:|  |      /:/\:\  \  
  /:/  /       /::\__\  /:/|:|  |__      /::\__\  /:/|:|  |__   /:/  \:\  \ 
 /:/__/     __/:/\/__/ /:/ |:| /\__\  __/:/\/__/ /:/ |:| /\__\ /:/__/ \:\__\
 \:\  \    /\/:/  /    \/__|:|/:/  / /\/:/  /    \/__|:|/:/  / \:\  \ /:/  /
  \:\  \   \::/__/         |:/:/  /  \::/__/         |:/:/  /   \:\  /:/  / 
   \:\  \   \:\__\         |::/  /    \:\__\         |::/  /     \:\/:/  /  
    \:\__\   \/__/         /:/  /      \/__/         /:/  /       \::/  /   
     \/__/                 \/__/                     \/__/         \/__/   
                                                                                       
            _______                     ________        __
           |       |.-----.-----.-----.|  |  |  |.----.|  |_
           |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
           |_______||   __|_____|__|__||________||__|  |____|
                    |__| W I R E L E S S   F R E E D O M

root@(none):/# mount_root
[   17.300000] jffs2: notice: (534) jffs2_build_xattr_subsystem: complete building xattr subsystem, 1 of xdatum (1 unchecked, 0 orphan) and 12 of xref (0 dead, 0 orphan) found.
[   18.930000] sd 0:0:0:0: [sda] 7716864 512-byte logical blocks: (3.95 GB/3.67 GiB)
[   18.930000] sd 0:0:0:0: [sda] Write Protect is off
[   18.930000] sd 0:0:0:0: [sda] No Caching mode page present
[   18.940000] sd 0:0:0:0: [sda] Assuming drive cache: write through
[   18.940000] sd 0:0:0:0: [sda] No Caching mode page present
[   18.940000] sd 0:0:0:0: [sda] Assuming drive cache: write through
[   18.950000]  sda: sda1
[   18.960000] sd 0:0:0:0: [sda] No Caching mode page present
[   18.960000] sd 0:0:0:0: [sda] Assuming drive cache: write through
[   18.960000] sd 0:0:0:0: [sda] Attached SCSI removable disk
switching to jffs2
root@(none):/# 
root@(none):/# vim /etc/inittab
root@(none):/# vim /etc/rc.local

Sorry for my ignorance, but I do not get the point of what noblepepper is suggesting:

Changing inittab to comment ash start, was stated to be dangerous (I don't know why because I still was able to connect via YunTerminal). And having a sketch sitting and waiting to get Linino started is also known practice. In what way is changing rc.local to reduce chatter an improvement?

Ah, that is a lot better.
I will try it out! Thanks!
Well, it is better because we still recieve boot messages that could be useful in case something goes wrong, but a sufficiently long wait or even an mcu-reset after linino boot might do it if sketch is well written. So not so much special handling from sketch.
And if failsafe mode enables console, then that could be used as last resort.

I do not get the point

The point is that this deals with two issues when a sketch tries to use the serial connection between the AR9331 and the 32u4 outside of the bridge:

  1. There is a shell or console connected to the serial port on the AR9331, this intercepts some communication on the connection. This is useful to send shell commands to the AR9331 but if you want a program on the AR9331 to use the data directly it is a problem.

In what way is changing rc.local to reduce chatter an improvement?

  1. The kernel considers this to be the "system console" so it sends messages there on occasion. For example, plugging and unplugging an ethernet connection to the Yun causes
 [   71.050000] eth1: link up (100Mbps/Full duplex)
[   79.050000] eth1: link down

to be sent to the serial port. This happens regardless of whether there is a shell running there. A sketch on the 32u4 needs to discriminate between this and the data which it needs.

dangerous

? Not really. Scary sometimes? Perhaps. The first time I disabled the shell and had some network issues it was very disconcerting. But you can still use YunSerialTerminal to fix things, either with failsafe or if really needed, uboot and sysupgrade. This works because the Yun goes through three stages when it boots, uboot which is kind of like the bios on a desktop, preinit which mounts the overlay filesystem and does other needed work, and init which brings up the final system. Uboot and preinit are not affected by these changes so they are still available (and you have to wait for them to get out of the way)

I don't know why because I still was able to connect via YunTerminal

You still see the uboot and preinit stuff but on my yun when I comment the ttyATH0::askfirst:/bin/ash --login in inittab there is no shell available once the init stage takes over.

All in all it just amounts to what you want, for most people none of this would be useful, in fact would be a bad thing since it disables a lot of the stuff the Arduino people worked very hard to put in place to make the Yun easier to use.

Many thanks for your explanations.
Maybe you forgot that I'm one of the guys who already uses serial communication between my sketch and my python web sever doing Web Sockets for client interaction.
So I already modified my inittab and got it to work.
I was just courious about the rc.local mod for which I do not see the advantage.
I'm a little disappointed about the Yun Team not natively giving the choice using tty or spi for doing the communication.
Blocking serial with a slow Bridge implementation is not what I would prefer.

brewmonkey:
...
If anyone knows of any better solution, I'd very much appreciate if you share the info.

Not better solution but work around.

Rootfs on External Storage microSD card (extroot)

http://wiki.openwrt.org/doc/howto/extroot

http://forum.arduino.cc/index.php?topic=228204.msg1651254#msg1651254

Edit /etc/inittab at Rootfs on microSD card, comment out or delete:

#ttyATH0::askfirst:/bin/ash --login

Whenever you need access serial port again, just remove microSD card and reboot.

an other work around:

Force AR9331 to device mode, then redirect tty to USB port, release UART port.

http://forum.arduino.cc/index.php?topic=238834.0

Plan C:

Wire one more PHY/Mac ( ethernet port ) from AR9331 and set it as static IP address. then we could release UART port.