Blinken’ Builtins¶

A post, Can we control the on-board leds, on the Raspberry Pi forums caught my eye: use the onboard LEDs to communicate the assigned IP address of the Pi! It’s often nice to run a Pi headless and log in via ssh but you may not know the IP address assigned by the router - especially if you work in a space where alot of wifi machines come and go.

I chose to use a simple system to blink out the last component of the IP address, done once for each decimal digit (3 times). On the Pi Zero, with only one green light, it blinks once to start a digit, pauses, then blinks the digit (0 to 9 blinks); on the Pi 3, it holds on the green light, blinking the digit out in red, then green goes off. After blinking all 3 digits, it waits 5 seconds, then does it again, repeating for a few minutes (I find it entertaining). The Python script needs to be run as root to access the LED devices in the filesystem (which is already the case for code run from rc.local, where I launch the script from after a sleep 30 to let the sytem initialize the network).

If the blinking is hard to count out, you can usually confirm the address with a scan, such as using nmap as described here.

I got wifi setup on my OS install for both home and my local Makerspace by attaching monitor, keyboard and mouse at each location, booting into the desktop and selecting the network and entering the password, which Raspian duly remembers (and I enabled ssh with raspi-config at the same time). See the links to running the Pi headless via an alternative to entering the wifi info with the desktop (I haven’t tried this method). Feel free to recommend a more up to date tutorial on getting started headless (this one is from a prior OS release).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#!/usr/bin/env python3
# -*- mode: Python; -*-

import subprocess, re, sys, time, os


ipaddr = subprocess.run(["/bin/hostname","-I"], stdout=subprocess.PIPE)
addrs  = re.findall(r'(\d+\.\d+\.\d+\.\d+)', ipaddr.stdout.decode('utf-8'))
for addr in addrs:
  fields = re.match(r'(\d+)\.(\d+)\.(\d+)\.(\d+)', addr)
  a = fields.group(1)
  b = fields.group(2)
  c = fields.group(3)
  d = fields.group(4)
  host = int(d)

# When I was working on two led support, I first tried to identify the model.
# Turned out led1 doesn't exist on pi zero, so the below test is easier.
#
# with open("/sys/firmware/devicetree/base/model") as f: pi = f.read()
# fields = re.match(r'Raspberry Pi (\w+) (?:W )?(?:Model (.) \.*)?Rev ([\d\.]+)', pi)
# print(fields)
# if fields != None:
#   a = fields.group(1)
#   b = fields.group(2)
#   c = fields.group(3)
#   if a == "Zero":
#     piversion = 0
#   else:
#     piversion = int(a)

twoleds = os.path.exists("/sys/class/leds/led1/trigger")

with open("/sys/class/leds/led0/trigger", "w") as f:
  f.write("none")

if twoleds:
  with open("/sys/class/leds/led1/trigger", "w") as f:
    f.write("none")

# On my Pi3, the red led is led1 and is brighter.
# On my Pi0, there is only one led and led0 refers to it
def brightled( state ):
  if twoleds:
    with open("/sys/class/leds/led1/brightness", "w") as f:
      f.write(str(state))
  else:
    with open("/sys/class/leds/led0/brightness", "w") as f:
      f.write(str(state))

def darkled( state ):
  if twoleds:
    with open("/sys/class/leds/led0/brightness", "w") as f:
      f.write(str(state))
  # No darkled on Zero

def blinky(n):
  if not twoleds:
    brightled(1)
    time.sleep(0.2)
    brightled(0)
    time.sleep(1)
  else:
    darkled(1)
    time.sleep(0.2)

  for i in range(n):
    brightled(1)
    time.sleep(0.2)
    brightled(0)
    time.sleep(0.2)

  darkled(0)

brightled(0)
darkled(0)
  
for k in range(50):
  blinky(int(host / 100))
  time.sleep(2)
  blinky(int(host / 10) % 10)  
  time.sleep(2)
  blinky(host % 10)  
  time.sleep(5)

# Restore default function
with open("/sys/class/leds/led0/trigger", "w") as f:
  f.write("mmc0")

if twoleds:
  with open("/sys/class/leds/led1/trigger", "w") as f:
    f.write("input")