This is an attempt to make it easy to control motors with a remote control over wifi using the ESP8266 board.
Last active
September 7, 2019 11:40
-
-
Save murilopolese/67c657863a14641df26abe670cb0da29 to your computer and use it in GitHub Desktop.
Fabulous Car!
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
// CODE FOR REMOTE CONTROLLED CAR USING 2 SERVOS | |
#include <Arduino.h> | |
#include <ESP8266WiFi.h> | |
#include <ESP8266WiFiMulti.h> | |
#include <WebSocketsServer.h> | |
#include <ESP8266WebServer.h> | |
#include <ESP8266mDNS.h> | |
#include <Hash.h> | |
#include <Servo.h> | |
#define USE_SERIAL Serial | |
#define PIN1 4 | |
#define PIN2 5 | |
Servo servo1, servo2; | |
ESP8266WebServer server (80); | |
ESP8266WiFiMulti WiFiMulti; | |
const char *ssid = "fabulouscar"; | |
const char *password = "bananabanana"; | |
WebSocketsServer webSocket = WebSocketsServer(81); | |
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { | |
switch(type) { | |
case WStype_DISCONNECTED: | |
USE_SERIAL.printf("[%u] Disconnected!\n", num); | |
break; | |
case WStype_CONNECTED: { | |
IPAddress ip = webSocket.remoteIP(num); | |
USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); | |
// send message to client | |
webSocket.sendTXT(num, "Connected"); | |
} | |
break; | |
case WStype_TEXT: | |
USE_SERIAL.printf("[%u] get Text: %s\n", num, payload); | |
String str((char*)payload); | |
parse_instructions(str); | |
break; | |
} | |
} | |
void parse_instructions(String str) | |
{ | |
int delimiter_pos = str.indexOf(" "); | |
String command = str.substring(0, delimiter_pos); // command | |
String params = str.substring(delimiter_pos+1); // parameter | |
if(command.equals("m1f")) { | |
// Motor 1 forward | |
servo1.attach(PIN1); | |
servo1.write(180); | |
} | |
if(command.equals("m1b")) { | |
// Motor 1 backward | |
servo1.attach(PIN1); | |
servo1.write(0); | |
} | |
if(command.equals("m1s")) { | |
// Motor 1 stop | |
servo1.detach(); | |
} | |
if(command.equals("m2f")) { | |
// Motor 2 forward | |
servo2.attach(PIN2); | |
servo2.write(0); | |
} | |
if(command.equals("m2b")) { | |
// Motor 2 backward | |
servo2.attach(PIN2); | |
servo2.write(180); | |
} | |
if(command.equals("m2s")) { | |
// Motor 2 stop | |
servo2.detach(); | |
} | |
if(command.equals("m1p")) { | |
// Motor 1 pwm | |
servo1.attach(PIN1); | |
servo1.write(params.toInt()); | |
} | |
if(command.equals("m2p")) { | |
// Motor 2 pwm | |
servo2.attach(PIN2); | |
servo2.write(params.toInt()); | |
} | |
} | |
void setup() { | |
//USE_SERIAL.begin(921600); | |
USE_SERIAL.begin(115200); | |
pinMode(PIN1, OUTPUT); | |
pinMode(PIN2, OUTPUT); | |
// servo1.attach(PIN1); | |
// servo2.attach(PIN2); | |
USE_SERIAL.setDebugOutput(true); | |
USE_SERIAL.println(); | |
USE_SERIAL.println(); | |
USE_SERIAL.println(); | |
for(uint8_t t = 4; t > 0; t--) { | |
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); | |
USE_SERIAL.flush(); | |
delay(1000); | |
} | |
// WiFiMulti.addAP("SSID", "XXX"); | |
// while(WiFiMulti.run() != WL_CONNECTED) { | |
// delay(100); | |
// } | |
USE_SERIAL.print("Setting soft-AP ... "); | |
WiFi.softAP(ssid, password); | |
IPAddress myIP = WiFi.softAPIP(); | |
USE_SERIAL.print("AP IP address: "); | |
USE_SERIAL.println(myIP); | |
// start webSocket server | |
webSocket.begin(); | |
webSocket.onEvent(webSocketEvent); | |
if(MDNS.begin("fabulouscar")) { | |
USE_SERIAL.println("MDNS responder started"); | |
} | |
// handle index | |
server.on("/", []() { | |
// send index.html | |
server.send(200, "text/html", "<meta charset=utf-8><title>Remote Control</title><meta content='width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no'name=viewport><style>.pad{width:50%;height:50%;position:absolute}</style><div style=width:100vw><div style=top:0;left:0;background:#6686b7 class=pad id=m1f></div><div style=top:50%;left:0;background:#54c1de class=pad id=m1b></div><div style=top:0;right:0;background:#ff5e63 class=pad id=m2f></div><div style=top:50%;right:0;background:#fcba55 class=pad id=m2b></div></div><script>window.onload=function(){boardPath=location.hash?location.hash.substring(1):location.hostname,connection=new WebSocket('ws://'+boardPath+':81/',['arduino']),connection.onopen=function(){connection.send('Connect '+new Date)},connection.onerror=function(e){console.log('WebSocket Error ',e)},connection.onmessage=function(e){console.log('Server: ',e.data)},createEvent=function(e){return function(t){console.log(e),t.preventDefault(),connection.send(e)}},registerEvents=function(e){forwardButton=document.getElementById('m'+e+'f'),backwardButton=document.getElementById('m'+e+'b'),forwardButton.addEventListener('touchstart',createEvent('m'+e+'f')),forwardButton.addEventListener('mousedown',createEvent('m'+e+'f')),forwardButton.addEventListener('touchend',createEvent('m'+e+'s')),forwardButton.addEventListener('mouseup',createEvent('m'+e+'s')),backwardButton.addEventListener('touchstart',createEvent('m'+e+'b')),backwardButton.addEventListener('mousedown',createEvent('m'+e+'b')),backwardButton.addEventListener('touchend',createEvent('m'+e+'s')),backwardButton.addEventListener('mouseup',createEvent('m'+e+'s'))},registerEvents(1),registerEvents(2)}</script>');"); | |
}); | |
server.begin(); | |
// Add service to MDNS | |
MDNS.addService("http", "tcp", 80); | |
MDNS.addService("ws", "tcp", 81); | |
} | |
void loop() { | |
webSocket.loop(); | |
server.handleClient(); | |
} |
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
// CODE FOR REMOTE CONTROLLED CAR USING DC MOTOR WITH H-BRIDGE (DRIVER) | |
// AND THE MOST REGULAR TOWER SERVO | |
#include <Arduino.h> | |
#include <ESP8266WiFi.h> | |
#include <ESP8266WiFiMulti.h> | |
#include <WebSocketsServer.h> | |
#include <ESP8266WebServer.h> | |
#include <ESP8266mDNS.h> | |
#include <Hash.h> | |
#include <Servo.h> | |
#define USE_SERIAL Serial | |
Servo servo; | |
int servoPin = 12; | |
int forwardPin = 5; | |
int backwardPin = 4; | |
ESP8266WiFiMulti WiFiMulti; | |
ESP8266WebServer server = ESP8266WebServer(80); | |
WebSocketsServer webSocket = WebSocketsServer(81); | |
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { | |
switch(type) { | |
case WStype_DISCONNECTED: | |
USE_SERIAL.printf("[%u] Disconnected!\n", num); | |
break; | |
case WStype_CONNECTED: { | |
IPAddress ip = webSocket.remoteIP(num); | |
USE_SERIAL.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload); | |
// send message to client | |
webSocket.sendTXT(num, "Connected"); | |
} | |
break; | |
case WStype_TEXT: | |
USE_SERIAL.printf("[%u] get Text: %s\n", num, payload); | |
String str((char*)payload); | |
parse_instructions(str); | |
break; | |
} | |
} | |
void parse_instructions(String str) | |
{ | |
int delimiter_pos = str.indexOf(" "); | |
String command = str.substring(0, delimiter_pos); // command | |
String params = str.substring(delimiter_pos+1); // parameter | |
if(command.equals("l")) { | |
// left | |
servo.write(180); | |
} | |
if(command.equals("c")) { | |
// center | |
servo.write(90); | |
} | |
if(command.equals("r")) { | |
// right | |
servo.write(0); | |
} | |
if(command.equals("f")) { | |
// forward | |
digitalWrite(forwardPin, LOW); | |
digitalWrite(backwardPin, HIGH); | |
} | |
if(command.equals("b")) { | |
// forward | |
digitalWrite(forwardPin, HIGH); | |
digitalWrite(backwardPin, LOW); | |
} | |
if(command.equals("s")) { | |
// stop | |
digitalWrite(forwardPin, HIGH); | |
digitalWrite(backwardPin, HIGH); | |
} | |
} | |
void setup() { | |
//USE_SERIAL.begin(921600); | |
USE_SERIAL.begin(115200); | |
servo.attach(servoPin); | |
pinMode(forwardPin, OUTPUT); | |
pinMode(backwardPin, OUTPUT); | |
digitalWrite(forwardPin, HIGH); | |
digitalWrite(backwardPin, HIGH); | |
USE_SERIAL.setDebugOutput(true); | |
USE_SERIAL.println(); | |
USE_SERIAL.println(); | |
USE_SERIAL.println(); | |
for(uint8_t t = 4; t > 0; t--) { | |
USE_SERIAL.printf("[SETUP] BOOT WAIT %d...\n", t); | |
USE_SERIAL.flush(); | |
delay(1000); | |
} | |
WiFiMulti.addAP("xxx", "xxx"); | |
while(WiFiMulti.run() != WL_CONNECTED) { | |
delay(100); | |
} | |
// start webSocket server | |
webSocket.begin(); | |
webSocket.onEvent(webSocketEvent); | |
if(MDNS.begin("speed2")) { | |
USE_SERIAL.println("MDNS responder started"); | |
} | |
// handle index | |
server.on("/", []() { | |
// send index.html | |
server.send(200, "text/html", "<html> <head> <meta charset='utf-8'> <title>Remote Control</title> <meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'/> <style>.pad{width:50%; height:50%; position:absolute}</style> </head> <body> <div style='width:100vw;height100vh;'> <div id='f' class='pad' style='top:0;left:0;background:#6686b7'></div><div id='s' class='pad' style='top:50%;left:0;background:#54c1de'></div><div id='l' class='pad' style='top:0;right:0;background:#ff5e63'></div><div id='r' class='pad' style='top:50%;right:0;background:#fcba55'></div></div><script type='text/javascript'> window.onload=function (){boardPath=location.hash ? location.hash.substring(1) : location.hostname; connection=new WebSocket('ws://'+boardPath+':81/', ['arduino']); connection.onopen=function (){connection.send('Connect ' + new Date());}; connection.onerror=function (error){console.log('WebSocket Error ', error);}; connection.onmessage=function (e){console.log('Server: ', e.data);}; createEvent=function (n){return function (e){console.log(n); e.preventDefault(); connection.send(n);};}; forwardButton=document.getElementById('f'); backwardButton=document.getElementById('s'); leftButton=document.getElementById('l'); rightButton=document.getElementById('r'); forwardButton.addEventListener('touchstart', createEvent('f')); forwardButton.addEventListener('mousedown', createEvent('f')); forwardButton.addEventListener('touchend', createEvent('s')); forwardButton.addEventListener('mouseup', createEvent('s')); backwardButton.addEventListener('touchstart', createEvent('b')); backwardButton.addEventListener('mousedown', createEvent('b')); backwardButton.addEventListener('touchend', createEvent('s')); backwardButton.addEventListener('mouseup', createEvent('s')); leftButton.addEventListener('touchstart', createEvent('l')); leftButton.addEventListener('mousedown', createEvent('l')); leftButton.addEventListener('touchend', createEvent('c')); leftButton.addEventListener('mouseup', createEvent('c')); rightButton.addEventListener('touchstart', createEvent('r')); rightButton.addEventListener('mousedown', createEvent('r')); rightButton.addEventListener('touchend', createEvent('c')); rightButton.addEventListener('mouseup', createEvent('c'));}; </script> </body></html>"); | |
}); | |
server.begin(); | |
// Add service to MDNS | |
MDNS.addService("http", "tcp", 80); | |
MDNS.addService("ws", "tcp", 81); | |
} | |
void loop() { | |
webSocket.loop(); | |
server.handleClient(); | |
} |
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
print('Booting...') | |
import network | |
import utime | |
import webrepl | |
SSID = 'WIFI NETWORK NAME' | |
PASSWORD = 'WIFI NETWORK PASSWORD' | |
sta = network.WLAN(network.STA_IF) | |
sta.active(True) | |
sta.connect(SSID, PASSWORD) | |
timeout = 50 | |
while not sta.isconnected(): | |
utime.sleep_ms(100) | |
timeout -= 1 | |
if timeout == 0: | |
print('Could not connect to wifi network') | |
break | |
if sta.isconnected(): | |
print('connected', sta.ifconfig()) | |
webrepl.start(password=123456) | |
else: | |
print('not connected') |
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
from machine import Pin, PWM | |
class Motor(): | |
def __init__(self, pin_number): | |
pin = Pin(pin_number, Pin.OUT) | |
self.motor = PWM(pin) | |
self.motor.freq(1000) | |
self.motor.duty(1) | |
def set_value(self, value=1): | |
self.motor.duty(value) | |
def forward(self): | |
self.set_value(1020) | |
def backward(self): | |
self.set_value(100) | |
def stop(self): | |
self.set_value(1) | |
motor1 = Motor(13) | |
motor2 = Motor(15) | |
m1f = motor1.forward | |
m1b = motor1.backward | |
m1s = motor1.stop | |
m2f = motor2.forward | |
m2b = motor2.backward | |
m2s = motor2.stop |
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
<!-- minified with on https://kangax.github.io/html-minifier/ --> | |
<html> | |
<head> | |
<meta charset='utf-8'> | |
<title>Remote Control</title> | |
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no' /> | |
<style> | |
.pad { | |
width:50%; | |
height:50%; | |
position:absolute | |
} | |
</style> | |
</head> | |
<body> | |
<div style='width:100vw;height100vh;'> | |
<div id='m1f' class='pad' style='top:0;left:0;background:#6686b7'></div> | |
<div id='m1b' class='pad' style='top:50%;left:0;background:#54c1de'></div> | |
<div id='m2f' class='pad' style='top:0;right:0;background:#ff5e63'></div> | |
<div id='m2b' class='pad' style='top:50%;right:0;background:#fcba55'></div> | |
</div> | |
<script type="text/javascript" src="webrepl.js"></script> | |
<script type='text/javascript'> | |
// Please: All the credit to the FABULOUS work of https://github.com/micropython/webrepl | |
class WebREPL { | |
constructor(opts) { | |
opts = opts || {} | |
this.binaryState = 0 | |
this.ip = opts.ip || '192.168.1.4' | |
this.password = opts.password || 'micropythoN' | |
this.sendFileName = '' | |
this.sendFileData = new ArrayBuffer() | |
this.getFileName = '' | |
this.getFileData = new ArrayBuffer() | |
this.STOP = '\r\x03' // CTRL-C 2x | |
this.RESET = '\r\x04' // CTRL-D | |
this.ENTER_RAW_REPL = '\r\x01' // CTRL-A | |
this.EXIT_RAW_REPL = '\r\x04\r\x02' // CTRL-D + CTRL-B | |
if (opts.autoconnect) { | |
this.connect() | |
} | |
} | |
_decodeResp(data) { | |
if (data[0] == 'W'.charCodeAt(0) && data[1] == 'B'.charCodeAt(0)) { | |
var code = data[2] | (data[3] << 8) | |
return code; | |
} else { | |
return -1; | |
} | |
} | |
_handleMessage(event) { | |
if (event.data instanceof ArrayBuffer) { | |
let data = new Uint8Array(event.data) | |
switch (this.binaryState) { | |
case 11: | |
// first response for put | |
if (this._decodeResp(data) == 0) { | |
// send file data in chunks | |
for (let offset = 0; offset < this.sendFileData.length; offset += 1024) { | |
this.ws.send(this.sendFileData.slice(offset, offset + 1024)) | |
} | |
this.binaryState = 12 | |
} | |
break | |
case 12: | |
// final response for put | |
if (this._decodeResp(data) == 0) { | |
console.log(`Sent ${this.sendFileName}, ${this.sendFileData.length} bytes`) | |
} else { | |
console.log(`Failed sending ${this.sendFileName}`) | |
} | |
this.binaryState = 0 | |
break; | |
case 21: | |
// first response for get | |
if (this._decodeResp(data) == 0) { | |
this.binaryState = 22 | |
var rec = new Uint8Array(1) | |
rec[0] = 0 | |
this.ws.send(rec) | |
} | |
break; | |
case 22: { | |
// file data | |
var sz = data[0] | (data[1] << 8) | |
if (data.length == 2 + sz) { | |
// we assume that the data comes in single chunks | |
if (sz == 0) { | |
// end of file | |
this.binaryState = 23 | |
} else { | |
// accumulate incoming data to this.getFileData | |
var new_buf = new Uint8Array(this.getFileData.length + sz) | |
new_buf.set(this.getFileData) | |
new_buf.set(data.slice(2), this.getFileData.length) | |
this.getFileData = new_buf | |
console.log('Getting ' + this.getFileName + ', ' + this.getFileData.length + ' bytes') | |
var rec = new Uint8Array(1) | |
rec[0] = 0 | |
this.ws.send(rec) | |
} | |
} else { | |
this.binaryState = 0 | |
} | |
break; | |
} | |
case 23: | |
// final response | |
if (this._decodeResp(data) == 0) { | |
console.log(`Got ${this.getFileName}, ${this.getFileData.length} bytes`) | |
this.saveAs(new Blob([this.getFileData], {type: "application/octet-stream"}), this.getFileName) | |
} else { | |
console.log(`Failed getting ${this.getFileName}`) | |
} | |
this.binaryState = 0 | |
break | |
case 31: | |
// first (and last) response for GET_VER | |
console.log('GET_VER', data) | |
this.binaryState = 0 | |
break | |
} | |
} | |
// If is asking for password, send password | |
if( event.data == 'Password: ' ) { | |
this.ws.send(`${this.password}\r`) | |
} | |
this.onMessage(event.data) | |
} | |
connect() { | |
this.ws = new WebSocket(`ws://${this.ip}:8266`) | |
this.ws.binaryType = 'arraybuffer' | |
this.ws.onopen = () => { | |
this.onConnected() | |
this.ws.onmessage = this._handleMessage.bind(this) | |
} | |
} | |
disconnect() { | |
this.ws.close() | |
} | |
onConnected() { | |
console.log('onConnected') | |
} | |
onMessage(msg) { | |
console.log('onMessage', msg) | |
} | |
saveAs(blob) { | |
console.log(`saving as: ${blob}`) | |
} | |
sendStop() { | |
this.eval(this.STOP) | |
} | |
softReset() { | |
this.sendStop() | |
this.eval(this.RESET) | |
} | |
enterRawRepl() { | |
this.eval(this.ENTER_RAW_REPL) | |
} | |
exitRawRepl() { | |
this.eval(this.EXIT_RAW_REPL) | |
} | |
execRaw(raw) { | |
this.eval(raw) | |
if (raw.indexOf('\n') == -1) { | |
this.eval('\r') | |
} | |
} | |
exec(command) { | |
this.eval(command) | |
} | |
execFromString(code) { | |
this.sendStop() | |
this.enterRawRepl() | |
this.execRaw(code) | |
this.exitRawRepl() | |
} | |
eval(command) { | |
this.ws.send(`${command}`) | |
} | |
_sendFile() { | |
let dest_fname = this.sendFileName | |
let dest_fsize = this.sendFileData.length | |
// WEBREPL_FILE = "<2sBBQLH64s" | |
let rec = new Uint8Array(2 + 1 + 1 + 8 + 4 + 2 + 64) | |
rec[0] = 'W'.charCodeAt(0) | |
rec[1] = 'A'.charCodeAt(0) | |
rec[2] = 1 // put | |
rec[3] = 0 | |
rec[4] = 0; rec[5] = 0; rec[6] = 0; rec[7] = 0; rec[8] = 0; rec[9] = 0; rec[10] = 0; rec[11] = 0; | |
rec[12] = dest_fsize & 0xff; rec[13] = (dest_fsize >> 8) & 0xff; rec[14] = (dest_fsize >> 16) & 0xff; rec[15] = (dest_fsize >> 24) & 0xff; | |
rec[16] = dest_fname.length & 0xff; rec[17] = (dest_fname.length >> 8) & 0xff; | |
for (let i = 0; i < 64; ++i) { | |
if (i < dest_fname.length) { | |
rec[18 + i] = dest_fname.charCodeAt(i) | |
} else { | |
rec[18 + i] = 0 | |
} | |
} | |
// initiate put | |
this.binaryState = 11 | |
console.log('Sending ' + this.sendFileName + '...') | |
this.ws.send(rec) | |
} | |
sendFile(file) { | |
this.sendFileName = file.name | |
let reader = new FileReader() | |
reader.onload = (e) => { | |
this.sendFileData = new Uint8Array(e.target.result) | |
this._sendFile() | |
}; | |
reader.readAsArrayBuffer(file) | |
} | |
loadFile(path) { | |
// WEBREPL_FILE = "<2sBBQLH64s" | |
let rec = new Uint8Array(2 + 1 + 1 + 8 + 4 + 2 + 64); | |
rec[0] = 'W'.charCodeAt(0); | |
rec[1] = 'A'.charCodeAt(0); | |
rec[2] = 2; // get | |
rec[3] = 0; | |
rec[4] = 0; rec[5] = 0; rec[6] = 0; rec[7] = 0; rec[8] = 0; rec[9] = 0; rec[10] = 0; rec[11] = 0; | |
rec[12] = 0; rec[13] = 0; rec[14] = 0; rec[15] = 0; | |
rec[16] = path.length & 0xff; rec[17] = (path.length >> 8) & 0xff; | |
for (let i = 0; i < 64; ++i) { | |
if (i < path.length) { | |
rec[18 + i] = path.charCodeAt(i); | |
} else { | |
rec[18 + i] = 0; | |
} | |
} | |
// initiate get | |
this.binaryState = 21; | |
this.getFileName = path; | |
this.getFileData = new Uint8Array(0); | |
console.log('Getting ' + this.getFileName + '...'); | |
this.ws.send(rec); | |
} | |
removeFile(filename) { | |
const pCode = `from os import remove | |
remove('${filename}')` | |
this.execFromString(pCode) | |
} | |
} | |
window.onload = function () { | |
boardPath = location.hash ? location.hash.substring(1) : location.hostname; | |
window.repl = new WebREPL({ | |
ip: boardPath || '192.168.0.17', | |
password: '123456', | |
autoconnect: true | |
}) | |
repl.onMessage = (msg) => { | |
if (typeof msg === 'string') { | |
console.log(msg) | |
// consoleOut.innerText = (consoleOut.innerText + msg).slice(-100) | |
} | |
} | |
createEvent = function (n) { | |
return function (e) { | |
// console.log(`${n}()\r\n`); | |
e.preventDefault(); | |
repl.eval(`${n}()\r\n`) | |
}; | |
}; | |
registerEvents = function (n) { | |
forwardButton = document.getElementById('m'+n+'f'); | |
backwardButton = document.getElementById('m'+n+'b'); | |
forwardButton.addEventListener('touchstart', createEvent('m'+n+'f')); | |
forwardButton.addEventListener('mousedown', createEvent('m'+n+'f')); | |
forwardButton.addEventListener('touchend', createEvent('m'+n+'s')); | |
forwardButton.addEventListener('mouseup', createEvent('m'+n+'s')); | |
backwardButton.addEventListener('touchstart', createEvent('m'+n+'b')); | |
backwardButton.addEventListener('mousedown', createEvent('m'+n+'b')); | |
backwardButton.addEventListener('touchend', createEvent('m'+n+'s')); | |
backwardButton.addEventListener('mouseup', createEvent('m'+n+'s')); | |
} | |
registerEvents(1); | |
registerEvents(2); | |
}; | |
</script> | |
</body> | |
</html> |
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
<!-- minified with on https://kangax.github.io/html-minifier/ --> | |
<html> | |
<head> | |
<meta charset='utf-8'> | |
<title>Remote Control</title> | |
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no' /> | |
<style> | |
.pad { | |
width:50%; | |
height:50%; | |
position:absolute | |
} | |
</style> | |
</head> | |
<body> | |
<div style='width:100vw;height100vh;'> | |
<div id='m1f' class='pad' style='top:0;left:0;background:#6686b7'></div> | |
<div id='m1b' class='pad' style='top:50%;left:0;background:#54c1de'></div> | |
<div id='m2f' class='pad' style='top:0;right:0;background:#ff5e63'></div> | |
<div id='m2b' class='pad' style='top:50%;right:0;background:#fcba55'></div> | |
</div> | |
<script type='text/javascript'> | |
window.onload = function () { | |
boardPath = location.hash ? location.hash.substring(1) : location.hostname; | |
connection = new WebSocket('ws://'+boardPath+':81/', ['arduino']); | |
connection.onopen = function () { | |
connection.send('Connect ' + new Date()); | |
}; | |
connection.onerror = function (error) { | |
console.log('WebSocket Error ', error); | |
}; | |
connection.onmessage = function (e) { | |
console.log('Server: ', e.data); | |
}; | |
createEvent = function (n) { | |
return function (e) { | |
console.log(n); | |
e.preventDefault(); | |
connection.send(n); | |
}; | |
}; | |
registerEvents = function (n) { | |
forwardButton = document.getElementById('m'+n+'f'); | |
backwardButton = document.getElementById('m'+n+'b'); | |
forwardButton.addEventListener('touchstart', createEvent('m'+n+'f')); | |
forwardButton.addEventListener('mousedown', createEvent('m'+n+'f')); | |
forwardButton.addEventListener('touchend', createEvent('m'+n+'s')); | |
forwardButton.addEventListener('mouseup', createEvent('m'+n+'s')); | |
backwardButton.addEventListener('touchstart', createEvent('m'+n+'b')); | |
backwardButton.addEventListener('mousedown', createEvent('m'+n+'b')); | |
backwardButton.addEventListener('touchend', createEvent('m'+n+'s')); | |
backwardButton.addEventListener('mouseup', createEvent('m'+n+'s')); | |
} | |
registerEvents(1); | |
registerEvents(2); | |
}; | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment