Amol Disale
Published © CC BY-NC

Wemos D1 Mini Wi-Fi Controlled 4-Wheeled Robot

Control a Four wheeled robot via using your smartphone!

IntermediateFull instructions provided24 hours6,211
Wemos D1 Mini Wi-Fi Controlled 4-Wheeled Robot

Things used in this project

Hardware components

Wemos D1 Mini
Espressif Wemos D1 Mini
×1
Robot PCB
This PCB is designed using Kicad and using it you can control four DC motors via WiFi
×1
Dual H-Bridge motor drivers L293D
Texas Instruments Dual H-Bridge motor drivers L293D
×2
PCF8574 Port Expander IC
×1
Four wheeled robot chassis
×1
12V 2A lithium ion battery
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Schematics

Wemos D1 Arduino IDE Tutorial Document

Download this document to get an idea about how to install the Esp8266 arduino core.

PCF8574 and L293d Connection Diagram

The "PCF8574_With_L293d" pdf file for the connection diagram of PCF8574 with the two L293d IC's

Schematic

Schematic of the whole Wi-Fi Robot PCB

Code

PCF8574 Header Files (.c file)

Arduino
#include "PCF8574.h"

#include <Wire.h>

PCF8574::PCF8574(const uint8_t deviceAddress)
{
    _address = deviceAddress;
    _dataIn = 0;
    _dataOut = 0xFF;
    _error = PCF8574_OK;
}

void PCF8574::begin(uint8_t val)
{
  Wire.begin();
  PCF8574::write8(val);
}

// removed Wire.beginTransmission(addr);
// with  @100KHz -> 265 micros()
// without @100KHz -> 132 micros()
// without @400KHz -> 52 micros()
// TODO @800KHz -> ??
uint8_t PCF8574::read8()
{
    if (Wire.requestFrom(_address, (uint8_t)1) != 1)
    {
        _error = PCF8574_I2C_ERROR;
        return _dataIn; // last value
    }
#if (ARDUINO <  100)
    _dataIn = Wire.receive();
#else
    _dataIn = Wire.read();
#endif
    return _dataIn;
}

void PCF8574::write8(const uint8_t value)
{
    _dataOut = value;
    Wire.beginTransmission(_address);
    Wire.write(_dataOut);
    _error = Wire.endTransmission();
}

uint8_t PCF8574::read(const uint8_t pin)
{
    if (pin > 7)
    {
        _error = PCF8574_PIN_ERROR;
        return 0;
    }
    PCF8574::read8();
    return (_dataIn & (1 << pin)) > 0;
}

void PCF8574::write(const uint8_t pin, const uint8_t value)
{
    if (pin > 7)
    {
        _error = PCF8574_PIN_ERROR;
        return;
    }
    if (value == LOW)
    {
        _dataOut &= ~(1 << pin);
    }
    else
    {
        _dataOut |= (1 << pin);
    }
    write8(_dataOut);
}


int PCF8574::lastError()
{
    int e = _error;
    _error = PCF8574_OK;
    return e;
}

PCF8574 Header Files (.h file)

Arduino
#ifndef _PCF8574_H
#define _PCF8574_H

#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

#define PCF8574_LIB_VERSION "0.1.9"

#define PCF8574_OK          0x00
#define PCF8574_PIN_ERROR   0x81
#define PCF8574_I2C_ERROR   0x82


class PCF8574
{
public:
    explicit PCF8574(const uint8_t deviceAddress);

    void begin(uint8_t val=0xFF);

    uint8_t read8();
    uint8_t read(uint8_t pin);
    uint8_t value() const { return _dataIn; };

    void write8(const uint8_t value);
    void write(const uint8_t pin, const uint8_t value);
    uint8_t valueOut() const { return _dataOut; }

    int lastError();

private:
    uint8_t _address;
    uint8_t _dataIn;
    uint8_t _dataOut;
    int _error;
};

#endif

ESP8266 Wi-Fi Controlled Four Wheeled Robot

Arduino
#include <ESP8266WiFi.h>
#include <WiFiClient.h> 
#include <ESP8266WebServer.h>
#include <Wire.h>
#include "PCF8574.h"

PCF8574 PCF_01(0x38);
//PCF8574 PCF_02(0x21);
//PCF8574 PCF_03(0x3A);

#define en1 14  //D5
#define en2 12  //D6  
#define en3 13  //D7
#define en4 15  //D8

const int motor_delay = 1250;

// Replace with your network credentials
const char* ssid     = "WiFi_Robot";
const char* password = "Automate@111";

// Set web server port number to 80
ESP8266WebServer server(80);

/* Just a little test message.  Go to http://192.168.4.1 in a web browser
 * connected to this access point to see it.
 */
void handleRoot() {
  server.send(200, "text/plain", "hello from Robot!");
}

void setup()
{
  pinMode(en1, OUTPUT);
  pinMode(en2, OUTPUT);
  pinMode(en3, OUTPUT);
  pinMode(en4, OUTPUT);
  
  robo_stop();
  delay(motor_delay);
  
  Serial.begin(9600);
  Serial.println("");
  Serial.println("");
  
  Serial.println("I2C WiFi Robot with Wemos");
  
  PCF_01.begin();

  int x = PCF_01.read8();
  Serial.print("Read ");
  Serial.println(x, HEX);

  /*
  PCF_02.begin();
  PCF_03.begin();
  
  x = PCF_02.read8();
  Serial.print("Read ");
  Serial.println(x, HEX);
  
  x = PCF_03.read8();
  Serial.print("Read ");
  Serial.println(x, HEX);
  */

  Serial.print("Configuring access point...");
  /* You can remove the password parameter if you want the AP to be open. */
  WiFi.softAP(ssid, password);

  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);
  
  server.on("/", handleRoot);
 
  server.on("/inline", []() {
    server.send(200, "text/plain", "this works as well");
  });

  server.on("/fw", []() {
    robo_forward();
    delay(motor_delay); 
    robo_stop();
    delay(motor_delay/2); 
    Serial.println("Robot Stop");
    server.send(200, "text/plain", "Forward");
  });
  
  server.on("/bk", []() {
    robo_backward();
    delay(motor_delay); 
    robo_stop();
    delay(motor_delay/2); 
    Serial.println("Robot Stop");
    server.send(200, "text/plain", "Back");
  });

  server.on("/st", []() {
    robo_stop();
    Serial.println("Robot Stop");
    server.send(200, "text/plain", "Stop");
  });
  
  server.on("/lt", []() {
    robo_left();
    delay(motor_delay/4); 
    robo_stop();
    delay(motor_delay/2); 
    Serial.println("Robot Stop");
    server.send(200, "text/plain", "Left");
  });
  
  server.on("/rt", []() {
    robo_right();
    delay(motor_delay/4); 
    robo_stop();
    delay(motor_delay/2); 
    Serial.println("Robot Stop");
    server.send(200, "text/plain", "Right");
  });

  server.begin();
  Serial.println("HTTP server started"); 
}


void loop()
{
  server.handleClient();
}

void doHigh(int pin)
{
  PCF_01.write(pin, HIGH);
}

void doLow(int pin)
{
  PCF_01.write(pin, LOW);
}

void motor1_forward(void)
{
  doHigh(0);
  doLow(1);
}

void motor2_forward(void)
{
  doHigh(2);
  doLow(3);
}

void motor3_forward(void)
{
  doHigh(4);
  doLow(5);
}

void motor4_forward(void)
{
  doHigh(6);
  doLow(7);
}

void motor1_backward(void)
{
  doHigh(1);
  doLow(0);
}

void motor2_backward(void)
{
  doHigh(3);
  doLow(2);
}

void motor3_backward(void)
{
  doHigh(5);
  doLow(4);
}

void motor4_backward(void)
{
  doHigh(7);
  doLow(6);
}

void motor1_stop(void)
{
  doLow(0);
  doLow(1);
}

void motor2_stop(void)
{
  doLow(2);
  doLow(3);
}

void motor3_stop(void)
{
  doLow(4);
  doLow(5);
}

void motor4_stop(void)
{
  doLow(6);
  doLow(7);
}

void motor_start(void)
{
  digitalWrite(en1, HIGH);
  digitalWrite(en2, HIGH);
  digitalWrite(en3, HIGH);
  digitalWrite(en4, HIGH);
}

void robo_stop(void)
{
  digitalWrite(en1, LOW);
  digitalWrite(en2, LOW);
  digitalWrite(en3, LOW);
  digitalWrite(en4, LOW);
}

void robo_forward(void)
{
  Serial.println("Forward Motion");
  motor1_forward();
  motor2_forward();
  motor3_forward();
  motor4_forward();
  motor_start();  
}

void robo_backward(void)
{
  Serial.println("Backward Motion");
  motor1_backward();
  motor2_backward();
  motor3_backward();
  motor4_backward();
  motor_start();  
}

void robo_left(void)
{
  Serial.println("Left Motion");
  motor1_forward();
  motor2_stop();
  motor3_forward();
  motor4_stop();
  motor_start();  
}

void robo_right(void)
{
  Serial.println("Right Motion");
  motor1_stop();
  motor2_forward();
  motor3_stop();
  motor4_forward();
  motor_start();
}

Credits

Amol Disale

Amol Disale

9 projects • 100 followers
I am passionate about the idea of open-source hardware and software. I am ready to help in prototyping IoT, Smart Home, and other products.

Comments