In this tutorial we're going to look at creating a touchscreen control and data system for the Raspberry Pi.
This touchscreen tutorial was written by Peter Juett and first appeared in The MagPi issue 69. Click here to download your free copy of The MagPi magazine issue 69.
Touchscreen Control and Data System
- 7-inch touchscreen and stand
- BMP180 – temperature / pressure (optional)
- GY30 – light (optional)
- DHT12 – temperature / humidity (optional)
- PIR – movement (optional)
From humble beginnings with the clock and local transport schedule, this system grew with needs and wants and includes the weather, temperature, humidity, stock prices, air quality, and even a family calendar!
There are several of these great touchscreens around our home that show everyday information, control the surroundings, and take care of some repetitive tasks.
Of course, there are apps on our phones that do some of this, but there is nothing quite like having data at a glance and control at your fingertips; and all completely adaptable and easily extendable.
The system is composed of lightweight message-enabled software modules which run independently on your main touchscreen Raspberry Pi, or other Pi boards around the home. The modules communicate with each other by exchanging Mosquitto messages and responding accordingly. In fact, each of the screen labels shows data from its associated message, and each of the buttons and events transmits a message or set of messages. We can configure them to our heart’s desire. Here’s some of what we have set up:
- Time and date
- Air quality (WHO)
- Temperature and humidity (inside and out)
- The weather
- Stock prices and exchange rates
- Google calendar
- Detected motion
- Lights over the Hue system
- Mains sockets using TP-Link Smart Plugs
- Day, time
- Temperature, humidity
- Light level
It also speaks, albeit with inspirational quotes and the time mainly, but also the occasional polite message.
The system is open and extendable and, perhaps a bit of a cliché, but it’s only really limited by your imagination.
Critically, for privacy, none of your data or activities is sent anywhere on the internet, with just some simple calls to APIs for weather, air quality, etc. It’s completely under your control. The open-source nature of the system gives you complete transparency – no black boxes here.
Nor is there any machine learning or artificial intelligence, nor voice control. However, with the flexibility here, this is all possible should you wish to extend it to include these features.
Install the Touchscreen Control system
To start setting up the system, you need to install the Kivy Pie build – this is an image of Raspbian Jessie with Kivy already installed and ready to go. Kivy is a cross-platform library that allows you to program the touchscreen to your heart’s content!
Next, install the Mosquitto MQTT libraries for the communications:
sudo wget http://repo.mosquitto.org/debian/mosquitto-jessie.list
sudo apt-get install mosquitto
sudo apt-get install mosquitto-clients -y
sudo pip install --upgrade pip
sudo pip install paho-mqtt
Install SQLite3 database libraries and set up the database to store settings, message profiles, and ‘macros’:
sudo apt-get install sqlite3
You’ll then need to install the Apache web server and PHP. Apache serves up the webpages for remote control and configuration. PHP is used to drive interactive webpages which store information to the database and transmit commands using Mosquitto:
sudo apt-get install apache2 -y
sudo apt-get install libapache2-mod-php5 -y
sudo apt-get install php5-sqlite
Install the source code modules from the GitHub repo (the Python modules, required libraries, webpages, and subfolders). You can find more details in the README.md file on GitHub.
How to customise it
Now we can customise the screens to our needs. We do this from the webpages, selecting which messages to associate with which screen labels, which text for the buttons, and whether they are toggle (two-state buttons – for lights and such) or simple buttons (single-state for alarm off and such).
Once we have done this, we can then assign messages to the buttons and events. Make sure not to forget to go to the configuration screen and set up your own custom settings for emails and IP address for our Mosquitto communications along with some other goodies.
In a browser, go to the ‘Display and Buttons’:
For each of the labels, select the message that you want to display. For the buttons, enter the text you want to appear on each button and the type of button (single/two-state) and save.
Then go to the ‘Events and Actions’:
For each event, enter a name, then which days it should be active (we can enter weekdays, weekends, everyday, Mondays, etc.), and also a time.
Now, for the actions, assign the list of messages to trigger. This is how we set up the button’s scheduled events and what to trigger on high/low sensor events.
Next, go to ‘Configuration’:
Under Mosquitto communications, set the Broker address to match your Raspberry Pi’s IP address, and make sure the port matches your setup (in reality we can probably leave this port as set).
Resist the temptation to change the name, for the moment at least (this is actually used as the host name in the Mosquitto messages).
Next, we should check that the launcher.py Python script suits our requirements. On the Raspberry Pi, navigate to /home/sysop/Glance and open the launcher.py file:
sudo nano launcher.py
The launcher.py script simply spawns a thread for each of the modules listed in the ‘bedroomtouch’ section.
This list of modules for each Raspberry Pi is a great way to keep things organised (especially with a distributed system of several Pi devices).
How to run the Touchscreen Control and Data System
We can run the touchscreen and sensor modules using launcher.py. Go to /home/sysop/Glance and run:
sudo python launcher.py &
The TouchScreen.py script works by using run_program at the bottom of the script, which creates the main application class, MyApp().
MyApp is responsible for creating the screen class, MainScreen, and also holds application-level variables and contains the Mosquitto code for communications. MainScreen sets up the labels, buttons and icons, and callback methods for updating the screen.
Data and control with HelloWorld.py
As mentioned previously, the system is scalable, flexible, and extendable with the modules following a standard template. Each module has a specific purpose, whether gathering data from the internet, the sensors, or controlling something cool! Using HelloWorld.py as an example, you can then easily adapt it for other data sources, actions, and interfacing with other systems.
First, the object is initialised, and creates the Mosquitto client, assigns the callback methods, and connects to the host (using values stored in the database).
self.start_mosquitto() self.mos_client.on_message = self.on_message self.mos_client.connect(self._db.get_value("mosbrokeraddress"), int(self._db.get_value("mosbrokerport")), 60)The ‘on-message’ callback method we assigned earlier will receive messages and is responsible for processing them. In this example, we check the host and the message to be sure it is the message that we are waiting for, and then just store the received value (extracted from the third part of the message)
def on_message(self, mosclient, userdata, msg): if messageparts == self._db.get_value("name"): if messageparts == "SetHelloWorld": self.set_data(messageparts)We use the ‘Publish’ loop in this example to simply to send the data onto the Mosquitto network, periodically. Other modules will periodically poll the internet for data and share on the Mosquitto network, or trigger a send on change of GPIO state, etc.
while(1): self.mos_client.publish(self._db.get_value("mostopic"), self._db.get_value("name") + "/HelloWorld/" + self.get_data()) time.sleep(SLEP_TIME)
As we saw earlier, we can remotely control the system from a smartphone! This works thanks to the Apache web server, which serves up the database-driven webpages, displaying the buttons that we configured earlier.
When we click one of these buttons, Mosquitto messages are sent from the PHP behind the control webpage according to the command sequence we configured. These messages are then intercepted by the relevant Python module which, in turn, triggers the code to be executed perform the action; e.g. switch the I/O on the Raspberry Pi.
All in the database
The database contains the settings and message definitions for the system. Most of the settings are configurable from the webpages; e.g. Mosquitto broker IP address.
The database also holds configurations for the screen layout, messages associated with screen labels and buttons, message sequences (i.e. the ‘macros’), and event schedules
There are two tables, ‘settings’ and ‘messages’, intentionally kept generic and simple:
CREATE TABLE settings( id INTEGER PRIMARY KEY AUTOINCREMENT , setting TEXT NOT NULL, value TEXT NOT NULL ); sqlite> .schema messages CREATE TABLE messages( id INTEGER PRIMARY KEY AUTOINCREMENT , host TEXT NOT NULL, name TEXT NOT NULL, value TEXT NULL, description TEXT NULL, display TEXT NULL, -- '1' – this message is suitable for screen display action TEXT NULL – '1' – this message is for triggering an action. );
One point to note is that all the messages used in the system are listed in the messages table. The host must match the host name of the Raspberry Pi to which they are associated.
The messages table also provides a more human-readable description. This is used in the message selection from the webpages.
From the Python code, each of the modules loads and reads the database:
self._db = DB.DB() self._db.load_settings()
Then refer to the settings with something like
self.db.getvalue("mosbrokeraddress") and refer to a message like self.db.get_message("lightsensor").
The wonders of I2C
It would be remiss of us not to include what you can do in terms of sensors. We put together a collection of some of our favourite sensors, a buzzer, a PIR motion sensor, and created a PCB to connect them all, for convenience mainly.
The I2C bus is neat, just requiring two connections for communications (plus power) and bundling these sensors up with motion detection and the buzzer. Using something like a PCF8574 I2C to I/O chip, you can interface the buzzer and PIR to the I2C, and expand the I/O at the same time. Alternatively, you can connect them directly to the GPIO using the the
We hope you find this system as useful and fun as we did and join the party to continue to evolve it, should you wish. These touchscreens are great little units and with the Raspberry Pi, internet, sensors, and data, the possibilities are endless.