ESP8266 to control a range of devices.
SSD1306 & ESP8266 controller
This gadget takes a bit of soldering !
When finished, it connects via WiFi to local servers to control lights, switches or anything that can be controlled via a http request. The examples show it being used to operate a music system via pHp on a raspberry Pi. It could as easily be used to get data: readings from sensors or updates.
The unit employs a Wemos ESP8266 connected to a ST7789 LED display. These are very inexpensive and rewarding to work with.
Here’s the basic setup.

It doesn’t really need the regulator or capacitor unless you want to run it from a battery. In that case the MPC1702 would be suitable for a 9 volt battery or a rechargeable LiPo 3.7v.
Otherwise the ESP’s USB port can power it !
Three pushbuttons are connected respectively to D1, D2 and D5.
Each button is held “low” at Gnd with a 10k resistor (ignore the colours).
Pressing a button connects that IO port to +vcc (3.3v).
The ST7789 only needs 3.3 volts to vcc, GND to Gnd and the connections for sda and scl to the Wemos.
IMPORTANT:
The ST7789 display pinouts can be different to the above. Some of mine have vcc and Gnd transposed ! Don’t fry your chips.
/**
OLED interface for Remote Control
2 menus each with 3 options talking to php functions file = /remote/3Buttons.php
MAIN 1 Play
2 Next
3 Genre
Genre 1 Classic
2 Jazz
3 Cancel
*/
#include <Wire.h> // Only needed for Arduino 1.6.5 and earlier
#include "SSD1306Wire.h"
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#include <elapsedMillis.h>
elapsedMillis elapsedTime;
HTTPClient http;
bool playing = false;
bool firstLoad = true;
SSD1306Wire display(0x3c, 0, 2);
ESP8266WiFiMulti WiFiMulti;
String swVersion = __FILE__;
String hostURL = "http://xxx.xxx.xxx.xxx/3btns.php"; // Wherever is your pHp server
String currentmenu;
void setup() {
Serial.begin(115200);
Serial.println("[SETUP] WAIT ...\n");
delay(1000);
Serial.println(hostURL);
//Display setup
display.init();
display.flipScreenVertically();
display.setFont(ArialMT_Plain_10);
//Start screen
display.setFont(ArialMT_Plain_16);
display.drawString(0, 0, "Wifi");
display.drawString(0, 20, "Controller: " + hostURL.substring(15, 20));
display.drawString(0, 42, swVersion);
display.display();
delay(1000);
display.clear();
display.drawString(12, 20, "Loading...");
WiFiMulti.addAP("SSID", "PWD");
WiFiMulti.addAP("OTHER_SSID", "OTHER_PWD");
while (WiFiMulti.run() != WL_CONNECTED) {
Serial.println("WiFi not connected!");
display.drawString(12, 20, "Search for Host...");
delay(500);
}
Serial.println(swVersion);
}
void loop() {
if (firstLoad) {
mainMenu();
firstLoad = false;
}
///////////////// Button 1 Options /////////////
if (digitalRead(4) == 1) {
if (currentmenu == "mainMenu") {
if (!playing) {
Serial.println("Main -1 > Play");
getfunction(hostURL + "?action=RadioPlay");
playing = true;
} else {
Serial.println("Main -1 > Stop");
getfunction(hostURL + "?action=RadioStop");
playing = false;
}
mainMenu();
}
else if (currentmenu == "genreMenu") {
Serial.println("Genre -1 > Classic");
getfunction(hostURL + "?action=classic");
delay(1000);
genreMenu();
}
}
///////////////// Button 2 Options /////////////
if (digitalRead(5) == 1) {
if (currentmenu == "mainMenu") {
Serial.println("Main -2 > Next station");
getfunction(hostURL + "?action=RadioNext");
delay(1000);
mainMenu();
}
else if (currentmenu == "genreMenu") {
Serial.println("Genre -2 > Jazz");
getfunction(hostURL + "?action=jazz");
delay(1000);
genreMenu();
}
}
///////////////// Button 3 Options /////////////
if (digitalRead(14) == 1) {
if (currentmenu == "mainMenu") {
genreMenu();
delay(700);
}
else if (currentmenu == "genreMenu") {
Serial.println("Genre -3 > Cancel");
mainMenu();
delay(700);
}
}
}
//////// Menus //////
void mainMenu() {
currentmenu = "mainMenu";
Serial.println("mainMenu loaded");
display.clear();
display.drawString(0, 0, "Main Menu");
display.drawString(0, 16, "1 - Play / Stop");
display.drawString(0, 32, "2 - Next");
display.drawString(0, 48, "3 - Genre");
display.display();
}
void genreMenu() {
currentmenu = "genreMenu";
display.clear();
display.drawString(0, 0, "Radio lists");
display.drawString(0, 16, "1 - Classical ");
display.drawString(0, 32, "2 - Jazz");
display.drawString(0, 48, "3 - Cancel");
display.display();
}
////////////////////////////////
void getfunction(String url) {
display.clear();
if ((WiFiMulti.run() == WL_CONNECTED)) {
WiFiClient client;
HTTPClient http;
http.begin(client, url); //HTTP
Serial.println("[HTTP] GET...\n");
Serial.println(url);
// start connection and send HTTP header
int httpCode = http.GET();
// httpCode will be negative on error
if (httpCode > 0) {
if (httpCode == HTTP_CODE_OK) {
String payload = http.getString();
Serial.println(payload);
// Display the payload
if (payload != "") {
display.drawStringMaxWidth(0, 0, 128, payload);
} else {
display.setFont(ArialMT_Plain_16);
display.drawString(5, 22, "Searching...");
}
display.display();
}
} else {
Serial.println("[HTTP] GET... failed, error: \n");
}
http.end();
}
delay(500); //1 second delay?
}
Some pHp code that the remote can call:
<?php
/*
MAIN 1 Play
2 Next
3 Genre
Genre 1 Classic
2 Jazz
3 Cancel
*/
$action = $_GET['action'];
if ($action == "RadioStop") { // Button
exec('mpc stop');
echo "Stopped";
}
if ($action == "RadioPlay") { // Button
exec('mpc play');
echo "Playing";
}
if ($action == "RadioNext") { // Button
exec('mpc next');
echo "Next";
}
if ($action == "jazz") { // Button
exec('mpc clear');
exec('mpc load jazz');
exec('mpc play');
echo "Jazz \nStations loaded";
}
if ($action == "classic") { // Button
exec('mpc clear');
exec('mpc load classical');
exec('mpc play');
echo "Classic \nStations loaded";
}
?>
This code is pretty crude. It’s main purpose is to make it easier for beginners to get the screen working, and to see the relationships between software and the hardware.
Ideas for development:
- Get the mpc playing information back from pHp and scroll it onto the screen.
- Use the deepsleep function of the ESP to save battery life.
- Add other menu layers.