Introduction: LED Transit Clock - Never Miss the Bus Again!

About: We're Hover Labs! We build beautiful and interactive electronic tools for makers.

We're going to build a scrolling LED display for bus schedules. You may have seen one of these at your subway station or bus stop. You can build one for the home to help you know exactly how much time you have left -- especially if you tend to hit the snooze alarm in the morning a lot! And sometimes it's much easier to glance at a display than to pull out your phone and get distracted with instagram notifications :)

Step 1: Parts

What we need:

  • Particle Photon or Core: This dev-board is great for internet connected projects. Particle can be purchased here.
  • Beam LED display: It's an LED matrix that has 120 LEDs on-board and lets you display scrolling text, animations, or custom lighting effects. Beam can be purchased here. For this example, we'll use four Beams and daisy chain them together to create a long scrolling display.
  • Wires and a breadboard.

Step 2: Hookup Particle to Beam

On the backside of the Beam PCB, there are two female connectors on each end. Both connectors are identical and either one can be used to connect to the your host microcontroller.

  • HOST_V+: Connect to either 5V or 3.3V depending on your microcontroller. For example, if using the Arduino UNO, this pin should be tied to 5V since it is a 5V platform. The Particle Photon is a 3.3V platform, so this pin should be tied to 3.3V instead.
  • 3.3V: Connect to the 3.3V pin on your host microcontroller
  • GND: Connect to ground pin.
  • SYNC: No need to connect this pin to your microcontroller. It's used when chaining multiple Beams in a row.
  • RESET: Connect to any Digital pin on your microcontroller.
  • IRQ: Not used at the moment. Leave unconnected.
  • SCL: Connect to SCL pin on your microcontroller
  • SDA: Connect to SDA pin on your microcontroller.

Step 3: Add MOAR Beams

Now you could just use a single Beam to recreate this example. If you're using a single Beam, make sure the switch at the back is set to 'A' and you're done. But if you're using four Beams like us in this example, read on.

Simply connect up to 4 Beams using the headers provided as shown. Going from left to right (facing the front), make sure the slider switch is set to 'A' for the first Beam, then 'B' for the second Beam, and so on. So of you're using a total of four Beams, then the switch setting should be A, B, C, D from left to right (facing the front of Beam).

Step 4: Sign Up for an Open Transit API

For this example, we're using the Translink Open API that's available for Vancouver, British Columbia. Your city probably will probably have their own API - a popular one for the US is NextBus. Go to https://developer.translink.ca/ and sign up for a free account.

Step 5: Find the Bus Stop Number for Your Daily Route

The easiest way is to use Google Maps. In this example, we searched from Fish Counter to BC Place. When you display the details of the Bus Directions, the bus stop ID will show up underneath the Bus Number and Route. In this case, the bus stop ID is 59837.

Step 6: Register Your Webhook on Particle Cloud

In the Particle CLI, register your webhook with the following code:

particle webhook GET bus_info "http://api.translink.ca/rttiapi/v1/stops/59837/estimates?apikey=AAAAAAAAAAAAAAAAAA&count=1&routeNo=003"

where apikey='AAAAAAAAAAAAAAAAAA' should be replaced with they key you obtained after signing up for the API.

Webhooks listen for events from your devices. When you send a matching event, the hook will send a request to the transitlink API and retrieve all the details. For more info on webhooks, click here: Particle Webhooks.

Step 7: Get the Code

Download the library and navigate to the /examples/BeamTransit folder. The Beam library is available on Github, so make sure to copy it over to the Particle IDE.

Grab the full library here.

Step 8: Code

The following subscribe method registers a callback called gotBusData to our webhook.

Particle.subscribe("hook-response/bus_info", gotBusData, MY_DEVICES);

In the gotBusData callback function, we try to extract the relevant info and print the string to Beam.

void gotBusData(const char *name, const char *data) {

String str = String(data); String leaveStr = tryExtractString(str, "", ""); String destinationStr = tryExtractString(str, "", ""); String countdownStr = tryExtractString(str, "", ""); String routeStr = tryExtractString(str, "", "");

if (routeStr != NULL) {

Serial.println("Route No: " + routeStr);

} if (destinationStr != NULL) {

Serial.println("Going to: " + destinationStr);

}

if (countdownStr != NULL) {

Serial.println("Leaving in: " + countdownStr + String("Mins"));

} if (routeStr !=NULL){

String beamString =String(routeStr + " " + destinationStr + " " + countdownStr + " MINS"); beamString.toUpperCase(); Serial.println(beamString);

char buf[1024]; beamString.toCharArray(buf, 1024);

b.begin(); b.print(buf); b.setSpeed(5); b.play();

}

}

In the above function, the following lines are used to "print" the text to Beam:

b.begin();
b.print(buf); b.setSpeed(5); b.play();

Finally, we call the publish method in our main loop every 30 seconds. This is to ensure we don't reach our limit for the daily API calls allowed.

Particle.publish("bus_info");
delay(30000);

Step 9: You're All Set!

Hopefully at this point, your project is working as expecting. Just mount Beam to any surface using 3M double sided stickers -- we hid stuck ours to a media cabinet and hid the wires and Particle Photon behind the doors. Any easy way to make sure everything is working is to open up your serial monitor and check for debug messages being printed by the Beam library.