Things used in this project

Hardware components:
D1 mini
Everything ESP Wemos D1 Mini
Great module with ESP8266. Features integrated 3V3 regulator, important PU/PD resistors, CH340G USB-UART and software jump to bootloader from Arduino IDE.
USB 2.0 Motherboard adapter cable
Needed if you want to power everything from your motherboard USB header, otherwise not crucial.
Adafruit industries ada239 image 75px
Solderless Breadboard Full Size
You could also fit it on a half-size (30 rows) breadboard without much effort.
Maxim Integrated DS18B20 1-Wire temperature sensor
Just as an additional feature, not needed for basic functionality. DS1
BC337 NPN transistor
Any generic NPN should do, but please check pinout before connecting (CBE used here). Q1, Q2.
09590 01
LED (generic)
Just for testing, any LED will do, I used green and red. LED1, LED2.
Mfr 25fbf52 2k21 sml
Resistor 2.21k ohm
2k2, exact value not that crucial for any resistor in this project. R1, R3, R8.
Resistor 6.81k ohm
6k8. R2, R5, R9, R10.
Mfr 25fbf52 475r sml
Resistor 475 ohm
470R. R4, R6.
Mfr 25fbf52 22k1 sml
Resistor 22.1k ohm
22k. R7.
11026 02
Jumper wires (generic)
Or you could use 0.6 mm single core wire, I got mine from ebay.
266 04
Female/Female Jumper Wires
You need 2x2 wires to connect to your PC's power switch and LED pins.
Te connectivity 4 103741 0 image 75px
Male Header 40 Position 1 Row (0.1")
You need 4x2 pins, or you could just use jumper wires. J1, J2, J3, J4.
Software apps and online services:
Ide web
Arduino IDE
Android MQTT Dash


EspPcSwitch schematic
Esppcsw diagram schem raliamfqlh
EspPcSwitch breadboard circuit
Esppcsw diagram bb 33b0li1e7j


EspPcSwitch codeArduino
Copy to Arduino IDE and upload, don't forget to insert your own credentials for WiFi and CloudMQTT.
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// Wemos D1 mini pins compared to ESP GPIO
// source:
// Wemos|ESP
// TX   TXD
// RX   RXD
// A0   A0
// D0   GPIO16, doesn't have interrupt/pwm
// D1   GPIO5/SCL
// D2   GPIO4/SDA
// D3   GPIO0, 10k PU, ESP special (set to 0 during reset to enter bootloader)
// D4   GPIO2, 10k PU, LED, ESP special (should be high during reset)
// D5   GPIO14/SCK
// D6   GPIO12/MISO
// D7   GPIO13/MOSI
// D8   GPIO15/SS, 10k PD, ESP special (should be low during reset)
// G    GND
// 5V   -
// 3V3  3.3V

// note: using ESP GPIO numbers rather than Wemos for easier portability to other ESP versions
#define GPIO_OUT_SW     12  // D6 // used as output, for toggling transistor that turns on/off the pc
#define GPIO_IN_STATUS  14  // D5 // used as input for PC on/off status
#define GPIO_ONEWIRE    0   // D3 // 1wire in/out pin

#define OUT_STATE_ACTIVE    1   // use define so it's simple to change if signal should be active high or low (NPN or PNP BJT)

#define OUT_TOGGLE_DURATION_MS  300 // how long to keep the pwr pin (GPIO_OUT_SW) active when triggered

#define IN_STATUS_INVERTED  true // true if reading 1 on input actually means the PC is off

#define WIFI_SSID   "Your SSID here"
#define WIFI_PASS   "Your password here"

#define CLOUDMQTT_PORT   Your port here
#define CLOUDMQTT_USER   "Your username here"
#define CLOUDMQTT_PASS   "Your password here"

#define MQTT_CLIENT_ID   "EspPcSwitch"  // note: if you have multiple devices, assign them different ID's
#define MQTT_USE_RETAIN   false         // set to true if you want last msg for all topics retained on server, so you get it automatically on client connect

#define TOPIC_OUT_CONN        "esp/pcsw/conn"
#define TOPIC_OUT_PC_STATUS   "esp/pcsw/status"
#define TOPIC_OUT_TEMP        "esp/pcsw/temp"
#define TOPIC_IN_PC_STATE     "esp/pcsw/state"
#define TOPIC_IN_SYNC         "esp/pcsw/sync"

#define PUB_PERIODIC_MS     1000 * 60 * 10  // publish data periodically every 10 minutes
#define PUB_TEMP_THRESHOLD  2.0f            // besides periodically, temperature will be transmitted if changed more than this
#define PUB_MIN_MS          1000            // don't publish more often that this, even on status/temp change

#define DEBOUNCE_STATUS_MS    2000    // 2 second debounce for PC on/off status
#define TEMP_REFRESH_MS       10000   // periodic read of 1wire temperature

// enum to cycle through all data that is to be sent periodically
typedef enum
  PUB_DATA_TEMP      =  1,
  PUB_DATA_MAX       =  2  
} PubData_e;

// setup instances for Wifi and 1Wire
WiFiClient espClient;
PubSubClient client(espClient);
OneWire oneWire(GPIO_ONEWIRE); 
DallasTemperature tempSensors(&oneWire);

// variables
char mqtt_msg[50];
uint16_t connect_cnt = 0;
uint16_t sync_cnt = 0;

uint8_t current_pc_status = 255;
uint8_t last_read_status = 255;
uint8_t last_published_status = 255;
long last_status_unstable_ms = 0;

float current_temp = -127.0;
float last_published_temp = -127.0;
long last_temp_request_ms = 0;

long last_published_ms = 0;
PubData_e data_to_publish = PUB_DATA_PC_STATUS;
uint8_t is_syncing = 0;

/// Init functions
void Wifi_Connect (void) 
  Serial.println(); // before this we have crap from ESP bootloader
  Serial.print("Connecting to ");

  // connect to Wifi network

  while (WiFi.status() != WL_CONNECTED) 

  Serial.print("WiFi connected! IP: ");

void OneWire_Start (void)
  Serial.print ("Initializing 1wire...");
  tempSensors.begin (); // init and start 1wire scan
  Serial.print("done! Sensors found: ");

  tempSensors.setWaitForConversion(false); // make temperature conversion async (don't wait for finish)
  tempSensors.requestTemperatures(); // initialize first temperature conversion
  last_temp_request_ms = millis (); 

/// Setup and main loop
void setup() 
  Serial.begin(115200, SERIAL_8N1);

  pinMode (GPIO_OUT_SW, OUTPUT);
  delay (500);

  // connect to Wifi

  // setup MQTT

  // start 1wire
  OneWire_Start ();

void loop() 
  // handle MQTT connection
  if (!client.connected()) 
    last_published_ms = last_status_unstable_ms = millis(); // init time here, it takes a while to connect

  // handle temperature reading
  if ((millis () - last_temp_request_ms) > TEMP_REFRESH_MS)
    // get temperature from first index (since we have only one sensor)   
    current_temp = tempSensors.getTempCByIndex(0);
    Serial.print("Temperature read: "); 

    // request new temperature conversion, which can take up to 750 ms (DS18B20)
    // we don't wait here for that since we setup async conversion
    last_temp_request_ms = millis ();
  long now_ms = millis();
  // read current input status
  uint8_t tmp_status = digitalRead (GPIO_IN_STATUS);
  // invert if needed
  if (IN_STATUS_INVERTED) tmp_status = !tmp_status;

  // check if unstable
  if (tmp_status != last_read_status)
    last_status_unstable_ms = now_ms;
    last_read_status = tmp_status;

  // check if debounce period elapsed, save new status
  if ((now_ms - last_status_unstable_ms) > DEBOUNCE_STATUS_MS)
    if (current_pc_status != tmp_status)
      current_pc_status = tmp_status;
      Serial.print ("PC status changed to ");
      Serial.println (current_pc_status);

  // limit minimal MQTT sending interval, publish data
  if ((now_ms - last_published_ms) > PUB_MIN_MS)
    // send on PC status change
    if (current_pc_status != last_published_status)
      Publish_PcStatus (current_pc_status);
      last_published_ms = now_ms;
    // or on temperature change
    else if (fabs (current_temp - last_published_temp) > PUB_TEMP_THRESHOLD)
      Publish_Temperature (current_temp);      
      last_published_ms = now_ms;
    // check if we were syncing data
    else if (is_syncing)
      char tmp_str[20];

      // increment counter and publish status
      snprintf (tmp_str, sizeof (tmp_str), "Synced(%d)", sync_cnt);
      Publish_Connection (tmp_str);
      is_syncing = 0; // sync complete at this point, everything that needed to be sent is above      
    // send periodically
    else if ((now_ms - last_published_ms) > PUB_PERIODIC_MS) 
      // cycle through data to publish periodically 
      if (data_to_publish >= PUB_DATA_MAX) data_to_publish = PUB_DATA_PC_STATUS;
      if (data_to_publish == PUB_DATA_PC_STATUS) Publish_PcStatus (current_pc_status);
      else if (data_to_publish == PUB_DATA_TEMP) Publish_Temperature (current_temp);    

      data_to_publish = (PubData_e) (data_to_publish + 1);  
      last_published_ms = now_ms;

/// MQTT functions
void Mqtt_Reconnect() 
  char tmp_str[30];
  // Loop until we're reconnected
  while (!client.connected()) 
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
      // Once connected, publish an announcement...
      snprintf (tmp_str, sizeof (tmp_str), "Connected(%d)", connect_cnt);
      Publish_Connection (tmp_str);
      // ... and resubscribe
      client.subscribe (TOPIC_IN_PC_STATE);
      client.subscribe (TOPIC_IN_SYNC);
      Serial.print("failed, rc=");
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying

void Publish_Connection (char * text)
  // report to terminal for debug
  snprintf (mqtt_msg, sizeof (mqtt_msg), "Publishing %s %s", TOPIC_OUT_CONN, text);
  Serial.println (mqtt_msg);
  // publish to MQTT server
  client.publish (TOPIC_OUT_CONN, text, MQTT_USE_RETAIN);   

void Publish_PcStatus (uint8_t pc_status)
  // report to terminal for debug
  snprintf (mqtt_msg, sizeof (mqtt_msg), "Publishing %s %s", TOPIC_OUT_PC_STATUS, String(pc_status).c_str());
  Serial.println (mqtt_msg);
  // publish to MQTT server
  client.publish (TOPIC_OUT_PC_STATUS, String(pc_status).c_str(), MQTT_USE_RETAIN); 

  // save last published status
  last_published_status = pc_status;  

void Publish_Temperature (float temp)
  int16_t temp_i16;
  char temp_string[10];
  // temperature value is in degrees C as float, we'll report with 
  // only one decimal since accuracy of sensor is +-0.5 degC

  // convert to integer to avoid float sprintf issues
  if (temp >= 0.0)
    temp_i16 = (temp + 0.05f) * 10; // add 0.05f to round up, x10 to keep one decimal in integer
    temp_i16 = (temp - 0.05f) * 10;

  // write integer temperature to string 
  snprintf (temp_string, sizeof (temp_string), "%d.%01d", temp_i16 / 10, abs (temp_i16) % 10); 

  // report to terminal for debug
  snprintf (mqtt_msg, sizeof (mqtt_msg), "Publishing %s %s", TOPIC_OUT_TEMP, temp_string);
  Serial.println (mqtt_msg);
  // publish to MQTT server
  client.publish (TOPIC_OUT_TEMP, temp_string, MQTT_USE_RETAIN);

  // remember last sent
  last_published_temp = temp;

void Subscription_Callback(char* topic, byte* payload, unsigned int length) 
  // report to terminal for debug
  Serial.print("MQTT msg arrived: ");
  Serial.print(" ");
  for (int i = 0; i < length; i++) 

  // check if we received our IN topic for state change
  if (strcmp (TOPIC_IN_PC_STATE, topic) == 0)
    uint8_t target_state = current_pc_status; 

    // check for valid values
    if ((char)payload[0] == '1')
      target_state = 1;
    else if ((char) payload[0] == '0')
      target_state = 0;

    // toggle output (PC power switch) if we need to change state
    if (target_state != current_pc_status)
      Serial.print ("Toggling state! target|current=");
      Serial.print (target_state);
      Serial.print ("|");
      Serial.println (current_pc_status);
      TogglePcState ();
  // check for sync topic
  else if (strcmp (TOPIC_IN_SYNC, topic) == 0)
    // we should get '1' as sync request
    if ((char) payload[0] == '1')
      is_syncing = 1;    
      // invalidate last sent data, triggering resend
      last_published_status = 255;
      last_published_temp = -127.0;  

void TogglePcState (void)
  Serial.println ("Out state toggled!");


Screenshot 2 sbdaajovzu
Zvonko Bockaj

Embedded developer, hardware and firmware.


Did you replicate this project? Share it!

I made one

Love this project? Think it could be improved? Tell us what you think!

Give feedback


Similar projects you might like

Smart Home 433MHz RF <-> MQTT Gateway With Some Extras
  • 819
  • 4

Full instructions

Control your RF devices via MQTT and integrate them into your smart home 🏡, using the WEMOS ESP8266 connected to MQTT service via WiFi.

Multi-Location Weather Station
  • 585
  • 9

Build your own multi-location weather station and display the data wirelessly on one screen.

NodeMCU Home Weather Station with Websocket
  • 1,134
  • 7

Full instructions

NodeMCU and BME280 Home Weather Station that serves a webpage using Websockets

 Inter-device communication using Blynk Bridge Widget
  • 1,097
  • 3

Full instructions

I tried communicating between Wi-Fi devices using Blynk's Bridge widget!

Arduino 101 BLE App
  • 3,247
  • 31

Work in progress

I want to show you how to make an application and connect it with the Arduino 101 platform for Internet of things applications.

The Arduino101 way of Caregiving!
  • 174
  • 2

Full instructions

Dealing with ill people or elderly at your home? No problem, here's the solution.

ProjectsCommunitiesContestsLiveAppsBetaFree StoreBlogAdd projectSign up / Login
Respect project