-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
329 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2021 Ujwal Nandanwar | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# WiFiCar | ||
This repository contains the code and diagram for WiFi car using esp32 and programmed using Arduino IDE |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,293 @@ | ||
#include <Arduino.h> | ||
#ifdef ESP32 | ||
#include <WiFi.h> | ||
#include <AsyncTCP.h> | ||
#elif defined(ESP8266) | ||
#include <ESP8266WiFi.h> | ||
#include <ESPAsyncTCP.h> | ||
#endif | ||
#include <ESPAsyncWebServer.h> | ||
|
||
#define UP 1 | ||
#define DOWN 2 | ||
#define LEFT 3 | ||
#define RIGHT 4 | ||
// #define UP_LEFT 5 | ||
// #define UP_RIGHT 6 | ||
// #define DOWN_LEFT 7 | ||
// #define DOWN_RIGHT 8 | ||
#define TURN_LEFT 9 | ||
#define TURN_RIGHT 10 | ||
#define STOP 0 | ||
|
||
#define FRONT_RIGHT_MOTOR 0 | ||
// #define BACK_RIGHT_MOTOR 1 | ||
#define FRONT_LEFT_MOTOR 1 | ||
// #define BACK_LEFT_MOTOR 3 | ||
|
||
#define FORWARD 1 | ||
#define BACKWARD -1 | ||
|
||
struct MOTOR_PINS | ||
{ | ||
int pinIN1; | ||
int pinIN2; | ||
}; | ||
|
||
std::vector<MOTOR_PINS> motorPins = | ||
{ | ||
{25, 33}, //FRONT_RIGHT_MOTOR | ||
{27, 26}, //FRONT_LEFT_MOTOR | ||
}; | ||
|
||
const char* ssid = "Wifi_Robo"; | ||
const char* password = "abhar123"; | ||
|
||
AsyncWebServer server(80); | ||
AsyncWebSocket ws("/ws"); | ||
|
||
|
||
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> | ||
.arrows { | ||
font-size:70px; | ||
color:red; | ||
} | ||
.circularArrows { | ||
font-size:80px; | ||
color:blue; | ||
} | ||
td { | ||
background-color:black; | ||
border-radius:25%; | ||
box-shadow: 5px 5px #888888; | ||
} | ||
td:active { | ||
transform: translate(5px,5px); | ||
box-shadow: none; | ||
} | ||
.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 */ | ||
} | ||
</style> | ||
</head> | ||
<body class="noselect" align="center" style="background-color:white"> | ||
<h1 style="color: teal;text-align:center;">Movement Controller</h1> | ||
<h2 style="color: teal;text-align:center;">Control ABHAR with Wi-Fi</h2> | ||
<table id="mainTable" style="width:400px;margin:auto;table-layout:fixed" CELLSPACING=10> | ||
<tr> | ||
<td style="background-color:white;box-shadow:none"></td><!-- <td ontouchstart='onTouchStartAndEnd("5")' ontouchend='onTouchStartAndEnd("0")'><span class="arrows" >⬉</span></td> --> | ||
<td ontouchstart='onTouchStartAndEnd("1")' ontouchend='onTouchStartAndEnd("0")'><span class="arrows" >⇧</span></td> | ||
<td style="background-color:white;box-shadow:none"></td><!-- <td ontouchstart='onTouchStartAndEnd("6")' ontouchend='onTouchStartAndEnd("0")'><span class="arrows" >⬈</span></td> --> | ||
</tr> | ||
<tr> | ||
<td ontouchstart='onTouchStartAndEnd("3")' ontouchend='onTouchStartAndEnd("0")'><span class="arrows" >⇦</span></td> | ||
<td style="background-color:white;box-shadow:none"></td> | ||
<td ontouchstart='onTouchStartAndEnd("4")' ontouchend='onTouchStartAndEnd("0")'><span class="arrows" >⇨</span></td> | ||
</tr> | ||
<tr> | ||
<td style="background-color:white;box-shadow:none"></td><!-- <td ontouchstart='onTouchStartAndEnd("7")' ontouchend='onTouchStartAndEnd("0")'><span class="arrows" >⬋</span></td> --> | ||
<td ontouchstart='onTouchStartAndEnd("2")' ontouchend='onTouchStartAndEnd("0")'><span class="arrows" >⇩</span></td> | ||
<td style="background-color:white;box-shadow:none"></td><!-- <td ontouchstart='onTouchStartAndEnd("8")' ontouchend='onTouchStartAndEnd("0")'><span class="arrows" >⬊</span></td> --> | ||
</tr> | ||
<tr> | ||
<td ontouchstart='onTouchStartAndEnd("9")' ontouchend='onTouchStartAndEnd("0")'><span class="circularArrows" >↺</span></td> | ||
<td style="background-color:white;box-shadow:none"></td> | ||
<td ontouchstart='onTouchStartAndEnd("10")' ontouchend='onTouchStartAndEnd("0")'><span class="circularArrows" >↻</span></td> | ||
</tr> | ||
</table> | ||
<script> | ||
var webSocketUrl = "ws:\/\/" + window.location.hostname + "/ws"; | ||
var websocket; | ||
function initWebSocket() | ||
{ | ||
websocket = new WebSocket(webSocketUrl); | ||
websocket.onopen = function(event){}; | ||
websocket.onclose = function(event){setTimeout(initWebSocket, 2000);}; | ||
websocket.onmessage = function(event){}; | ||
} | ||
function onTouchStartAndEnd(value) | ||
{ | ||
websocket.send(value); | ||
} | ||
window.onload = initWebSocket; | ||
document.getElementById("mainTable").addEventListener("touchend", function(event){ | ||
event.preventDefault() | ||
}); | ||
</script> | ||
</body> | ||
</html> | ||
)HTMLHOMEPAGE"; | ||
|
||
|
||
void rotateMotor(int motorNumber, int motorDirection) | ||
{ | ||
if (motorDirection == FORWARD) | ||
{ | ||
digitalWrite(motorPins[motorNumber].pinIN1, HIGH); | ||
digitalWrite(motorPins[motorNumber].pinIN2, LOW); | ||
} | ||
else if (motorDirection == BACKWARD) | ||
{ | ||
digitalWrite(motorPins[motorNumber].pinIN1, LOW); | ||
digitalWrite(motorPins[motorNumber].pinIN2, HIGH); | ||
} | ||
else | ||
{ | ||
digitalWrite(motorPins[motorNumber].pinIN1, LOW); | ||
digitalWrite(motorPins[motorNumber].pinIN2, LOW); | ||
} | ||
} | ||
|
||
void processCarMovement(String inputValue) | ||
{ | ||
Serial.printf("Got value as %s %d\n", inputValue.c_str(), inputValue.toInt()); | ||
switch(inputValue.toInt()) | ||
{ | ||
|
||
case UP: | ||
rotateMotor(FRONT_RIGHT_MOTOR, FORWARD); | ||
// rotateMotor(BACK_RIGHT_MOTOR, FORWARD); | ||
rotateMotor(FRONT_LEFT_MOTOR, FORWARD); | ||
// rotateMotor(BACK_LEFT_MOTOR, FORWARD); | ||
break; | ||
|
||
case DOWN: | ||
rotateMotor(FRONT_RIGHT_MOTOR, BACKWARD); | ||
// rotateMotor(BACK_RIGHT_MOTOR, BACKWARD); | ||
rotateMotor(FRONT_LEFT_MOTOR, BACKWARD); | ||
// rotateMotor(BACK_LEFT_MOTOR, BACKWARD); | ||
break; | ||
|
||
case LEFT: | ||
rotateMotor(FRONT_RIGHT_MOTOR, FORWARD); | ||
// rotateMotor(BACK_RIGHT_MOTOR, BACKWARD); | ||
rotateMotor(FRONT_LEFT_MOTOR, BACKWARD); | ||
// rotateMotor(BACK_LEFT_MOTOR, FORWARD); | ||
break; | ||
|
||
case RIGHT: | ||
rotateMotor(FRONT_RIGHT_MOTOR, BACKWARD); | ||
// rotateMotor(BACK_RIGHT_MOTOR, FORWARD); | ||
rotateMotor(FRONT_LEFT_MOTOR, FORWARD); | ||
// rotateMotor(BACK_LEFT_MOTOR, BACKWARD); | ||
break; | ||
|
||
case STOP: | ||
rotateMotor(FRONT_RIGHT_MOTOR, STOP); | ||
// rotateMotor(BACK_RIGHT_MOTOR, STOP); | ||
rotateMotor(FRONT_LEFT_MOTOR, STOP); | ||
// rotateMotor(BACK_LEFT_MOTOR, STOP); | ||
break; | ||
|
||
default: | ||
rotateMotor(FRONT_RIGHT_MOTOR, STOP); | ||
// rotateMotor(BACK_RIGHT_MOTOR, STOP); | ||
rotateMotor(FRONT_LEFT_MOTOR, STOP); | ||
// rotateMotor(BACK_LEFT_MOTOR, STOP); | ||
break; | ||
} | ||
} | ||
|
||
void handleRoot(AsyncWebServerRequest *request) | ||
{ | ||
request->send_P(200, "text/html", htmlHomePage); | ||
} | ||
|
||
void handleNotFound(AsyncWebServerRequest *request) | ||
{ | ||
request->send(404, "text/plain", "File Not Found"); | ||
} | ||
|
||
|
||
void onWebSocketEvent(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()); | ||
//client->text(getRelayPinsStatusJson(ALL_RELAY_PINS_INDEX)); | ||
break; | ||
case WS_EVT_DISCONNECT: | ||
Serial.printf("WebSocket client #%u disconnected\n", client->id()); | ||
processCarMovement("0"); | ||
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); | ||
processCarMovement(myData.c_str()); | ||
} | ||
break; | ||
case WS_EVT_PONG: | ||
case WS_EVT_ERROR: | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
|
||
void setUpPinModes() | ||
{ | ||
for (int i = 0; i < motorPins.size(); i++) | ||
{ | ||
pinMode(motorPins[i].pinIN1, OUTPUT); | ||
pinMode(motorPins[i].pinIN2, OUTPUT); | ||
rotateMotor(i, STOP); | ||
} | ||
} | ||
|
||
|
||
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); | ||
|
||
ws.onEvent(onWebSocketEvent); | ||
server.addHandler(&ws); | ||
|
||
server.begin(); | ||
Serial.println("HTTP server started"); | ||
} | ||
|
||
void loop() | ||
{ | ||
ws.cleanupClients(); | ||
} |