Cleanup and fixes
This commit is contained in:
5
testsystem/.gitignore
vendored
Normal file
5
testsystem/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
.pio
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
||||
12
testsystem/platformio.ini
Normal file
12
testsystem/platformio.ini
Normal file
@@ -0,0 +1,12 @@
|
||||
[platformio]
|
||||
default_envs = esp
|
||||
|
||||
[env:esp]
|
||||
platform = espressif8266
|
||||
board = nodemcuv2
|
||||
framework = arduino
|
||||
monitor_port = /dev/ttyUSB0
|
||||
upload_port = /dev/ttyUSB0
|
||||
monitor_speed = 115200
|
||||
lib_deps =
|
||||
ArduinoJson
|
||||
76
testsystem/src/MotorControl.cpp
Normal file
76
testsystem/src/MotorControl.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
#include "MotorControl.h"
|
||||
#include <Arduino.h>
|
||||
|
||||
constexpr int PORT_FORWARD = 4;
|
||||
constexpr int PORT_BACKWARD = 16;
|
||||
constexpr int PORT_SPEED = 5;
|
||||
|
||||
// PWM settings
|
||||
constexpr int PWM_FREQ = 20000;
|
||||
constexpr int PWM_CHANNEL = 0;
|
||||
constexpr int PWM_RESOLUTION = 255;
|
||||
|
||||
void MotorControl::begin()
|
||||
{
|
||||
pinMode(PORT_SPEED, OUTPUT);
|
||||
pinMode(PORT_FORWARD, OUTPUT);
|
||||
pinMode(PORT_BACKWARD, OUTPUT);
|
||||
|
||||
analogWriteRange(PWM_RESOLUTION);
|
||||
analogWriteFreq(PWM_FREQ);
|
||||
startTime_ = millis();
|
||||
}
|
||||
|
||||
void MotorControl::addCmd(float signedSpeed, unsigned long duration)
|
||||
{
|
||||
if (numCmds_ < MAX_MOTOR_COMMANDS)
|
||||
motorCommands_[numCmds_++] = {int(signedSpeed * PWM_RESOLUTION), duration};
|
||||
else
|
||||
Serial.println("Too many commands");
|
||||
}
|
||||
|
||||
float MotorControl::speed(int cmdIdx) const
|
||||
{
|
||||
return float(motorCommands_[cmdIdx].directionAndSpeed) / float(PWM_RESOLUTION);
|
||||
}
|
||||
|
||||
unsigned long MotorControl::duration(int cmdIdx) const
|
||||
{
|
||||
return motorCommands_[cmdIdx].delayToNextCmdInMs;
|
||||
}
|
||||
|
||||
void MotorControl::iteration()
|
||||
{
|
||||
if (numCmds_ == 0)
|
||||
{
|
||||
analogWrite(PORT_SPEED, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned long timeElapsed = millis() - startTime_;
|
||||
while (timeElapsed > motorCommands_[currentCmd_].delayToNextCmdInMs)
|
||||
{
|
||||
const auto curCmdDuration = motorCommands_[currentCmd_].delayToNextCmdInMs;
|
||||
timeElapsed -= curCmdDuration;
|
||||
startTime_ += curCmdDuration;
|
||||
currentCmd_ = (currentCmd_ + 1) % numCmds_;
|
||||
}
|
||||
|
||||
const auto &curCmd = motorCommands_[currentCmd_];
|
||||
const auto &nextCmd = motorCommands_[(currentCmd_ + 1) % numCmds_];
|
||||
const float fraction = float(timeElapsed) / float(curCmd.delayToNextCmdInMs);
|
||||
const int interpolated = int((1.f - fraction) * curCmd.directionAndSpeed + fraction * nextCmd.directionAndSpeed);
|
||||
|
||||
if (interpolated < 0)
|
||||
{
|
||||
analogWrite(PORT_SPEED, -interpolated);
|
||||
digitalWrite(PORT_FORWARD, 0);
|
||||
digitalWrite(PORT_BACKWARD, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
analogWrite(PORT_SPEED, interpolated);
|
||||
digitalWrite(PORT_FORWARD, 1);
|
||||
digitalWrite(PORT_BACKWARD, 0);
|
||||
}
|
||||
}
|
||||
31
testsystem/src/MotorControl.h
Normal file
31
testsystem/src/MotorControl.h
Normal file
@@ -0,0 +1,31 @@
|
||||
|
||||
|
||||
class MotorControl
|
||||
{
|
||||
public:
|
||||
void begin();
|
||||
void clear()
|
||||
{
|
||||
numCmds_ = 0;
|
||||
currentCmd_ = 0;
|
||||
}
|
||||
void addCmd(float signedSpeed, unsigned long duration);
|
||||
void iteration();
|
||||
|
||||
int numCommands() const { return numCmds_; }
|
||||
float speed(int cmdIdx) const;
|
||||
unsigned long duration(int cmdIdx) const;
|
||||
|
||||
private:
|
||||
static constexpr int MAX_MOTOR_COMMANDS = 1024;
|
||||
struct MotorCmd
|
||||
{
|
||||
int directionAndSpeed; // fraction of PWM_RESO
|
||||
unsigned long delayToNextCmdInMs;
|
||||
};
|
||||
|
||||
int currentCmd_ = 0;
|
||||
int numCmds_ = 0;
|
||||
MotorCmd motorCommands_[MAX_MOTOR_COMMANDS];
|
||||
unsigned long startTime_ = 0;
|
||||
};
|
||||
87
testsystem/src/main.cpp
Normal file
87
testsystem/src/main.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#include "MotorControl.h"
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266WebServer.h>
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
ESP8266WebServer server(80);
|
||||
MotorControl motorCtl;
|
||||
const char *webBuffer[1024 * 4];
|
||||
|
||||
void wifiSetup()
|
||||
{
|
||||
static const char *ssid = "WLAN";
|
||||
static const char *password = "Bau3rWLAN";
|
||||
|
||||
WiFi.begin(ssid, password);
|
||||
WiFi.hostname("swimtracker-tester");
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
delay(500);
|
||||
Serial.println("Waiting to connect...");
|
||||
}
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.localIP());
|
||||
}
|
||||
|
||||
void handleGetRoot()
|
||||
{
|
||||
DynamicJsonDocument doc(motorCtl.numCommands() * 16 + 128);
|
||||
JsonArray speeds = doc.createNestedArray("speeds");
|
||||
JsonArray durations = doc.createNestedArray("durations");
|
||||
for (int i = 0; i < motorCtl.numCommands(); ++i)
|
||||
{
|
||||
speeds.add(motorCtl.speed(i));
|
||||
durations.add(motorCtl.duration(i));
|
||||
}
|
||||
size_t length = serializeJson(doc, webBuffer, sizeof(webBuffer));
|
||||
server.send(200, "application/json", (const char *)webBuffer, length);
|
||||
}
|
||||
|
||||
void handlePostRoot()
|
||||
{
|
||||
String postBody = server.arg("plain");
|
||||
DynamicJsonDocument doc(postBody.length() * 2 + 256);
|
||||
DeserializationError error = deserializeJson(doc, postBody);
|
||||
if (error || !doc.containsKey("speeds") || !doc.containsKey("durations"))
|
||||
server.send(400, "application/json", "{ \"msg\" : \"Parsing error\" }");
|
||||
else
|
||||
{
|
||||
JsonArray speeds = doc["speeds"].as<JsonArray>();
|
||||
JsonArray durations = doc["durations"].as<JsonArray>();
|
||||
if (speeds.size() != durations.size())
|
||||
server.send(400, "application/json", "{ \"msg\" : \"Arrays have to have same length!\" }");
|
||||
else
|
||||
{
|
||||
motorCtl.clear();
|
||||
auto speedIt = speeds.begin();
|
||||
auto durationIt = durations.begin();
|
||||
for (; speedIt != speeds.end() && durationIt != durations.end(); ++durationIt, ++speedIt)
|
||||
{
|
||||
motorCtl.addCmd(speedIt->as<float>(), durationIt->as<unsigned long>());
|
||||
}
|
||||
server.send(200, "application/json", "{ \"msg\" : \"Ok\" }");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
wifiSetup();
|
||||
|
||||
server.on("/", HTTP_GET, handleGetRoot);
|
||||
server.on("/", HTTP_POST, handlePostRoot);
|
||||
|
||||
server.begin(); //Start the server
|
||||
Serial.println("Server listening");
|
||||
|
||||
motorCtl.begin();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
server.handleClient(); //Handling of incoming client requests
|
||||
motorCtl.iteration();
|
||||
}
|
||||
Reference in New Issue
Block a user