How to read ans set GPIO values in GL-AR150?

Today I just recieved my GL-AR150 and wanted to experiment a little bit with GPIO.
I wanted to read the GPIO value for the switch near the reset button and the GPIO value for the USB port.
For the USB port I also would like to set the power on and off with the GPIO.

I found this document http://wiki.openwrt.org/toh/gl-inet/gl-inet and then this document http://wiki.openwrt.org/doc/hardware/port.gpio

I managed it to turn the power on and off at the USB host connection (GPIO 6), but when I want to read the value of GPIO 8 (the switch near the reset button) the following happens:

root@GL-iNet:/sys/devices/virtual/gpio/gpio6# echo "8" > /sys/class/gpio/export
ash: write error: Device or resource busy

And when I restart the router and want to control the USB host power:

root@GL-iNet:/sys/class/gpio#  echo "0" > /sys/class/gpio/gpio6/value
-ash: can't create /sys/class/gpio/gpio6/value: nonexistent directory

The directory to set the GPIO value seems to be lost.

Does anyone have some information and tips about how to do this? I’m a pretty newbie with this kind of things like GPIO.

1 Like

I don’t think you can read the Button (GPIO11)/Switch (GPIO 7 and 8) as general GPIO, as they have already been registered. And you cannot change GPIO 7 and 8 Value using software, as they are pulled up or down by hardware directly.

There should be a way to read its status, but I don’t know how.

Well, what’s the intended use of the switch then? If none and intended to use for at scripts how can I make use of it?

Here is how you can use the switch. You are not supposed to read its value from script, but rather to assign script to it directly.

Here is the place:

/etc/rc.button/BTN_8

Modify this script. For example:

`
#!/bin/sh

if [ “${ACTION}” = “pressed” ]; then
#do something when pressed
else
#do something when released
fi

`

Thank you very much!
Your example and the following 2 webpages helped me a lot:
https://forum.openwrt.org/viewtopic.php?id=32810
http://wiki.openwrt.org/doc/howto/hardware.button

I am now able to turn my Blink(1) mk2 light on and off. :slight_smile:

This is the script I am using:

#!/bin/sh

logger "Button: $BUTTON ; State: ${ACTION}";

if [ "${ACTION}" == "pressed" ]; then
        /data/local/ar71xx/blink1-tool --on > /dev/zero;
        logger "Blink(1) switched to 'on'.";
else
        /data/local/ar71xx/blink1-tool --off > dev/zero;
        logger "Blink(1) switched to 'off'.";
fi

After executing the script by operating the switch you can use “logread” to read the logs.

And for the people who own a Blink(1) mk2, here you can download a working binairy for the GL-AR150: https://github.com/todbot/blink1/releases/tag/v1.95
You have to download the ar71xx version!
Found it via: blink1-tool for OpenWrt and Arduino Yun — ThingM

1 Like

The switch does have 3 physical states to control GPIO 7 and 8, but GPIO 7 can’t be reached because the enclosure does not allow that (no space to manouvre the switch to GPIO 7). Is there any reason for that?

Thanks for the sample. Will you write a more detailed post about using GL-AR150 and Blink(1) mk2 and the configuration. We can put it in our technical blog with reference to you.

As to your question, here is why: When we design the PCB, we think it is good to have a 3-state switch. But we found its concept is not as clear as 2-state. As 2-state generally means ON and OFF. For example, we can turn on/off a service, a device etc. But for 3-state, we need to think of some service/devices that have 3 states. Except for quickly shift configurations for WAN (PPPoE, DHCP, Static) we don’t have a lot of ideas for 3 states. Another example maybe QOS levels, power saving. But it is also much easier to just set 2-state for these kind of service.

So finally we decided just to reserve 2 state in the case without change the PCB. If you want to use 3 state, you can use a drill to make the switch hole on the case longer.

Ah that’s explains it! I already cut a way the thinner part of the enclosure with a pincer. As you can see on the photo. On the photo also the Blink(1) mk2 light.

photo GL-AR150_mod_zpsrza1dlpc.png

Would you like to have more technical details right here on the forum or by e-mail? In that case: to which e-mailaddress?
It could take some time. One of the reasons is: English is not my native language.

It did go quicker then I expected. :stuck_out_tongue:

You also have the right to use my photo I placed above this post. I can deliver you the same photo at a higher resolution if you want.

====================================================================
How to use your Blink(1) / Blink(1) mk2 of ThingM on your GL-AR150 (or other OpenWRT router AR71xx based)

Let me explain some things: English is not my native language (Dutch is my native language) and I do have only a basic knowledge about Linux based on Debian / Raspbian (Raspberry Pi). Some sentences may be wierd due this reasons. My apologies for that. I hope the text is still readable and understable.

A few things I assume you already know or already did:

  • You are logged on as root through a SSH session.
  • You are familiar with how to tranfer files to your GL-AR150 (FTP, SCP, etc.)
  • You are familiar how to extract ZIP-files.

Step 1: create directory to store blink1-tool

At first we need to create a directory to store the blink1-tool at.

I mainly create a directory /data on all linux devices I own with local storage and mountpoints in it. On my Raspberry Pi for example I mount my USB-storage to /data/usb and share it with Samba to my Windows PC. On both my Raspberry Py and my GL iNet GL-AR150 I also use the local storage and only create it under /data/local (so no special mount).

I asume you already have logged on on your GL-AR150 as root through a SSH session.
Then you can go to the root by executing

cd /

Then we will create the needed directory’s (I have based my steps on the information found here: Setting up a Raspberry Pi Samba Server - The Urban Penguin):

mkdir -m 1777 /data
mkdir -m 1777 /data/local
mkdir -m 0755 /data/local/blink1

Step 2: download the right blink1-tool version

Go to the created directory:
cd /data/local/blink1

Download “blink1-tool-openwrt-ar71xx.zip” from https://github.com/todbot/blink1/releases/tag/v1.95.
Extract the file “blink1-tool” out of the ZIP-file.
Transfer the file “blink1-tool” to your GL-AR150 router at the directory /data/local/blink1

Step 3: give the correct rights to blink1-tool

The file “blink1-tool” needs executing rights.
Provide the execute rights by executing the following command:
chmod +x blink1-tool

Step 4: connect your Blink(1) and test it

Now connect your Blink1 to test it.
You can simply turn a white bright light on on the Blink(1) with the following command:
./blink1-tool --on
To turn it off:
./blink1-tool --off

Step 5: create script to execute Blink(10 commands by switching the switch on the GL-AR150

I use the programm “nano” to edit files. It is a small programm and a lot easier to control then “vi”. If you prefer to use “vi” and you are familiar with how to use “vi” you may keep using “vi” on your own.

To install “nano” execute:
opkg install nano

Then we will navigate to the button scripts by executing:
cd /etc/rc.button

When you have installed “nano” you can load the file “BTN_8” into it by executing:
nano BTN_8

The we will place the following content:

#!/bin/sh

logger "Button: $BUTTON ; State: ${ACTION}";
if [ "${ACTION}" == "pressed" ]; then
        /data/local/blink1/blink1-tool --on > /dev/zero;
		logger "Blink(1) switched to 'on'.";
else
        /data/local/blink1/blink1-tool --off > dev/zero;
        logger "Blink(1) switched to 'off'.";
fi

“#!/bin/sh” should always stay on the very first line!
The variable “$BUTTON” contains the name of the button which is being used within this script. In this case it will contain the value “BTN_8”.
The variable “${ACTION}” will contain the state of the button: “pressed” or “released”.
After the blink1 commands you see “> /dev/zero”. This will prevent any output to the console since we don’t need to see that output.
“logger” will log the text after it to the logs which you can read later on with the command “logread” on the console.

When you use “nano” you can now exit “nano” bij pressing CTRL+X on your keyboard, then press “y” to save the file and press enter to keep using the filename “BTN_8”.

Step 6: test the switch

At startup of your GL-AR150 the state of the button will not have any effect on your Blink(1). You need to switch the switch.
If you switch the switch to the left position the script will fetch the “pressed” state and turns your Blink(1) on. If you switch the switch to the right position the script will fetch the “released” state and turns your Blink(1) off.

Advanced example 1: Blink(1) mk2 with different colors per LED

The Blink(1) mk2 does have 2 different LED’s on the same device which you can control indepently.
Here’s a example script for “BTN_8” which will swap the right and green light from side when you switch the switch to the different positions:

#!/bin/sh
logger "Button: $BUTTON ; State: ${ACTION}";
if [ "${ACTION}" == "pressed" ]; then
        /data/local/blink1/blink1-tool --rgb=0,075,0 --led=1 > /dev/zero
        /data/local/blink1/blink1-tool --rgb=075,0,0 --led=2 > /dev/zero
else
        /data/local/blink1/blink1-tool --rgb=075,0,0 --led=1 > /dev/zero
        /data/local/blink1/blink1-tool --rgb=0,075,0 --led=2 > /dev/zero
fi

This will turn LED 1 on with a soft green color and LED 2 on with a soft red color when the button has the state “pressed” (switched to the left position).
It will turn LED 1 with a soft red color and LED 2 on with a soft green color when the button has the state “released” (switched to the right position).

Advanced example 2: Blink(1) mk2 with 3 LED states

The switch actually has 3 positions. Because the manufacturer has limited the use of the switch by putting the enclosure in front of the third position you weren’t able to use the third position. You can see a small thinner part of the enclosure at the right side of the switch. When you open the enclosure with caution and drill away that thin part you will be able to use the third position of the switch.

The switch actually drives BTN_7 when the button is switched to the most right position. The middle position sets the “released” state to BTN_7 or BTN_8 following where the switch came from:

  • When the switch is at the most left position it sets BTN_8 to “pressed”.
  • When manouvre the switch to the middle position it sets BTN_8 to “released”.
  • When the switch is at the most right position it sets BTN_7 to “pressed”.
  • When manouvre the switch back to the middle position it now sets BTN_7 to the “released” state.

That makes it possible to also provided 3 states for the Blink(1) mk2.
I use it as follows:

  • Most left: LED 1 soft green, LED 2 soft red
  • Middle: LED 1 soft green, LED 2 soft green
  • Right: LED 1 soft red, LED 2 soft green

My content for the BTN_8 file at /etc/rc.button :

#!/bin/sh

logger "Button: $BUTTON ; State: ${ACTION}";
if [ "${ACTION}" == "pressed" ]; then
        /data/local/blink1/blink1-tool --rgb=0,075,0 --led=1 > /dev/zero
        /data/local/blink1/blink1-tool --rgb=075,0,0 --led=2 > /dev/zero
else
        /data/local/blink1/blink1-tool --rgb=0,075,0 --led=1 > /dev/zero
        /data/local/blink1/blink1-tool --rgb=0,075,0 --led=2 > /dev/zero
fi

And my content for the BTN_7 file at /etc/rc.button :

#!/bin/sh

logger "Button: $BUTTON ; State: ${ACTION}";
if [ "${ACTION}" == "pressed" ]; then
        /data/local/blink1/blink1-tool --rgb=075,0,0 --led=1 > /dev/zero
        /data/local/blink1/blink1-tool --rgb=0,075,0 --led=2 > /dev/zero
else
        /data/local/blink1/blink1-tool --rgb=0,075,0 --led=1 > /dev/zero
        /data/local/blink1/blink1-tool --rgb=0,075,0 --led=2 > /dev/zero
fi

Of course you can edit both BTN_8 and BTN_7 to your own wishes. The scripts do also have effect when you connect the Blink(1) to an USB hub which is connected to the GL-AR150.

Thanks, This is really nice!

You have nice label for LEDs too.

Regarding the 3 state switch… To me it would have made more sense to have two 2-state switches (that would have given 4 states in total)

For most people it would make more sense to have two 2-state buttons / switches indeed, but there are a lot (mostly tiny) routers who have a 2- or 3-state switch to switch between functionalities like accesspoint, UTP-cable-router, 3G-modem-router, etc.

Jeroen, I think what many of us want is to move the switch and have the router copy a set of config files from a folder, say /etc/config/config1, /etc/config/config2 to the /etc/config folder and then reboot (restart?). This would allow me to store different configs (Router, AP, Router w/VPN1, Router w/VPN2, etc), flip the switch and go.

Can you help us non-programmers accomplish this?

A bit to difficult to me. It should be possible if I have a look at the script at /etc/rc.buttons/reset : that scripts executes a command which resets the router to the default settings.

To be able to config the router modus from router to accesspoint and vice versa is something on my wishlist and something I need to discover. :wink:

Additional photo’s of my GL-AR150. They are free to use, but please inform me when you use my photo’s.

Left side view without USB device:
photo IMG_2767_zpsxeof9sfm.jpg

Top view:
photo IMG_2769_zpsa6f5d2lr.jpg

Rear view:
photo IMG_2770_zps9yj7zsch.jpg

Left side view with ThingM Blink(1) mk2 and switch to left position:
photo IMG_2772_zpsxldfmula.jpg

Left side view with ThingM Blink(1) mk2 and switch at middle position:
photo IMG_2773_zpstwpfneuv.jpg

Left side view with ThingM Blink(1) mk2 and switch to right position:
photo IMG_2774_zpswq5wckcj.jpg

The last three photo’s do refer to my “Advanced example 2 scripts” a few posts above this one.

I shot a video with several LED effects. The Blink(1) mk2 is in it.
Watch the video here: Buttons, LED's, scripts, etc. Fun on GL iNET GL-AR150 - YouTube

What if we use a endless rotary encoder (that should work with 2 GPIO’s)

Then you could make an infinite number of choices (maybe to many) But lets say the encoder has 20 positions (18degree steps)
When the unit powers up then it always starts and it assumes that that is position 1. Could be a bit confusing without an indicator though. But it would enable a lot of functionality on merely 2 GPIO pins.

…This then could also be used as an old safe … 2 clicks left 5 right 3 left 10 right, then a Picasso pops from the wall and the safe opens. haha

I also see RangerZ’s point that an intuitive selection is important. Maybe combining rotary positions with LED’s

Position 1 = LED1 2 = LED 1+2 3 = LED 1+2+3 4 = LED 2 5 = LED 1+2 etc…
That in turn could be replaced by an RGB LED…

Every position a different colour…

RED = WiFi off
Green = AP mode
Blue = Repeater
Orange = TOR
Cyan = …
Magenta = …
Yellow =…
White = …
Off = no WAN

That already makes 9 options with 2 GPIO’s

After 10 seconds the LEDS start to report data. R=PHY0 RX G=PHY1 RX B=Wifi RX
That could be a bit too funky lightshow?

I don’t have any knowledge about PCB’s, transistors, resistors, ohms, etc. So that would be well… undoable for me. :stuck_out_tongue: But it would be funky yeah. :slight_smile:

I just managed it to let the reset button do different things depending on how long you press it.
Default it is less then 2 seconds to turn the WiFi off or on and more then 5 seconds to reset the GL-AR150 to factory defaults.

I temporarily disabled the “reset to factory default” lines to test more modes.
I managed my GL-AR150 to do the following:

  • Less then 2 seconds: still toggling between WiFi on / WiFi off
  • More then 5 seconds, but less then 10 seconds: toggle my Blink(1) mk2 LED on / off
  • More then 10 seconds: let my Blink(1) mk2 blink red 3 times

With this you would be able to switch between different modes, but counting the seconds exactly as the router does becomes very difficult and not practical.

The script for /etc/rc.button/reset:

#!/bin/sh

[ "${ACTION}" = "released" ] || exit 0

. /lib/functions.sh

logger "$BUTTON pressed for $SEEN seconds"

if [ "$SEEN" -lt 2 ]; then
        logger "< 2 sec: Wifi on / off";
        /usr/bin/wifionoff
elif [ "$SEEN" -gt 5 ]; then
        logger "> 5 sec";
        if [ "$SEEN" -lt 10 ]; then
                logger "< 10 sec";
                blink1resetstate=<code>cat /data/local/blink1/resetstate.conf</code>;
                logger "blink1resetstate: $blink1resetstate";
                if [[ "$blink1resetstate" == "on" ]]; then
                        logger "Blink(1) to off";
                        echo "off" > /data/local/blink1/resetstate.conf;
                        /data/local/blink1/blink1-tool --off;
                else
                        logger "Blink(1) to on";
                        echo "on" > /data/local/blink1/resetstate.conf;
                        /data/local/blink1/blink1-tool --on;
                fi
        else
                #echo "FACTORY RESET" > /dev/console
                #/usr/bin/flashleds &
                #jffs2reset -y && reboot &
                logger "> 10 sec: Blink(1) to blink red 3 times";
                /data/local/blink1/blink1-tool --red --blink=3;
        fi
fi

Not sure what /lib/functions.sh does in the original reset script so I did leave it in here.

Edit: the forum parser did a recursive replace for the code-tags. Please replace < code> and < /code> with backtics at the above script.

Lets see if we can hack this. :slight_smile:
Would be cool if the LED GPIO’s could have done PWM.
But the above should be not to hard to accomplish when we can add a rotary encoder to your code.
I want to give it a try, I’ll hook up a rotary encoder… After that I’ll need someone who can write the code. :slight_smile:
I bet you don’t live anywhere close to the Dutch mountains do you? (Limburg)
:slight_smile: