Making a LED powered METAR map for your wall

While waiting for my airplane kit to arrive I got inspired to make a small crafty project after seeing someone post about it on reddit and showing it to my girlfriend who said we can make one together.

We did a bit more research and because I’ve made some projects with Raspberry Pi before, we decided to go that route. Here’s a picture of the finished project:

METAR Map

Supplies needed

Here’s a list of the things you will need:

Plotting your chart area

Unless you want to make your own frame, the dimensions of your project will be limited by what size shadow box frame you can easily purchase. The simplest size is 16 x 20 inch frames, so I used that as a guide of the area to size out.
This worked out great for the Puget Sound Area to cover the airports from Bellingham in the north to Olympia in the South and Hoquiam and Quillayute on the coast using my old expired sectional chart from my private pilot training.

Plotting out the area and using some wooden meeples to highlight the airports

To light up the airports with the flight category, we’re using the data reported from www.aviationweather.gov so we checked the airports we want to highlight via the API to ensure they are reporting data.

After we were satisfied with the area, we created a 16 x 20 inch transparent sheet by cutting up some sheet protectors and taping them together and then overlaying them onto the area and marking down the airports so we could transfer the locations onto the back of foam board for the LEDs to go into.

Transparent sheet with airport locations

Software and Wiring

Since the project is pretty simple, we used a Raspberry Pi Zero W, which has WIFI built in and can run the code to download the weather data using the above mentioned web API to pull the weather for all the airports in one go.

For the code, I’ve started by looking at some of the other projects people have done and the NeoPixel documentation for python.

We wrote an updated and optimized script and published it on Github, along with the instructions to set it up.

We ended up with a total of 22 lit up LEDs, so we wired it directly to the Raspberry as shown here. Before attaching the wires to the Raspberry headers, I soldered the header strip onto the Raspberry so it creates a good connection.

Raspberry Pi LED wiring (image courtesy of adafruit - https://learn.adafruit.com/assets/63929)

Here’s a picture of the wiring while I was testing out the code. I was using a breadboard while doing this since it made it easier to disconnect the wires during testing.

LED wiring in action

To finalize the order of the LEDs you will need to arrange them on the board and make changes to the airport list accordingly.

Another important note is to test the LEDs for all the colors in case there is a bad one, in our case the 5th LED couldn’t show RED light, so we skipped over that one.
The easiest way to test this once you’ve installed the software is to just manually control the colors of the LEDs by opening the python3 console:

sudo python3

Then entering the following to light up 30 LEDs at once (if you are using more, just replace the number below):

import board
import neopixel
pixels = neopixel.NeoPixel(board.D18, 30)
pixels.fill((0,255,0))

This will light up all LEDs in red, if you see a bad one, mark it with some tape so you don’t use it for an airport.
Repeat the step for green:

pixels.fill((255,0,0))

Blue:

pixels.fill((0,0,255))

Purple:

pixels.fill((0,125,125))

Once you’re done you can turn off the lights by typing

pixels.deinit()

and then pressing CTRL+Z to exit the python console.

Board Assembly

Once we figured out the software portion and what airports to light up it was time to drill some holes in the foam board for the LEDs to go into using the template made earlier.

Foam board holes drilled

After we had the holes made we tested it by temporarily affixing the sectional chart onto the board and sticking some of the LEDs into the holes and turning on the project, but we found that the LEDs created a lot of light and the LEDs were sticking out a bit, so we decided to double up the foam board, which made the light more defined and allowed the sectional chart to sit flush on the board, so we glued together the two foam boards.

We did a second quick test and pinned the sectional chart onto the board for the first complete light up test:

First light up test

After that it was time put everything together. we made the final cuts to the chart to fit perfectly onto the board and align with the lights and then glued it to the board using a glue stick.

Then it was time to glue the LEDs onto the board, as you can see from the picture below, some of the LEDs are not lit, one of them because the red light didn’t work and some others because the gap between two airports was too much and it was easier to just skip the light than to cut the lights and having to solder in some wires. at the end we just cut off the remaining LEDs we didn’t need (disconnect the Raspberry power when you do this).

Lit LEDs back of board

Once that was all done and good it was time to assemble it all into the frame – we drilled a hole into the bottom of the frame for the power cable to go through.

Raspberry assembly in frame

And here is the final picture of the completed project:

METAR Map

I hope this was helpful for you.

39 thoughts on “Making a LED powered METAR map for your wall

  1. Erick

    This looks great! Question, what are my options for dimmer lights? Something that glows less. Are they certain specifics I would need to meet? Can you recommend something? Cheers!

    Reply
    1. Dave

      Change the color to less intence

      COLOR_VFR= (67,0,0) # Green
      COLOR_MVFR= (0,0,67) # Blue
      COLOR_IFR= (0,67,0) # Red
      COLOR_LIFR= (0,34,34) # Magenta
      COLOR_CLEAR= (0,0,0)

      Thats 25% bright
      you could go (2,0,0) etc for really dim

      D

      Reply
  2. Bob Berlyn

    Looks like a great project and I would like to build. I am an analog electronics guy and pilot but not a programmer. I have discovered that PYTHON is a language but thats really all I know. Does the pi run PYTHON using the operating system (Rasberian) or do I have to get PYTHON software or just load the scrips you wrote into the pi and go.

    Thanks

    Reply
    1. Philip Rueker Post author

      You just need to load the scripts into the Raspberry file system, “install python” by running the scripts that I’ve documented here and and modify the airports file to have the name of the airports that are relevant to you.

      Reply
  3. Ulrich Pommer

    Hey Philip,
    First of all, this is a great project. I’m from Germany and would like to take German airports. Is that possible? Do I have to change only the names in the file (airports)? Sorry for my bad english:-(

    greetings Uli

    Reply
    1. Philip Rueker Post author

      Yes the web service I’m using does also support many international airports, you just need to use the 4 digit ICAO codes like EDDF for Frankfurt and EDDM for Munich.

      Reply
  4. Rick Sayles

    Philip,
    I saw a MetarMap at SUNnFUN last year and then seeing your project you inspired me to give it a go.

    Thanks for your excellent documentation. Made it work for a non-programmer. It all works now, but it doesn’t update, until you rerun the program, and the pi doesn’t automatically run the program. I have it now where the pi is connected to monitor so I can run the program. I assume you have automated both of those operations?

    Thanks!

    Reply
    1. Philip Rueker Post author

      Hi,

      Yes you can automate this using crontab.
      As I mention on the Github, here’s how you do it:

      If you’d like to have the script refresh in regular intervals, use crontab and set the appropriate interval. For an example you can refer to the crontab file in the GitHub repo (make sure you grant the file execute permissions beforehand). To edit your crontab type: crontab -e, after you are done with the edits, exit out by pressing ctrl+x and confirm the write operation
      The sample crontab will run the script every 5 minutes (the */5) between the hours of 7 to 21, which includes the 21 hour, so it means it will run until 21:55
      Then at 22:05 it will run the lightsoff.sh script, which will turn all the lights off

      Reply
  5. Sameer

    This is great! I’m working on this project now as well. I ran into a snag with the level shifter. Everything works great on the breadboard, but when I connect jumper wires to the level shifter directly the LEDs go rainbow colors instead of red or green etc. I just purchased some veroboard to solder the level shifter and create connections without jumper wires.

    How many LEDs are you able to light up directly off the 5v pin without risking the pi? Thx!

    Reply
    1. Philip Rueker Post author

      I’m running 22 active LEDs directly off the Pi 5v without issues.

      Reply
  6. Chris

    Using your command sequence for checking all the LED’s:
    import board
    import neopixel
    pixels = neopixel.NeoPixel(board.D18, 30)
    pixels.fill((0,255,0))
    I am presented with Attribute Error ‘neopixel’ has no attribute ‘Neopixel’
    Any solutions for this? I am not a code literate.

    Reply
    1. Philip Rueker Post author

      Make sure that prior to this you have successfully installed the neopixel library by running the following command as listed in the github instructions:
      sudo pip3 install rpi_ws281x adafruit-circuitpython-neopixel
      After that command, you open python3 by entering:
      sudo python3
      and then enter the commands and it should work:
      Testing pixels screenshot

      Reply
    1. Bob

      I changed the corntab file by just adding

      */5 7-21 * * * /home/pi/refresh.sh
      05 22 * * * /home/pi/lightsoff.sh

      I guess I am not understanding root permission. I did run sudo chmod +x corntab

      Thanks for the project just wish I knew more about pi but working on it.

      Reply
      1. Philip Rueker Post author

        Ah, you need to grant the files that are being executed inside the crontab execute permissions, so you should run the chmod command for the refresh.sh and the lightsoff.sh file.

        After you have done that you can check that you’ve done it correctly by running "ls -al" and you should see “x” for the files 3 times, similar to this:
        executepermissions

        Also just to be clear, you have to edit your system crontab by typing "crontab -e", not by copying my sample file into the folder.

        Reply
  7. Bob

    looks like it is working, I was doing “sudo nano crontab -e”. Thanks for your help and thanks for the program. I had a thought and it is way above my knowledge with pi. I was thinking could you add a screen somewhere on a chart with 5/10 day forecast or scrolling local weather. Again thanks now I need to start on my frame.

    Reply
  8. Ron Heberlein

    Thanks for the instructions! I was able to get metar.py running manually, but I can’t get it to start on power-up.
    Here’s what the statrup.log shows:

    Thu 07 May 2020 06:46:43 AM PDT
    /home/pi/startup.sh: 2: /home/pi/startup.sh: echo
    : not found
    Running metar.py
    /home/pi/startup.sh: 4: /home/pi/startup.sh:
    : not found
    /usr/bin/python3: can’t open file ‘/home/pi/metar.py
    ‘: [Errno 2] No such file or directory

    And here is my ls -al:
    pi@raspberrypi:~ $ ls -al
    total 132
    drwxr-xr-x 17 pi pi 4096 May 7 06:46 .
    drwxr-xr-x 3 root root 4096 Feb 13 07:55 ..
    -rw-r–r– 1 pi pi 244 May 6 06:50 airports
    -rw——- 1 pi pi 905 May 7 06:46 .bash_history
    -rw-r–r– 1 pi pi 220 Feb 13 07:55 .bash_logout
    -rw-r–r– 1 pi pi 3523 Feb 13 07:55 .bashrc
    drwxr-xr-x 7 pi pi 4096 May 5 22:11 .cache
    drwx—— 11 pi pi 4096 May 6 07:20 .config
    drwxr-xr-x 2 pi pi 4096 Feb 13 08:17 Desktop
    drwxr-xr-x 2 pi pi 4096 Feb 13 08:17 Documents
    drwxr-xr-x 2 pi pi 4096 May 6 20:42 Downloads
    drwx—— 3 pi pi 4096 Feb 13 08:17 .gnupg
    -rwxr-xr-x 1 pi pi 53 Apr 19 14:48 lightsoff.sh
    drwxr-xr-x 3 pi pi 4096 Feb 13 08:03 .local
    drwxr-xr-x 2 pi pi 4096 Feb 13 08:03 MagPi
    drwxr-xr-x 3 pi pi 4096 May 7 06:46 METARMAP
    -rwxr-xr-x 1 pi pi 2568 May 5 22:51 metar.py
    drwxr-xr-x 2 pi pi 4096 Feb 13 08:17 Music
    drwxr-xr-x 2 pi pi 4096 Feb 13 08:17 Pictures
    -rw-r–r– 1 pi pi 108 Apr 19 14:48 pixelsoff.py
    drwx—— 3 pi pi 4096 May 5 21:41 .pki
    -rw-r–r– 1 pi pi 807 Feb 13 07:55 .profile
    drwxr-xr-x 2 pi pi 4096 Feb 13 08:17 Public
    -rwxr-xr-x 1 pi pi 48 Apr 19 14:48 refresh.sh
    -rw-r–r– 1 pi pi 74 May 7 06:44 .selected_editor
    -rw-r–r– 1 root root 264 May 7 06:46 startup.log
    -rwxr-xr-x 1 pi pi 107 Apr 19 14:48 startup.sh
    -rwxr-xr-x 1 pi pi 129 May 6 20:48 startup.sh_test
    drwxr-xr-x 2 pi pi 4096 Feb 13 08:17 Templates
    drwxr-xr-x 2 pi pi 4096 Feb 13 08:17 Videos
    -rw——- 1 pi pi 56 May 7 06:46 .Xauthority
    -rw——- 1 pi pi 2425 May 7 06:47 .xsession-errors
    -rw——- 1 pi pi 2425 May 7 06:35 .xsession-errors.old

    Any thoughts as to what is going on?
    Thanks! Ron

    Reply
    1. Philip Rueker Post author

      Hi,
      I just updated the instructions on the github and removed the step about setting up rc.local since it seems to cause strange issues with startup.
      I found it easier to just rely on the crontab instead to automatically run the script regularly, so I suggest you just forget the rc.local startup and instead use the crontab.

      Reply
      1. Ron Heberlein

        That did it. It took a minute to start after a restart, but it came on automatically!
        50 lights setup, now I have to get the sectionals. Thanks for the help!

        Reply
  9. Steve Peck

    there is no startup.sh file in github now… and can you please update the instructions about what you’re saying about cron?

    Reply
    1. Philip Rueker Post author

      Correct, I removed the startup.sh file, since for the crontab I just used refresh.sh (which basically does the same).
      The instructions about crontab have been on the Github all this time:

      To have the script start up automatically and refresh in regular intervals, use crontab and set the appropriate interval. For an example you can refer to the crontab file in the GitHub repo (make sure you grant the file execute permissions beforehand to the refresh.sh and lightsoff.sh file). To edit your crontab type: crontab -e, after you are done with the edits, exit out by pressing ctrl+x and confirm the write operation
      The sample crontab will run the script every 5 minutes (the */5) between the hours of 7 to 21, which includes the 21 hour, so it means it will run until 21:55
      Then at 22:05 it will run the lightsoff.sh script, which will turn all the lights off

      Reply
  10. Ron Heberlein

    Phillip,

    Have you tried to incorporate blinking lights into the program?
    I’d like to be able to have a light blink if the wind speed (or gust) exceeds a certain value. I’ve been searching on the internet for this and haven’t seen anything that seemed like it would plug into your code. That being said I’m not a programmer…

    Reply
    1. Philip Rueker Post author

      I felt inspired by your question and since I am a programmer, I expanded the script to support blinking for windy conditions.

      I just uploaded the updated version of the script that now supports animation for wind conditions, if you go to the github, please use the updated refresh.sh, metar.py and lightsoff.sh with the latest version I just uploaded (it makes sure that any currently running scripts will be closed when the next one runs).

      I also added some information to the Readme instructions about the new parameters that I’ve added to the metar.py script that you can adjust as needed.

      Reply
      1. Ron Heberlein

        How awesome!!!
        I found one error in your code. On line 22 and 23, both variables were named “COLOR_IFR_FADE”. I updated line 22 to remove the “_FADE” and everything worked perfectly!

        Reply
  11. Jordan

    Hi Philip,

    Thanks so much for the tutorial, build a huge map to go in my work area and everyone loves it. Ive seen now the commercial Maps have the ability to flash white when there is lightning reported in the area? Is there any way we could add a line in the script to run this kind of like how you ran the wind one? That would be super cool!

    Reply
    1. Philip Rueker Post author

      Hey,
      Sure, I just added this functionality in the script, it will flash to white to represent lightning in the vicinity as reported by that airports METAR.
      You can get the latest version with the updated changes from the github.

      Reply
  12. Kit

    Hi Philip.

    I have an issue where only the first led lights up. I have a strand of 50, the ones you suggested. I can issue “pixels = neopixel.NeoPixel(board.D18, 30)” or use 20, or 10, or 50, I still only get the first led to light up after issuing “pixels.fill()”. Do you think I have a bad strand of leds?

    Reply
    1. Philip Rueker Post author

      I think there’s two possibilities.
      1) Yes maybe the strand is bad
      2) Did you make sure that you connect the correct ends to the Raspberry? On the LEDs you will find a small arrow on one side like this, this is the side that you have to connect the wires to the Raspberry. direction on LEDs.

      Reply
      1. Kit

        I did connect the pi to the input end of the led strand. After some testing, the strand is defective. Will give it a try again when the new strand arrives! Thanks for the help.

        Reply
  13. Chuck

    I just finished making one of these, i love it! thanks for putting together this guide, and the upkeep with the code!

    Reply
  14. Ron Heberlein

    I wanted to see if anyone else was having issues with the map not refreshing?
    For about the past week, I have to turn the Pi off and then back on to get the map to refresh with the latest weather data. It then will refresh for a while (maybe a few hours), and then gets stuck again.

    Is there a way to plug in a monitor and see how the program is running (other than manually starting the program)?

    Reply
    1. Philip Rueker Post author

      Maybe your WIFI connection is weak and it fails at some point randomly? I’m not quite sure how the raspberry PI handles that.

      In any case, you could write to a logfile every time the script gets executed.
      If you just want to see if the script get’s started at all you could add something like this to the start of the refresh.sh script:
      echo $(date) - running metar script >> myfile.txt
      This will write the current date/time into a new text file called myfile.txt

      And if you want to just print the entire output of every time the script gets executed automatically, you can modify your crontab to something like this and it will print the entire output that would usually be seen on the console:
      * 7-21 * * * /home/pi/refresh.sh > /home/pi/outputlog.log 2>&1
      This will print everything that happens in the script into a new file called outputlog.log

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.