Implemented overcurrent detection
Implemented manual and overcurrent screens Basically it's ready for a real world test!
This commit is contained in:
parent
c8ccd519fc
commit
b9f5394d53
@ -4,6 +4,26 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Determines if logging over the serial port is enabled.
|
||||||
|
Uses a baud rate of 115200.
|
||||||
|
|
||||||
|
Verbose logging outputs even more, including logging
|
||||||
|
every loop. Only turn on when required.
|
||||||
|
|
||||||
|
|
||||||
|
At the time of writing, turning both on uses more RAM
|
||||||
|
than the ATMega328P has.
|
||||||
|
|
||||||
|
Turning DebugLog off saves around 1k of RAM and 3k of flash.
|
||||||
|
Turning VerboseLog off saves around 300 bytes of RAM and 1k of flash.
|
||||||
|
*/
|
||||||
|
//#define DebugLog
|
||||||
|
//#define VerboseLog
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Config
|
class Config
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -83,6 +103,10 @@ class Config
|
|||||||
static const uint8_t MotorPinSleep = 16;
|
static const uint8_t MotorPinSleep = 16;
|
||||||
static const uint8_t MotorPinCurrentSensing = 17;
|
static const uint8_t MotorPinCurrentSensing = 17;
|
||||||
|
|
||||||
|
static const constexpr float MotorCurrentLimit = 6.0;
|
||||||
|
static const uint16_t MotorCurrentCheckInterval = 100;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Colors
|
Colors
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
enum class ScreenId
|
enum class ScreenId
|
||||||
{
|
{
|
||||||
Home,
|
Home = 1,
|
||||||
Calibrate,
|
Calibrate,
|
||||||
Move,
|
Move,
|
||||||
MoveOvercurrent,
|
MoveOvercurrent,
|
||||||
|
@ -49,13 +49,17 @@ ControlUpdateResult ControlManager::update()
|
|||||||
|
|
||||||
|
|
||||||
// Check for over-current
|
// Check for over-current
|
||||||
// TODO: don't check current every update
|
if (moving && CurrentTime - lastCurrentCheck >= Config::MotorCurrentCheckInterval)
|
||||||
if (moving && motorIsOvercurrent())
|
|
||||||
{
|
{
|
||||||
dln("[ CONTROL ] Overcurrent detected!");
|
lastCurrentCheck = CurrentTime;
|
||||||
this->moveStop();
|
|
||||||
|
|
||||||
return ControlUpdateResult::Overcurrent;
|
if (motorIsOvercurrent())
|
||||||
|
{
|
||||||
|
dln("[ CONTROL ] Overcurrent detected!");
|
||||||
|
this->moveStop();
|
||||||
|
|
||||||
|
return ControlUpdateResult::Overcurrent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read sensor
|
// Read sensor
|
||||||
@ -83,6 +87,8 @@ ControlUpdateResult ControlManager::update()
|
|||||||
this->currentMeasurement = measurement;
|
this->currentMeasurement = measurement;
|
||||||
this->lastValidMeasurement = CurrentTime;
|
this->lastValidMeasurement = CurrentTime;
|
||||||
|
|
||||||
|
// TODO: PWM the motor when we're getting close, if overshoot turns out to be an issue in testing
|
||||||
|
|
||||||
// Check if target has been reached
|
// Check if target has been reached
|
||||||
if (moving && this->targetReached())
|
if (moving && this->targetReached())
|
||||||
{
|
{
|
||||||
|
@ -64,6 +64,8 @@ class ControlManager
|
|||||||
uint16_t lastMeasurement = 0;
|
uint16_t lastMeasurement = 0;
|
||||||
uint32_t lastValidMeasurement = 0;
|
uint32_t lastValidMeasurement = 0;
|
||||||
|
|
||||||
|
uint32_t lastCurrentCheck = 0;
|
||||||
|
|
||||||
MoveDirection moveDirection;
|
MoveDirection moveDirection;
|
||||||
uint16_t moveTargetHeight;
|
uint16_t moveTargetHeight;
|
||||||
|
|
||||||
|
@ -2,9 +2,7 @@
|
|||||||
#define __debug
|
#define __debug
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
#include "include/config.h"
|
||||||
#define DebugLog
|
|
||||||
//#define VerboseLog
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef DebugLog
|
#ifdef DebugLog
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "./motor.h"
|
#include "./motor.h"
|
||||||
#include "include/config.h"
|
#include "include/config.h"
|
||||||
|
#include "./debug.h"
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
|
||||||
@ -13,11 +14,17 @@ void motorInit()
|
|||||||
|
|
||||||
pinMode(Config::MotorPinDirection, OUTPUT);
|
pinMode(Config::MotorPinDirection, OUTPUT);
|
||||||
pinMode(Config::MotorPinCurrentSensing, INPUT);
|
pinMode(Config::MotorPinCurrentSensing, INPUT);
|
||||||
|
|
||||||
|
// See motorIsOvercurrent
|
||||||
|
analogReference(INTERNAL);
|
||||||
|
delay(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void motorStart(MotorDirection direction)
|
void motorStart(MotorDirection direction)
|
||||||
{
|
{
|
||||||
|
dl("[ MOTOR ] Starting in direction: "); dln((uint8_t)direction);
|
||||||
|
|
||||||
digitalWrite(Config::MotorPinDirection, direction == MotorDirection::Up ? HIGH : LOW);
|
digitalWrite(Config::MotorPinDirection, direction == MotorDirection::Up ? HIGH : LOW);
|
||||||
digitalWrite(Config::MotorPinSleep, HIGH);
|
digitalWrite(Config::MotorPinSleep, HIGH);
|
||||||
digitalWrite(Config::MotorPinPWM, HIGH);
|
digitalWrite(Config::MotorPinPWM, HIGH);
|
||||||
@ -26,6 +33,8 @@ void motorStart(MotorDirection direction)
|
|||||||
|
|
||||||
void motorStop()
|
void motorStop()
|
||||||
{
|
{
|
||||||
|
dln("[ MOTOR ] Stopping");
|
||||||
|
|
||||||
digitalWrite(Config::MotorPinPWM, LOW);
|
digitalWrite(Config::MotorPinPWM, LOW);
|
||||||
digitalWrite(Config::MotorPinSleep, LOW);
|
digitalWrite(Config::MotorPinSleep, LOW);
|
||||||
digitalWrite(Config::MotorPinDirection, LOW);
|
digitalWrite(Config::MotorPinDirection, LOW);
|
||||||
@ -34,8 +43,15 @@ void motorStop()
|
|||||||
|
|
||||||
bool motorIsOvercurrent()
|
bool motorIsOvercurrent()
|
||||||
{
|
{
|
||||||
// TODO: implement motorIsOvercurrent
|
// The Polugu G2 module outputs 20 mV/A plus a 50 mV offset
|
||||||
return false;
|
// The analog reference has been set to internal, which is 1.1v for the ATMega328P,
|
||||||
|
// divided by 1024 units is 1.074mV per unit. This means we can measure up to 52.5A.
|
||||||
|
// I sure hope we never reach that value :-)
|
||||||
|
auto value = analogRead(Config::MotorPinCurrentSensing);
|
||||||
|
float voltage = (float)value * (1100.0 / 1024.0);
|
||||||
|
float current = (voltage - 50) / 20;
|
||||||
|
|
||||||
|
dl("[ MOTOR ] Measured current: value = "); dl(value); dl(", V = "); dl(voltage); dl(", A = "); dln(current);
|
||||||
|
|
||||||
|
return current >= Config::MotorCurrentLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,7 +61,9 @@ void HomeScreen::onButton(Button button)
|
|||||||
|
|
||||||
if (targetHeight > 0)
|
if (targetHeight > 0)
|
||||||
{
|
{
|
||||||
|
MoveReturnScreen = this->screenId();
|
||||||
Control.moveStart(targetHeight);
|
Control.moveStart(targetHeight);
|
||||||
|
|
||||||
this->screenManager->show<MoveScreen>();
|
this->screenManager->show<MoveScreen>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,41 @@
|
|||||||
#include "./manual.h"
|
#include "./manual.h"
|
||||||
|
#include "./home.h"
|
||||||
|
#include "./move.h"
|
||||||
|
#include "include/metrics.h"
|
||||||
|
#include "lib/settings.h"
|
||||||
|
#include "../state.h"
|
||||||
|
|
||||||
|
|
||||||
void ManualScreen::onShow()
|
|
||||||
|
void ManualScreen::initHeights()
|
||||||
{
|
{
|
||||||
// TODO: implement ManualScreen
|
this->height = Control.getCurrentHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ManualScreen::onButton(Button button)
|
bool ManualScreen::nextPage()
|
||||||
{
|
{
|
||||||
|
if (this->height == Control.getCurrentHeight())
|
||||||
|
{
|
||||||
|
this->screenManager->show<HomeScreen>();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
MoveReturnScreen = this->screenId();
|
||||||
|
Control.moveStart(this->height);
|
||||||
|
|
||||||
|
this->screenManager->show<MoveScreen>();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ManualScreen::onTick()
|
|
||||||
|
void ManualScreen::setHeight(uint16_t value)
|
||||||
{
|
{
|
||||||
|
if (value < Settings.Height.Minimum)
|
||||||
|
this->height = Settings.Height.Minimum;
|
||||||
|
else if (value > Settings.Height.Maximum)
|
||||||
|
this->height = Settings.Height.Maximum;
|
||||||
|
else
|
||||||
|
this->height = value;
|
||||||
}
|
}
|
@ -2,6 +2,7 @@
|
|||||||
#define __screen_manual
|
#define __screen_manual
|
||||||
|
|
||||||
#include "include/screenids.h"
|
#include "include/screenids.h"
|
||||||
|
#include "./baseheightentry.h"
|
||||||
#include "../screen.h"
|
#include "../screen.h"
|
||||||
#include "../Control.h"
|
#include "../Control.h"
|
||||||
|
|
||||||
@ -10,18 +11,24 @@
|
|||||||
* Manual screen
|
* Manual screen
|
||||||
* Allows manual entry of the preferred height.
|
* Allows manual entry of the preferred height.
|
||||||
*/
|
*/
|
||||||
class ManualScreen : public BaseScreen
|
class ManualScreen : public BaseHeightEntryScreen
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ManualScreen(ScreenManager* screenManager, Adafruit_GFX* display) : BaseScreen(screenManager, display) { }
|
ManualScreen(ScreenManager* screenManager, Adafruit_GFX* display) : BaseHeightEntryScreen(screenManager, display) { }
|
||||||
|
|
||||||
void onShow();
|
|
||||||
void onButton(Button button);
|
|
||||||
void onTick();
|
|
||||||
|
|
||||||
ScreenId screenId() { return ScreenId::Manual; };
|
ScreenId screenId() { return ScreenId::Manual; };
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void initHeights();
|
||||||
|
uint16_t getHeight() { return this->height; }
|
||||||
|
void setHeight(uint16_t value);
|
||||||
|
bool nextPage();
|
||||||
|
|
||||||
|
bool isValidHeight() { return true; }
|
||||||
|
const char* getTitle() { return "Manual"; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
uint16_t height;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -94,8 +94,7 @@ void MenuScreen::activateMenuItem(MenuItem item)
|
|||||||
switch (item)
|
switch (item)
|
||||||
{
|
{
|
||||||
case MenuItem::Manual:
|
case MenuItem::Manual:
|
||||||
// TODO: show manual screen
|
this->screenManager->show<ManualScreen>();
|
||||||
//this->screenManager->show<ManualScreen>();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MenuItem::Presets:
|
case MenuItem::Presets:
|
||||||
|
@ -1,14 +1,39 @@
|
|||||||
#include "./move-overcurrent.h"
|
#include "./move-overcurrent.h"
|
||||||
|
#include "./home.h"
|
||||||
|
#include "include/config.h"
|
||||||
|
#include "include/metrics.h"
|
||||||
|
#include "lib/control.h"
|
||||||
|
#include "lib/state.h"
|
||||||
|
|
||||||
|
|
||||||
void MoveOvercurrentScreen::onShow()
|
void MoveOvercurrentScreen::onShow()
|
||||||
{
|
{
|
||||||
// TODO: implement MoveOvercurrentScreen
|
auto y = Metrics::LargeTextLineHeight + Metrics::LargeTextLineYOffset;
|
||||||
|
|
||||||
|
this->display->fillScreen(Config::ColorErrorBackground);
|
||||||
|
|
||||||
|
|
||||||
|
this->display->setFont(Metrics::LargeFont);
|
||||||
|
this->display->setTextSize(Metrics::LargeFontTextSize);
|
||||||
|
|
||||||
|
this->display->setTextColor(Config::ColorErrorText);
|
||||||
|
this->printCentered("ERROR", y);
|
||||||
|
y += Metrics::LargeTextLineHeight;
|
||||||
|
|
||||||
|
this->display->setFont(Metrics::SmallFont);
|
||||||
|
this->display->setTextSize(Metrics::SmallFontTextSize);
|
||||||
|
|
||||||
|
this->printCentered("motor overcurrent", y);
|
||||||
|
y += Metrics::SmallTextLineHeight;
|
||||||
|
|
||||||
|
this->printCentered("press any button", y);
|
||||||
|
y += Metrics::SmallTextLineHeight + Metrics::LargeTextLineHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MoveOvercurrentScreen::onButton(Button button)
|
void MoveOvercurrentScreen::onButton(Button button)
|
||||||
{
|
{
|
||||||
|
this->screenManager->show<HomeScreen>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
#include "Control.h"
|
#include "state.h"
|
||||||
|
|
||||||
uint32_t CurrentTime;
|
uint32_t CurrentTime;
|
||||||
|
ScreenId MoveReturnScreen = (ScreenId)0;
|
@ -2,7 +2,9 @@
|
|||||||
#define __state
|
#define __state
|
||||||
|
|
||||||
#include "stdint.h"
|
#include "stdint.h"
|
||||||
|
#include "include/screenids.h"
|
||||||
|
|
||||||
extern uint32_t CurrentTime;
|
extern uint32_t CurrentTime;
|
||||||
|
extern ScreenId MoveReturnScreen;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
12
src/main.cpp
12
src/main.cpp
@ -15,6 +15,7 @@
|
|||||||
#include "./lib/state.h"
|
#include "./lib/state.h"
|
||||||
#include "./lib/screen/home.h"
|
#include "./lib/screen/home.h"
|
||||||
#include "./lib/screen/calibrate.h"
|
#include "./lib/screen/calibrate.h"
|
||||||
|
#include "./lib/screen/manual.h"
|
||||||
#include "./lib/screen/move-overcurrent.h"
|
#include "./lib/screen/move-overcurrent.h"
|
||||||
#include "./lib/screen/move-sensorerror.h"
|
#include "./lib/screen/move-sensorerror.h"
|
||||||
|
|
||||||
@ -175,7 +176,16 @@ void loop()
|
|||||||
switch (Control.update())
|
switch (Control.update())
|
||||||
{
|
{
|
||||||
case ControlUpdateResult::TargetReached:
|
case ControlUpdateResult::TargetReached:
|
||||||
screenManager.show<HomeScreen>();
|
switch (MoveReturnScreen)
|
||||||
|
{
|
||||||
|
case ScreenId::Manual:
|
||||||
|
screenManager.show<ManualScreen>();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
screenManager.show<HomeScreen>();
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ControlUpdateResult::SensorError:
|
case ControlUpdateResult::SensorError:
|
||||||
|
Loading…
Reference in New Issue
Block a user