In our modern connected world, there is a wealth of information available to assist people with most mundane daily tasks. Many commuters rely on public transit, and need to be aware of the status of the status of their normal route to work while preparing to leave the house in the morning. Public transit schedules can be highly variable during rush hours when delays can be significant, and an informed commuter will want to be aware of the actual time they need to leave the house to streamline their morning routine. Accessing public transit data takes time and attention, which can both be in short supply in the morning. This project aims to create an engine that collects transit data, processes it, and then displays it in a glanceable way so that the commuter can be constantly updated on the status of their morning transit without expending time and effort.
What it does
This project interfaces with the SEPTA Regional Rail system, and uses the commuter’s specified commute time (to train station), desired route, and preferred time warning thresholds to update a display that tells the commuter how long they have until they should leave the house. An additional feature was also included to give the commuter a visible warning if rain is expected during the day. The intention is to use this software and hardware as an engine to create an enchanted object which unobtrusively resides in the user’s home and provides information without requiring any interaction or undue attention. The software engine is flexible enough to output data in many ways, so the engine can be adapted to different objects.
The Raspi, running the Raspbian OS and coded in Python, is the primary controller of the design. The Raspi’s Ethernet jack provides internet connectivity to make calls to the SEPTA and WeatherUnderground API’s, as well as keeping the system clock synced with internet time. For this particular system, data is output on a 16x2 LCD, as well as an RGB LED (for time remaining to leave) and blue LED (for rain forecast). The LCD is driven by the Raspi GPIO, and the LEDs are driven by the Arduino. Since the LCD is limited to 32 characters, display is done on two alternating pages that swap every 5 seconds.
The Arduino is connected to the Raspi via USB. A photoresistor circuit is connected to the Arduino to provide an auto-dimming function for the LEDs and LCD. Since the LEDs and the LCD backlight are driven by PWM outputs from the Arduino, the analog voltage from the photoresistor is used to scale the PWM outputs and thus dim or brighten the displays in response to ambient light.
The core “smart” algorithm uses data provided by the user in conjunction with the SEPTA data to output all of the relevant information for the morning commute. From the SEPTA module, the main algorithm gets the scheduled arrival time of the next train, as well as the delay of that train in minutes. The SEPTA module also uses this data, along with the current time, to compute the number of minutes until the next train arrives.
The weather module makes an API call to WeatherUnderground, and extracts the precipitation forecast for the day from the returned JSON object.
The master module makes regular calls to the SEPTA and weather modules to keep its data current. These calls are managed by a scheduling library. By default, SEPTA is polled every 20 seconds, and weather is polled every 30 minutes. The master module also contains the global variables that set the user’s preferences:
cTime: Commute time from home to station (minutes)
lowWarning: Threshold for low time remaining warning (minutes)
midWarning: Threshold for medium time remaining warning (minutes)
highWarning: Threshold for high time remaining warning (minutes)
When the SEPTA module returns the time until the next train, cTime is subtracted from it to give the time remaining until the user should leave home. Based on this remaining time, the RGB LED changes color (Green -> Yellow -> Orange -> Red -> Flashing Red) as the remaining time passes through the range of warning thresholds.
The LCD display always shows the time of the next train, its delay, and the time until the user should leave the house. The blue LED illuminates when rain is expected during the current day, and is otherwise off.
The Raspi is loaded with the latest distribution of the Raspbian OS, which is a fork of Debian. Python 3.4 and the Arduino IDE are installed. The scheduler and pyFirmata Python modules are required because of dependencies in the Python code.
The scheduler module handles the periodic tasks required to run the system – checking API’s, updating displays, auto-dimming. It is a convenient library with a simple interface to set update intervals for all of the functions one needs to call periodically. Before using scheduler, I was manually setting up threads for each task. Performance suffered as the number of threads grew, since the Pi B+ is a single-core system. The scheduler does a better job of handling system resources.
The pyFirmata module is what allows the Raspi to control the Arduino. Firmata is a standard library of serial communication protocols that allows software control of the Arduino hardware from remote code. The Arduino is loaded with standard Firmata code, and then can be controlled over USB serial communication by Python code using the pyFirmata module.
The Raspi is configured to boot to the desktop environment, and the engine begins functioning once master.py is opened and running in the Python IDE. User configuration (network connection, user variables) must be performed initially, but is saved for future use. Once the engine has been configured, the Raspi can be set up to boot to command line and automatically run master.py, so the device can be powered up and operated headless.
lcd.py contains the code to drive the LCD display. This module uses a technique known as “bit banging” to control the LCD via software without using a special hardware controller. Data is programmatically sent to the LCD by setting the states of the data pins, then toggling the Enable pin to write to the LCD. The LCD is connected in 4-bit mode to reduce wiring and GPIO usage. The 8 bits of data per character is sent by first sending the 4 most significant bits, then the 4 least significant bits. Data is written when the module starts to send initialization commands to the LCD, and every time the LCD display needs to be changed thereafter.
As mentioned previously, the SEPTA API module (json_fetch.py) begins by making a call to the API, which returns a JSON object. The module then decodes the object into a Python dictionary so that its fields may be accessed. The contents of the fields are strings, so functions had to be written to translate these strings in to more useable variables. Strings representing times are converted in to Python DateTime objects. Since DateTime does not have useful methods for comparing and adding/subtracting from times, these DateTime objects are translated into absolute time (measured in minutes from t = 0 at 12:00AM) when comparisons and arithmetic must be performed.
The required files for the engine are master.py, lcd.py, json_fetch.py (SEPTA API), and weather.py (WUnderground API). master.py imports and calls these other files as needed.
What's next for Commuter Helper
- Replace the Arduino with an ADC and PWM driver
- Place all components on a single PCB
- Integrate into an enchanted object