|
|
MCP23017-E/SP |
x 1 | |
|
|
CH340CWCH / SparkFun
|
x 1 | |
|
|
ESP8266-12EEspressive
|
x 1 | |
|
|
LM3940IMPX-3.3/NOPBTI
|
x 1 | |
|
|
L293D |
x 1 | |
|
|
LM1084IT-5.0/NOPB |
x 1 | |
|
|
BC337-25 B1Taiwan Semiconductor
|
x 1 | |
|
|
Relay 5VAXICOM
|
x 1 | |
|
|
47uF-16V |
x 2 | |
|
|
2-pin header, 2.54mm |
x 4 | |
|
|
4-pin header, 2.54mm |
x 3 | |
|
|
1kΩ 1/4 W resistor |
x 3 | |
|
|
100kΩ 1/4 W resistor |
x 1 | |
|
|
2kΩ 1/4 W resistor |
x 2 | |
|
|
3kΩ 1/4 W resistor |
x 2 | |
|
|
10kΩ 1/4 W resistor |
x 2 | |
|
|
470Ω 1/4 W resistor |
x 1 | |
|
|
TL1105AF1600 E-switch |
x 2 | |
|
|
11-pin header,2.54mm |
x 1 |
WalkeremoteBoard
The WalkeremoteBoard is an IoT development board designed to enable remote monitoring and control of devices, sensors, and actuators over the internet. The project originally started before the COVID-19 pandemic, but I decided to develop it further during the pandemic period, when travel restrictions and work-related mobility made it difficult to stay close to certain places and loved ones.
As I was frequently traveling for work, I needed a versatile system that would allow me to monitor remote environments, collect sensor data, and control devices from a distance with minimal infrastructure. This experience motivated me to transform the idea into a hardware platform capable of supporting multiple real-world applications, from simple automation tasks to more advanced remote telepresence.
The board is based on the ESP8266 IoT module, chosen for its compact size, low power consumption, Wi-Fi connectivity, and excellent community support. It can be used to control relays, motors, and actuators, or to receive data from a wide range of sensors and send that information to remote servers or user interfaces.
Thanks to this architecture, the board can serve several purposes:
Remote control of motors and relays
Telepresence and robotics projects
Environmental or security monitoring
Sensor data acquisition and data logging
IoT prototyping and automation
The development of WalkeremoteBoard is still ongoing, and I am actively working on software and hardware integration, testing different communication protocols, user interfaces, and cloud services to achieve more reliable performance and scalability.
The goal is to create a board that is easy to integrate into custom projects, adaptable to different fields, and capable of enabling remote interaction with physical objects and environments in a simple and efficient way.
As the project evolves, I continue to study and experiment with new technologies to improve usability, reliability, and real-time communication between software and hardware.
Images and videos will demonstrate different prototypes, control tests, and remote monitoring experiments performed during development.
#include <Adafruit_MCP23X17.h>
#include <WiFiManager.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Stepper.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266httpUpdate.h>
#include <ESP_Mail_Client.h>
// client email configuration
#define SMTP_HOST "smtp.gmail.com"
#define SMTP_PORT 465
#define AUTHOR_EMAIL "yourEmail@gmail.com"
#define AUTHOR_PASSWORD "YourPassword"
#define RECIPIENT_EMAIL "YourEmail@gmail.com" //to receive some information from sensors , in this case will receive battery voltage.
SMTPSession smtp;
int battcheck;
float Tvoltage=0.0;
float Vvalue=0.0,Rvalue=0.0;
float batteryPercentage = 0.0;
int BAT= A0; //Analog channel A0 as used to measure battery voltage
float RatioFactor=5.714; //Resistors Ration Factor
int buttonState = 0;
int manager = 0;
int st = 0;
int led = D0;
int line = 0;
int go = 0;
int Bled = D4;
#define relaytwo 15
#define relay 0 //answer
//int pin0 = D0;
#define pinzero 1 //stepper
//int pin1 = D1;
#define pinuno 2 //stepper
//int pin2 = D2;
#define pindue 3 //stepper
//int pin3 = D3;
#define pintre 4 //stepper
#define dcinque 5
#define dsei 6
#define dsette 7
#define dotto 8
#define online 9
#define extrelay 10
#define p4 11
#define p5 12
#define p6 13
#define p7 14
char myvalue[25] = "KeyCommands";
String keyCommands = String(myvalue);
const char *mqtt_broker = "brokerName";
const char *topic = "InsertYourTopic";
const int mqtt_port = 1883; //port
const char* update_url = "link to ota remote upgrade of walkeremoteboard"; // URL for OTA upgrade
void(* resetFunc) (void) = 0;
WiFiClient espClient;
PubSubClient client(espClient);
long previousMillis = 0;
Adafruit_MCP23X17 mcp;
void setup() {
Serial.begin(9600);
//WiFiManager.setTimeout(60);
mcp.begin_I2C();
pinMode(led, OUTPUT);
pinMode(D0,INPUT);
mcp.pinMode(relay,OUTPUT);
mcp.pinMode(online, OUTPUT);
pinMode(Bled, OUTPUT);
// pinMode(9, FUNCTION_3); //rx PIN
//pinMode(9, OUTPUT);
//analogWrite(1, 100);
//analogWrite(03, LOW);
digitalWrite(Bled, HIGH);
digitalWrite(led, HIGH);
digitalWrite(D0, LOW);
mcp.pinMode(pinzero,OUTPUT);
mcp.pinMode(pinuno,OUTPUT);
mcp.pinMode(pindue,OUTPUT);
mcp.pinMode(extrelay,OUTPUT);
mcp.pinMode(p4,OUTPUT);
mcp.pinMode(p5,OUTPUT);
mcp.pinMode(p6,OUTPUT);
mcp.pinMode(p7,OUTPUT);
mcp.pinMode(pintre,OUTPUT);
mcp.pinMode(dcinque,OUTPUT);
mcp.pinMode(dsei,OUTPUT);
mcp.pinMode(dsette,OUTPUT);
mcp.pinMode(dotto,OUTPUT);
mcp.digitalWrite(dcinque,LOW);
mcp.pinMode(relaytwo, OUTPUT);
mcp.digitalWrite(dsei,LOW);
mcp.digitalWrite(dsette, LOW);
mcp.digitalWrite(dotto,LOW);
mcp.digitalWrite (pinzero,LOW);
mcp.digitalWrite (pinuno,LOW);
mcp.digitalWrite (pindue,LOW);
mcp.digitalWrite (pintre,LOW);
//mcp.digitalWrite (extrelay, HIGH);
//mcp.digitalWrite(charge, HIGH);
Serial.println(WiFi.macAddress());
Serial.println("Looping...");
//IPAddress staticIP(192, 168, 0, 24); // Your desired static IP address
//IPAddress gateway(192, 168, 0, 1); // Your router's IP address
//IPAddress subnet(255, 255, 255, 0); // Subnet mask
//IPAddress dns(8, 8, 8, 8); // DNS server address (Google DNS)
//WiFi.config(staticIP, gateway, subnet, dns);
// Set software serial baud to 115200;
// connecting to a WiFi network
//WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println(WiFi.macAddress());
Serial.println("Connecting to WiFi..");
mcp.digitalWrite(online,LOW);
manager++;
Serial.println(manager);
if (manager > 30){
WiFiManager wm;
wm.setTimeout(120);
bool res;
res = wm.autoConnect("walkeremoterelay01","password"); //insert the name of walkermoteboard(ssid) and the password to have access to wifi manager.
manager = 0;
wm.setCustomHeadElement("<style>html{filter: invert(100%); -webkit-filter: invert(100%);}</style>");
//delay(20000);
}
}
client.setKeepAlive(500);
//Serial.println("Connected to the WiFi network");
//WiFi.setAutoReconnect(true);
WiFi.persistent(true);
//connecting to a mqtt broker
client.setServer(mqtt_broker, mqtt_port);
client.setCallback(callback);
while (!client.connected()) {
String client_id = "mqttx_2dc8c784";
Serial.println("Connecting to public emqx mqtt broker.....");
//digitalWrite(D4,HIGH);
manager = 0;
//if (client.connect((char*)client_id.c_str(), mqtt_username, mqtt_password)) {
if (client.connect((char*)client_id.c_str())){
Serial.println("Public emqx mqtt broker connected");
Serial.println("the keycommands is: " + keyCommands);
mcp.digitalWrite(online,HIGH);
line = 1;
} else{
mcp.digitalWrite(online,LOW);
mcp.digitalWrite(dcinque,LOW);
pinMode(relaytwo, LOW);
mcp.digitalWrite(dsei,LOW);
mcp.digitalWrite(dsette, LOW);
mcp.digitalWrite(dotto,LOW);
line = 0;
manager = 0;
//Serial.print("failed with state ");
//Serial.print(client.state());
//digitalWrite(D4, HIGH);
delay(2000);
Serial.println("client disconnected");
riparti();
}}
/////////battery/////////////////////
for(unsigned int i=0;i<10;i++){
Vvalue=Vvalue+analogRead(BAT); //Read analog Voltage
delay(5); //ADC stable
}
String v;
//String vString = String(v);
Vvalue=(float)Vvalue/10.0; //Find average of 10 values
Rvalue=(float)(Vvalue/1024.0)*5; //Convert Voltage in 5v factor
Tvoltage=Rvalue*RatioFactor; //Find original voltage by multiplying with factor
delay(1);
/////////////////////////////////////Battery Voltage//////////////////////////////////
float minVoltage = 4.42;
float maxVoltage = 7.88;
Serial.println(Tvoltage);
float batteryPercentage = ((Tvoltage - minVoltage) / (maxVoltage - minVoltage)) * 100.0;
batteryPercentage = constrain(batteryPercentage, 0, 100);
///send email in case of batteryPercerntage <50% ///////////
///////////////////////////////////////////////////////
Serial.print("the battery percentage is: ");
Serial.println(batteryPercentage);
if (batteryPercentage < 25 && battcheck == 0) {
sendemail();
}
String batteryPercentageStr = String(batteryPercentage);
////////////////////////////////////
// publish and subscribe
client.publish(topic, "online00000000000000000000000000000000"); //online + keycommand
// client.publish(topic, v.c_str());
String message = "voltage" + batteryPercentageStr;
//client.publish(topic, "voltage" batteryPercentageStr.c_str()); //voltage
client.publish(topic, message.c_str());
client.subscribe(topic);
}
void callback(char *topic, byte *payload, unsigned int length) {
//Serial.print("Message arrived in topic: ");
//Serial.println(topic);
//Serial.print("Message:");
String message;
for (int i = 0; i < length; i++) {
message = message + (char) payload[i]; // convert *byte to string
// Serial.println(message);
}
if (message == "79452" + keyCommands) {
go = 1;
Serial.println("right arived");
mcp.digitalWrite(dcinque,LOW);
mcp.digitalWrite(dsei,HIGH);
mcp.digitalWrite(dsette, LOW);
mcp.digitalWrite(dotto,HIGH);
//mcp.digitalWrite(relay,LOW);
mcp.digitalWrite(relaytwo,LOW);
previousMillis = millis();
}else{Serial.println(message);}
////////////////////////battery voltage/////////////////////////
if (message == "reboot" + keyCommands) {
setup();
}
//////////////////////////////////////////////////////////
if (message == "command" + keyCommands) {
//mcp.digitalWrite(relay, LOW);
mcp.digitalWrite(relaytwo,LOW);
Serial.println("stop arived");
mcp.digitalWrite(dcinque,LOW);
mcp.digitalWrite(dsei,LOW);
mcp.digitalWrite(dsette,LOW);
mcp.digitalWrite(dotto,LOW);
//mcp.digitalWrite(charge , LOW);
//mcp.digitalWrite (extrelay, LOW); //mcpPin3
go = 0;
previousMillis = millis();
}
if (message == "command" + keyCommands) {
go = 1;
Serial.println("left arived");
mcp.digitalWrite(dcinque,HIGH);
mcp.digitalWrite(dsei,LOW);
mcp.digitalWrite(dsette, HIGH);
mcp.digitalWrite(dotto,LOW);
//mcp.digitalWrite(relay , LOW);
mcp.digitalWrite(relaytwo,LOW);
previousMillis = millis();
}
if (message == "command" + keyCommands) {
go = 1;
Serial.println("bottom arived");
mcp.digitalWrite(dcinque,LOW);
mcp.digitalWrite(dsei,HIGH);
mcp.digitalWrite(dsette, HIGH);
mcp.digitalWrite(dotto,LOW);
//mcp.digitalWrite(relay , LOW);
mcp.digitalWrite(relaytwo,LOW);
previousMillis = millis();
}
if (message == "command" + keyCommands) {
WiFi.disconnect();
ESP.reset();
delay(1000);
}
if (message == "command" + keyCommands) {
go = 1;
Serial.println("go arived");
mcp.digitalWrite(dcinque,HIGH);
mcp.digitalWrite(dsei,LOW);
mcp.digitalWrite(dsette, LOW);
mcp.digitalWrite(dotto,HIGH);
//mcp.digitalWrite(relay , LOW);
mcp.digitalWrite(relaytwo,LOW);
previousMillis = millis();
}
if (message == "command" + keyCommands ) {
//mcp.digitalWrite(relay, HIGH);
mcp.digitalWrite (extrelay, HIGH);
Serial.print("Light On");
}
if (message == "command" + keyCommands) {
//Serial.write(mystr , 2);
//mcp.digitalWrite(relay, LOW);
mcp.digitalWrite (extrelay, LOW);
Serial.print("Light off");
}
if (message == "command" + keyCommands ) { //p4
//mcp.digitalWrite(relay, HIGH);
mcp.digitalWrite (p4, HIGH);
Serial.print("Light On");
}
if (message == "command" + keyCommands) {
//Serial.write(mystr , 2);
//mcp.digitalWrite(relay, LOW);
mcp.digitalWrite (p4, LOW);
Serial.print("Light off");
}
if (message == "command" + keyCommands ) {
//mcp.digitalWrite(relay, HIGH);
mcp.digitalWrite (p5, HIGH);
Serial.print("Light On");
}
if (message == "command" + keyCommands) {
//Serial.write(mystr , 2);
//mcp.digitalWrite(relay, LOW);
mcp.digitalWrite (p5, LOW);
Serial.print("Light off");
}
if (message == "command" + keyCommands ) {
//mcp.digitalWrite(relay, HIGH);
mcp.digitalWrite (p6, HIGH);
Serial.print("Light On");
}
if (message == "command" + keyCommands) {
//Serial.write(mystr , 2);
//mcp.digitalWrite(relay, LOW);
mcp.digitalWrite (p6, LOW);
Serial.print("Light off");
}
if (message == "command" + keyCommands ) {
//mcp.digitalWrite(relay, HIGH);
mcp.digitalWrite (p7, HIGH);
Serial.print("Light On");
}
if (message == "command" + keyCommands) {
//Serial.write(mystr , 2);
//mcp.digitalWrite(relay, LOW);
mcp.digitalWrite (p7, LOW);
Serial.print("Light off");
}
if (message == "ota_update" + keyCommands) {
Serial.println("OTA Update Command Received");
otaUpdate();
}
if (message == "command" + keyCommands ) { //answer on
//mcp.digitalWrite(relay, HIGH);
mcp.digitalWrite (relay, HIGH);
Serial.print("autoanswer On");
Serial.print("TheKeyCommandsIs: " + keyCommands);
}
if (message == "command" + keyCommands) { //answer off
//Serial.write(mystr , 2);
//mcp.digitalWrite(relay, LOW);
mcp.digitalWrite (relay, LOW);
Serial.print("autoanswer off");
}
if(message =="command" + keyCommands){
Serial.println("sud sent");
for (int i=0;i<20;i++){
mcp.digitalWrite (pinzero,LOW); //step1
mcp.digitalWrite (pinuno,HIGH);
mcp.digitalWrite (pindue,HIGH);
mcp.digitalWrite (pintre,LOW);
//delay(1);
mcp.digitalWrite (pinzero,LOW); //step2
mcp.digitalWrite (pinuno,HIGH);
mcp.digitalWrite (pindue,LOW);
mcp.digitalWrite (pintre,HIGH);
//delay(1);
mcp.digitalWrite (pinzero,HIGH); //step3
mcp.digitalWrite (pinuno,LOW);
mcp.digitalWrite (pindue,LOW);
mcp.digitalWrite (pintre,HIGH);
//delay(1);
mcp.digitalWrite (pinzero,HIGH); //step4
mcp.digitalWrite (pinuno,LOW);
mcp.digitalWrite (pindue,HIGH);
mcp.digitalWrite (pintre,LOW);
//delay(1);
// myStepper3.step(1);
if (i>3){
mcp.digitalWrite (pinzero,LOW);
mcp.digitalWrite (pinuno,LOW);
mcp.digitalWrite (pindue,LOW);
mcp.digitalWrite (pintre,LOW);
}
}
}
if(message == "3398725" + keyCommands){
Serial.println("nord sent");
for (int i=0;i<20;i++){
mcp.digitalWrite(pinzero, HIGH); // Step 1 - reversed
mcp.digitalWrite(pindue, LOW);
mcp.digitalWrite(pinuno, LOW);
mcp.digitalWrite(pintre, HIGH);
mcp.digitalWrite(pinzero, LOW); // Step 2 - reversed
mcp.digitalWrite(pindue, LOW);
mcp.digitalWrite(pinuno, HIGH);
mcp.digitalWrite(pintre, LOW);
mcp.digitalWrite(pinzero, LOW); // Step 3 - reversed
mcp.digitalWrite(pindue, HIGH);
mcp.digitalWrite(pinuno, HIGH);
mcp.digitalWrite(pintre, LOW);
mcp.digitalWrite(pinzero, HIGH); // Step 4 - reversed
mcp.digitalWrite(pindue, HIGH);
mcp.digitalWrite(pinuno, LOW);
mcp.digitalWrite(pintre, LOW);
if (i>3){
mcp.digitalWrite (pinzero,LOW);
mcp.digitalWrite (pinuno,LOW);
mcp.digitalWrite (pindue,LOW);
mcp.digitalWrite (pintre,LOW);
}
}
}
//Serial.println();
//Serial.println("-----------------------");
}
void loop() {
if (go == 1 && !client.connected()){
mcp.digitalWrite(dcinque,LOW);
mcp.digitalWrite(dsei,LOW);
mcp.digitalWrite(dsette, LOW);
mcp.digitalWrite(dotto,LOW);
delay(2000);
mcp.digitalWrite(dcinque,LOW);
mcp.digitalWrite(dsei,HIGH);
mcp.digitalWrite(dsette, HIGH);
mcp.digitalWrite(dotto,LOW);
//mcp.digitalWrite(relay , LOW);
mcp.digitalWrite(relaytwo,LOW);
delay(20000);
mcp.digitalWrite(dcinque,LOW);
mcp.digitalWrite(dsei,LOW);
mcp.digitalWrite(dsette, LOW);
mcp.digitalWrite(dotto,LOW);
//mcp.digitalWrite(relay , LOW);
mcp.digitalWrite(relaytwo,LOW);
delay(2000);
ESP.reset();
}
buttonState = digitalRead(D0);
if (buttonState == HIGH){
WiFi.disconnect();
ESP.reset();
delay(1000);
}
if(line == 1){
mcp.digitalWrite(online, HIGH);
}
if(line == 0){
mcp.digitalWrite(online, LOW);
}
unsigned long currentMillis = millis();
//mcp.digitalWrite(charge,HIGH);
//mcp.digitalWrite(charge, LOW);
if(currentMillis - previousMillis > 10000) {
//mcp.digitalWrite(relay,HIGH);
mcp.digitalWrite(relaytwo,HIGH);
st = 0;
}
if(currentMillis - previousMillis > 180000) {
previousMillis = currentMillis;
currentMillis = 0;
//resetFunc();
battcheck = 0;
riparti();
//setup();
}
client.loop();
//Serial.write(mystr,6);
}
void riparti(){
setup();
}
void otaUpdate() {
mcp.digitalWrite(online ,LOW);
digitalWrite(Bled, LOW);
WiFiClientSecure client;
client.setInsecure();
HTTPClient http;
http.begin(client, update_url);
// Callback upgrade progress
ESPhttpUpdate.onProgress([](int current, int total) {
Serial.printf("Progress: %d%%\n", (current * 100) / total);
});
Serial.println("starting ota update...");
t_httpUpdate_return ret = ESPhttpUpdate.update(client, update_url);
switch(ret) {
case HTTP_UPDATE_FAILED:
Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s\n", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
ESP.reset();
break;
case HTTP_UPDATE_NO_UPDATES:
Serial.println("HTTP_UPDATE_NO_UPDATES");
break;
case HTTP_UPDATE_OK:
Serial.println("HTTP_UPDATE_OK"); //in this case the upgrade was ok
break;
}
http.end();
}
void sendemail() {
SMTP_Message message;
message.sender.name = "walkeremoteRelay01";
message.sender.email = AUTHOR_EMAIL;
message.subject = "critical battery level";
message.addRecipient("Driver", RECIPIENT_EMAIL);
String htmlMsg = "<div style=\"color:#2f4468;\"><h1><blink>Low Battery</blink></h1><p>The Battery percentage of walkeremote113 is < 25% (about7,5/12 v),need charge</p></div>";
//String formattedHtmlMsg = String::format(htmlMsg.c_str(), batteryPercentage);
message.html.content = htmlMsg.c_str();
message.html.charSet = "us-ascii";
message.html.transfer_encoding = Content_Transfer_Encoding::enc_7bit;
ESP_Mail_Session session;
session.server.host_name = SMTP_HOST;
session.server.port = SMTP_PORT;
session.login.email = AUTHOR_EMAIL;
session.login.password = AUTHOR_PASSWORD;
session.login.user_domain = "";
if (!smtp.connect(&session)) {
Serial.println("Connessione SMTP fallita.");
return;
}
if (!MailClient.sendMail(&smtp, &message)) {
Serial.println("Invio email fallito.");
} else {
Serial.println("Email inviata con successo.");
battcheck = 1;
delay(1000);
riparti();
}
}
WalkeremoteBoard
*PCBWay community is a sharing platform. We are not responsible for any design issues and parameter issues (board thickness, surface finish, etc.) you choose.
- Comments(0)
- Likes(0)
- 0 USER VOTES
- YOUR VOTE 0.00 0.00
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
More by Michele Tavolacci
-
WalkeremoteBoard
The WalkeremoteBoard is an IoT development board designed to enable remote monitoring and control of...
-
WalkeremoteBoard Rev3
The WalkeremoteBoard Rev 3 is a compact and efficient control board built around the ESP8266 Wi-Fi m...
-
actionoiseNoise-Bridge
With this Small Board connected to the mobile or notebook will be possible to take control from remo...
-
Playpad for Actionoiseboard
This board is like a joypad but is not the same because instead of to send i/o signal to a consolle ...
-
ACTIONOISEBOARD for telepresence with a simple videocall,NO CLOUD REQUIRED....!!!
First of all, I would like to thank you in advance for reading , because it means that this project ...
-
remote module for actionoiseboard
with this board will be possible to take control from remote of 4 relays or more for control light f...
-
-
AEL-2011 Power Supply Module
319 0 1 -
AEL-2011 50W Power Amplifier
292 0 1 -
-
-
Custom Mechanical Keyboard
562 0 0 -
Tester for Touch Screen Digitizer without using microcontroller
228 2 2 -
Audio reactive glow LED wristband/bracelet with NFC / RFID-Tags
233 0 1 -
-
-







