Go Down

Topic: Making sense of the YUN wifi and the Linino configuration.  (Read 10208 times) previous topic - next topic

WhidbeyBill

The new year hasn't started well as a Yun WiFi issue continues to haunt me.
OpenWRTYun Attitude Adjustment 1 | Load: 0.15 0.08 0.06
I have had a pair of Yuns on my desk/bench since last August. Fact is I thought I had bricked the first one when the WiFi quit unexpectedly within a week or so. So I bought another a few days later. It too has exhibited the WiFI drop-out issue, though not as often. The first one recovered mysteriously after I got the second. I had immediately updated them and reflashed one twice. I don't know if i have missed something obscure.

If I am debugging or composing code, I run direct on USB [Serial()]. To exercise the sketch [via Console()] over WiFi, I generally run the Yun(s) on an uninterruptable 5V Li-Ion Battery pack that stays on a charger, a configuration I thought would resolve any power-up issues. The Wifi Bug has haunted me from the beginning. I use an ASUS RT68U for wireless and never have any issues with the other gear on my household network.

I admit that I have just begun to scratch the surface of the C++ programming of the Arduino, but the WiFi is the only feature on the Yun that beats me up. I have attached a typical testing sketch that just gets A2D data from A0, A1, A2 and writes it to the SD Card. That works fine.
When WiFi drops off, either Yun won't always restart in Wifi.  Further I thought I had forever corrupted one or both because I chose to alter the wlan to static with a fixed address. After resetting, they sometimes recover to the 192.168.240.1 default, sometimes not. Sometimes it defaults to DHCP and I find it in the wireless addresses listed on the router config panel. Sometimes the blue wlan netdev 'link' LED comes back when the wifi comes up, (as I think I have it configured), sometimes not.

The robust feature set of Linino-Openwrt is desirable but I can't begin to think the product will suffice in the remote application I've proposed for our community well-house, which is to notify me by msg or e-mail the service company if the pumps or 3-PH electricity go down.

Anyway, after multiple tries this week I got both Yun's to reset and recover on DHCP. Not where I wanted but at least I know they aren't entirely useless. Hoping a clue comes along, as this issue was also experienced by one or more users describing their experience on GitHub.

Now, I am still not sure I have the WLAN Blue LED properly activated on the advanced configuration page. I can activate (save & apply) the blue LED triggered by netdev, wlan0, link, and save the setup in the configuration panel. I power off and back on, wait for a restart, and soon, say a couple of minutes, the IP shows up in the router's list of wireless devices, as it should. Shortly thereafter, the blue LED comes ON. When I start the console (monitor over wifi ) I will eventually get the printed data from the sketch, but the Blue LED has now mysteriously turned OFF. I reopen the configuration files and I can see that the settings are as I saved them. What is happening? (or not) Does this behavior have anything to do with the SD card write? I can SSH into the SD file and see the data updating.

I need to get the hardware behavior sorted out before I start making a dashboard to display various data types that i want to retrieve from an array of the yun's - if they can be made reliable over wifi. All suggestions appreciated. BTW this is my first chance to 'code' since visual basic. mercy.

EOL

jessemonroy650

#1
Jan 05, 2015, 10:03 am Last Edit: Jan 05, 2015, 10:05 am by jessemonroy650
Hi WhidbeyBill,

I've been running my Yun for about two weeks. I'm working to document the boot up procedure. I've noticed problems with the wifi.

If for instance when powering up the Yun, and the AP is NOT UP or busy, then the Yun will try and try, and eventually give and try to go back to the factory defaults. Typically this takes about 5 minutes, but it could take as much as 20 minutes.

As far as programming from a sketch goes, if the wifi is unreliable, then sketch has problems -- especially if the wifi is not working.

NOTE: because there are two (2) processors on the Yun, rebooting is not straight forward.

If you have not, read this:

Resetting the processors (AR9331, WiFi, and 32U4)
http://arduino.cc/en/Guide/ArduinoYun#toc6

Jesse

ShapeShifter

If for instance when powering up the Yun, and the AP is NOT UP or busy, then the Yun will try and try, and eventually give and try to go back to the factory defaults. Typically this takes about 5 minutes
This is a feature to try and make it more friendly and tolerant of configuration issues. If someone is inexperienced with the platform or networking in general, they could make an error in the network configuration. If this happens, the board may be unreachable through the network, and the beginner may have trouble getting back to their Yun to fix it. Instead of documenting all of the ways to get back in to fix the configuration, and then trying to support all of the beginners attempting to follow those procedures, the decision was apparently made for the Yun to automatically reset back to it's initial configuration access point. This provides a simple and consistent way to get back to the configuration pages and try again.

That's a nice concept, but it falls flat if you are in a situation where the WiFi network is not 100% reliable: maybe the network is down temporarily for maintenance, maybe there was a failure, or maybe the Yun is mobile and has temporarily moved out of range. Either way, once the configuration is correct and stable, this automatic revert to default access point mode is no longer helpful.

Fortunately, it's an easy fix. The script to check if the WiFi is associated and revert to defaults if not is in /usr/bin/wifi-live-or-reset. This script is called during the boot process by /etc/rc.local. If you want to stop this revert to default process, simply edit rc.local and comment out the call to wifi-live-or-reset. That will make the network configuration more stable.

Another way that the network connections can be unstable, leading to a Yun that is unreachable, is if the sketch is writing to the serial port (or using the Bridge library) as OpenWRT is booting up. The issue is that the serial port is connected to the Linux console, and any characters sent at the wrong time can stop the boot process. There is a discussion of it here: Arduino Playground - Yun

I have noticed another cause of instability that pops up sometimes. On one of my Yun's, the script launches a couple asynchronous processes. These are Python scripts that open Linux devices. When the Yun first boots, I don't get any data back from the Python scripts. I believe the issue is that the sketch starts up right away, and tries to start the Bridge. While this takes a while, the bridge finally starts up before Linux has finished booting, and the devices that the Python script tries to access haven't been enumerated yet, so the open of those devices fail. The solution I used goes back to rc.local: there is a commented out call to reset-mcu. I removed the comment so that reset-mcu does get called after the boot process is complete. This restarts the sketch, and this time everything starts up properly.

I made one additional change to rc.local: because that previously mentioned sketch acts as a network server, and because it can take a relatively long time for OpenWRT to boot, and because that sketch is restarted when the OpenWRT boot is complete, it can be difficult to know when the server is up and a connection can be made. I used the "HANDSHAKE"' line that runs between GP19 on the OpenWRT AR9331 processor, and D7 of the Arduino 32U4 processor. First, I added these lines to /etc/rc.local:
Code: [Select]
# Added section to set the handshake line.
# GP19 is connected to D7 of the 32U4 processor.
# This requires setting GP22 high to enable the U7 level shifter.
# This GPIO is already exported.
# Then GP19 needs to be exported, set to output, and finally brought low.
echo 1 > /sys/class/gpio/gpio22/value
echo 19 > /sys/class/gpio/export
echo "high" > /sys/class/gpio/gpio19/direction
echo 0 > /sys/class/gpio/gpio19/value

That causes the HANDSHAKE line to be driven low once the boot process is complete. Then, in the sketch, I added some code to drive an LED to let me monitor the boot process: The LED is on steady while the bridge is starting up, flashes rapidly while waiting for the HANDSHAKE line to go low, and is off when ready. To read the line, I turn on the internal pullup resistor so the line is high while the AR3391 side is floating, and goes low once the code in rc.local brings the line low. The relevant part of my sketch's synchronization code is:

Code: [Select]

#define READY_PIN 7
#define STATUS_LED 8

void setup()
{
  // Bridge startup
  pinMode(READY_PIN, INPUT_PULLUP);
  pinMode(STATUS_LED, OUTPUT);
  
  digitalWrite(STATUS_LED, HIGH);
  Bridge.begin();
  digitalWrite(STATUS_LED, LOW);
  
  // Start server and other tasks here...
}



void loop()
{
  // Flash the status LED if the HANDSHAKE line has not yet been pulled low by the AR3391
  if (digitalRead(READY_PIN) == HIGH)
  {
    // Yes, I know delay() is a cheap way out, but nothing else is
    // really happening until the AR3391 is fully up.
    digitalWrite(STATUS_LED, HIGH);
    delay(100);
    digitalWrite(STATUS_LED, LOW);
    delay(100);
  }
  else
  {
    // The AR3391 is fully booted.

    // The rest of the work to be done inside of loop()...
  }
}


With all of this in place, the power up sequence is:
  • The LED is on steady for a long time while waiting for the Bridge to start
  • The LED then starts flashing rapidly while waiting for OpenWRT to finish booting
  • The LED is on steady for a few seconds while the Bridge restarts after the sketch is rebooted
  • The LED is off and the sketch and OpenWRT are fully booted and ready for action


Bill, each one of these operations has improved the reliability of my Yuns. Hopefully something in here will help you with your stability problems:
  • Commenting out wifi-live-or-reset
  • Implementing the reboot stability enhancements
  • Resetting the 32U4 when AR3391 boot is complete
  • Implementing the HANDSHAKE line

ShapeShifter

Quick update: I optimized the startup code above. Everything is done at the beginning of setup(), nothing has to be done in loop(). I wait for the HANDSHAKE line to go low before doing anything: only after it goes low do I even try to start the Bridge or try to start the processes that depend on Linux being fully up. This means that it is no longer to reset the MCU when the AR3391 boot is complete, and there isn't any danger of the startup code interrupting the boot process, since no communications are attempted until AFTER the handshake line as gone low. (There is still the need to reset the MCU when resetting the AR3391, because the Bridge would still be active in that case.)

The light pattern is now:
  • Solid on during the initial delay
  • Quick flashing while Linux is booting
  • Solid on while Bridge is starting
  • Off when system is up and ready for use

Once the system is up, the LED can be used for any other purpose. In my actual sketch, the LED is turned on when a client is connected to the server (not shown in the code below.)

The complete optimized sketch skeleton:
Code: [Select]
#include <Bridge.h>

#define READY_PIN 7
#define STATUS_LED 13

void setup(){
  pinMode(STATUS_LED, OUTPUT);
  pinMode(READY_PIN, INPUT_PULLUP);

  digitalWrite(STATUS_LED, HIGH);
  // Give a delay for the AR3391 to reset, in case we were reset as part of a reboot command.
  // See http://playground.arduino.cc/Hardware/Yun#rebootStability, case 3.
  delay (2500);

  // Wait for the ready pin to go low, signaling that the AR3391 is fully booted.
  while (digitalRead(READY_PIN))
  {
    // The pin is still high, so give the LED a quick flash to show we're waiting.
    digitalWrite(STATUS_LED, HIGH);
    delay(100);
    digitalWrite(STATUS_LED,LOW);
    delay(100);
  }
  // When reaching this point, AR3391 is ready.

  // Bridge startup
  digitalWrite(STATUS_LED, HIGH);
  Bridge.begin();
  digitalWrite(STATUS_LED, LOW);

  // Rest of application initalization goes here.
}

void loop() {
  // put your main code here, to run repeatedly:

}

jessemonroy650

#4
Jan 06, 2015, 01:04 am Last Edit: Jan 06, 2015, 01:10 am by jessemonroy650
Quick update: I optimized the startup code above. Everything is done at the beginning of setup(), nothing has to be done in
::::SNIP:::

ShapeShifter,
I like the changes you have made since the last message. I would make one (1) suggestion. Perhaps put a long pulse at the end. So end it like this.

Code: [Select]

  // Bridge startup
  digitalWrite(STATUS_LED, HIGH);
  Bridge.begin();
  delay(2000);  // <<===================== ADD THIS
  digitalWrite(STATUS_LED, LOW);
  // vvvvvvvvv <<====================== ADD this too
  delay(200);
  digitalWrite(STATUS_LED, HIGH);
  delay(200);
  digitalWrite(STATUS_LED, LOW);
  delay(200);
  digitalWrite(STATUS_LED, HIGH);
  delay(200);
  digitalWrite(STATUS_LED, LOW);


Next, as you know I'm working on documenting the boot process. From what I see so far, 10+ seconds is wasted on nothing. Apparently, the boot process is generic and those person porting it to Yun ADD alot, SUBTRACTED some, and lived with the mess.

In any case, my purpose of documenting this is to give other developers the opportunity to optimize this, if they feel inclined.

Jesse




ShapeShifter

I would make one (1) suggestion. Perhaps put a long pulse at the end. So end it like this.
The delay after Bridge.begin() seems redundant to me, it takes the bridge a few seconds to start, so there is already a long pulse at the end.

And if you like the extra few flashes at the end, go for it. I don't see it serving a purpose, if anything it detracts: flashing means it's waiting for the Linux side to finish booting, followed by the several seconds of steady on while the Bridge starts. What's the purpose of the extra flashes at the end? I don't know about you, I'm not designing a light show, just trying to convey useful information. (Like for that particular project, when the light is on or flashing, don't try opening a port to it yet, it's not ready and the socket open will just fail.)

jessemonroy650

The delay after Bridge.begin() seems redundant to me, it takes the bridge a few seconds to start, so there is already a long pulse at the end.

And if you like the extra few flashes at the end, go for it. I don't see it serving a purpose, if anything it detracts: flashing means it's waiting for the Linux side to finish booting, followed by the several seconds of steady on while the Bridge starts. What's the purpose of the extra flashes at the end?
::::SNIP::::
ShapeShifter,
it's purely a poetic ending... In old style concerts, and even in rock concerts, there are two final notes - DANT, DANT.
If you listen, you'll hear it. It comes from the middle ages to let the audience know it's THE END (DANT, DANT).

It's just a suggestion.
Jesse

ShapeShifter

I had another thought about this waiting for the handshake signal delay. I like that I put everything in setup(), but this relies on the 32U4 always being reset when Linux is reset. One can modify the Linux reboot command to also reboot the 32U4, but that doesn't catch the case where the '3391 is rest by pressing its reset button.

What if the delay loop was moved back into loop()? At the top of loop(), check if the handshake signal is high. If so, spin loop there until it's high, then re-initialize anything that depends on the Linux side, like the Bridge or any Process or server objects that were started. The goal is to stop the 32U4 from attempting to send anything to the Linux side while the handshake line is high, so it can't interrupt the boot process.

I have to think about the best way to re-initialize things when the handshake line comes back. Just calling setup() again sounds problematical. Duplicating the code in loop() sounds worse. The obvious solution is to put that bridge initialization code in a separate function that is called from setup() and after this loop in loop().

Or, is there a way to trigger the 32U4 to reset from inside a sketch, so that it starts from scratch? If so, keep the initialization the way I have it in my last post. Then all that's needed is a simple test in loop(): if the handshake line is high, then reset the sketch.

WhidbeyBill

I hadn't been back to this thread in awhile and find your ShapeShifter suggestions and examples to be very helpful. I apologize for not following up sooner, but I think i forgot to check the e-mail notification.  After i have incorporated your comments I'll respond with results. This is a great dissertation and I think you so much for the detail and patience. The forum rocks. (redundant i know)
Whidbey Bill.

WhidbeyBill

I have completed all of the config changes and having no issues with the wifi coming up quickly. Until I am ready to reload sketches I won't be putting the front end "boot manager" code in so that will be a little while. Thanks so much for detailing the process and writing up the procedure.

WhidbeyBill

This is a follow up to the prior work everyone has helped with to improve the start-up behavior of the Yun. I am using Pin 8 for the "boot finished" indicator. Reason why below.
BUT i have one issue which haunts. And it has since new.
It is the blue LED  - WLAN - which i like to have active after the sketch starts as I am totally dependent now on the Linux and WiFi since I use the network Time for the data stamps. This is for home use so a minute startup delay is unimportant.

If the sketch is active, I can open the system configuration page and reload LED configuration, a function I call wlanledon, and the LED becomes active again. and stays active. until power down.

If i power down and up, the WLAN LED is active for a second or two after the reboot LED extinguishes but then goes out as soon as the as the first pulse from the meter comes in.  And if I reload  the sketch the WLAN LED doesn't restart.

So I am suspecting that maybe configuring the GPIO ports somehow conflicts with the WiFi LED function. I dunno.

First, I am using Pin 13 as my ICP (pin) for the Pulse counter in my sketch. this has to do with the PJRC example code. So I set  pin13 as an input. The LED driver is still connected, of course, and the red LED blinks with each pulse  - a nice feature.
Is there a way I can restart the wlanledon in the linux boot? after the sketch restarts? do I need to move it or call it in another script?

Other info: I write all sketch data to files on the Arduino partition on the SD. The Yun/OpenWrt Crons take care of loading the data files to my off-site Web pages. There are occasional read-write timing conflicts resulting in blank fields on the web pages but this is an experiment and I don't care.

I do recognize the the use  of millis() in the sketch forever is a hazard, so I plan to reboot the Yun, restarting the sketch at midnight and get a new date for the file name. - A time-date scheme for file naming is NOT implemented yet though the function runs. Two ALPHA characters and a six digit date will be the file name convention I plan to use. I append the six-digit date function only on the console strings for now.

Here's the sketch code as an attachment. I still don't know where the wlanledon function resides. A snapshot is from the configuration page.

And etc/init.d/rc.local
Code: [Select]

# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.
# from ShapeShifter_20150105.
# removed wifi. . .   20150517 WCG

# wifi-live-or-reset
boot-complete-notify

# Added section to set the handshake line.
# GP19 is connected to D7 of the 32U4 processor.
# This requires setting GP22 high to enable the U7 level shifter.
# This GPIO is already exported.
# Then GP19 needs to be exported, set to output, and finally brought low.
echo 1 > /sys/class/gpio/gpio22/value
echo 19 > /sys/class/gpio/export
echo "high" > /sys/class/gpio/gpio19/direction
echo 0 > /sys/class/gpio/gpio19/value

# Uncomment the following line in order to reset the microntroller
# right after linux becomes ready

reset-mcu

# Uncomment the following line in order to disable kernel console
# debug messages, thus having a silent and clean serial communication
# with the microcontroller

#echo 0 > /proc/sys/kernel/printk

exit 0



jessemonroy650

#11
May 23, 2015, 10:51 pm Last Edit: May 23, 2015, 10:54 pm by jessemonroy650
::::SNIP::::
First, I am using Pin 13 as my ICP (pin) for the Pulse counter in my sketch. this has to do with the PJRC example code. So I set  pin13 as an input. The LED driver is still connected, of course, and the red LED blinks with each pulse  - a nice feature.
Is there a way I can restart the wlanledon in the linux boot? after the sketch restarts? do I need to move it or call it in another script?

::::SNIP::::

@WhidbeyBill,
it's good to see you back. In the time you've been absent, I've documented the LEDs for the Yun you can find them here:
Arduino Yun LEDs
http://codesnippets.altervista.org/documentation/yun/leds/leds.html

On controlling the LED labeled WLAN, I have found that it is mostly used by programs not loaded on the Yun. If you scroll down on those reference notes, you'll find a host of different solutions.

The LEDs that are most active are the TX and RX. Those are used by the USB micro port (the one used to power the Yun. They are activated by the internal software that drives that port.

Lastly, I just added this link to that page.

LED Configuration With OpenWRT
http://n-dimensional.de/blog/2014/07/04/led-configuration-with-openwrt/

It is not a Yun used in the example, but it uses alot of the OpenWrt tools available.

Jesse

WhidbeyBill

#12
May 24, 2015, 08:07 am Last Edit: May 24, 2015, 08:18 am by WhidbeyBill Reason: add attachment
The wlan LED blinks as it should near the end of the boot cycle. But as soon as the handshake line goes back low, the activity on the wlan LED stops. wifi is fine. I can have the sketch running, restart the wlanledon on the configuration page, and the LED will function just fine until i reboot, or power cycle.

There are a lot of kmod-led-* scripts in the running processes.  I have a screen shot of the ROM and overlay folders. I'll look at other anomolies in the next few days.

here is the /etc/config/system file:
Code: [Select]

config system
option hostname 'AYun'
option timezone 'PST8PDT,M3.2.0,M11.1.0'
option timezone_desc 'America/Los Angeles'

config timeserver 'ntp'
list server '0.openwrt.pool.ntp.org'
list server '1.openwrt.pool.ntp.org'
list server '2.openwrt.pool.ntp.org'
list server '3.openwrt.pool.ntp.org'
option enable_server '0'

config led
option name 'wlanledon'
option sysfs 'ds:green:wlan'
option default '1'
option trigger 'netdev'
option dev 'wlan0'
option mode 'link tx rx'


I don't have enough savvy to decipher an anomaly in a Kernel Log, or System Log, though the Kernel log does have a mention of the wlan led.
Code: [Select]

6.220000] Registered led device: ds:green:wlan

also this: (twice)
Code: [Select]

4.990000] Error: Driver 'gpio-keys-polled' is already registered, aborting...
42.510000] Error: Driver 'gpio-keys-polled' is already registered, aborting..

I'll do more looking in the next few days.
I am not the first user to encounter this erratic, or at least unexplained, behavior.

Thanks for your interest,
Whidbey Bill

jessemonroy650

@WhidbeyBill,


Quote
There are a lot of kmod-led-* scripts in the running processes.  I have a screen shot of the ROM and overlay folders. I'll look at other anomolies in the next few days.
The files that are listed in your jpg image is from the directory
/rom/usr/lib/opkg/info
Those are description files for the opkg utility. Open them up in your text editor and you'll see something similar to what you get when you type opkg info <pkgname>

Quote
6.220000] Registered led device: ds:green:wlan
It is the kernel reporting it has a driver for that LED.

Quote
4.990000] Error: Driver 'gpio-keys-polled' is already registered, aborting...
42.510000] Error: Driver 'gpio-keys-polled' is already registered, aborting..
The Atheros chip (the Linux part) has GPIO pins. As far as I know they are not used, maybe someone else has an answer for that, but everyone gets that so I would not worry to much about it.

Jesse

WhidbeyBill

http://forum.arduino.cc/Smileys/arduino/smiley-mr-green.png
 :smiley-mr-green:
As a refresher, I've been haunted by the fact the the blue WLAN LED would not function after a sketch started.
I could refresh from the YUN configuration panel or typing
Code: [Select]
/etc/init.d/led restart from the command line.

I couldn't get the rc.local command in openwrt to do the same thing since there must be a disconnect that occurs when a sketch starts.

I added the following to my sketch to RE-start the LED function at the beginning of the setup() and after the Bridge() . Now the WLAN LED always works when the Yun restarts from power cycle. Takes 300 bytes or only 2% of resources.

 
Code: [Select]

#include Process p;

  // Added 5-25-2015, to restart LED triggers for Wireless LAN. Yun RST reboot doesn't complete.
  Process p; // Added 5-25-2015, WCG http://forum.arduino.cc/index.php?topic=206800.0
  p.runShellCommand("/etc/init.d/led restart");


Moving on to other tasks as the YUN RST button isn't an essential function. Power Down recovery is. :smiley-mr-green:

Go Up