Wafibot
Wafibot turns a switch on using wifi.
Wafiperson turns the switch back on using manual labor.
Challenges
1. Programming the ESP32
Programming the ESP32 took the first 2-3 weeks. Whre my initial plan was to get the bluetooth functionality working, the ESP32 didn’t support it.
So I pivoted into using Wifi over HTML.
2. Programming & Calibrating the Motor
The next 2-3 weeks were spent getting the motor to properly calibrate and build the final design. Instead of mounting the motor to the circuitboard directly.
One design improvement I made involved separating the motor from the circuitboard. This, then, can support more than one motor per circuit board.
Current maximum is 4.
Wins
The switchbot costs $25 if you buy a pack of 4. That’s $25 per switch.
The wafibot costs $10 per switch. If I add additional support. I can reduce the cost to $5 per switch, if I connect 4 to one board.
Losses
Looks incredibly ugly.
Coin Battery not driving enough power. Switched to Lipo battery
Appendix
Board Design
Schematic
Motor Calibration
This servo wasn’t working with the Esp32Servo.h
library so I had to find a way to manually send the pwm signals. I finalized on the following PWM settings
Full Arduino Code
/*
WiFiAccessPoint.ino creates a WiFi access point and provides a web server on it.
Steps:
1. Connect to the access point "yourAp"
2. Point your web browser to http://192.168.4.1/H to turn the LED on or http://192.168.4.1/L to turn it off
OR
Run raw TCP "GET /H" and "GET /L" on PuTTY terminal with 192.168.4.1 as IP address and 80 as port
Created for arduino-esp32 on 04 July, 2018
by Elochukwu Ifediora (fedy0)
*/
#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiAP.h>
#include <ESP32Servo.h>
#define SERVO 12 // Set the GPIO pin where you connected your test LED or comment this line out if your dev board has a built-in LED
// Set these to your desired credentials.
const char *ssid = "wafiwifi";
const char *password = "wafi1234";
int APin = 12;
ESP32PWM pwm;
int freq = 1000;
const int ServoPin = 12; /* GPIO16 */
int dutyCycle;
/* Setting PWM Properties */
const int PWMChannel = 0;
const int PWMFreq = 50; /* 50 Hz */
const int PWMResolution = 10;
const int MAX_DUTY_CYCLE = (int)(pow(2, PWMResolution) - 1);
WiFiServer server(80);
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println("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.begin();
// Allow allocation of all timers
ESP32PWM::allocateTimer(0);
ESP32PWM::allocateTimer(1);
ESP32PWM::allocateTimer(2);
ESP32PWM::allocateTimer(3);
// Motor Setup
Serial.println("Server started");
ledcSetup(PWMChannel, PWMFreq, PWMResolution);
ledcAttachPin(SERVO, PWMChannel);
ledcWrite(PWMChannel, 54);
delay(2);
}
void loop() {
WiFiClient client = server.available(); // listen for incoming clients
if (client) { // if you get a client,
Serial.println("New Client."); // print a message out the serial port
String currentLine = ""; // make a String to hold incoming data from the client
while (client.connected()) { // loop while the client's connected
if (client.available()) { // if there's bytes to read from the client,
char c = client.read(); // read a byte, then
Serial.write(c); // print it out the serial monitor
if (c == '\n') { // if the byte is a newline character
// if the current line is blank, you got two newline characters in a row.
// that's the end of the client HTTP request, so send a response:
if (currentLine.length() == 0) {
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
// and a content-type so the client knows what's coming, then a blank line:
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println();
// the content of the HTTP response follows the header:
client.print("Version 1 | ");
client.print("GPIO");
client.print(SERVO);
client.print("<br>");
client.print("Click <a href=\"/H\">here</a> to turn Trigger the switch.<br>");
// The HTTP response ends with another blank line:
client.println();
// break out of the while loop:
break;
} else { // if you got a newline, then clear currentLine:
currentLine = "";
}
} else if (c != '\r') { // if you got anything else but a carriage return character,
currentLine += c; // add it to the end of the currentLine
}
// Check to see if the client request was "GET /H" or "GET /L":
if (currentLine.endsWith("GET /H")) {
ledcWrite(PWMChannel, 66);
delay(2500);
ledcWrite(PWMChannel, 48);
delay(2500);
}
}
}
// close the connection:
client.stop();
Serial.println("Client Disconnected.");
}
}