Servo + NodeMCU Esp8266
Download file BIN:
Coding 1
( Link Simulasi: https://wokwi.com/projects/343390109446439507 )
Servo + NodeMCU Esp8266:
#include <Servo.h>
Servo myservo;
int sudut= 90;
void setup(){
myservo.attach(D0);
}
void loop(){
myservo.write(sudut);
}
Coding 2
Servo + OTA + NodeMCU Esp8266
/*******************
Servo Gerak 3 Sudut dg Esp8266
plus:
- AccessPoint AP
- WebServer
- OTA
iot2 - fajar himawan
********************/
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ArduinoOTA.h>
#include <Servo.h>
Servo myservo;
int sudut1= 0;
int sudut2= 90;
int sudut3= 180;
const int wifiLedPin = D0; // set digital pin D0 as indication, the LED turn on if NodeMCU connected to WiFi as STA mode
ESP8266WebServer server(80); // Create a webserver object that listens for HTTP request on port 80
unsigned long previousMillis = 0;
String sta_ssid = "ota"; // set Wifi networks you want to connect to
String sta_password = "12345678"; // set password for Wifi networks
void setup(){
myservo.attach(D4);
Serial.begin(115200); // set up Serial library at 115200 bps
Serial.println();
Serial.println("*WiFi Robot Remote Control Mode - L298N 2A*");
Serial.println("------------------------------------------------");
pinMode(wifiLedPin, OUTPUT); // sets the Wifi LED pin as an Output
digitalWrite(wifiLedPin, HIGH);
// set NodeMCU Wifi hostname based on chip mac address
String chip_id = String(ESP.getChipId(), HEX);
int i = chip_id.length()-4;
chip_id = chip_id.substring(i);
chip_id = "07-IOT-" + chip_id;
String hostname(chip_id);
Serial.println();
Serial.println("Hostname: "+hostname);
// first, set NodeMCU as STA mode to connect with a Wifi network
WiFi.mode(WIFI_STA);
WiFi.begin(sta_ssid.c_str(), sta_password.c_str());
Serial.println("");
Serial.print("Connecting to: ");
Serial.println(sta_ssid);
Serial.print("Password: ");
Serial.println(sta_password);
// try to connect with Wifi network about 1 seconds
unsigned long currentMillis = millis();
previousMillis = currentMillis;
while (WiFi.status() != WL_CONNECTED && currentMillis - previousMillis <= 1500) {
delay(500);
Serial.print(".");
currentMillis = millis();
}
// if failed to connect with Wifi network set NodeMCU as AP mode
if (WiFi.status() == WL_CONNECTED) {
Serial.println("");
Serial.println("*WiFi-STA-Mode*");
Serial.print("IP: ");
Serial.println(WiFi.localIP());
digitalWrite(wifiLedPin, LOW); // Wifi LED on when connected to Wifi as STA mode
delay(3000);
} else {
WiFi.mode(WIFI_AP);
WiFi.softAP(hostname.c_str());
IPAddress myIP = WiFi.softAPIP();
Serial.println("");
Serial.println("WiFi failed connected to " + sta_ssid);
Serial.println("");
Serial.println("*WiFi-AP-Mode*");
Serial.print("AP IP address: ");
Serial.println(myIP);
digitalWrite(wifiLedPin, HIGH); // Wifi LED off when status as AP mode
delay(1000);
}
server.on ( "/", HTTP_handleRoot ); // call the 'handleRoot' function when a client requests URI "/"
server.onNotFound ( HTTP_handleRoot ); // when a client requests an unknown URI (i.e. something other than "/"), call function "handleNotFound"
server.begin(); // actually start the server
ArduinoOTA.begin(); // enable to receive update/uploade firmware via Wifi OTA
}
void loop() {
ArduinoOTA.handle(); // listen for update OTA request from clients
server.handleClient(); // listen for HTTP requests from clients
delay (1000);
myservo.write(sudut1);
delay (1000);
myservo.write(sudut2);
delay (1000);
myservo.write(sudut3);
}
// function prototypes for HTTP handlers
void HTTP_handleRoot(void){
server.send ( 200, "text/html", "" ); // Send HTTP status 200 (Ok) and send some text to the browser/client
if( server.hasArg("State") ){
Serial.println(server.arg("State"));
}
}
void handleNotFound(){
server.send(404, "text/plain", "404: Not found"); // Send HTTP status 404 (Not Found) when there's no handler for the URI in the request
}
Coding 3
Servo + RECORD + NodeMCU Esp8266
Rekam Gerak Servo ESP8266
/*
#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <ESP32Servo.h>
#include <iostream>
#include <sstream>
*/
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <Servo.h>
#include <iostream>
#include <sstream>
#include <ArduinoOTA.h>
struct ServoPins
{
Servo servo;
int servoPin;
String servoName;
int initialPosition;
};
std::vector<ServoPins> servoPins =
{
{ Servo(), D1 , "Base", 90},
{ Servo(), D2 , "Shoulder", 90},
{ Servo(), D3 , "Elbow", 90},
{ Servo(), D4 , "Gripper", 90},
};
struct RecordedStep
{
int servoIndex;
int value;
int delayInStep;
};
std::vector<RecordedStep> recordedSteps;
bool recordSteps = false;
bool playRecordedSteps = false;
unsigned long previousTimeInMilli = millis();
const char* ssid = "wificarjurnalku";
const char* password = "wificarjurnalku";
AsyncWebServer server(80);
AsyncWebSocket wsRobotArmInput("/RobotArmInput");
const char* htmlHomePage PROGMEM = R"HTMLHOMEPAGE(
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<style>
input[type=button]
{
background-color:red;color:white;border-radius:30px;width:100%;height:40px;font-size:20px;text-align:center;
}
.noselect {
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently
supported by Chrome and Opera */
}
.slidecontainer {
width: 100%;
}
.slider {
-webkit-appearance: none;
width: 100%;
height: 20px;
border-radius: 5px;
background: #d3d3d3;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
}
.slider:hover {
opacity: 1;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 40px;
height: 40px;
border-radius: 50%;
background: red;
cursor: pointer;
}
.slider::-moz-range-thumb {
width: 40px;
height: 40px;
border-radius: 50%;
background: red;
cursor: pointer;
}
</style>
</head>
<body class="noselect" align="center" style="background-color:white">
<h1 style="color: teal;text-align:center;">Hash Include Electronics</h1>
<h2 style="color: teal;text-align:center;">Robot Arm Control</h2>
<table id="mainTable" style="width:400px;margin:auto;table-layout:fixed" CELLSPACING=10>
<tr/><tr/>
<tr/><tr/>
<tr>
<td style="text-align:left;font-size:25px"><b>Gripper:</b></td>
<td colspan=2>
<div class="slidecontainer">
<input type="range" min="0" max="180" value="90" class="slider" id="Gripper" oninput='sendButtonInput("Gripper",value)'>
</div>
</td>
</tr>
<tr/><tr/>
<tr>
<td style="text-align:left;font-size:25px"><b>Elbow:</b></td>
<td colspan=2>
<div class="slidecontainer">
<input type="range" min="0" max="180" value="90" class="slider" id="Elbow" oninput='sendButtonInput("Elbow",value)'>
</div>
</td>
</tr>
<tr/><tr/>
<tr>
<td style="text-align:left;font-size:25px"><b>Shoulder:</b></td>
<td colspan=2>
<div class="slidecontainer">
<input type="range" min="0" max="180" value="90" class="slider" id="Shoulder" oninput='sendButtonInput("Shoulder",value)'>
</div>
</td>
</tr>
<tr/><tr/>
<tr>
<td style="text-align:left;font-size:25px"><b>Base:</b></td>
<td colspan=2>
<div class="slidecontainer">
<input type="range" min="0" max="180" value="90" class="slider" id="Base" oninput='sendButtonInput("Base",value)'>
</div>
</td>
</tr>
<tr/><tr/>
<tr>
<td style="text-align:left;font-size:25px"><b>Record:</b></td>
<td><input type="button" id="Record" value="OFF" ontouchend='onclickButton(this)'></td>
<td></td>
</tr>
<tr/><tr/>
<tr>
<td style="text-align:left;font-size:25px"><b>Play:</b></td>
<td><input type="button" id="Play" value="OFF" ontouchend='onclickButton(this)'></td>
<td></td>
</tr>
</table>
<script>
var webSocketRobotArmInputUrl = "ws:\/\/" + window.location.hostname + "/RobotArmInput";
var websocketRobotArmInput;
function initRobotArmInputWebSocket()
{
websocketRobotArmInput = new WebSocket(webSocketRobotArmInputUrl);
websocketRobotArmInput.onopen = function(event){};
websocketRobotArmInput.onclose = function(event){setTimeout(initRobotArmInputWebSocket, 2000);};
websocketRobotArmInput.onmessage = function(event)
{
var keyValue = event.data.split(",");
var button = document.getElementById(keyValue[0]);
button.value = keyValue[1];
if (button.id == "Record" || button.id == "Play")
{
button.style.backgroundColor = (button.value == "ON" ? "green" : "red");
enableDisableButtonsSliders(button);
}
};
}
function sendButtonInput(key, value)
{
var data = key + "," + value;
websocketRobotArmInput.send(data);
}
function onclickButton(button)
{
button.value = (button.value == "ON") ? "OFF" : "ON" ;
button.style.backgroundColor = (button.value == "ON" ? "green" : "red");
var value = (button.value == "ON") ? 1 : 0 ;
sendButtonInput(button.id, value);
enableDisableButtonsSliders(button);
}
function enableDisableButtonsSliders(button)
{
if(button.id == "Play")
{
var disabled = "auto";
if (button.value == "ON")
{
disabled = "none";
}
document.getElementById("Gripper").style.pointerEvents = disabled;
document.getElementById("Elbow").style.pointerEvents = disabled;
document.getElementById("Shoulder").style.pointerEvents = disabled;
document.getElementById("Base").style.pointerEvents = disabled;
document.getElementById("Record").style.pointerEvents = disabled;
}
if(button.id == "Record")
{
var disabled = "auto";
if (button.value == "ON")
{
disabled = "none";
}
document.getElementById("Play").style.pointerEvents = disabled;
}
}
window.onload = initRobotArmInputWebSocket;
document.getElementById("mainTable").addEventListener("touchend", function(event){
event.preventDefault()
});
</script>
</body>
</html>
)HTMLHOMEPAGE";
void handleRoot(AsyncWebServerRequest *request)
{
request->send_P(200, "text/html", htmlHomePage);
}
void handleNotFound(AsyncWebServerRequest *request)
{
request->send(404, "text/plain", "File Not Found");
}
void onRobotArmInputWebSocketEvent(AsyncWebSocket *server,
AsyncWebSocketClient *client,
AwsEventType type,
void *arg,
uint8_t *data,
size_t len)
{
switch (type)
{
case WS_EVT_CONNECT:
Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
sendCurrentRobotArmState();
break;
case WS_EVT_DISCONNECT:
Serial.printf("WebSocket client #%u disconnected\n", client->id());
break;
case WS_EVT_DATA:
AwsFrameInfo *info;
info = (AwsFrameInfo*)arg;
if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT)
{
std::string myData = "";
myData.assign((char *)data, len);
std::istringstream ss(myData);
std::string key, value;
std::getline(ss, key, ',');
std::getline(ss, value, ',');
Serial.printf("Key [%s] Value[%s]\n", key.c_str(), value.c_str());
int valueInt = atoi(value.c_str());
if (key == "Record")
{
recordSteps = valueInt;
if (recordSteps)
{
recordedSteps.clear();
previousTimeInMilli = millis();
}
}
else if (key == "Play")
{
playRecordedSteps = valueInt;
}
else if (key == "Base")
{
writeServoValues(0, valueInt);
}
else if (key == "Shoulder")
{
writeServoValues(1, valueInt);
}
else if (key == "Elbow")
{
writeServoValues(2, valueInt);
}
else if (key == "Gripper")
{
writeServoValues(3, valueInt);
}
}
break;
case WS_EVT_PONG:
case WS_EVT_ERROR:
break;
default:
break;
}
}
void sendCurrentRobotArmState()
{
for (int i = 0; i < servoPins.size(); i++)
{
wsRobotArmInput.textAll(servoPins[i].servoName + "," + servoPins[i].servo.read());
}
wsRobotArmInput.textAll(String("Record,") + (recordSteps ? "ON" : "OFF"));
wsRobotArmInput.textAll(String("Play,") + (playRecordedSteps ? "ON" : "OFF"));
}
void writeServoValues(int servoIndex, int value)
{
if (recordSteps)
{
RecordedStep recordedStep;
if (recordedSteps.size() == 0) // We will first record initial position of all servos.
{
for (int i = 0; i < servoPins.size(); i++)
{
recordedStep.servoIndex = i;
recordedStep.value = servoPins[i].servo.read();
recordedStep.delayInStep = 0;
recordedSteps.push_back(recordedStep);
}
}
unsigned long currentTime = millis();
recordedStep.servoIndex = servoIndex;
recordedStep.value = value;
recordedStep.delayInStep = currentTime - previousTimeInMilli;
recordedSteps.push_back(recordedStep);
previousTimeInMilli = currentTime;
}
servoPins[servoIndex].servo.write(value);
}
void playRecordedRobotArmSteps()
{
if (recordedSteps.size() == 0)
{
return;
}
//This is to move servo to initial position slowly. First 4 steps are initial position
for (int i = 0; i < 4 && playRecordedSteps; i++)
{
RecordedStep &recordedStep = recordedSteps[i];
int currentServoPosition = servoPins[recordedStep.servoIndex].servo.read();
while (currentServoPosition != recordedStep.value && playRecordedSteps)
{
currentServoPosition = (currentServoPosition > recordedStep.value ? currentServoPosition - 1 : currentServoPosition + 1);
servoPins[recordedStep.servoIndex].servo.write(currentServoPosition);
wsRobotArmInput.textAll(servoPins[recordedStep.servoIndex].servoName + "," + currentServoPosition);
delay(50);
}
}
delay(2000); // Delay before starting the actual steps.
for (int i = 4; i < recordedSteps.size() && playRecordedSteps ; i++)
{
RecordedStep &recordedStep = recordedSteps[i];
delay(recordedStep.delayInStep);
servoPins[recordedStep.servoIndex].servo.write(recordedStep.value);
wsRobotArmInput.textAll(servoPins[recordedStep.servoIndex].servoName + "," + recordedStep.value);
}
}
void setUpPinModes()
{
for (int i = 0; i < servoPins.size(); i++)
{
servoPins[i].servo.attach(servoPins[i].servoPin);
servoPins[i].servo.write(servoPins[i].initialPosition);
}
}
void setup(void)
{
setUpPinModes();
Serial.begin(115200);
WiFi.softAP(ssid, password);
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);
server.on("/", HTTP_GET, handleRoot);
server.onNotFound(handleNotFound);
wsRobotArmInput.onEvent(onRobotArmInputWebSocketEvent);
server.addHandler(&wsRobotArmInput);
server.begin();
Serial.println("HTTP server started");
ArduinoOTA.begin(); // enable to receive update/uploade firmware via Wifi OTA
}
void loop()
{
wsRobotArmInput.cleanupClients();
if (playRecordedSteps)
{
playRecordedRobotArmSteps();
ArduinoOTA.handle(); // listen for update OTA request from clients
}
}
No comments