---
title: "W5300 Home Automation using STM32 BLUEPILL (STM32F103)"
url: "https://maker.wiznet.io/nk_maker/contest/w5300-home-automation-using-stm32-bluepill-stm32f103/"
markdown_url: "https://maker.wiznet.io/nk_maker/contest/w5300-home-automation-using-stm32-bluepill-stm32f103/md"
type: "Contests"
author: "nisarg k bhatt"
author_url: "https://maker.wiznet.io/nk_maker/"
original_author: "Nisarg K Bhatt"
license: "Creative Commons Attribution CC BY version 4.0 or later (CC BY 4+)"
published: "2023-08-20"
language: "en"
tags: ["AIoT", "toe-design-contest", "Home Automation"]
hardware: ["WIZnet W5300-TOE-Shield", "STMicroelectronics STM32F103RCT6"]
likes: 8
views: 3959
comments: 0
source: "WIZnet Makers (https://maker.wiznet.io/)"
---

# W5300 Home Automation using STM32 BLUEPILL (STM32F103)

> W5300 Home Automation using STM32 BLUEPILL (STM32F103) developed using ARDUINO IDE

Original author: Nisarg K Bhatt

## Components

- **WIZnet W5300-TOE-Shield** x 1: W5300 ([docs](https://wiznetshop.io/))
- **STMicroelectronics STM32F103RCT6** x 1: STM32F103 BLUEPILL BOARD ([docs](https://estore.st.com/en/stm32f103rct6-cpn.html))
- Software: **Arduino IDE**: Arduino IDE ([docs](https://www.arduino.cc/en/software))
- Software: **MQTT**: MQTT Client Arduino

## Documents and links

- [Arduino W5300 STM32F103 Bluepill Ethernet Library](https://github.com/nkmakerin/w5300_arduino_stm32f103) (code): Arduino W5300 STM32F103 Bluepill Ethernet Library edited version
- [W5300 STM32F103 IOT HOME CIRCUIT DIAGRAM](https://maker.wiznet.io/_lib/download.asp?path=project/7988&downfile=stm%5Fconn%2Epng) (schematics): W5300 STM32F103 IOT HOME CIRCUIT DIAGRAM
- [Arduino code for IoT Home Automation Project](https://maker.wiznet.io/_lib/download.asp?path=project/7988&downfile=STM32BLUEPILL%5FIOT%5FHOME%2Erar): Arduino code for IoT Home Automation Project for W5300 + STM32F103 BLUEPILL

## Article

**W5300 TOE SHIELD + STM32F103 Based STM32 Bluepill Board + Arduino IDEBased IoT Home Automation SystemWorking Video :**

[Embedded media](https://www.youtube.com/embed/fGlcPzmuZAI)

**Components :**

1. [W5300 TOE Shield](https://docs.wiznet.io/Product/iEthernet/W5300/W5300-TOE-Shield)

2. [0.96 inch I2C OLED](https://www.electronicscomp.com/0.96-inch-i2c-iic-128x64-oled-display-module-4-pin-blue-color)

3. [4 - relay Module](https://www.electronicscomp.com/4-channel-12v-relay-module-with-optocoupler)

4. [STM32F103 Bluepill Board](https://robocraze.com/blogs/post/introduction-to-the-stm32-bluepill)

5. [DS18B20 Temperature Sensor](https://www.electronicscomp.com/ds18b20-water-proof-temperature-sensor-probe-india)

**Software :**

1. [Arduino IDE with STM32 Board package](https://github.com/stm32duino/Arduino_Core_STM32)

2. [W5300 Arduino Library](https://github.com/MadhuriVaghasia/W5300AnyArduino/tree/main) - I edited this to use it with STM32F103 Bluepill and provided in this project document

3. [MQTT Arduino Client library](https://github.com/knolleary/pubsubclient)

4. [Android MQTT Dash app](https://play.google.com/store/apps/details?id=net.routix.mqttdash)

**Hardware Development : **Hardware with STM32F103 Bluepill , OLED Display , Relay interface and DS18B20 Temperature Sensor Interface developed by me. W5300 TOE Shield with useful IO expansion is received from my professor.

![](https://maker.wiznet.io/upload/ckeditor5/947327900%5F1692900016%2Ejpg) ![](https://maker.wiznet.io/upload/ckeditor5/947327900%5F1692900024%2Ejpg)

![](https://maker.wiznet.io/upload/ckeditor5/947327900%5F1692901880%2Ejpg)

**Circuit Diagram :**

![](https://maker.wiznet.io/upload/ckeditor5/942629896%5F1693513997%2Epng)

**STM32F103 BLUE PILL and W5300 Connection :**

![](https://maker.wiznet.io/upload/ckeditor5/733503401%5F1692890265%2Epng)

![](https://maker.wiznet.io/upload/ckeditor5/733503401%5F1692890289%2Epng)

**Android MQTT Dash App:**

![](https://maker.wiznet.io/upload/ckeditor5/947327900%5F1692902650%2Ejpg)

**Arduino Ethernet Library for STM32F103+W5300 :**Here is edited W5300 Ethernet library to use with STM32F103 Bluepill - edited library is in document for download

**1-w5300_anymcu.h**

```plaintext
// Edited By NK MAKER to use STM32 BLUEPILL
#ifndef	_W5300_ANYMCU_H_
#define	_W5300_ANYMCU_H_
#include <Arduino.h>
// D7...D0 -> PA7...PA0
#define DATA_DIR  GPIOA->CRL
#define DATA_OUT  GPIOA->ODR
#define DATA_IN   GPIOA->IDR
#define DATA_OUT_SET 0x33333333
#define DATA_IN_SET  0x88888888

//PA10 -> ADDR2, PA09 -> ADDR1, PA08 -> ADDR0 
#define ADDR_DIR  GPIOA->CRH
#define ADDR_OUT  GPIOA->ODR
#define ADDR_OUT_MASK 0xFFFFF000
#define ADDR_OUT_SET  0x00000333

//PC15 -> CS, PC14 -> WR, PC13 -> RD 
#define CTRL_DIR  GPIOC->CRH
#define CTRL_OUT  GPIOC->ODR
#define CTRL_OUT_MASK 0x000FFFFF
#define CTRL_OUT_SET  0x33300000

#define DATA_MASK ~(0x00FF<<0)
#define ADDR_MASK ~(0x0007<<8)
#define CTRL_MASK ~(0x0007<<13)

#define ADDR_0  0x0000<<8  //bit seq A2 A1 A0
#define ADDR_1  0x0001<<8
#define ADDR_2  0x0002<<8
#define ADDR_3  0x0003<<8
#define ADDR_4  0x0004<<8
#define ADDR_5  0x0005<<8
#define ADDR_6  0x0006<<8
#define ADDR_7  0x0007<<8

#define CTRL_IDLE 0x0007<<13  //b111  //bit seq CS WR RD
#define CTRL_RDST 0x0006<<13  //b110
#define CTRL_RDEX 0x0002<<13  //b010
#define CTRL_WRST 0x0005<<13  //b101
#define CTRL_WREX 0x0001<<13  //b001

uint16_t w5300_read_indirect(uint16_t addr);
void w5300_write_indirect(uint16_t addr, uint16_t data1);
void w5300_setup_indirect_MR(void);
void w5300_init(void);
void w5300_reset(void);

#endif
```

**2-w5300_anymcu.cpp**

```plaintext
// Edited By NK MAKER to use STM32 BLUEPILL
#include "w5300_anymcu.h"
#include <Arduino.h>

// Initlize W5300 in use 8 bit Indirect addressing mode
void w5300_init(void)
{  
	// init all w5300 connection pins as output and set all pins high
	DATA_DIR = DATA_OUT_SET;
	ADDR_DIR = (ADDR_DIR & ADDR_OUT_MASK) | ADDR_OUT_SET ;
	CTRL_DIR = (CTRL_DIR & CTRL_OUT_MASK) | CTRL_OUT_SET ;
	DATA_OUT |= ~DATA_MASK; 
	ADDR_OUT |= ~ADDR_MASK;     
	CTRL_OUT |= ~CTRL_MASK; 
	delay(1000);
	Serial.println("\r\n--> Modified W5300 Arduino ethernet library for any mcu with Indirect Addressing  (need 14 GPIO Only) \r\n--> Developed by - M.Vaghasia (rcele_85@yahoo.com) \r\n--> edited by NK MAKER to use STM32 BLUEPILL \r\n--> Current MCU Selected - STM32 BLUEPILL");
	Serial.println("--> Soft Reset W5300");
	w5300_reset();
	delay(1000);
	// configure W5300 to work in indirect addressing mode
	w5300_setup_indirect_MR();
	//Serial.println(w5300_read_indirect(0),HEX);
	delay(1000);
	if(w5300_read_indirect(0) == 0x3801)	  Serial.println("--> w5300 indirect addressing Init - Success ;)");
	else 
	  {
		while(1)
		 {
			Serial.println("--> w5300 indirect addressing Init - Fail :(\r\n--> Check w5300 hardware connections and reset mcu");
			delay(5000);
		  }
	  }
	delay(1000);
}

// Setup W5300 to use 8 bit Indirect addressing mode
void w5300_setup_indirect_MR(void)
{
	DATA_DIR = DATA_OUT_SET; // Set Databus as output
	// Write 0x01 to MR_LOW (Addr - 0x01) for configure w5300 indirect addressing
	DATA_OUT |= ~DATA_MASK; DATA_OUT &= DATA_MASK | 0x0001;
	ADDR_OUT |= ~ADDR_MASK; ADDR_OUT &= ADDR_MASK | ADDR_1;     
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_WRST;  
	delayMicroseconds(1);
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_WREX; 
	delayMicroseconds(1);
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_IDLE;  
	delayMicroseconds(1);
}

// Soft Reset W5300
void w5300_reset(void)
{
	DATA_DIR = DATA_OUT_SET; // Set Databus as output
	// Write 0x80 to MR_LOW (Addr - 0x01) for soft reset w5300
	DATA_OUT |= ~DATA_MASK; DATA_OUT &= DATA_MASK | 0x0080;
	ADDR_OUT |= ~ADDR_MASK; ADDR_OUT &= ADDR_MASK | ADDR_1;     
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_WRST;  
	  
	delayMicroseconds(1);
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_WREX; 
	delayMicroseconds(1);
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_IDLE;  
	delayMicroseconds(1);
}

// Write 16 Bit register of W5300 using 8 bit indirect addressing
void w5300_write_indirect(uint16_t addr, uint16_t data1)
{
	uint16_t data = data1;
	DATA_DIR = DATA_OUT_SET; // Set Databus as output
	// set desired addr in indirect address reg 0x02, 0x03 address
	DATA_OUT |= ~DATA_MASK; DATA_OUT &= DATA_MASK | ((addr>>8) & 0xFF);
	ADDR_OUT |= ~ADDR_MASK; ADDR_OUT &= ADDR_MASK | ADDR_2;     
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_WRST;  
	delayMicroseconds(1);
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_WREX; 
	delayMicroseconds(1);
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_IDLE;  
	delayMicroseconds(1);

	DATA_OUT |= ~DATA_MASK; DATA_OUT &= DATA_MASK | (addr & 0xFF);
	ADDR_OUT |= ~ADDR_MASK; ADDR_OUT &= ADDR_MASK | ADDR_3;     
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_WRST;  
	delayMicroseconds(1);
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_WREX; 
	delayMicroseconds(1);
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_IDLE;  
	delayMicroseconds(1);
	  
	// set desired data in indirect data reg 0x04, 0x05 address
	DATA_OUT |= ~DATA_MASK; DATA_OUT &= DATA_MASK | ((data1>>8) & 0xFF);
	ADDR_OUT |= ~ADDR_MASK; ADDR_OUT &= ADDR_MASK | ADDR_4;     
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_WRST;  
	delayMicroseconds(1);
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_WREX; 
	delayMicroseconds(1);
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_IDLE;  
	delayMicroseconds(1);

	DATA_OUT |= ~DATA_MASK; DATA_OUT &= DATA_MASK | (data1 & 0xFF);
	ADDR_OUT |= ~ADDR_MASK; ADDR_OUT &= ADDR_MASK | ADDR_5;     
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_WRST;  
	delayMicroseconds(1);
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_WREX; 
	delayMicroseconds(1);
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_IDLE;  
	delayMicroseconds(1);
}

// Read 16 Bit register of W5300 using 8 bit indirect addressing
uint16_t w5300_read_indirect(uint16_t addr)
{
	uint16_t data =0;
	uint32_t data1 = 0;
	uint32_t data2 = 0;
	DATA_DIR = DATA_OUT_SET; // Set Databus as output
	  
	// set desired addr in indirect address reg 0x02, 0x03 address
	DATA_OUT |= ~DATA_MASK; DATA_OUT &= DATA_MASK | ((addr>>8) & 0xFF);
	ADDR_OUT |= ~ADDR_MASK; ADDR_OUT &= ADDR_MASK | ADDR_2;     
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_WRST;  
	delayMicroseconds(1);
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_WREX; 
	delayMicroseconds(1);
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_IDLE;  
	delayMicroseconds(1);

	DATA_OUT |= ~DATA_MASK; DATA_OUT &= DATA_MASK | (addr & 0xFF);
	ADDR_OUT |= ~ADDR_MASK; ADDR_OUT &= ADDR_MASK | ADDR_3;     
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_WRST;  
	delayMicroseconds(1);
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_WREX; 
	delayMicroseconds(1);
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_IDLE;  
	delayMicroseconds(1);
	   
	DATA_DIR = DATA_IN_SET; // Set Data Bus input
	  
	// read data from indirect data register
	ADDR_OUT |= ~ADDR_MASK; ADDR_OUT &= ADDR_MASK | ADDR_4;     
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_RDEX; 
	delayMicroseconds(2);
	data1 = DATA_IN & 0xFF;
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_IDLE; 
	delayMicroseconds(1);

	ADDR_OUT |= ~ADDR_MASK; ADDR_OUT &= ADDR_MASK | ADDR_5;     
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_RDEX;  
	delayMicroseconds(2);
	data2 = DATA_IN & 0xFF;
	data = (data1<<8)|data2;
	CTRL_OUT |= ~CTRL_MASK; CTRL_OUT &= CTRL_MASK | CTRL_IDLE; 
	delayMicroseconds(1);
	return data;
}
```

**Arduino Code for this project application of IoT Home automation: **Full code in documentation for download

```plaintext
// W5300 AND STM32F103 Based IoT Home automation
// Developed By - NK MAKER 
#include <Ethernet.h> // This library should be replaced with library available in project
#include <PubSubClient.h>
#include <Wire.h> 

// OLED libs
#include "SSD1306.h" 

#define LED    	PC13 // for STM32F103 onboard LED
#define RELAY1 	PB7
#define RELAY2 	PB6
#define RELAY3 	PB5
#define RELAY4 	PB3

#define DSPIN	PB4
// Update these with values suitable for your network.
byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
IPAddress ip(192, 168, 137, 5);

//IPAddress server(52,57,167,165);
char* server= "broker.hivemq.com";

uint32_t premillis = 0;
uint32_t premillis1 = 0;

uint8_t oled_flag1 = 10;
uint8_t oled_flag2 = 20;
uint8_t oled_flag3 = 30;
uint8_t oled_flag4 = 40;

char tempc[20] = {' '} ;
EthernetClient ethClient;
PubSubClient client(ethClient);

// Oled Display Instance
SSD1306  display(0x3C, PB9, PB8);


void setup()
{
  Serial.begin(115200);
  pinMode(LED,OUTPUT);
  pinMode(RELAY1,OUTPUT);
  pinMode(RELAY2,OUTPUT);
  pinMode(RELAY3,OUTPUT);
  pinMode(RELAY4,OUTPUT);
  digitalWrite(RELAY1,HIGH);
  digitalWrite(RELAY2,HIGH);
  digitalWrite(RELAY3,HIGH);
  digitalWrite(RELAY4,HIGH);

  // Init OLED Sisplay
  display.init();
  display.flipScreenVertically();
  display.clear();
  display.setTextAlignment(TEXT_ALIGN_CENTER);
  display.setFont(ArialMT_Plain_16);
  display.drawString(64, 16, "W5300 IOT Hub");
  display.drawString(64, 32, "STM32F103");
  display.drawString(64, 48, "By NK Maker");
  display.display();
  delay(4000);

  client.setServer(server, 1883);
  client.setCallback(callback);

  Serial.println("** W5300 + STM32F103 BLUEPILL IOT HUB By - NK Maker **");
  Ethernet.begin(mac, ip);
  // Allow the hardware to sort itself out
  delay(1500);
}

void loop()
{
  if(millis() - premillis1 > 500)
  {
    premillis1 = millis();
    display.clear();
    display.setTextAlignment(TEXT_ALIGN_LEFT);
    display.setFont(ArialMT_Plain_10);
    if(oled_flag1 == 10)display.drawString(0, 0,  "S1 OFF");
    if(oled_flag2 == 20)display.drawString(0, 16, "S2 OFF");
    if(oled_flag3 == 30)display.drawString(0, 32, "S3 OFF");
    if(oled_flag4 == 40)display.drawString(0, 48, "S4 OFF");
    if(oled_flag1 == 11)display.drawString(0, 0,  "S1 ON");
    if(oled_flag2 == 21)display.drawString(0, 16, "S2 ON");
    if(oled_flag3 == 31)display.drawString(0, 32, "S3 ON");
    if(oled_flag4 == 41)display.drawString(0, 48, "S4 ON");
    display.drawString(64, 0, "NW - YES");
    
    display.setFont(ArialMT_Plain_16);
    display.drawString(64, 24, " TEMP");
    display.drawString(64, 44, tempc);
    display.display();  
  }
  
  if (!client.connected()) {
    reconnect();
  }
  if(millis() - premillis > 4000)
  {
    premillis = millis();
    // put your main code here, to run repeatedly:
    double temp = TempRead();
    temp  = temp * 0.0625; // conversion accuracy is 0.0625 / LSB
    Serial.print("Temperature: ");
    Serial.print(temp);
    Serial.println(" °C");
    int val_int = (int)temp;   // compute the integer part of the float
    float val_float = (abs(temp) - abs(val_int)) * 100;
    int val_fra = (int)val_float;
    sprintf (tempc, "%d.%d", val_int, val_fra); 
    //Serial.println (tempc) ;
    client.publish("W5300_IOT_PUBT",tempc);
  }
  delay(10);
  client.loop();
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i=0;i<length;i++) {
    if(payload[0] == 'a') {digitalWrite(RELAY1, LOW);Serial.println("RELAY1 turned ON");client.publish("W5300_IOT_PUB","a");oled_flag1 = 11;}
    else if(payload[0] == 'b') {digitalWrite(RELAY2, LOW);Serial.println("RELAY2 turned ON");client.publish("W5300_IOT_PUB","b");oled_flag2 = 21;}
    else if(payload[0] == 'c') {digitalWrite(RELAY3, LOW);Serial.println("RELAY3 turned ON");client.publish("W5300_IOT_PUB","c");oled_flag3 = 31;}
    else if(payload[0] == 'd') {digitalWrite(RELAY4, LOW);Serial.println("RELAY4 turned ON");client.publish("W5300_IOT_PUB","d");oled_flag4 = 41;}
    else if(payload[0] == 'A') {digitalWrite(RELAY1, HIGH);Serial.println("RELAY1 turned OFF");client.publish("W5300_IOT_PUB","A");oled_flag1 = 10;}
    else if(payload[0] == 'B') {digitalWrite(RELAY2, HIGH);Serial.println("RELAY2 turned OFF");client.publish("W5300_IOT_PUB","B");oled_flag2 = 20;}
    else if(payload[0] == 'C') {digitalWrite(RELAY3, HIGH);Serial.println("RELAY3 turned OFF");client.publish("W5300_IOT_PUB","C");oled_flag3 = 30;}
    else if(payload[0] == 'D') {digitalWrite(RELAY4, HIGH);Serial.println("RELAY4 turned OFF");client.publish("W5300_IOT_PUB","D");oled_flag4 = 40;}
    else if(payload[0] == 'x') {digitalWrite(RELAY1, LOW);digitalWrite(RELAY2, LOW);digitalWrite(RELAY3, LOW);digitalWrite(RELAY4, LOW);Serial.println("ALL RELAY turned ON");client.publish("W5300_IOT_PUB","x");client.publish("W5300_IOT_PUB","a");client.publish("W5300_IOT_PUB","b");client.publish("W5300_IOT_PUB","c");client.publish("W5300_IOT_PUB","d");oled_flag1 = 11;oled_flag2 = 21;oled_flag3 = 31;oled_flag4 = 41;}
    else if(payload[0] == 'X') {digitalWrite(RELAY1, HIGH);digitalWrite(RELAY2, HIGH);digitalWrite(RELAY3, HIGH);digitalWrite(RELAY4, HIGH);Serial.println("ALL RELAY turned OFF");client.publish("W5300_IOT_PUB","X");client.publish("W5300_IOT_PUB","A");client.publish("W5300_IOT_PUB","B");client.publish("W5300_IOT_PUB","C");client.publish("W5300_IOT_PUB","D");oled_flag1 = 10;oled_flag2 = 20;oled_flag3 = 30;oled_flag4 = 40;}
    
    }
}


void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("arduinoclient")) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("W5300_IOT_PUB","X");
      client.publish("W5300_IOT_PUB","A");
      client.publish("W5300_IOT_PUB","B");
      client.publish("W5300_IOT_PUB","C");
      client.publish("W5300_IOT_PUB","D");
      // ... and resubscribe
      client.subscribe("W5300_IOT_SUB");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

boolean DS18B20_Init()
{
  pinMode(DSPIN, OUTPUT);
  digitalWrite(DSPIN, HIGH);
  delayMicroseconds(5);
  digitalWrite(DSPIN, LOW);
  delayMicroseconds(750);//480-960
  digitalWrite(DSPIN, HIGH);
  pinMode(DSPIN, INPUT);
  int t = 0;
  while (digitalRead(DSPIN))
  {
    t++;
    if (t > 60) return false;
    delayMicroseconds(1);
  }
  t = 480 - t;
  pinMode(DSPIN, OUTPUT);
  delayMicroseconds(t);
  digitalWrite(DSPIN, HIGH);
  return true;
}
 
void DS18B20_Write(byte data)
{
  pinMode(DSPIN, OUTPUT);
  for (int i = 0; i < 8; i++)
  {
    digitalWrite(DSPIN, LOW);
    delayMicroseconds(10);
    if (data & 1) digitalWrite(DSPIN, HIGH);
    else digitalWrite(DSPIN, LOW);
    data >>= 1;
    delayMicroseconds(50);
    digitalWrite(DSPIN, HIGH);
  }
}
 
byte DS18B20_Read()
{
  pinMode(DSPIN, OUTPUT);
  digitalWrite(DSPIN, HIGH);
  delayMicroseconds(2);
  byte data = 0;
  for (int i = 0; i < 8; i++)
  {
    digitalWrite(DSPIN, LOW);
    delayMicroseconds(1);
    digitalWrite(DSPIN, HIGH);
    pinMode(DSPIN, INPUT);
    delayMicroseconds(5);
    data >>= 1;
    if (digitalRead(DSPIN)) data |= 0x80;
    delayMicroseconds(55);
    pinMode(DSPIN, OUTPUT);
    digitalWrite(DSPIN, HIGH);
  }
  return data;
}
 
int TempRead()
{
  if (!DS18B20_Init()) return 0;
  DS18B20_Write (0xCC); // Send skip ROM command
  DS18B20_Write (0x44); // Send reading start conversion command
  if (!DS18B20_Init()) return 0;
  DS18B20_Write (0xCC); // Send skip ROM command
  DS18B20_Write (0xBE); // Read the register, a total of nine bytes, the first two bytes are the conversion value
  int temp = DS18B20_Read (); // Low byte
  temp |= DS18B20_Read () << 8; // High byte
  return temp;
}
```

---

Source: https://maker.wiznet.io/nk_maker/contest/w5300-home-automation-using-stm32-bluepill-stm32f103/
