Author SHA1 Message Date
kleiax 5081290164 edit manualControl for new ControlPad 2023-04-20 12:34:45 +02:00
kleiax ef451a75fd some configs 2023-04-20 12:34:09 +02:00
kleiax 455981fd5f adjust deadzones from controlPad 2023-04-20 12:33:13 +02:00
kleiax 974118b643 fix motor running with empty battery 2023-04-20 12:32:21 +02:00
kleiax 07f09d691f fix speedometer for new encoder 2023-04-20 12:31:48 +02:00
kleiax 3fab7c7f83 working remoteControl via espNow 2023-04-11 12:47:32 +02:00
kleiax e3c452436d switch from rf24 to espnow 2023-04-08 20:28:34 +02:00
kleiax ede68db3df first try working module - fail 2023-04-06 16:27:00 +02:00
kleiax f20f4938e4 spelling 2023-04-02 17:03:24 +02:00
kleiax 33fe6916ed remove all PS3 things and begin with ControllPad 2023-03-30 22:20:28 +02:00
kleiax e4cdc5f98d finished new encoder 2023-03-23 19:31:02 +01:00
kleiax 2f0027b68b improve battery tracking 2023-02-21 11:49:25 +01:00
35 changed files with 585 additions and 231 deletions
+4
View File
@@ -82,11 +82,15 @@
"cSpell.words": [ "cSpell.words": [
"Ahnung", "Ahnung",
"akku", "akku",
"ardui",
"blox", "blox",
"bluedroid", "bluedroid",
"CIPO",
"COPI",
"gast", "gast",
"GNSS", "GNSS",
"GPGGA", "GPGGA",
"HSPI",
"Huus", "Huus",
"Keine", "Keine",
"kleiax", "kleiax",
+3
View File
@@ -33,3 +33,6 @@
#define UBLOX_GNSS_SPI_CIPO 4 #define UBLOX_GNSS_SPI_CIPO 4
#define UBLOX_GNSS_SPI_SCK 5 #define UBLOX_GNSS_SPI_SCK 5
///@} ///@}
#define RF24_CSN_PIN 18
#define RF24_CE_PIN 2
+8
View File
@@ -80,6 +80,12 @@ class MoveControl {
*/ */
void setDrivingStatus(DrivingStatus status); void setDrivingStatus(DrivingStatus status);
/**
* @brief Stops the engine immediately
*
*/
void emergencyStop();
/** /**
* @brief Set the target speed * @brief Set the target speed
* *
@@ -156,6 +162,8 @@ class MoveControl {
void setDelay(uint8_t delay) { this->delay = delay; } void setDelay(uint8_t delay) { this->delay = delay; }
private: private:
void setSpeedometerDirection(Speedometer *speedometer, double value);
/** /**
* @brief Converts values into wheel speeds * @brief Converts values into wheel speeds
* *
+2 -2
View File
@@ -18,7 +18,7 @@
#define M_DIR_21 23 #define M_DIR_21 23
#define M_DIR_22 14 #define M_DIR_22 14
#define M_PWM_2 22 #define M_PWM_2 22
#define M_ENCODE_RIGHT 12 #define M_ENCODE_RIGHT 33
// PID config // PID config
#define PID_OUT_MIN -100 #define PID_OUT_MIN -100
@@ -39,4 +39,4 @@
// SPEEDOMETER // SPEEDOMETER
#define WHEEL_DIAMETER 0.1263 #define WHEEL_DIAMETER 0.1263
#define ENC_STEPS 2048 #define ENC_STEPS 360
+10
View File
@@ -15,9 +15,13 @@
#include <iostream> #include <iostream>
#include <WiFi.h> #include <WiFi.h>
#include <PubSubClient.h> #include <PubSubClient.h>
#include <esp_now.h>
#include "networkConfig.h" #include "networkConfig.h"
typedef void (*recieveCallbackPtr) (const uint8_t * mac, const uint8_t *incomingData, int len);
typedef void (*sendCallbackPtr) (const uint8_t *mac_addr, esp_now_send_status_t status);
/** /**
* @brief This class handles all network stuff * @brief This class handles all network stuff
* *
@@ -39,6 +43,7 @@ class Network {
* @return false Timeout * @return false Timeout
*/ */
static bool connectWifi(); static bool connectWifi();
static bool connectEspNow(recieveCallbackPtr reci, sendCallbackPtr send);
/** /**
* @brief Set all general settings to connect to a broker. * @brief Set all general settings to connect to a broker.
@@ -71,6 +76,7 @@ class Network {
* @return PubSubClient* * @return PubSubClient*
*/ */
static PubSubClient* getMqttClient(); static PubSubClient* getMqttClient();
static const uint8_t * getBroadcastAddress() { return broadcastAddress; }
private: private:
/** /**
@@ -80,6 +86,10 @@ class Network {
* @return false if the connect attemp was unsuccessful * @return false if the connect attemp was unsuccessful
*/ */
static bool connectMQTT(); static bool connectMQTT();
static int32_t getWiFiChannel(const char *ssid);
static esp_now_peer_info_t peerInfo;
static uint8_t broadcastAddress[6];
static IPAddress local_IP; static IPAddress local_IP;
static IPAddress gateway; static IPAddress gateway;
+1
View File
@@ -30,6 +30,7 @@
*/ */
#define WLAN_CONNECT_LOOP_TIME 500 #define WLAN_CONNECT_LOOP_TIME 500
#define WLAN_DNS_SERVER "8.8.8.8" #define WLAN_DNS_SERVER "8.8.8.8"
#define ESP_NOW_CONTROLER_MAC {0xC8, 0xC9, 0xA3, 0xC8, 0x57, 0x10}
#define NTRIP_RTK2GO #define NTRIP_RTK2GO
+6
View File
@@ -33,6 +33,12 @@ double Battery::getBatteryVoltage() {
return (int)(res*100+0.5)/100.0; return (int)(res*100+0.5)/100.0;
} }
bool Battery::isBatteryLow(uint8_t percent) {
if (this->getBatteryPercent() <= percent && this->batteryVoltage > this->absurdLowVoltage)
return true;
return false;
}
double Battery::readInputVoltage() { double Battery::readInputVoltage() {
// Reference voltage is 3v3 so maximum reading is 3v3 = 4095 in range 0 to 4095 // Reference voltage is 3v3 so maximum reading is 3v3 = 4095 in range 0 to 4095
double reading = analogRead(this->pin); double reading = analogRead(this->pin);
+15
View File
@@ -73,13 +73,28 @@ class Battery {
*/ */
uint8_t getBatteryPercent() {return this->batteryPercent;} uint8_t getBatteryPercent() {return this->batteryPercent;}
/**
* @brief Checks if the battery is low.
*
* The function will also return false if the battery voltage is
* absurd low. This is for the case that the uController is powered
* by usb and no battery is connected.
*
* @param percent the limit the battery have to
* @return true if the battery is low
* @return false if the battery is high
*/
bool isBatteryLow(uint8_t percent);
private: private:
double readInputVoltage(); double readInputVoltage();
void calculateBatteryVoltage(); void calculateBatteryVoltage();
void calculateBatteryPercent(); void calculateBatteryPercent();
uint8_t absurdLowVoltage = 5;
uint8_t pin; uint8_t pin;
uint8_t batteryPercent; uint8_t batteryPercent;
uint8_t batteryLowPercent = 10;
uint16_t delay = 20000; uint16_t delay = 20000;
uint32_t r1; uint32_t r1;
uint32_t r2; uint32_t r2;
+80
View File
@@ -0,0 +1,80 @@
/**
* @file controlPad.cpp
* @author Alexander Klein (alex@kleiax.de)
* @brief
* @version 0.1
* @date 2023-03-30
*
* @copyright Copyright (c) 2023
*
*/
#include "controlPad.h"
ControlPad::ControlPad() {
}
bool ControlPad::loop() {
if (millis() - this->lastLoopMillis < this->loopDelay)
return false;
this->lastLoopMillis = millis();
if(!this->connected)
return false;
if (millis() - this->lastMessageReceive > this->disconnectTime) {
this->connected = false;
this->controlInput.buttons = 0;
this->controlInput.x = 127;
this->controlInput.y = 127;
return false;
}
if (this->lastButtons != controlInput.buttons)
this->updated = true;
if (this->menuControl && this->controlInput.buttons > 0 && this->updated) {
if (this->firstButtonPress) {
this->menuControl->printMenu();
this->firstButtonPress = false;
std::cout << "ControlPad::loop - First menu print" << std::endl;
return true;
}
if (ControlPadButton::isControlPadButtonPressed(&this->controlInput, ControlPadButton::PadButton::Left))
this->menuControl->left();
else if (ControlPadButton::isControlPadButtonPressed(&this->controlInput, ControlPadButton::PadButton::Right))
this->menuControl->right();
else if (ControlPadButton::isControlPadButtonPressed(&this->controlInput, ControlPadButton::PadButton::Up))
this->menuControl->up();
else if (ControlPadButton::isControlPadButtonPressed(&this->controlInput, ControlPadButton::PadButton::Down))
this->menuControl->down();
else if (ControlPadButton::isControlPadButtonPressed(&this->controlInput, ControlPadButton::PadButton::Yes))
this->menuControl->yes();
else if (ControlPadButton::isControlPadButtonPressed(&this->controlInput, ControlPadButton::PadButton::No))
this->menuControl->no();
this->updated = false;
this->lastButtons = controlInput.buttons;
}
return true;
}
void ControlPad::insertData(const uint8_t *data) {
this->connected = true;
this->lastMessageReceive = millis();
uint8_t lastCount = this->controlInput.counter + 1;
memcpy(&(this->controlInput), data, sizeof(this->controlInput));
if (lastCount != this->controlInput.counter)
std::cout << "ControlPad::insertData counter wrong value" << std::endl;
if (this->controlInput.x > 127 - this->deadZoneX
&& this->controlInput.x < 127 + this->deadZoneX)
this->controlInput.x = 127;
if (this->controlInput.y > 127 - this->deadZoneY
&& this->controlInput.y < 127 + this->deadZoneY)
this->controlInput.y = 127;
}
+50
View File
@@ -0,0 +1,50 @@
/**
* @file controlPad.h
* @author Alexander Klein (alex@kleiax.de)
* @brief
* @version 0.1
* @date 2023-03-30
*
* @copyright Copyright (c) 2023
*
*/
#pragma once
#include <menuControl.h>
#include "controlPadInput.h"
class ControlPad {
public:
ControlPad();
bool loop();
void insertData(const uint8_t *data);
void setMenuControl(MenuControl* menuControl) { this->menuControl = menuControl; }
const ControlPadInput * getControlPadDataPtr() const { return &this->controlInput; }
bool isControlPadConnected() const { return this->connected; }
private:
MenuControl* menuControl = nullptr;
ControlPadInput controlInput;
bool connected = false;
bool updated = false;
bool firstButtonPress = true;
uint8_t deadZoneX = 20;
uint8_t deadZoneY = 20;
uint8_t lastButtons = 0;
uint16_t disconnectTime = 100;
uint16_t loopDelay = 5;
uint32_t lastMessageReceive = 0;
uint32_t lastLoopMillis = 0;
};
+74
View File
@@ -0,0 +1,74 @@
/**
* @file controlPadInput.h
* @author Alexander Klein (alex@kleiax.de)
* @brief
* @version 0.1
* @date 2023-03-30
*
* @copyright Copyright (c) 2023
*
*/
#ifndef CONTROL_PAD_INPUT_H
#define CONTROL_PAD_INPUT_H
#include <stdint.h>
struct ControlPadInput {
uint8_t buttons;
uint8_t x;
uint8_t y;
uint8_t counter;
};
class ControlPadButton {
public:
enum PadButton {
Left = 4,
Right = 8,
Up = 2,
Down = 1,
Yes = 32,
No = 16,
Action = 64
};
static bool isControlPadButtonPressed(const ControlPadInput *input, PadButton button) {
uint8_t buttonNum = input->buttons;
switch (button) {
case PadButton::Left :
return buttonNum & (uint8_t) PadButton::Left;
break;
case PadButton::Right :
return buttonNum & (uint8_t) PadButton::Right;
break;
case PadButton::Up :
return buttonNum & (uint8_t) PadButton::Up;
break;
case PadButton::Down :
return buttonNum & (uint8_t) PadButton::Down;
break;
case PadButton::Yes :
return buttonNum & (uint8_t) PadButton::Yes;
break;
case PadButton::No :
return buttonNum & (uint8_t) PadButton::No;
break;
case PadButton::Action :
return buttonNum & (uint8_t) PadButton::Action;
break;
default:
return false;;
}
}
};
#endif // CONTROL_PAD_INPUT_H
+56
View File
@@ -0,0 +1,56 @@
#include "counter.h"
#include <inttypes.h>
uint8_t Counter::amountOfCounter = 0;
Counter::Counter(uint8_t pin) {
this->pulsePin = pin;
this->unit = static_cast<pcnt_unit_t>(Counter::amountOfCounter);
if (Counter::amountOfCounter < 7)
Counter::amountOfCounter++;
pcnt_config_t config;
config.unit = this->unit;
config.channel = PCNT_CHANNEL_0;
config.counter_h_lim = COUNTER_HIGH_LIMIT;
config.counter_l_lim = COUNTER_LOW_LIMIT;
config.ctrl_gpio_num = PCNT_PIN_NOT_USED;
config.hctrl_mode = PCNT_CHANNEL_LEVEL_ACTION_KEEP;
config.lctrl_mode = PCNT_CHANNEL_LEVEL_ACTION_KEEP;
config.pulse_gpio_num = this->pulsePin;
config.pos_mode = PCNT_CHANNEL_EDGE_ACTION_INCREASE;
config.neg_mode = PCNT_CHANNEL_EDGE_ACTION_HOLD;
pcnt_unit_config(&config);
}
void Counter::pause() {
pcnt_counter_pause(this->unit);
}
void Counter::resume() {
pcnt_counter_resume(this->unit);
}
void Counter::clear() {
pcnt_counter_clear(this->unit);
}
int16_t Counter::getValue() {
int16_t res;
pcnt_get_counter_value(this->unit, &res);
return res;
}
void Counter::setFilterValue(uint16_t value) {
pcnt_set_filter_value(this->unit, value);
this->filterEnable();
}
void Counter::filterEnable() {
pcnt_filter_enable(this->unit);
}
void Counter::filterDisable() {
pcnt_filter_disable(this->unit);
}
+30
View File
@@ -0,0 +1,30 @@
#pragma once
#include <Arduino.h>
#include <driver/pcnt.h>
#define COUNTER_HIGH_LIMIT INT16_MAX
#define COUNTER_LOW_LIMIT 0
class Counter {
public:
Counter(uint8_t pin);
void pause();
void resume();
void clear();
int16_t getValue();
void setFilterValue(uint16_t value);
void filterEnable();
void filterDisable();
private:
static uint8_t amountOfCounter;
bool initalised = false;
uint8_t pulsePin;
pcnt_unit_t unit;
};
+12 -7
View File
@@ -18,14 +18,19 @@ LcdWrapper::LcdWrapper(LiquidCrystal_I2C* lcd) {
} }
void LcdWrapper::loop() { void LcdWrapper::loop() {
if (this->changed) { if (!this->changed)
this->lcd->clear(); return;
for (uint8_t i = 0; i < DISPLAY_WRAPPER_LINES; i++) {
this->lcd->setCursor(0, i); this->lcd->clear();
this->lcd->print(this->data[i]); for (uint8_t i = 0; i < DISPLAY_WRAPPER_LINES; i++) {
} this->lcd->setCursor(0, i);
this->changed = false; this->lcd->print(this->data[i]);
} }
if (this->callback)
this->callback(this->data, DISPLAY_WRAPPER_LINES, DISPLAY_WRAPPER_ROWS);
this->changed = false;
} }
void LcdWrapper::clear() { void LcdWrapper::clear() {
+4
View File
@@ -19,6 +19,8 @@
#define DISPLAY_WRAPPER_ROWS 16 #define DISPLAY_WRAPPER_ROWS 16
#define DISPLAY_WRAPPER_LINES 2 #define DISPLAY_WRAPPER_LINES 2
typedef void (*LcdWrapperCallback) (const char data[][DISPLAY_WRAPPER_ROWS], uint8_t lines, uint8_t rows);
/** /**
* @brief A class for the Menu class to print information * @brief A class for the Menu class to print information
* *
@@ -54,6 +56,7 @@ class LcdWrapper : public DisplayWrapper {
* @param line * @param line
*/ */
void setCursor(uint8_t row, uint8_t line) override; void setCursor(uint8_t row, uint8_t line) override;
void setCallback(LcdWrapperCallback callback) { this->callback = callback; }
/** /**
* @brief Save the data to be printed * @brief Save the data to be printed
@@ -65,6 +68,7 @@ class LcdWrapper : public DisplayWrapper {
private: private:
LiquidCrystal_I2C* lcd; LiquidCrystal_I2C* lcd;
LcdWrapperCallback callback = nullptr;
char data[DISPLAY_WRAPPER_LINES][DISPLAY_WRAPPER_ROWS]; char data[DISPLAY_WRAPPER_LINES][DISPLAY_WRAPPER_ROWS];
uint8_t cursorRow = 0; uint8_t cursorRow = 0;
+50 -44
View File
@@ -30,59 +30,59 @@ uint16_t Speedometer::loop() {
return -1; return -1;
uint32_t time = millis(); uint32_t time = millis();
uint16_t elapsed_time = time - this->last_millis_loop; uint16_t elapsedTime = time - this->lastMillisLoop;
//Cancel if delayLoop is not reached //Cancel if delayLoop is not reached
if (elapsed_time < this->delayLoop) if (elapsedTime < this->delayLoop)
return elapsed_time; return elapsedTime;
runSpeedometer(); runSpeedometer();
this->last_millis_loop = time; this->lastMillisLoop = time;
return elapsed_time; return elapsedTime;
} }
void Speedometer::runSpeedometer() { void Speedometer::runSpeedometer() {
uint32_t time = millis(); uint32_t time = millis();
uint16_t elapsed_time = time - last_millis_calc; uint16_t elapsedTime = time - this->lastMillisCalc;
last_millis_calc = time; this->lastMillisCalc = time;
int16_t count = this->pulseCounter->get_value();
switch (this->currentDirection) {
case Direction::Forward :
this->addValToBuf(count);
break;
case Direction::Backward :
this->addValToBuf(-count);
break;
case Direction::None :
this->addValToBuf(0);
break;
default:
std::cout << "Wrong value in Speedometer::runSpeedometer" << std::endl;
break;
}
this->addValToBuf(this->pulseCounter->getValue());
this->pulseCounter->clear(); this->pulseCounter->clear();
this->pulseCounter->resume(); this->pulseCounter->resume();
uint16_t count_abs = abs(this->calcAverage()); // Absolute time in milliseconds
double n = (double)count_abs / steps; // Wheel revolutions in absolute time
double u = (double)n / ((double)elapsed_time / 1000); // Wheel revolutions per second
double ms = u * (diameter * PI); // Speed in m/s
if (count > 0) { double n = (double)this->calcAverage() / this->steps; // Wheel revolutions in absolute time
this->speed = ms; double u = n / ((double)elapsedTime / 1000); // Wheel revolutions per second
} else if (count < 0) { double ms = u * (diameter * PI); // Speed in m/s
this->speed = ms * (-1);
} else { switch (this->currentDirection) {
this->speed = 0; case Direction::Forward :
this->speed = ms;
break;
case Direction::Backward :
this->speed = -ms;
break;
case Direction::None :
this->speed = 0;
break;
} }
// std::cout << "Speedometer::runSpeedometer speed: " << (int) this->speed << std::endl; // if (this->speed)
// this->printCounter++;
// if (this->printCounter > 10) {
// this->printCounter = 0;
// std::cout << "Speedometer::runSpeedometer speed: " << (int) this->speed << std::endl;
// }
}
void Speedometer::setDirection(Direction dir) {
if (this->currentDirection == dir)
return;
this->currentDirection = dir;
this->clearAvgBuf();
} }
void Speedometer::setNumOfValForAvg(uint8_t val) { void Speedometer::setNumOfValForAvg(uint8_t val) {
@@ -93,20 +93,23 @@ void Speedometer::setNumOfValForAvg(uint8_t val) {
void Speedometer::setEncFilter(uint16_t val) { void Speedometer::setEncFilter(uint16_t val) {
if (val > 1023) if (val > 1023)
val = 1023; val = 1023;
this->pulseCounter->set_filter_value(val); this->pulseCounter->setFilterValue(val);
} }
void Speedometer::calibrationMeasurementStart() { void Speedometer::calibrationMeasurementStart() {
std::cout << "Start" << std::endl;
this->calibrationRunning = true; this->calibrationRunning = true;
this->pulseCounter->clear(); this->pulseCounter->clear();
this->pulseCounter->resume(); this->pulseCounter->resume();
} }
uint16_t Speedometer::calibrationMeasurementStop() { uint16_t Speedometer::calibrationMeasurementStop() {
std::cout << "Ende" << std::endl;
this->calibrationRunning = false; this->calibrationRunning = false;
uint16_t res = abs(this->pulseCounter->get_value()); uint16_t res = abs(this->pulseCounter->getValue());
this->pulseCounter->clear(); this->pulseCounter->clear();
this->pulseCounter->resume(); this->pulseCounter->resume();
std::cout << "Result: " << res << std::endl;
return res; return res;
} }
@@ -114,10 +117,8 @@ void Speedometer::init(uint8_t pin, double diameter, uint16_t steps) {
this->diameter = diameter; this->diameter = diameter;
this->steps = steps; this->steps = steps;
this->pulseCounter = new PulseCounter(); this->pulseCounter = new Counter(pin);
this->pulseCounter->initialise(pin, PCNT_PIN_NOT_USED); this->pulseCounter->setFilterValue(1000); // ignore pulses less than 1000 x 2.5ns
this->pulseCounter->set_mode(PCNT_COUNT_INC, PCNT_COUNT_DIS, PCNT_MODE_KEEP, PCNT_MODE_KEEP);
this->pulseCounter->set_filter_value(1000); // ignore pulses less than 1000 x 2.5ns
this->pulseCounter->clear(); this->pulseCounter->clear();
this->pulseCounter->resume(); this->pulseCounter->resume();
@@ -131,12 +132,17 @@ void Speedometer::initAvgBuf() {
this->buf[i] = 0; this->buf[i] = 0;
} }
void Speedometer::clearAvgBuf() {
for (uint8_t i = 0; i < bufSize; i++)
this->buf[i] = 0;
}
void Speedometer::addValToBuf(int16_t val) { void Speedometer::addValToBuf(int16_t val) {
this->buf[this->bufPos] = val; this->buf[this->bufPos] = val;
this->bufPos++; this->bufPos++;
if (bufPos == bufSize) if (bufPos == bufSize)
bufPos = 0; bufPos = 0;
} }
void Speedometer::updateAvgBufSize() { void Speedometer::updateAvgBufSize() {
+8 -5
View File
@@ -15,7 +15,8 @@
#include <Arduino.h> #include <Arduino.h>
#include <cstdint> #include <cstdint>
#include <iostream> #include <iostream>
#include <esp32_pcnt.h>
#include "counter.h"
/** /**
* @brief The default size of numbers to be taken in account for the average. * @brief The default size of numbers to be taken in account for the average.
@@ -88,7 +89,7 @@ class Speedometer {
* *
* @param dir Direction * @param dir Direction
*/ */
void setDirection(Direction dir) { this->currentDirection = dir; } void setDirection(Direction dir);
/** /**
* @brief Set the number of last values to be taken into account for the average. * @brief Set the number of last values to be taken into account for the average.
@@ -149,11 +150,12 @@ class Speedometer {
private: private:
void init(uint8_t pin, double diameter, uint16_t steps); void init(uint8_t pin, double diameter, uint16_t steps);
void initAvgBuf(); void initAvgBuf();
void clearAvgBuf();
void addValToBuf(int16_t val); void addValToBuf(int16_t val);
void updateAvgBufSize(); void updateAvgBufSize();
int16_t calcAverage(); int16_t calcAverage();
PulseCounter* pulseCounter; Counter* pulseCounter;
Direction currentDirection = Direction::None; Direction currentDirection = Direction::None;
bool calibrationRunning = false; bool calibrationRunning = false;
@@ -161,6 +163,7 @@ class Speedometer {
double speed = 0; double speed = 0;
double diameter; double diameter;
uint8_t printCounter = 0;
uint8_t bufSize = BUFSIZE; uint8_t bufSize = BUFSIZE;
uint8_t delayLoop = DELAY_SPEEDOMETER; uint8_t delayLoop = DELAY_SPEEDOMETER;
uint8_t bufPos = 0; uint8_t bufPos = 0;
@@ -168,8 +171,8 @@ class Speedometer {
int16_t *buf = nullptr; int16_t *buf = nullptr;
uint32_t last_millis_loop = 0; uint32_t lastMillisLoop = 0;
uint32_t last_millis_calc = 0; uint32_t lastMillisCalc = 0;
}; };
#endif // SPEEDOMETER_H #endif // SPEEDOMETER_H
+2 -5
View File
@@ -17,25 +17,22 @@ monitor_speed = 115200
upload_speed = 921600 upload_speed = 921600
monitor_port = COM3 monitor_port = COM3
lib_deps = lib_deps =
jvpernis/PS3 Controller Host@^1.1.0
sparkfun/SparkFun u-blox GNSS Arduino Library@^2.2.7 sparkfun/SparkFun u-blox GNSS Arduino Library@^2.2.7
knolleary/PubSubClient@^2.8 knolleary/PubSubClient@^2.8
br3ttb/PID@^1.2.1 br3ttb/PID@^1.2.1
marcoschwartz/LiquidCrystal_I2C@^1.1.4 marcoschwartz/LiquidCrystal_I2C@^1.1.4
marian-craciunescu/ESP32Ping@^1.7
bblanchon/ArduinoJson@^6.20.0 bblanchon/ArduinoJson@^6.20.0
mprograms/QMC5883LCompass@^1.1.1 mprograms/QMC5883LCompass@^1.1.1
mike-gofton/ESP32PulseCounter@^0.2.0
https://git.kleiax.de/PlatformIO-Libs/Menu.git#v1.0 https://git.kleiax.de/PlatformIO-Libs/Menu.git#v1.0
nrf24/RF24@^1.4.5
upload_port = COM3 upload_port = COM3
[env:release] [env:release]
build_type = release build_type = release
lib_deps = mike-gofton/ESP32PulseCounter@^0.2.0
[env:debug] [env:debug]
monitor_filters = esp32_exception_decoder
build_type = debug build_type = debug
monitor_filters = esp32_exception_decoder
check_tool = clangtidy check_tool = clangtidy
[platformio] [platformio]
@@ -11,10 +11,9 @@
#include "menuSysteminformation.h" #include "menuSysteminformation.h"
MenuSysteminformation::MenuSysteminformation(Battery* mainBattery, Ps3Controller* gamepad) MenuSysteminformation::MenuSysteminformation(Battery* mainBattery)
: MenuInformationSites(5) { : MenuInformationSites(5) {
this->mainBattery = mainBattery; this->mainBattery = mainBattery;
this->gamepad = gamepad;
} }
void MenuSysteminformation::printPage() const { void MenuSysteminformation::printPage() const {
@@ -44,11 +43,11 @@ void MenuSysteminformation::printPage() const {
lineTwo.concat(this->mainBattery->getBatteryVoltage()); lineTwo.concat(this->mainBattery->getBatteryVoltage());
break; break;
case 4: // case 4:
lineOne = "PS3 battery"; // lineOne = "PS3 battery";
lineTwo = "is "; // lineTwo = "is ";
lineTwo.concat(MenuSysteminformation::ps3ToString(this->gamepad->data.status.battery)); // lineTwo.concat(MenuSysteminformation::ps3ToString(this->gamepad->data.status.battery));
break; // break;
default: default:
this->printDefault(); this->printDefault();
@@ -58,12 +57,3 @@ void MenuSysteminformation::printPage() const {
this->print(lineOne, lineTwo); this->print(lineOne, lineTwo);
} }
String MenuSysteminformation::ps3ToString(uint8_t battery) {
if( battery == ps3_status_battery_charging ) return "LOAD";
else if( battery == ps3_status_battery_full ) return "FULL";
else if( battery == ps3_status_battery_high ) return "HIGH";
else if( battery == ps3_status_battery_low) return "LOW";
else if( battery == ps3_status_battery_dying ) return "BAD";
else if( battery == ps3_status_battery_shutdown ) return "OFF";
else return "UNDEF";
}
@@ -13,8 +13,8 @@
#define MENU_SYSTEMINFORMATION_H #define MENU_SYSTEMINFORMATION_H
#include <Arduino.h> #include <Arduino.h>
#include <Ps3Controller.h>
#include "controlPadInput.h"
#include "menuInformationSites.h" #include "menuInformationSites.h"
#include "battery.h" #include "battery.h"
@@ -31,14 +31,12 @@ class MenuSysteminformation : public MenuInformationSites {
* @param mainBattery * @param mainBattery
* @param gamepad * @param gamepad
*/ */
MenuSysteminformation(Battery* mainBattery, Ps3Controller* gamepad); MenuSysteminformation(Battery* mainBattery);
private: private:
void printPage() const override; void printPage() const override;
static String ps3ToString(uint8_t battery);
Battery* mainBattery; Battery* mainBattery;
Ps3Controller* gamepad;
}; };
#endif // MENU_SYSTEMINFORMATION_H #endif // MENU_SYSTEMINFORMATION_H
@@ -78,7 +78,7 @@ void MenuTestMode::init() {
this->driveManager->changeModus(Modi::TestMode); this->driveManager->changeModus(Modi::TestMode);
this->testMode = (TestMode*) this->driveManager->getDriveModiPtr(); this->testMode = (TestMode*) this->driveManager->getDriveModiPtr();
testMode->setSpeed(15); testMode->setSpeed(50);
testMode->setRotationSpeed(100); testMode->setRotationSpeed(100);
@@ -93,7 +93,6 @@ void MenuTestMode::init() {
Menu* encoderMenu = new Menu; Menu* encoderMenu = new Menu;
// Sound // Sound
// Ping google // Ping google
// WheelEncoder
MenuIntInput* drivingMenu = new MenuIntInput(2, new MenuTestModeWrapper(this, &TestMode::drive)); MenuIntInput* drivingMenu = new MenuIntInput(2, new MenuTestModeWrapper(this, &TestMode::drive));
MenuIntInput* engineLeftMenu = new MenuIntInput(2, new MenuTestModeWrapper(this, &TestMode::leftEngine)); MenuIntInput* engineLeftMenu = new MenuIntInput(2, new MenuTestModeWrapper(this, &TestMode::leftEngine));
@@ -13,6 +13,7 @@
SpeedometerTest::SpeedometerTest(Speedometer* speedometer) { SpeedometerTest::SpeedometerTest(Speedometer* speedometer) {
this->speedometer = speedometer; this->speedometer = speedometer;
this->speedometer->setDirection(Speedometer::Forward);
} }
+3 -3
View File
@@ -11,8 +11,8 @@
#include "driveModi/Modi/Autopilot/autopilot.h" #include "driveModi/Modi/Autopilot/autopilot.h"
Autopilot::Autopilot(MoveControl* moveControl, Ps3Controller *gamepad, Navigation* navigation) Autopilot::Autopilot(MoveControl* moveControl, const ControlPadInput *input, Navigation* navigation)
: ManualControl(moveControl, gamepad) { : ManualControl(moveControl, input) {
this->navigation = navigation; this->navigation = navigation;
this->navigationStarted = this->navigation->startNavigation(); this->navigationStarted = this->navigation->startNavigation();
this->routeInfo = this->navigation->getRouteInfo(); this->routeInfo = this->navigation->getRouteInfo();
@@ -45,7 +45,7 @@ void Autopilot::runAutopilot() {
this->selfDrivingAvailable = true; this->selfDrivingAvailable = true;
if (!this->selfDriving && this->selfDrivingAvailable) if (!this->selfDriving && this->selfDrivingAvailable)
this->setSelfDriving(this->gamepad->data.button.triangle); this->setSelfDriving(ControlPadButton::isControlPadButtonPressed(this->input, ControlPadButton::PadButton::Action));
if (this->routeInfo.currentPoint == this->routeInfo.totalPoints) { if (this->routeInfo.currentPoint == this->routeInfo.totalPoints) {
this->navigationEnded = true; this->navigationEnded = true;
+2 -2
View File
@@ -35,7 +35,7 @@ class Autopilot : public ManualControl {
* @param moveControl for ManualControl * @param moveControl for ManualControl
* @param navigation for route instructions * @param navigation for route instructions
*/ */
Autopilot(MoveControl* moveControl, Ps3Controller *gamepad, Navigation* navigation); Autopilot(MoveControl* moveControl, const ControlPadInput *input, Navigation* navigation);
/** /**
* @brief Calls runAutopilot or ManualControl loop * @brief Calls runAutopilot or ManualControl loop
@@ -50,7 +50,7 @@ class Autopilot : public ManualControl {
void loop(); void loop();
/** /**
* @brief Manges the autoipilot * @brief Manges the autopilot
* *
* If the first Point is near to current location you can turn * If the first Point is near to current location you can turn
* the autopilot on. * the autopilot on.
@@ -11,8 +11,8 @@
#include "driveModi/Modi/CaptureRoute/captureRoute.h" #include "driveModi/Modi/CaptureRoute/captureRoute.h"
CaptureRoute::CaptureRoute(MoveControl* moveControl, Ps3Controller *gamepad, Navigation* navigation) CaptureRoute::CaptureRoute(MoveControl* moveControl, const ControlPadInput *input, Navigation* navigation)
: ManualControl(moveControl, gamepad) { : ManualControl(moveControl, input) {
this->navigation = navigation; this->navigation = navigation;
this->routeInfo = navigation->getRouteInfo(); this->routeInfo = navigation->getRouteInfo();
} }
@@ -28,7 +28,7 @@ void CaptureRoute::loop() {
} }
void CaptureRoute::runCaptureRoute() { void CaptureRoute::runCaptureRoute() {
if (this->gamepad->data.button.triangle) { if (ControlPadButton::isControlPadButtonPressed(this->input, ControlPadButton::PadButton::Action)) {
if (this->navigation->addCurrentPosToRoute()) { if (this->navigation->addCurrentPosToRoute()) {
this->routeInfo = navigation->getRouteInfo(); this->routeInfo = navigation->getRouteInfo();
this->updateDisplay = true; this->updateDisplay = true;
@@ -33,7 +33,7 @@ class CaptureRoute : public ManualControl {
* @param moveControl for ManualControl * @param moveControl for ManualControl
* @param navigation to add Points * @param navigation to add Points
*/ */
CaptureRoute(MoveControl* moveControl, Ps3Controller *gamepad, Navigation* navigation); CaptureRoute(MoveControl* moveControl, const ControlPadInput *input, Navigation* navigation);
/** /**
* @brief Calls runCaptureRoute and ManualControl::loop * @brief Calls runCaptureRoute and ManualControl::loop
@@ -10,9 +10,9 @@
*/ */
#include "manualControl.h" #include "manualControl.h"
ManualControl::ManualControl(MoveControl *moveControl, Ps3Controller *gamepad) { ManualControl::ManualControl(MoveControl *moveControl, const ControlPadInput *input) {
this->moveControl = moveControl; this->moveControl = moveControl;
this->gamepad = gamepad; this->input = input;
this->moveControl->setDrivingStatus(DrivingStatus::drive); this->moveControl->setDrivingStatus(DrivingStatus::drive);
} }
@@ -31,12 +31,18 @@ void ManualControl::loop() {
} }
void ManualControl::runManualControl() { void ManualControl::runManualControl() {
int8_t x = this->gamepad->data.analog.stick.lx; // Have to be int16_t to avoid overflow (int8_t = 255 - 127 = -128)
int8_t y = this->gamepad->data.analog.stick.ly; int16_t y = this->input->x - 127;
int16_t x = this->input->y - 127;
// if (x || y) {
// std::cout << "x: " << (int) this->input->x << " y: " << (int) this->input->y << std::endl;
// std::cout << "x: " << (int) x << " y: " << (int) y << std::endl;
// }
double value_per_step = this->max_speed * 2 / 256; double value_per_step = this->max_speed * 2 / 256;
this->moveControl->setSpeed((y * -1) * value_per_step); this->moveControl->setSpeed(-y * value_per_step);
value_per_step = this->max_rotation * 2 / 256; value_per_step = this->max_rotation * 2 / 256;
this->moveControl->setRotationSpeed(-x * value_per_step); this->moveControl->setRotationSpeed(x * value_per_step);
} }
@@ -13,6 +13,7 @@
#include "moveControl.h" #include "moveControl.h"
#include "driveModi/driveModi.h" #include "driveModi/driveModi.h"
#include "controlPadInput.h"
/** /**
* @brief Drive the Rover with a Joystick * @brief Drive the Rover with a Joystick
@@ -24,7 +25,7 @@
*/ */
class ManualControl : public DriveModi { class ManualControl : public DriveModi {
public: public:
ManualControl(MoveControl *moveControl, Ps3Controller *gamepad); ManualControl(MoveControl *moveControl, const ControlPadInput *input);
/** /**
* @brief Destroy the Manual Control object * @brief Destroy the Manual Control object
@@ -71,7 +72,7 @@ class ManualControl : public DriveModi {
protected: protected:
MoveControl *moveControl; MoveControl *moveControl;
Ps3Controller *gamepad; const ControlPadInput* input;
private: private:
uint32_t lastMillis = 0; uint32_t lastMillis = 0;
+1 -1
View File
@@ -79,7 +79,7 @@ bool TestMode::drive(int16_t cm, int16_t degree) {
else if (cm > 0) else if (cm > 0)
this->moveControl->setSpeed(this->speed); this->moveControl->setSpeed(this->speed);
this->maneuverTime = (uint32_t) (((double) cm / 100.0) / this->speed) * 1000; this->maneuverTime = (uint32_t) (((double) abs(cm) / 100.0) / this->speed) * 1000;
this->busy = true; this->busy = true;
this->maneuver = Maneuver::Drive; this->maneuver = Maneuver::Drive;
return true; return true;
+6 -7
View File
@@ -15,12 +15,11 @@ Modi& operator++(Modi& m, int) {
return m = (m == Modi::TestMode) ? Modi::Off : static_cast<Modi>(static_cast<int>(m)+1); return m = (m == Modi::TestMode) ? Modi::Off : static_cast<Modi>(static_cast<int>(m)+1);
} }
DriveManager::DriveManager(MoveControl *moveControl, Ps3Controller *gamepad, bool wifi) { DriveManager::DriveManager(MoveControl *moveControl, SPIClass *spiPort, const ControlPadInput *input, bool wifi) {
this->moveControl = moveControl; this->moveControl = moveControl;
this->gamepad = gamepad; this->input = input;
this->spiPort = new SPIClass(HSPI); this->spiPort = spiPort;
spiPort->begin(UBLOX_GNSS_SPI_SCK, UBLOX_GNSS_SPI_CIPO, UBLOX_GNSS_SPI_COPI, UBLOX_GNSS_SPI_CS);
this->navigation = new Navigation(spiPort, UBLOX_GNSS_SPI_CS); this->navigation = new Navigation(spiPort, UBLOX_GNSS_SPI_CS);
if (wifi) if (wifi)
this->navigation->initNtrip(NTRIP_HOST, NTRIP_PORT, NTRIP_MOUNT_POINT, NTRIP_USER, NTRIP_PASSWORD); this->navigation->initNtrip(NTRIP_HOST, NTRIP_PORT, NTRIP_MOUNT_POINT, NTRIP_USER, NTRIP_PASSWORD);
@@ -66,17 +65,17 @@ void DriveManager::changeModus(Modi modus) {
break; break;
case Modi::ManualControl: { case Modi::ManualControl: {
this->currentModusPtr = new ManualControl(this->moveControl, this->gamepad); this->currentModusPtr = new ManualControl(this->moveControl, this->input);
} }
break; break;
case Modi::CaptureRoute: { case Modi::CaptureRoute: {
this->currentModusPtr = new CaptureRoute(this->moveControl, this->gamepad, this->navigation); this->currentModusPtr = new CaptureRoute(this->moveControl, this->input, this->navigation);
} }
break; break;
case Modi::Autopilot: { case Modi::Autopilot: {
this->currentModusPtr = new Autopilot(this->moveControl, this->gamepad, this->navigation); this->currentModusPtr = new Autopilot(this->moveControl, this->input, this->navigation);
} }
break; break;
+3 -2
View File
@@ -21,6 +21,7 @@
#include "config.h" #include "config.h"
#include "networkConfig.h" #include "networkConfig.h"
#include "debugTimes.h" #include "debugTimes.h"
#include "controlPadInput.h"
// All Drive Modi // All Drive Modi
#include "driveModi/Modi/ManualControl/manualControl.h" #include "driveModi/Modi/ManualControl/manualControl.h"
@@ -51,7 +52,7 @@ class DriveManager {
* *
* @param moveControl * @param moveControl
*/ */
DriveManager(MoveControl *moveControl, Ps3Controller *gamepad, bool wifi = false); DriveManager(MoveControl *moveControl, SPIClass *spiPort, const ControlPadInput *input, bool wifi = false);
/** /**
* @brief Destroy the Drive Manager object * @brief Destroy the Drive Manager object
@@ -117,7 +118,7 @@ class DriveManager {
private: private:
Modi currentModus = Modi::Off; Modi currentModus = Modi::Off;
MoveControl *moveControl; MoveControl *moveControl;
Ps3Controller *gamepad; const ControlPadInput* input;
DriveModi *currentModusPtr = nullptr; DriveModi *currentModusPtr = nullptr;
Navigation* navigation; Navigation* navigation;
SPIClass* spiPort; SPIClass* spiPort;
-2
View File
@@ -12,8 +12,6 @@
#ifndef DRIVEMODI_H #ifndef DRIVEMODI_H
#define DRIVEMODI_H #define DRIVEMODI_H
#include <Ps3Controller.h>
/** /**
* @brief Baseclass to build DriveModi * @brief Baseclass to build DriveModi
* *
+50 -111
View File
@@ -17,13 +17,10 @@
#include "config.h" #include "config.h"
#include <Ps3Controller.h>
#include <iostream> #include <iostream>
#include <Wire.h> #include <Wire.h>
#include <LiquidCrystal_I2C.h> #include <LiquidCrystal_I2C.h>
#include <ESP32Ping.h> #include <SPI.h>
#include <BluetoothSerial.h>
#include <esp_bt_main.h>
#include "driveModi/driveManager.h" #include "driveModi/driveManager.h"
#include "OutputBuf/outputBuf.h" #include "OutputBuf/outputBuf.h"
@@ -33,6 +30,7 @@
#include "debugMqtt.h" #include "debugMqtt.h"
#include "battery.h" #include "battery.h"
#include "debugTimes.h" #include "debugTimes.h"
#include "controlPad.h"
#include "menu.h" #include "menu.h"
#include "menuAction.h" #include "menuAction.h"
@@ -53,21 +51,17 @@ LcdWrapper* lcdWrapper;
OutputBuf* outputBuf; OutputBuf* outputBuf;
DebugMqtt* debugMqtt = nullptr; DebugMqtt* debugMqtt = nullptr;
Battery* mainBattery; Battery* mainBattery;
Ps3Controller* gamepad; SPIClass* spiPort;
BluetoothSerial SerialBT; ControlPad* controlPad;
bool wifiIsActive; bool wifiIsActive;
bool disconnectPs3 = false;
void configureController(void);
void callbackControllerAction(void);
void callbackControllerConnect(void);
void callbackControllerDisconnect(void);
void i2cScanner(void); void i2cScanner(void);
void makeMenu(void); void makeMenu(void);
void restart(void); void restart(void);
void disconnectController(void); void receiveCallback (const uint8_t * mac, const uint8_t *incomingData, int len);
void sendCallback (const uint8_t *mac_addr, esp_now_send_status_t status);
void lcdWrapperCallback (const char data[][DISPLAY_WRAPPER_ROWS], uint8_t lines, uint8_t rows);
void setup() { void setup() {
@@ -76,7 +70,15 @@ void setup() {
DebugTimes setupTime; DebugTimes setupTime;
char wifiIndicator = 'X'; char wifiIndicator = 'X';
WiFi.mode(WIFI_MODE_STA);
Serial.print("MAC Address: ");
Serial.println(WiFi.macAddress());
spiPort = new SPIClass(HSPI);
spiPort->begin(UBLOX_GNSS_SPI_SCK, UBLOX_GNSS_SPI_CIPO, UBLOX_GNSS_SPI_COPI, UBLOX_GNSS_SPI_CS);
mainBattery = new Battery(35, 692000, 218500); mainBattery = new Battery(35, 692000, 218500);
controlPad = new ControlPad();
Wire.begin(21, 19); Wire.begin(21, 19);
Wire.setClock(400000); Wire.setClock(400000);
@@ -90,14 +92,6 @@ void setup() {
Network::setupMQTT(); Network::setupMQTT();
wifiIsActive = Network::connectWifi(); wifiIsActive = Network::connectWifi();
if (wifiIsActive) { if (wifiIsActive) {
// const char* remoteHost = "www.google.com";
// std::cout << "Pinging host: " << remoteHost << std::endl;
// if (Ping.ping(remoteHost))
// std::cout << "Ping successful..." << std::endl;
// else
// std::cout << "Ping failed. :/" << std::endl;
if (Network::checkMQTT()) { if (Network::checkMQTT()) {
DebugMqtt::init(Network::getMqttClient(), Loglevel::debug); DebugMqtt::init(Network::getMqttClient(), Loglevel::debug);
std::cout << "Activate additional output via MQTT..." << std::endl; std::cout << "Activate additional output via MQTT..." << std::endl;
@@ -106,17 +100,16 @@ void setup() {
} else } else
outputBuf = new OutputBuf(); outputBuf = new OutputBuf();
wifiIndicator = '-'; wifiIndicator = '-';
} else { } else
outputBuf = new OutputBuf(); outputBuf = new OutputBuf();
}
std::cout.rdbuf(outputBuf); std::cout.rdbuf(outputBuf);
Network::connectEspNow(receiveCallback, sendCallback);
std::cout << "Welcome to Kleiax-Rover" << std::endl; std::cout << "Welcome to Kleiax-Rover" << std::endl;
std::cout << "All actions from the main program run on Core -> " << xPortGetCoreID() << std::endl; std::cout << "All actions from the main program run on Core -> " << xPortGetCoreID() << std::endl;
gamepad = new Ps3Controller; driveManager = new DriveManager(&moveController, spiPort, controlPad->getControlPadDataPtr(), wifiIsActive);
driveManager = new DriveManager(&moveController, gamepad, wifiIsActive);
configureController();
outputBuf->activateMqtt(false); outputBuf->activateMqtt(false);
@@ -125,6 +118,7 @@ void setup() {
lcd->setCursor(0, 1); lcd->setCursor(0, 1);
lcd->print("Press PS-Button"); lcd->print("Press PS-Button");
lcdWrapper = new LcdWrapper(lcd); lcdWrapper = new LcdWrapper(lcd);
lcdWrapper->setCallback(lcdWrapperCallback);
makeMenu(); makeMenu();
@@ -139,90 +133,23 @@ void loop() {
wifiTime.stopConsol("WiFi-Time", 10); wifiTime.stopConsol("WiFi-Time", 10);
} }
driveManager->loop(); driveManager->loop();
controlPad->loop();
main_m->update();
lcdWrapper->loop(); lcdWrapper->loop();
mainBattery->loop(); mainBattery->loop();
if (mainBattery->getBatteryPercent() <= 10) { if (mainBattery->isBatteryLow(10)) {
moveController.setDrivingStatus(DrivingStatus::stop); moveController.emergencyStop();
moveController.setSpeed(0);
moveController.setRotationSpeed(0); uint16_t voltage = (uint16_t) (mainBattery->getBatteryVoltage() * 100);
lcd->setCursor(0, 0); lcd->setCursor(0, 0);
lcd->printf("Low Battery..."); lcd->printf("Low Battery: %u", voltage);
lcd->setCursor(0, 1); lcd->setCursor(0, 1);
lcd->print("Please turn off."); lcd->print("Please turn off.");
while (1); while (true);
} }
if (disconnectPs3) {
DebugTimes disconnectPS3Time;
std::cout << "Disconnect PS3 Controller." << std::endl;
gamepad->end();
esp_bluedroid_disable();
esp_bluedroid_deinit();
configureController();
disconnectPs3 = false;
disconnectPS3Time.stopConsol("Ps3 Disconnect");
}
}
void configureController() {
gamepad->attach(callbackControllerAction);
gamepad->attachOnConnect(callbackControllerConnect);
gamepad->attachOnDisconnect(callbackControllerDisconnect);
std::cout << "\nReady to connect a PS3 Controller... \n";
gamepad->begin(CONTROLLER_MAC);
}
void callbackControllerAction() {
auto isDelayReached = [](bool reset = false) -> bool {
static uint32_t lastMillis = 0;
if (reset)
lastMillis = millis();
static const uint16_t delay = 100;
bool res = false;
if (millis() - lastMillis > delay)
res = true;
return res;
};
// Menu controlling
if (isDelayReached()) {
if (gamepad->data.button.up)
main_m->up();
else if (gamepad->data.button.down)
main_m->down();
else if (gamepad->data.button.left)
main_m->left();
else if (gamepad->data.button.right)
main_m->right();
else if (gamepad->data.button.circle)
main_m->yes();
else if (gamepad->data.button.cross)
main_m->no();
else if (gamepad->data.button.select)
std::cout << "main.cpp callbackControllerAction - Here we are!" << std::endl;
isDelayReached(true);
}
// This have to be stand here because it have to be run on the other Core
main_m->update();
}
void callbackControllerConnect() {
std::cout << "Controller connected to ESP32" << std::endl;
std::cout << "All actions from the Controller run on Core -> " << xPortGetCoreID() << std::endl;
main_m->printMenu();
}
void callbackControllerDisconnect() {
std::cout << "Controller disconnected..." << std::endl;
// gamepad->end();
} }
void i2cScanner() { void i2cScanner() {
@@ -272,7 +199,7 @@ void makeMenu() {
MenuAutopilot* auto_m = new MenuAutopilot(driveManager); MenuAutopilot* auto_m = new MenuAutopilot(driveManager);
MenuTestMode* testM_m = new MenuTestMode(driveManager); MenuTestMode* testM_m = new MenuTestMode(driveManager);
MenuGPS* gps_m = new MenuGPS(driveManager); MenuGPS* gps_m = new MenuGPS(driveManager);
MenuSysteminformation* sys_m = new MenuSysteminformation(mainBattery, gamepad); MenuSysteminformation* sys_m = new MenuSysteminformation(mainBattery);
MenuRoute* rout_m = new MenuRoute(driveManager->getNavigation()->getRoute()); MenuRoute* rout_m = new MenuRoute(driveManager->getNavigation()->getRoute());
// Set Menus on LCD // Set Menus on LCD
@@ -295,7 +222,6 @@ void makeMenu() {
MenuAction* gps_e = new MenuAction("GPS", gps_m); MenuAction* gps_e = new MenuAction("GPS", gps_m);
MenuAction* pid_e = new MenuAction("PID", pid_m); MenuAction* pid_e = new MenuAction("PID", pid_m);
MenuAction* restart_e = new MenuAction("Restart", restart); MenuAction* restart_e = new MenuAction("Restart", restart);
MenuAction* contr_e = new MenuAction("Remove PS3", disconnectController);
MenuAction* sys_e = new MenuAction("Systeminfo", sys_m); MenuAction* sys_e = new MenuAction("Systeminfo", sys_m);
MenuAction* rout_e = new MenuAction("Route", rout_m); MenuAction* rout_e = new MenuAction("Route", rout_m);
main_m->addEntry(mode_e); main_m->addEntry(mode_e);
@@ -303,7 +229,6 @@ void makeMenu() {
main_m->addEntry(rout_e); main_m->addEntry(rout_e);
main_m->addEntry(pid_e); main_m->addEntry(pid_e);
main_m->addEntry(sys_e); main_m->addEntry(sys_e);
main_m->addEntry(contr_e);
main_m->addEntry(restart_e); main_m->addEntry(restart_e);
// Entry for the mode Menu // Entry for the mode Menu
@@ -334,6 +259,8 @@ void makeMenu() {
pidr_m->setEntry(0, "P-Part", (uint8_t) moveController.getPID(1)->GetKp()); pidr_m->setEntry(0, "P-Part", (uint8_t) moveController.getPID(1)->GetKp());
pidr_m->setEntry(1, "I-Part", (uint8_t) moveController.getPID(1)->GetKi()); pidr_m->setEntry(1, "I-Part", (uint8_t) moveController.getPID(1)->GetKi());
pidr_m->setEntry(2, "D-Part", (uint8_t) moveController.getPID(1)->GetKd()); pidr_m->setEntry(2, "D-Part", (uint8_t) moveController.getPID(1)->GetKd());
controlPad->setMenuControl(main_m);
} }
void restart(void) { void restart(void) {
@@ -343,11 +270,23 @@ void restart(void) {
ESP.restart(); ESP.restart();
} }
void disconnectController(void) { void receiveCallback (const uint8_t * mac, const uint8_t *incomingData, int len) {
disconnectPs3 = true; if (len != sizeof(ControlPadInput))
lcdWrapper->clear(); return;
lcdWrapper->setCursor(0, 0); controlPad->insertData(incomingData);
lcdWrapper->print("Controller is"); }
lcdWrapper->setCursor(0, 1);
lcdWrapper->print("disconnected."); void sendCallback (const uint8_t *mac_addr, esp_now_send_status_t status) {
if (status != ESP_NOW_SEND_SUCCESS)
std::cout << "sendCallback - Delivery Fail" << std::endl;
}
void lcdWrapperCallback (const char data[][DISPLAY_WRAPPER_ROWS], uint8_t lines, uint8_t rows) {
if (!controlPad->isControlPadConnected())
return;
esp_err_t result = esp_now_send(Network::getBroadcastAddress(), (uint8_t *) data, lines * rows);
if (result != ESP_OK)
Serial.println("Error sending the data");
} }
+39 -6
View File
@@ -60,6 +60,10 @@ void MoveControl::loop() {
|| left_speed_time > 50 || left_speed_time > 50
|| right_speed_time > 50) { || right_speed_time > 50) {
// Dont count overTimeCounter if one speedometer is in TestMode.
if (left_speed_time == UINT16_MAX || right_speed_time == UINT16_MAX)
this->overTimeCounter--;
this->overTimeCounter++; this->overTimeCounter++;
if (this->overTimeCounter >= this->overTimeMax) { if (this->overTimeCounter >= this->overTimeMax) {
char buf[128]; char buf[128];
@@ -108,18 +112,32 @@ void MoveControl::setDrivingStatus(DrivingStatus status) {
// } // }
} }
void MoveControl::emergencyStop() {
this->left_motor->emergencyStop();
this->right_motor->emergencyStop();
this->setSpeed(0);
this->setRotationSpeed(0);
this->setRawPowerLeft(0);
this->setRawPowerRight(0);
this->driving_status = DrivingStatus::stop;
}
void MoveControl::setSpeed(double speed) { void MoveControl::setSpeed(double speed) {
if (speed < 0.1 && speed > -0.1) if (speed < 0.1 && speed > -0.1) {
this->x_speed = 0; this->x_speed = 0;
else return;
this->x_speed = speed; }
this->x_speed = speed;
} }
void MoveControl::setRotationSpeed(double speed) { void MoveControl::setRotationSpeed(double speed) {
if (speed < 0.1 && speed > -0.1) if (speed < 0.1 && speed > -0.1){
this->rotation_speed = 0; this->rotation_speed = 0;
else return;
this->rotation_speed = speed; }
this->rotation_speed = speed;
} }
void MoveControl::setRawPowerLeft(int16_t power) { void MoveControl::setRawPowerLeft(int16_t power) {
@@ -151,6 +169,15 @@ PID* MoveControl::getPID(uint8_t side) {
return nullptr; return nullptr;
} }
void MoveControl::setSpeedometerDirection(Speedometer *speedometer, double value) {
if (value > 0)
speedometer->setDirection(Speedometer::Direction::Forward);
else if (value < 0)
speedometer->setDirection(Speedometer::Direction::Backward);
else
speedometer->setDirection(Speedometer::Direction::None);
}
void MoveControl::calcTargetWheelSpeed() { void MoveControl::calcTargetWheelSpeed() {
/* original formula: /* original formula:
(1 / r) / 1 b \ / x \ = / Xl \ (1 / r) / 1 b \ / x \ = / Xl \
@@ -170,16 +197,22 @@ void MoveControl::regulateMotors() {
case DrivingStatus::stop : case DrivingStatus::stop :
this->left_motor->setTargetPower(0); this->left_motor->setTargetPower(0);
this->right_motor->setTargetPower(0); this->right_motor->setTargetPower(0);
this->setSpeedometerDirection(this->left_speedometer, 0);
this->setSpeedometerDirection(this->right_speedometer, 0);
break; break;
case DrivingStatus::drive : case DrivingStatus::drive :
this->left_motor->setTargetPower( (int8_t) this->left_pid_out); this->left_motor->setTargetPower( (int8_t) this->left_pid_out);
this->right_motor->setTargetPower( (int8_t) this->right_pid_out); this->right_motor->setTargetPower( (int8_t) this->right_pid_out);
this->setSpeedometerDirection(this->left_speedometer, this->left_pid_out);
this->setSpeedometerDirection(this->right_speedometer, this->right_pid_out);
break; break;
case DrivingStatus::raw : case DrivingStatus::raw :
this->left_motor->setTargetPower(this->rawPowerLeft); this->left_motor->setTargetPower(this->rawPowerLeft);
this->right_motor->setTargetPower(this->rawPowerRight); this->right_motor->setTargetPower(this->rawPowerRight);
this->setSpeedometerDirection(this->left_speedometer, this->rawPowerLeft);
this->setSpeedometerDirection(this->right_speedometer, this->rawPowerRight);
break; break;
default: default:
+37
View File
@@ -20,6 +20,9 @@ IPAddress Network::dnsServer;
WiFiClient Network::wifi_client; WiFiClient Network::wifi_client;
PubSubClient* Network::mqtt_client; PubSubClient* Network::mqtt_client;
esp_now_peer_info_t Network::peerInfo;
uint8_t Network::broadcastAddress[6] = ESP_NOW_CONTROLER_MAC;
void Network::setIps() { void Network::setIps() {
local_IP.fromString(WLAN_IP); local_IP.fromString(WLAN_IP);
gateway.fromString(WLAN_GATEWAY); gateway.fromString(WLAN_GATEWAY);
@@ -58,6 +61,10 @@ bool Network::connectMQTT() {
} }
bool Network::connectWifi() { bool Network::connectWifi() {
// Configures static IP address // Configures static IP address
if (!WiFi.mode(WIFI_AP_STA))
std::cout << "Network::connectWiFi failed WiFi.mode" << std::endl;
if (!WiFi.config(local_IP, gateway, subnet, dnsServer)) if (!WiFi.config(local_IP, gateway, subnet, dnsServer))
std::cout << "STA Failed to configure" << std::endl; std::cout << "STA Failed to configure" << std::endl;
@@ -81,6 +88,28 @@ bool Network::connectWifi() {
std::cout << "WiFi connected." << std::endl; std::cout << "WiFi connected." << std::endl;
std::cout << "IP address: " << std::endl; std::cout << "IP address: " << std::endl;
std::cout << WLAN_IP << std::endl; std::cout << WLAN_IP << std::endl;
// std::cout << "WiFi MAC Address: " << WiFi.macAddress() << std::endl << std::endl;
return true;
}
bool Network::connectEspNow(recieveCallbackPtr reci, sendCallbackPtr send) {
if (esp_now_init() != ESP_OK) {
std::cout << "Network::connectEspNow - Error initializing ESP-NOW" << std::endl;
return false;
}
esp_now_register_send_cb(send);
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
std::cout << "Network::connectEspNow - Failed to add peer" << std::endl;
return false;
}
esp_now_register_recv_cb(reci);
return true; return true;
} }
@@ -100,6 +129,14 @@ bool Network::checkMQTT() {
return true; return true;
} }
int32_t Network::getWiFiChannel(const char *ssid) {
if (int32_t n = WiFi.scanNetworks())
for (uint8_t i=0; i<n; i++)
if (!strcmp(ssid, WiFi.SSID(i).c_str()))
return WiFi.channel(i);
return 0;
}
void Network::checkWiFi() { void Network::checkWiFi() {
static uint64_t previousMillis = 0; static uint64_t previousMillis = 0;
static uint16_t delay = 5000; static uint16_t delay = 5000;