change to joystick

This commit is contained in:
2023-11-06 21:24:55 +01:00
parent bff0995309
commit 183b087ed7
11 changed files with 295 additions and 456 deletions

5
FW/.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch

10
FW/.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,10 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}

View File

@@ -14,9 +14,11 @@ board = esp32dev
framework = arduino
monitor_speed = 115200
lib_deps =
me-no-dev/AsyncTCP@^1.1.1
madhephaestus/ESP32Servo@^1.1.0
ottowinter/ESPAsyncWebServer-esphome@^3.1.0
ArduinoWebsockets
AsyncTCP
joaolopesf/ESP32MotorControl@^0.1.0
build_flags =
-DCORE_DEBUG_LEVEL=3
-DNDEF_DEBUG=1

View File

@@ -5,64 +5,61 @@ bool removeArmMomentum = false;
Servo bucketServo;
Servo auxServo;
void motor::drive(int dirspeed)
{
if(dirspeed == 0)
{
motorStop(motorindex);
}
if(dirspeed > 0)
{
//map(value, fromLow, fromHigh, toLow, toHigh)
uint8_t speed = map(dirspeed,-255,0,0,100);
log_i("motor forward");
motorForward(motorindex, speed);
}
else
{
uint8_t speed = map(dirspeed,0,255,0,100);
log_i("motor reverse");
motorReverse(motorindex, speed);
}
}
std::vector<MOTOR_PINS> motorPins =
{
{RMOTOR_IN1, RMOTOR_IN2}, //RIGHT_MOTOR Pins (IN1, IN2)
{LMOTOR_IN1, LMOTOR_IN2}, //LEFT_MOTOR Pins
{ARM_IN1, ARM_IN2}, //ARM_MOTOR pins
// {ARM_IN1, ARM_IN2}, //ARM_MOTOR pins
};
void setUpPinModes()
motor motors[2];
void setupmotors()
{
for (int i = 0; i < motorPins.size(); i++)
{
pinMode(motorPins[i].pinIN1, OUTPUT);
pinMode(motorPins[i].pinIN2, OUTPUT);
{
motors[i].attachMotor(motorPins[i].pinIN1,motorPins[i].pinIN2); // pinMode(motorPins[i].pinIN1, OUTPUT);
motors[i].motorStop(0);
}
moveCar(STOP, false);
bucketServo.attach(bucketServoPin);
auxServo.attach(auxServoPin);
auxControl(default_auxControl);
bucketTilt(default_bucketTilt);
}
void rotateMotor(int motorNumber, int motorDirection)
void drivemotor(uint8_t num, int dirspeed)
{
if (motorDirection == FORWARD)
if(num < motorPins.size())
{
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
{
if(removeArmMomentum)
{
digitalWrite(motorPins[ARM_MOTOR].pinIN1, HIGH);
digitalWrite(motorPins[ARM_MOTOR].pinIN2, LOW);
delay(10);
digitalWrite(motorPins[motorNumber].pinIN1, LOW);
digitalWrite(motorPins[motorNumber].pinIN2, LOW);
delay(5);
digitalWrite(motorPins[ARM_MOTOR].pinIN1, HIGH);
digitalWrite(motorPins[ARM_MOTOR].pinIN2, LOW);
delay(10);
removeArmMomentum = false;
}
digitalWrite(motorPins[motorNumber].pinIN1, LOW);
digitalWrite(motorPins[motorNumber].pinIN2, LOW);
motors[num].drive(dirspeed);
}
}
void setMomentum(bool val)
{
removeArmMomentum = val;
}
void bucketTilt(int bucketServoValue)
@@ -74,100 +71,3 @@ void auxControl(int auxServoValue)
auxServo.write(auxServoValue);
}
void moveCar(int inputValue, bool horizontal)
{
Serial.printf("Got value as %d\n", inputValue);
if(!(horizontal))
{
switch(inputValue)
{
case UP:
rotateMotor(RIGHT_MOTOR, FORWARD);
rotateMotor(LEFT_MOTOR, FORWARD);
break;
case DOWN:
rotateMotor(RIGHT_MOTOR, BACKWARD);
rotateMotor(LEFT_MOTOR, BACKWARD);
break;
case LEFT:
rotateMotor(RIGHT_MOTOR, BACKWARD);
rotateMotor(LEFT_MOTOR, FORWARD);
break;
case RIGHT:
rotateMotor(RIGHT_MOTOR, FORWARD);
rotateMotor(LEFT_MOTOR, BACKWARD);
break;
case STOP:
rotateMotor(ARM_MOTOR, STOP);
rotateMotor(RIGHT_MOTOR, STOP);
rotateMotor(LEFT_MOTOR, STOP);
break;
case ARMUP:
rotateMotor(ARM_MOTOR, FORWARD);
break;
case ARMDOWN:
rotateMotor(ARM_MOTOR, BACKWARD);
setMomentum(true);
break;
default:
rotateMotor(ARM_MOTOR, STOP);
rotateMotor(RIGHT_MOTOR, STOP);
rotateMotor(LEFT_MOTOR, STOP);
break;
}
}else {
switch(inputValue)
{
case UP:
rotateMotor(RIGHT_MOTOR, BACKWARD);
rotateMotor(LEFT_MOTOR, FORWARD);
break;
case DOWN:
rotateMotor(RIGHT_MOTOR, FORWARD);
rotateMotor(LEFT_MOTOR, BACKWARD);
break;
case LEFT:
rotateMotor(RIGHT_MOTOR, BACKWARD);
rotateMotor(LEFT_MOTOR, BACKWARD);
break;
case RIGHT:
rotateMotor(RIGHT_MOTOR, FORWARD);
rotateMotor(LEFT_MOTOR, FORWARD);
break;
case STOP:
rotateMotor(ARM_MOTOR, STOP);
rotateMotor(RIGHT_MOTOR, STOP);
rotateMotor(LEFT_MOTOR, STOP);
break;
case ARMUP:
rotateMotor(ARM_MOTOR, FORWARD);
break;
case ARMDOWN:
rotateMotor(ARM_MOTOR, BACKWARD);
setMomentum(true);
break;
default:
rotateMotor(ARM_MOTOR, STOP);
rotateMotor(RIGHT_MOTOR, STOP);
rotateMotor(LEFT_MOTOR, STOP);
break;
}
}
}

View File

@@ -15,7 +15,7 @@
//defaults
#define default_auxControl 150
#define default_bucketTilt 140
#define default_bucketTilt 100

View File

@@ -1,219 +1,187 @@
#include "html.h"
const char htmlHomePage[] PROGMEM = R"HTMLHOMEPAGE(
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=.9, maximum-scale=1, user-scalable=yes">
<style>
.arrows {
font-size:50px;
color:grey;
}
td.button {
background-color:black;
border-radius:20%;
box-shadow: 5px 5px #888888;
}
td.button:active {
transform: translate(5px,5px);
box-shadow: none;
}
//https://mischianti.org/online-converter-file-to-cpp-gzip-byte-array-3/
.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">
<div class="slidecontainer">
<label for="powerSwitch" style="font-size: 20px;">HorizontalScreen:</label>
<input type="checkbox" id="powerSwitch" class="power-switch" onchange='sendButtonInput("Switch", 0)'>
</div>
<h1 style="color: black;text-align:center;">MINISKIDI</h1>
<table id="mainTable" style="width:400px;margin:auto;table-layout:fixed" CELLSPACING=10>
<tr>
<td></td>
<td class="button" ontouchstart='sendButtonInput("MoveCar","1")'onmousedown='sendButtonInput("MoveCar","1")'onmouseup='sendButtonInput("MoveCar","0")' ontouchend='sendButtonInput("MoveCar","0")'><span class="arrows" >&#8679;</span></td>
<td></td>
</tr>
<tr>
<td class="button" ontouchstart='sendButtonInput("MoveCar","3")'onmousedown='sendButtonInput("MoveCar","3")'onmouseup='sendButtonInput("MoveCar","0")' ontouchend='sendButtonInput("MoveCar","0")'><span class="arrows" >&#8678;</span></td>
<td class="button"></td>
<td class="button" ontouchstart='sendButtonInput("MoveCar","4")'onmousedown='sendButtonInput("MoveCar","4")'onmouseup='sendButtonInput("MoveCar","0")' ontouchend='sendButtonInput("MoveCar","0")'><span class="arrows" >&#8680;</span></td>
</tr>
<tr>
<td></td>
<td class="button" ontouchstart='sendButtonInput("MoveCar","2")'onmousedown='sendButtonInput("MoveCar","2")'onmouseup='sendButtonInput("MoveCar","0")' ontouchend='sendButtonInput("MoveCar","0")'><span class="arrows" >&#8681;</span></td>
<td></td>
</tr>
<tr/>
<tr/>
<tr/><tr/>
<tr>
<td class="button" ontouchstart='sendButtonInput("MoveCar","6")'onmousedown='sendButtonInput("MoveCar","6")'onmouseup='sendButtonInput("MoveCar","0")' ontouchend='sendButtonInput("MoveCar","0")'><span class="arrows" >&#8678;</span></td>
<td class="button"></td>
<td class="button" ontouchstart='sendButtonInput("MoveCar","5")'onmousedown='sendButtonInput("MoveCar","5")'onmouseup='sendButtonInput("MoveCar","0")' ontouchend='sendButtonInput("MoveCar","0")'><span class="arrows" >&#8680;</span></td>
</tr>
<tr/>
<tr/>
<tr/><tr/>
<tr>
<td style="text-align:left;font-size:25px"><b>Bucket:</b></td>
<td colspan=2>
<div class="slidecontainer">
<input type="range" min="10" max="180" value="90" class="slider" id="Bucket" oninput='sendButtonInput("Bucket",value)'>
</div>
</td>
</tr>
<tr/>
<tr/>
<tr/><tr/>
<tr>
<td style="text-align:left;font-size:25px"><b>AUX:</b></td>
<td colspan=2>
<div class="slidecontainer">
<input type="range" min="10" max="180" value="90" class="slider" id="AUX" oninput='sendButtonInput("AUX",value)'>
</div>
</td>
</tr>
</table>
<script>
var webSocketCarInputUrl = "ws:\/\/" + window.location.hostname + "/CarInput";
var websocketCarInput;
const auxSlider = document.getElementById('AUX');
const bucketSlider = document.getElementById('Bucket');
function initCarInputWebSocket()
{
websocketCarInput = new WebSocket(webSocketCarInputUrl);
websocketCarInput.onclose = function(event){setTimeout(initCarInputWebSocket, 2000);};
websocketCarInput.onmessage = function(event){};
}
function sendButtonInput(key, value)
{
var data = key + "," + value;
websocketCarInput.send(data);
}
function handleKeyDown(event) {
if (event.keyCode === 38) {
sendButtonInput("MoveCar", "1");
}
if (event.keyCode === 40)
{
sendButtonInput("MoveCar", "2");
}
if (event.keyCode ===37)
{
sendButtonInput("MoveCar", "3");
}
if (event.keyCode ===39)
{
sendButtonInput("MoveCar", "4");
}
if (event.keyCode === 87)
{
sendButtonInput("MoveCar", "5");
}
if (event.keyCode === 83)
{
sendButtonInput("MoveCar", "6");
}
if(event.keyCode === 69)
{
auxSlider.value = parseInt(auxSlider.value) + 5; // You can adjust the increment value as needed
sendButtonInput("AUX",auxSlider.value);
// Trigger the 'input' event on the slider to update its value
auxSlider.dispatchEvent(new Event('input'));
}
if(event.keyCode === 68)
{
auxSlider.value = parseInt(auxSlider.value) - 5; // You can adjust the increment value as needed
sendButtonInput("AUX",auxSlider.value);
// Trigger the 'input' event on the slider to update its value
auxSlider.dispatchEvent(new Event('input'));
}
if(event.keyCode === 81)
{
bucketSlider.value = parseInt(bucketSlider.value) + 5; // You can adjust the increment value as needed
sendButtonInput("Bucket",bucketSlider.value);
// Trigger the 'input' event on the slider to update its value
bucketSlider.dispatchEvent(new Event('input'));
}
if(event.keyCode === 65)
{
bucketSlider.value = parseInt(bucketSlider.value) - 5; // You can adjust the increment value as needed
sendButtonInput("Bucket",bucketSlider.value);
// Trigger the 'input' event on the slider to update its value
bucketSlider.dispatchEvent(new Event('input'));
}
}
function handleKeyUp(event) {
if (event.keyCode === 37 || event.keyCode === 38 || event.keyCode === 39 || event.keyCode === 40 || event.keyCode === 87 || event.keyCode === 83) {
sendButtonInput("MoveCar", "0");
}
}
window.onload = initCarInputWebSocket;
document.getElementById("mainTable").addEventListener("touchend", function(event){
event.preventDefault()
});
document.addEventListener('keydown', handleKeyDown);
document.addEventListener('keyup', handleKeyUp);
</script>
</body>
</html>
)HTMLHOMEPAGE";
//File: web_smars.html.gz, Size: 2875
const uint8_t web_smars_html_gz[] PROGMEM = {
0x1F, 0x8B, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xC5, 0x1A, 0x6B, 0x6F, 0xDB, 0x46,
0xF2, 0xBB, 0x7F, 0xC5, 0x44, 0xC1, 0xD5, 0x54, 0x2C, 0x51, 0x0F, 0x37, 0x6D, 0x6A, 0x59, 0x2E,
0x1C, 0xDB, 0x71, 0x53, 0x38, 0xAD, 0x61, 0xF9, 0xEA, 0x18, 0x87, 0x83, 0xB1, 0x22, 0x57, 0xD2,
0x26, 0x4B, 0x2E, 0xB1, 0x5C, 0x4A, 0x72, 0x5B, 0xFF, 0xF7, 0x9B, 0x59, 0xBE, 0x29, 0xC9, 0x49,
0x0E, 0x38, 0x9C, 0x80, 0x58, 0xE4, 0xEC, 0xCC, 0xEC, 0xEC, 0xBC, 0x67, 0x95, 0xE3, 0x17, 0xE7,
0xBF, 0x9F, 0xDD, 0xDE, 0x5F, 0x5F, 0xC0, 0xC2, 0x04, 0xF2, 0x64, 0x6F, 0xEF, 0xB8, 0xF8, 0xE6,
0xCC, 0x3F, 0xD9, 0x03, 0xFC, 0x1C, 0x07, 0xDC, 0x30, 0x08, 0x59, 0xC0, 0xC7, 0xFB, 0x4B, 0xC1,
0x57, 0x91, 0xD2, 0x66, 0x1F, 0x3C, 0x15, 0x1A, 0x1E, 0x9A, 0xF1, 0xFE, 0x4A, 0xF8, 0x66, 0x31,
0xF6, 0xF9, 0x52, 0x78, 0xBC, 0x6B, 0x5F, 0x3A, 0x90, 0x7F, 0x44, 0x28, 0x8C, 0x60, 0xB2, 0x1B,
0x7B, 0x4C, 0xF2, 0xF1, 0xC0, 0xED, 0x97, 0x4B, 0x49, 0xCC, 0xB5, 0x85, 0xB3, 0x29, 0x2E, 0x85,
0x6A, 0x1F, 0x7A, 0xD5, 0xED, 0xBC, 0x05, 0xD3, 0x31, 0x37, 0xE3, 0x56, 0x62, 0x66, 0xDD, 0x37,
0x2D, 0x5A, 0xDC, 0x4B, 0x97, 0x8D, 0x30, 0x92, 0x9F, 0xFC, 0xAA, 0x1E, 0x63, 0x23, 0xBC, 0xCF,
0x60, 0x78, 0x6C, 0x8E, 0x7B, 0x29, 0x30, 0x47, 0x89, 0xCD, 0x23, 0xBD, 0xE5, 0x5B, 0xBD, 0x24,
0x59, 0x99, 0x08, 0xB9, 0x86, 0xBF, 0x0A, 0x20, 0x7D, 0xAC, 0xB4, 0x47, 0x30, 0xE8, 0xF7, 0xFF,
0x31, 0xAA, 0x2D, 0x2C, 0xB8, 0x98, 0x2F, 0xCC, 0x11, 0x7C, 0xFF, 0xD3, 0x72, 0x51, 0x5F, 0x99,
0x32, 0xEF, 0xF3, 0x5C, 0xAB, 0x24, 0xF4, 0xBB, 0x9E, 0x92, 0x4A, 0x1F, 0xC1, 0xCB, 0xC3, 0xC3,
0xC3, 0x3A, 0x8E, 0x2F, 0xE2, 0x48, 0xB2, 0xC7, 0x23, 0x98, 0x49, 0xBE, 0xAE, 0x2F, 0x31, 0x29,
0xE6, 0x61, 0x57, 0x18, 0x1E, 0xC4, 0x47, 0xE0, 0xA1, 0xFE, 0xB8, 0xAE, 0x23, 0x7C, 0x4A, 0xF0,
0x58, 0xB3, 0xC7, 0x6E, 0xA6, 0xDE, 0xED, 0x48, 0x6A, 0xC9, 0xF5, 0x4C, 0xAA, 0xD5, 0x11, 0x2C,
0x84, 0xEF, 0xF3, 0xB0, 0x21, 0xA2, 0xD2, 0x3E, 0xEA, 0x56, 0x33, 0x5F, 0x24, 0xB8, 0xCB, 0x8F,
0x51, 0x43, 0x06, 0xA3, 0x12, 0x6F, 0xD1, 0x65, 0x9E, 0x11, 0x2A, 0x3C, 0x82, 0x50, 0x85, 0xBC,
0x5C, 0x7F, 0xDA, 0x2B, 0xB5, 0x46, 0x52, 0xEE, 0x54, 0x58, 0x93, 0x69, 0xAE, 0xB1, 0x2D, 0x4B,
0x9B, 0x2A, 0xD3, 0xF3, 0xA9, 0x33, 0xFC, 0xFE, 0x75, 0x07, 0x86, 0x87, 0xE8, 0x11, 0x3F, 0xFD,
0xD4, 0xDE, 0x76, 0x00, 0xE2, 0x15, 0xAD, 0x21, 0x56, 0x52, 0xF8, 0x44, 0xC1, 0x9C, 0xC1, 0xE1,
0x0F, 0x1D, 0x28, 0xFF, 0xB8, 0xAF, 0xB7, 0xD2, 0x15, 0x07, 0x7F, 0xDD, 0xB4, 0xEA, 0x73, 0x07,
0xA7, 0x4F, 0xEA, 0x92, 0x5C, 0x72, 0xCF, 0x7C, 0x49, 0x2F, 0x47, 0xC4, 0x65, 0xC9, 0x1B, 0xEA,
0xD9, 0x7A, 0x52, 0x94, 0xFB, 0x87, 0x37, 0x78, 0xD4, 0x01, 0xFD, 0x19, 0xE2, 0x79, 0x31, 0x0C,
0xFA, 0xED, 0x67, 0x58, 0x2F, 0xC8, 0xBC, 0x0D, 0xCE, 0x5E, 0xA2, 0x63, 0xE2, 0x17, 0x29, 0xB1,
0xE9, 0x0E, 0xD9, 0xB9, 0x33, 0xE3, 0x0C, 0x6B, 0x06, 0xA8, 0x72, 0x67, 0x9A, 0xB3, 0x06, 0xDF,
0x48, 0xC5, 0x22, 0x55, 0xC7, 0x4C, 0xAC, 0xB9, 0x5F, 0xE7, 0xAB, 0x53, 0x93, 0xF6, 0x9B, 0x5A,
0x8C, 0x6A, 0xB0, 0xA7, 0x34, 0xE6, 0x7A, 0x59, 0xD0, 0xE5, 0x21, 0xE8, 0x69, 0x11, 0x19, 0x30,
0x8F, 0x11, 0x1F, 0xB7, 0x0C, 0x5F, 0x9B, 0xDE, 0x27, 0xB6, 0x64, 0x29, 0xB4, 0x55, 0x86, 0xE6,
0x92, 0x69, 0xC0, 0x50, 0x9E, 0xD8, 0x50, 0x1E, 0xC3, 0x2C, 0x09, 0xAD, 0x75, 0xC0, 0x31, 0x1D,
0xE0, 0x6D, 0xF8, 0xCB, 0x22, 0x08, 0x5C, 0x59, 0x2A, 0xF4, 0x82, 0x3E, 0x8C, 0xC7, 0x63, 0x70,
0x38, 0xBE, 0x73, 0xF8, 0xFB, 0x6F, 0xF8, 0xEB, 0xA9, 0xED, 0xDA, 0xC8, 0x87, 0x9F, 0xA1, 0xF5,
0x29, 0xCB, 0x08, 0x2D, 0x38, 0x02, 0x9E, 0x82, 0x3B, 0x10, 0xD6, 0x49, 0xB9, 0x6B, 0x95, 0x84,
0xE8, 0x7D, 0x8B, 0x95, 0xA5, 0x2B, 0xD5, 0xC4, 0x4A, 0xBD, 0xB9, 0x40, 0x4B, 0x5F, 0x3B, 0xB0,
0x68, 0xE2, 0x59, 0x63, 0x84, 0x4C, 0xBE, 0x13, 0x52, 0x9E, 0x91, 0xC5, 0x49, 0x90, 0x97, 0xFD,
0xFE, 0xE9, 0x69, 0xBF, 0x9F, 0xCA, 0xB1, 0x81, 0xD1, 0x01, 0xBD, 0x8B, 0xCB, 0x15, 0xA6, 0xA8,
0xBB, 0x4C, 0xBE, 0x61, 0x8D, 0xBA, 0x58, 0xE9, 0x80, 0xBF, 0x8B, 0x7A, 0x62, 0xB4, 0xFA, 0xCC,
0xAB, 0x52, 0x1C, 0x1E, 0x36, 0xA5, 0xA8, 0xE0, 0x74, 0x80, 0x35, 0x39, 0xA1, 0x95, 0x76, 0xC8,
0xB1, 0xB1, 0xD2, 0x01, 0xB9, 0x8B, 0x7A, 0x53, 0x8E, 0x37, 0xFD, 0x5C, 0x8E, 0x2D, 0x38, 0x1D,
0xF0, 0x90, 0x93, 0xAF, 0xBC, 0x24, 0xC0, 0x4C, 0xE7, 0xCE, 0xB9, 0xB9, 0x90, 0x9C, 0x1E, 0xDF,
0x3E, 0xBE, 0xF7, 0x1D, 0xD3, 0xEE, 0x40, 0x52, 0x5D, 0xF7, 0xD0, 0x87, 0x0D, 0xCF, 0x50, 0x9C,
0x96, 0xC7, 0x42, 0xF4, 0xAA, 0x56, 0x7B, 0x04, 0x89, 0x2B, 0x48, 0x35, 0xA2, 0x63, 0x05, 0x42,
0xC3, 0x7F, 0xF7, 0x1D, 0x38, 0x64, 0x7E, 0xCF, 0xF5, 0xA4, 0x40, 0x64, 0x2B, 0x77, 0x3B, 0x5B,
0x56, 0x76, 0x59, 0x55, 0x96, 0x7F, 0xB1, 0x36, 0xA6, 0xED, 0x32, 0x1F, 0x41, 0x1E, 0xF4, 0x92,
0xB9, 0x02, 0x92, 0xA0, 0xA4, 0x2E, 0x8B, 0x22, 0x1E, 0xFA, 0x67, 0x0B, 0x21, 0x7D, 0x27, 0xC1,
0x5D, 0xC9, 0x3D, 0x63, 0x5C, 0x4C, 0x48, 0xF0, 0x33, 0xCA, 0xD9, 0x6B, 0x94, 0x6A, 0xE8, 0xB7,
0x90, 0xD1, 0x0C, 0xE1, 0x18, 0xEE, 0x4B, 0xFC, 0x1A, 0xC2, 0x2B, 0xF8, 0xC0, 0xCC, 0xC2, 0xBD,
0x7E, 0xDF, 0x81, 0x39, 0x02, 0x9C, 0x7C, 0x97, 0x2E, 0x0C, 0x06, 0xFD, 0x36, 0xF4, 0x60, 0xD8,
0x81, 0x15, 0x2E, 0xCC, 0xE1, 0x00, 0x30, 0x31, 0x9E, 0x65, 0x8F, 0x94, 0x1F, 0x03, 0xCB, 0x3F,
0x45, 0xB7, 0x78, 0x91, 0x05, 0x64, 0x82, 0x59, 0xC8, 0x55, 0x0D, 0x65, 0x80, 0x44, 0x17, 0x08,
0xE9, 0x0E, 0x70, 0xDB, 0xAB, 0x0E, 0x4C, 0xEA, 0xF8, 0xB4, 0xFC, 0x39, 0x5F, 0x9E, 0x74, 0xE0,
0x0E, 0x9F, 0x83, 0x0E, 0x5C, 0xE2, 0x57, 0x34, 0x2A, 0x43, 0x70, 0xED, 0x50, 0xFC, 0xC5, 0xEE,
0x94, 0xCF, 0x45, 0x78, 0x8D, 0xC2, 0x3B, 0x78, 0xA6, 0xD8, 0x65, 0xDA, 0x73, 0x10, 0x3B, 0x42,
0x19, 0x3B, 0xF6, 0x78, 0x1D, 0x78, 0x31, 0xB0, 0x2B, 0xB2, 0x70, 0x9B, 0x31, 0x30, 0x02, 0xC4,
0xD6, 0xCA, 0x13, 0xCA, 0x0B, 0x08, 0x92, 0x25, 0x08, 0x39, 0x3F, 0x95, 0x1B, 0x3D, 0x6E, 0xDB,
0xE8, 0x0E, 0x8E, 0x51, 0x01, 0x64, 0x24, 0x12, 0x6F, 0x65, 0x21, 0x07, 0x08, 0x39, 0x29, 0xCE,
0x99, 0xAF, 0x95, 0x9A, 0x24, 0xAC, 0xCB, 0x82, 0xEE, 0x32, 0xA3, 0xBB, 0x2C, 0xE8, 0x32, 0x0D,
0xE4, 0x8B, 0x05, 0x20, 0xA5, 0x4C, 0x8F, 0x76, 0x87, 0x04, 0x68, 0xA2, 0xCA, 0xD1, 0x52, 0x23,
0x93, 0x07, 0xC4, 0x99, 0xF7, 0xDD, 0x60, 0x81, 0x61, 0xF2, 0x92, 0xEA, 0x0C, 0x39, 0x61, 0xAA,
0x0D, 0x34, 0x5A, 0xFA, 0x30, 0xA4, 0xEC, 0x0E, 0xC6, 0x65, 0xBE, 0x6F, 0x1D, 0x7C, 0x82, 0x09,
0xD3, 0x41, 0x6E, 0xE4, 0x7B, 0x0D, 0xE8, 0x00, 0xC3, 0xD9, 0xEE, 0x3C, 0xC3, 0xEC, 0x90, 0xEB,
0xC9, 0xE4, 0x00, 0x67, 0x43, 0xAB, 0x7A, 0x53, 0xAB, 0x7E, 0x43, 0xAB, 0x2D, 0xF4, 0x41, 0x2A,
0x73, 0xB1, 0x61, 0xDA, 0xB4, 0xB0, 0x01, 0x2B, 0x43, 0x27, 0x7F, 0xC8, 0x82, 0x07, 0x83, 0x13,
0xBD, 0x10, 0xE5, 0xB9, 0x58, 0xE2, 0xDB, 0x95, 0x88, 0xB1, 0xDF, 0xE0, 0xDA, 0x69, 0x55, 0xC8,
0x3B, 0xD5, 0x84, 0x4C, 0x46, 0x22, 0x97, 0x1E, 0xC0, 0x53, 0x66, 0xF2, 0x9D, 0xD4, 0x01, 0x56,
0xB0, 0x4D, 0x62, 0xE3, 0x46, 0x9A, 0x13, 0xF6, 0x39, 0x9F, 0xB1, 0x44, 0x1A, 0x3A, 0xDF, 0x80,
0x82, 0x71, 0x56, 0xD8, 0xD2, 0xB8, 0x96, 0x9E, 0xC7, 0xFF, 0xEA, 0xFF, 0xDB, 0x8D, 0xD8, 0x9C,
0x7F, 0x4C, 0xFD, 0x72, 0x03, 0x7E, 0x4F, 0xFE, 0xD0, 0x25, 0x1B, 0xAA, 0xD9, 0x0C, 0xFB, 0xC4,
0x2B, 0x3E, 0x33, 0x84, 0x5A, 0x01, 0xDD, 0xAA, 0x88, 0x74, 0xE3, 0x49, 0xCE, 0xF4, 0x0D, 0x96,
0x74, 0xB2, 0x41, 0xBF, 0x08, 0xEF, 0x32, 0xB4, 0x51, 0x8A, 0x35, 0x89, 0x82, 0x6E, 0xD8, 0xFE,
0xF2, 0xD1, 0x30, 0xFA, 0xB7, 0xAB, 0xA5, 0x5F, 0x0F, 0xA4, 0x6F, 0xDD, 0x3A, 0xDB, 0xB9, 0x8D,
0x69, 0x72, 0xAB, 0x55, 0x02, 0x85, 0xDD, 0x89, 0xAF, 0x56, 0xE1, 0x7F, 0x63, 0x14, 0x4B, 0xBC,
0xDD, 0x28, 0x1B, 0x06, 0xA8, 0x69, 0xFD, 0xFF, 0xA5, 0x6A, 0x2B, 0x70, 0x12, 0xFD, 0x4F, 0x35,
0x5D, 0x42, 0x30, 0x2E, 0x17, 0x22, 0x76, 0x2F, 0xB9, 0xC9, 0x03, 0xAD, 0xDC, 0x95, 0x36, 0xD5,
0xDC, 0x24, 0x3A, 0x2C, 0x12, 0xCD, 0x53, 0x89, 0xFF, 0x4B, 0x5E, 0x1C, 0x76, 0x10, 0x64, 0x09,
0xA6, 0x42, 0x71, 0xAD, 0xE2, 0x8F, 0xBB, 0xF0, 0xEF, 0x1A, 0x88, 0xF7, 0xBB, 0x10, 0x2F, 0xAB,
0x88, 0x3B, 0xD9, 0x39, 0x68, 0xD1, 0x2E, 0x04, 0x54, 0x5C, 0x56, 0x98, 0xE9, 0xB1, 0x33, 0xC7,
0x6E, 0x49, 0xBD, 0xA3, 0x3E, 0x2F, 0xD5, 0x42, 0xCE, 0x61, 0xE7, 0x3E, 0x0E, 0xE6, 0xC9, 0x2E,
0x44, 0x15, 0x0E, 0xF8, 0xB7, 0x3B, 0xD8, 0xC1, 0xE6, 0x5C, 0xE8, 0x0D, 0x46, 0x79, 0xEA, 0x6C,
0xA1, 0x29, 0x29, 0x5D, 0x59, 0x89, 0x3A, 0xB6, 0xA3, 0xB3, 0xAC, 0x47, 0xF9, 0x56, 0x02, 0x4E,
0xC6, 0x58, 0x95, 0xD0, 0x0F, 0x05, 0x1C, 0x8F, 0xB1, 0x64, 0x91, 0x47, 0x5A, 0xCA, 0x33, 0xAA,
0xA5, 0x08, 0x4C, 0x57, 0x53, 0xD8, 0x6F, 0x29, 0xEC, 0xA4, 0x8A, 0x37, 0x21, 0x18, 0x47, 0xBC,
0x0B, 0x0B, 0x43, 0x3A, 0x72, 0x6D, 0x4A, 0x73, 0x76, 0xF9, 0x8E, 0x3A, 0x10, 0x03, 0x07, 0xF6,
0xD1, 0x62, 0x9E, 0x60, 0xD9, 0xDC, 0x86, 0x79, 0x51, 0x62, 0x5E, 0x10, 0x26, 0xDA, 0x0F, 0x9E,
0x46, 0x79, 0x97, 0x6B, 0x3B, 0xD8, 0x93, 0xBD, 0xE3, 0x5E, 0x3A, 0x20, 0xE3, 0xA4, 0x3C, 0x55,
0xFE, 0xE3, 0x49, 0xD6, 0xF6, 0xFA, 0x62, 0x09, 0xC2, 0x1F, 0xEF, 0xAB, 0x04, 0x1B, 0x9D, 0xB3,
0x7C, 0xEC, 0xDC, 0x2F, 0x1B, 0x5E, 0x8B, 0x61, 0x5B, 0xE5, 0x71, 0xAB, 0x98, 0x32, 0xFB, 0x38,
0x65, 0xB6, 0x4E, 0x8E, 0x7B, 0xB8, 0xD6, 0xC0, 0x44, 0x5E, 0xD4, 0xD8, 0x9E, 0x8B, 0x65, 0x2B,
0xA7, 0x4A, 0xDB, 0xFC, 0xA1, 0x9D, 0xB3, 0x32, 0x0E, 0xE9, 0x4B, 0xC0, 0x34, 0x16, 0xD0, 0x23,
0x96, 0x18, 0x55, 0x72, 0xCB, 0xC4, 0xAE, 0x3C, 0xE7, 0x27, 0x28, 0x07, 0x03, 0x9C, 0x35, 0x63,
0x03, 0x34, 0xDA, 0x3F, 0xD3, 0x89, 0xED, 0x63, 0x91, 0xE1, 0x2C, 0xD8, 0xAF, 0x4C, 0x2E, 0x29,
0xDD, 0xDD, 0xE4, 0xE1, 0x9F, 0x37, 0xD4, 0x80, 0xB4, 0x56, 0xF1, 0x51, 0xAF, 0xD7, 0xC2, 0x72,
0xBB, 0x12, 0x21, 0xA6, 0x2A, 0x57, 0x2A, 0x8F, 0x91, 0x2B, 0xB8, 0x0B, 0x85, 0x78, 0x07, 0xD0,
0x3A, 0x7A, 0x33, 0x6C, 0x35, 0xC9, 0x57, 0xD4, 0x3E, 0x85, 0xB8, 0xF5, 0x1D, 0x9F, 0x4E, 0x94,
0xF7, 0x99, 0x1B, 0x27, 0xE5, 0x88, 0x1B, 0x15, 0xA8, 0xAB, 0xD8, 0x55, 0x61, 0xC0, 0xE3, 0x18,
0xF3, 0x11, 0x85, 0x7E, 0xFE, 0x74, 0xD2, 0x18, 0x67, 0xC4, 0x0C, 0x9C, 0x6C, 0xD1, 0xF5, 0x99,
0x61, 0x58, 0xFF, 0xB0, 0x92, 0x85, 0x1E, 0x57, 0x33, 0x78, 0x2B, 0xD5, 0xB4, 0xDD, 0xC0, 0xCF,
0x47, 0x90, 0x44, 0xCB, 0xDF, 0xA7, 0x9F, 0x30, 0x7F, 0x20, 0x73, 0xDC, 0x3A, 0xAB, 0xF3, 0x29,
0x08, 0xDF, 0x6B, 0x3C, 0x1B, 0x43, 0xA7, 0x65, 0x81, 0xAA, 0x73, 0x63, 0x4D, 0x8D, 0x6C, 0xC1,
0xA9, 0x8E, 0xF5, 0x54, 0x8E, 0x4B, 0xA3, 0x8A, 0xE6, 0x69, 0x6F, 0xC9, 0x62, 0x73, 0x8B, 0x6D,
0x63, 0xC7, 0x3E, 0x4D, 0xB0, 0xC0, 0x60, 0x46, 0xC3, 0xBF, 0xB7, 0x22, 0xE0, 0xE8, 0x46, 0x25,
0x9F, 0x5E, 0x0F, 0xA4, 0x08, 0x84, 0xB1, 0xAB, 0x22, 0x9C, 0xE3, 0x24, 0x06, 0x38, 0xA4, 0x16,
0xDA, 0xC0, 0xDA, 0xAA, 0x1F, 0xB1, 0x63, 0x84, 0x20, 0xAE, 0xD2, 0x2C, 0x8C, 0x89, 0xC8, 0x30,
0x73, 0x61, 0x16, 0xC9, 0xD4, 0xF5, 0x54, 0xD0, 0x0B, 0xB9, 0x0A, 0x05, 0xA6, 0xD8, 0x9E, 0x54,
0xAB, 0x4F, 0xF1, 0x03, 0x8F, 0xA3, 0xC3, 0xE1, 0x03, 0x5F, 0xB3, 0x20, 0x92, 0x3C, 0xEE, 0x4D,
0x51, 0x51, 0xBD, 0x00, 0x65, 0xE1, 0xBA, 0xC0, 0x7C, 0xC0, 0x8D, 0x7A, 0x1E, 0x97, 0x32, 0x5A,
0xE0, 0xD3, 0x03, 0xDD, 0x4E, 0x68, 0x25, 0x25, 0xF7, 0x1F, 0xB4, 0xF7, 0xE0, 0x31, 0xDD, 0x5B,
0xAD, 0x56, 0x3D, 0xB4, 0x3A, 0x5F, 0xBB, 0x74, 0x81, 0x54, 0xEC, 0x5F, 0x64, 0x03, 0x92, 0xD9,
0x31, 0x6B, 0xD3, 0xB4, 0x00, 0x69, 0x20, 0x54, 0xAB, 0xCC, 0x07, 0xCE, 0x51, 0xEB, 0x4E, 0x9B,
0x5C, 0x8F, 0x4E, 0xEF, 0x34, 0x54, 0x4D, 0xD6, 0xCD, 0x75, 0x64, 0x87, 0x0E, 0x1C, 0xB4, 0xF9,
0x0C, 0x03, 0xCC, 0xA7, 0x61, 0x90, 0xB8, 0x74, 0x0B, 0x1D, 0x52, 0x3A, 0x39, 0xEC, 0x6F, 0xB3,
0xB7, 0x41, 0x25, 0x6D, 0x42, 0xE9, 0x83, 0x5E, 0x56, 0x88, 0xB9, 0x69, 0x64, 0xFA, 0x94, 0xBB,
0x7F, 0x85, 0xB8, 0xF9, 0x27, 0xCD, 0x70, 0x9B, 0x6B, 0x4F, 0x80, 0xE1, 0xE1, 0x2D, 0x70, 0x9E,
0xDD, 0x26, 0x26, 0x7D, 0x28, 0x42, 0x94, 0xE4, 0x18, 0x48, 0x73, 0x44, 0xDA, 0xC2, 0x61, 0x87,
0x8F, 0xE5, 0xA2, 0x92, 0x5B, 0x51, 0x1D, 0x5F, 0x9B, 0x4D, 0x45, 0xBE, 0xA8, 0xF8, 0xD8, 0xAE,
0xB0, 0x08, 0x28, 0x36, 0x8B, 0x33, 0xBF, 0xA8, 0x69, 0xFC, 0x67, 0xF2, 0xB4, 0x2E, 0x8E, 0x58,
0x35, 0xB5, 0x53, 0xFF, 0x72, 0xD8, 0xDF, 0x94, 0xD4, 0x06, 0x66, 0x8C, 0xC9, 0xB9, 0xDF, 0xDE,
0x7A, 0x52, 0xBB, 0xD3, 0x16, 0xBA, 0x8A, 0x90, 0xD4, 0x80, 0xA7, 0x8A, 0xC6, 0x17, 0x07, 0xAB,
0xCB, 0x46, 0xF4, 0x6F, 0x27, 0x0A, 0x13, 0x29, 0xB7, 0x1B, 0xC6, 0x1A, 0x3B, 0xD7, 0xD3, 0x36,
0xF5, 0x62, 0x4B, 0x1F, 0xB7, 0x77, 0x06, 0x72, 0x9E, 0x5B, 0xCB, 0x92, 0x90, 0x55, 0x82, 0xAF,
0xB9, 0xFC, 0xC0, 0xC0, 0x3C, 0xB3, 0x49, 0xA6, 0xBC, 0xFE, 0x50, 0x69, 0x06, 0xC2, 0x59, 0x5D,
0x61, 0x4D, 0xE5, 0x70, 0xFE, 0xFE, 0x0F, 0xD8, 0x4F, 0x93, 0xFF, 0xFE, 0x5E, 0x6E, 0x12, 0x7C,
0xCF, 0x9C, 0x2F, 0xA7, 0x73, 0x72, 0x9C, 0x4C, 0x52, 0x7B, 0x63, 0x12, 0x46, 0x49, 0xDE, 0x6A,
0xEC, 0x4A, 0xE8, 0x2D, 0xBA, 0xFB, 0xF9, 0x13, 0x63, 0x93, 0x7F, 0x6C, 0x6D, 0x21, 0xBD, 0xFF,
0x2A, 0xD2, 0xFB, 0x2A, 0xA9, 0x2F, 0x34, 0xB7, 0xD0, 0xE7, 0x48, 0x0B, 0xA4, 0x2A, 0xE5, 0x2C,
0xE1, 0xFA, 0x4F, 0xF6, 0xFE, 0x39, 0xBA, 0x0C, 0x65, 0x93, 0xEA, 0xFC, 0xCB, 0x54, 0xE7, 0x55,
0xAA, 0xF5, 0x73, 0xF8, 0x35, 0x55, 0x3C, 0x3E, 0x87, 0x69, 0x4F, 0xBE, 0x97, 0xE5, 0xF2, 0x5E,
0x6F, 0x62, 0x38, 0xD7, 0x94, 0x94, 0xB3, 0xD4, 0x08, 0x91, 0x56, 0x73, 0xCD, 0xB0, 0xD7, 0x99,
0x32, 0x6C, 0xDC, 0x31, 0x51, 0xC3, 0x51, 0x6E, 0xF8, 0x73, 0x31, 0x9B, 0x71, 0x8D, 0x9C, 0x70,
0x8A, 0x84, 0x82, 0xB0, 0xB8, 0xD1, 0x3E, 0x95, 0x73, 0xA5, 0x31, 0x59, 0x07, 0x39, 0x3E, 0xC0,
0xF4, 0x11, 0xCE, 0x98, 0x5C, 0xE2, 0x34, 0xF7, 0x0B, 0x8B, 0xE3, 0x12, 0x9E, 0xE7, 0x76, 0xCC,
0xBE, 0xAE, 0x08, 0xA2, 0x44, 0xC6, 0xD8, 0x94, 0x50, 0x2B, 0x9D, 0x68, 0x6E, 0x33, 0x3D, 0x5D,
0x66, 0xF6, 0x52, 0x19, 0x8B, 0x54, 0x8C, 0x27, 0x49, 0xD5, 0xE2, 0x84, 0xB8, 0x27, 0xF6, 0xFA,
0xF4, 0x75, 0x5F, 0xCD, 0x01, 0x36, 0x29, 0x7F, 0x50, 0xE6, 0x83, 0x58, 0x5F, 0x8D, 0xB6, 0x41,
0x6F, 0xEA, 0xD0, 0xD9, 0xB5, 0x58, 0xDE, 0x5F, 0xD9, 0xDA, 0x84, 0x59, 0x77, 0xE8, 0xF6, 0x47,
0x28, 0xDE, 0x2D, 0xBA, 0xB0, 0x59, 0x68, 0x1E, 0x2F, 0x94, 0xF4, 0x81, 0x61, 0xA5, 0x5F, 0x08,
0xCC, 0x76, 0xE4, 0xD9, 0x91, 0x58, 0x2A, 0x03, 0x2C, 0xAB, 0x0C, 0x34, 0x6A, 0xD6, 0x2A, 0x56,
0xE3, 0x73, 0x8B, 0xFD, 0x65, 0x85, 0x13, 0xBE, 0x04, 0x9C, 0xC5, 0x78, 0x42, 0x9F, 0xC6, 0xDB,
0x24, 0x14, 0x26, 0x26, 0xF5, 0x12, 0xE3, 0xFB, 0x2E, 0x5B, 0x8B, 0xE7, 0x78, 0xB1, 0x15, 0x7B,
0x84, 0x99, 0x56, 0x81, 0x45, 0xFF, 0x68, 0xD1, 0xC1, 0xB9, 0x1F, 0x63, 0x6B, 0x0C, 0xA7, 0x30,
0xB7, 0x11, 0xA9, 0xF1, 0x4C, 0x32, 0xE1, 0xD8, 0xC5, 0x48, 0x09, 0xA8, 0x6E, 0x31, 0x0F, 0x9F,
0xE1, 0x18, 0x28, 0xCD, 0x01, 0xDB, 0x0B, 0xE2, 0x97, 0x5F, 0x41, 0xEE, 0xC7, 0xA0, 0x59, 0x88,
0x25, 0x19, 0x23, 0xB9, 0x7A, 0xD6, 0xD8, 0x7D, 0x86, 0xD1, 0xA9, 0xC4, 0x6A, 0x4C, 0x3F, 0x86,
0xA4, 0xB4, 0x38, 0x07, 0xF6, 0x5D, 0xF7, 0x60, 0x30, 0xFC, 0xB1, 0xBD, 0x57, 0xA5, 0xBA, 0xBD,
0xF8, 0x70, 0x0D, 0x7F, 0x9C, 0xDE, 0xBC, 0x3F, 0x7D, 0x7B, 0x75, 0x31, 0xD9, 0x30, 0xCE, 0xB5,
0xE6, 0x01, 0x59, 0x2D, 0xC3, 0x46, 0x88, 0xD2, 0x58, 0x35, 0x71, 0x66, 0x6B, 0x03, 0xFA, 0x24,
0x2D, 0x92, 0x37, 0x26, 0x06, 0xA3, 0x3C, 0xA7, 0x75, 0xBA, 0x83, 0xE1, 0x9B, 0x7C, 0xAF, 0xED,
0x0C, 0x6F, 0x1A, 0x0C, 0xED, 0xD5, 0x70, 0xFB, 0xDB, 0x19, 0xA2, 0xA3, 0x4C, 0x22, 0xCE, 0xFD,
0x51, 0x71, 0x9E, 0x6B, 0xAB, 0x1F, 0x0B, 0x6C, 0x6A, 0xA4, 0xFC, 0xEC, 0x64, 0x48, 0x9E, 0x37,
0xA1, 0x1F, 0x97, 0x46, 0xA5, 0x86, 0xDE, 0x32, 0x49, 0x2D, 0x1F, 0xD8, 0x1F, 0x9D, 0x60, 0xDA,
0x5B, 0x81, 0xAF, 0xE9, 0xAE, 0x9E, 0x61, 0x0D, 0x4B, 0xAD, 0x41, 0x1C, 0xF1, 0x1F, 0xEA, 0x77,
0x80, 0x5F, 0x75, 0xFD, 0x62, 0x9C, 0x79, 0x89, 0xA4, 0xC4, 0x7C, 0x6E, 0xA9, 0x6E, 0x69, 0x3A,
0xC9, 0x8E, 0xE7, 0x27, 0xD6, 0xA4, 0x45, 0xA4, 0x7E, 0x4C, 0xB3, 0x65, 0x41, 0x4E, 0x55, 0xCE,
0x06, 0x13, 0x75, 0x1F, 0x1B, 0xCD, 0x07, 0x32, 0x7F, 0xA7, 0xF4, 0x8A, 0x69, 0xBF, 0x06, 0xAE,
0x58, 0x8D, 0x2E, 0x06, 0x6D, 0x4C, 0x5A, 0x7A, 0x2C, 0xB1, 0x38, 0x71, 0xB9, 0x74, 0x05, 0x9D,
0x7E, 0x1F, 0x40, 0x44, 0x3F, 0x8A, 0xBD, 0x93, 0x8A, 0x99, 0x14, 0xAF, 0xDD, 0xA8, 0x4E, 0x15,
0x83, 0xED, 0xE0, 0xD5, 0x85, 0x14, 0x98, 0xF1, 0xAC, 0xFE, 0x0E, 0x01, 0x1C, 0xD3, 0xC7, 0xA6,
0xCC, 0x37, 0xD4, 0x57, 0xC6, 0xFC, 0x1B, 0x65, 0xDE, 0xBD, 0xCF, 0xD7, 0xC9, 0xF9, 0x75, 0x67,
0x7E, 0xAA, 0x99, 0xCE, 0x3A, 0x42, 0x66, 0xB6, 0x1D, 0x16, 0xBB, 0x4F, 0x2D, 0x86, 0x23, 0xE3,
0x42, 0x2B, 0x63, 0x24, 0x2F, 0xDD, 0xA9, 0x7E, 0xA6, 0xEA, 0xDB, 0xAB, 0x34, 0x43, 0xDA, 0xAB,
0x53, 0x94, 0x69, 0xB4, 0x85, 0xE4, 0xA6, 0x46, 0x72, 0xB3, 0x49, 0x52, 0x95, 0xF3, 0x37, 0x6C,
0x99, 0xBC, 0xC2, 0xCD, 0xB2, 0x04, 0x11, 0xA8, 0x24, 0x34, 0x55, 0xAC, 0x2E, 0x96, 0x06, 0x2C,
0x12, 0x73, 0xB3, 0xA0, 0xF4, 0x92, 0x62, 0x39, 0x45, 0x00, 0xB5, 0xCB, 0xBA, 0xB2, 0xD3, 0x1D,
0x2D, 0x93, 0xB7, 0x32, 0x9B, 0x16, 0x0A, 0x26, 0xCB, 0x38, 0x0B, 0x08, 0xA7, 0x88, 0x9E, 0x6D,
0xDC, 0xEE, 0x1B, 0xDC, 0x8A, 0xAD, 0xE9, 0xA8, 0x64, 0x88, 0x52, 0x0F, 0x05, 0x1F, 0x32, 0xA6,
0xBD, 0xE7, 0x66, 0xD3, 0xD8, 0xC9, 0xCA, 0xCA, 0x49, 0xA5, 0x3C, 0xB4, 0xE9, 0x27, 0x15, 0x6B,
0x5D, 0x67, 0x60, 0x9D, 0xA4, 0x89, 0xDC, 0xAB, 0x22, 0x8F, 0x76, 0x04, 0x26, 0x36, 0xA0, 0x58,
0x38, 0x51, 0xCF, 0x74, 0xA6, 0xF3, 0x22, 0xB6, 0x6D, 0x26, 0xA9, 0xD9, 0xE6, 0x43, 0xE6, 0x9F,
0xE9, 0x5E, 0x95, 0xD3, 0xBE, 0xAA, 0xD9, 0xF7, 0xA0, 0x72, 0x80, 0x57, 0x55, 0x1D, 0x8F, 0x9A,
0xDC, 0x6E, 0xBE, 0xC8, 0xED, 0xA6, 0xC9, 0xAD, 0x5B, 0x65, 0xB7, 0x57, 0x99, 0xFD, 0xB2, 0x8B,
0x0F, 0xAB, 0x01, 0xFB, 0x9B, 0xA1, 0x53, 0x88, 0xFC, 0x0A, 0x86, 0xEE, 0xEB, 0xD7, 0x6D, 0x1A,
0x99, 0x3B, 0x34, 0x4F, 0x6F, 0xE2, 0xDC, 0xE4, 0x38, 0xA3, 0x54, 0x39, 0x54, 0x6C, 0x8B, 0x02,
0x9F, 0x72, 0x8E, 0xD3, 0x52, 0xAB, 0x95, 0x9F, 0x60, 0x57, 0x49, 0xD6, 0x1F, 0xA4, 0x29, 0x70,
0xB8, 0x57, 0x09, 0x1D, 0x6C, 0xA9, 0xDF, 0xD3, 0x8F, 0x43, 0x58, 0xF2, 0x9C, 0xFA, 0xD5, 0x8D,
0xED, 0x8E, 0xCB, 0x5E, 0x01, 0x6B, 0x9B, 0xBD, 0x6D, 0xA2, 0xEB, 0xB2, 0xEC, 0xF9, 0xDE, 0x69,
0x63, 0x30, 0x52, 0x9B, 0x7C, 0x68, 0x7F, 0xD1, 0xDC, 0x2B, 0x7B, 0x61, 0xBA, 0x1F, 0xA1, 0xFF,
0x48, 0xF0, 0x1F, 0x50, 0x6D, 0xCF, 0xB3, 0x60, 0x20, 0x00, 0x00
};

View File

@@ -2,4 +2,5 @@
#include <Arduino.h>
//declare here, define in cpp to prevent multiple declarations
extern const char htmlHomePage[] PROGMEM;
#define web_smars_html_gz_len 2875
extern const uint8_t web_smars_html_gz[] PROGMEM;

View File

@@ -12,7 +12,7 @@ const char* pwd = "Rijnstraat214";
void setup(void)
{
log_i("init hardware");
setUpPinModes();
setupmotors();
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid,pwd );

View File

@@ -2,8 +2,10 @@
#include <Arduino.h>
#include <vector>
#include "ESP32MotorControl.h"
#include <ESP32Servo.h> //by Kevin Harrington
#include "config.h"
#define RIGHT_MOTOR 1
@@ -29,13 +31,25 @@ struct MOTOR_PINS
};
//general functions
void setUpPinModes();
void moveCar(int inputValue, bool horizontal);
void setupmotors();
void loop_motors();
//void moveCar(int inputValue, bool horizontal);
//motor functions
void rotateMotor(int motorNumber, int motorDirection);
void setMomentum(bool val);
//void rotateMotor(int motorNumber, int motorDirection);
//void setMomentum(bool val);
void drivemotor(uint8_t num, int dirspeed);
//Servo functions
void bucketTilt(int bucketServoValue);
void auxControl(int auxServoValue);
void auxControl(int auxServoValue);
class motor: public ESP32MotorControl
{
const uint8_t motorindex = 0;
public:
void drive(int dirspeed);
};

View File

@@ -1,96 +1,47 @@
#include "webserver.h"
using namespace websockets;
WebsocketsServer server;
AsyncWebServer webserver(80);
WebsocketsClient client;
int LValue, RValue, commaIndex;
bool horizontalScreen;//When screen orientation is locked vertically this rotates the D-Pad controls so that forward would now be left.
AsyncWebServer server(80);
AsyncWebSocket wsCarInput("/CarInput");
void loop_webserver()
{
wsCarInput.cleanupClients();
// handle http messages
void handle_message(WebsocketsMessage msg) {
commaIndex = msg.data().indexOf(',');
LValue = msg.data().substring(0, commaIndex).toInt();
RValue = msg.data().substring(commaIndex + 1).toInt();
drivemotor(0, LValue);
drivemotor(1, RValue);
}
void setup_webserver()
{
server.on("/", HTTP_GET, handleRoot);
server.onNotFound(handleNotFound);
wsCarInput.onEvent(onCarInputWebSocketEvent);
server.addHandler(&wsCarInput);
Serial.begin(9600);
server.begin();
Serial.println("HTTP server started");
// HTTP handler assignment
webserver.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", web_smars_html_gz, web_smars_html_gz_len);
response->addHeader("Content-Encoding", "gzip");
request->send(response);
});
// start server
webserver.begin();
server.listen(82);
log_i("Is server live? %s",server.available() ? "true" : "false");
client = server.accept();
client.onMessage(handle_message);
}
void handleRoot(AsyncWebServerRequest *request)
void loop_webserver()
{
request->send_P(200, "text/html", htmlHomePage);
}
void handleNotFound(AsyncWebServerRequest *request)
{
request->send(404, "text/plain", "File Not Found");
}
void onCarInputWebSocketEvent(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());
break;
case WS_EVT_DISCONNECT:
Serial.printf("WebSocket client #%u disconnected\n", client->id());
moveCar(STOP, horizontalScreen);
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 == "MoveCar")
{
moveCar(valueInt, horizontalScreen);
}
else if (key == "AUX")
{
auxControl(valueInt);
}
else if (key == "Bucket")
{
bucketTilt(valueInt);
}
else if (key =="Switch")
{
if(!(horizontalScreen))
{
horizontalScreen = true;
}
else{
horizontalScreen = false;
}
}
}
break;
case WS_EVT_PONG:
case WS_EVT_ERROR:
break;
default:
break;
if (client.available()) {
client.poll();
delay(50);
}
}

View File

@@ -4,13 +4,9 @@
#include "html.h"
#include "motors.h"
#ifdef ESP32
#include <ArduinoWebsockets.h>
#include <WiFi.h>
#include <AsyncTCP.h> //by dvarrel
#elif defined(ESP8266)
#include <ESPAsyncTCP.h> //by dvarrel
#endif
#include <ESPAsyncWebServer.h> //by dvarrel
#include <ESPAsyncWebServer.h>
#include <iostream>
#include <sstream>
@@ -19,11 +15,3 @@
void loop_webserver();
void setup_webserver();
void handleRoot(AsyncWebServerRequest *request);
void handleNotFound(AsyncWebServerRequest *request);
void onCarInputWebSocketEvent(AsyncWebSocket *server,
AsyncWebSocketClient *client,
AwsEventType type,
void *arg,
uint8_t *data,
size_t len);