Skip to content

Commit

Permalink
LCD
Browse files Browse the repository at this point in the history
  • Loading branch information
ryodine committed Jun 20, 2020
1 parent c76eb34 commit bdcb070
Show file tree
Hide file tree
Showing 13 changed files with 565 additions and 148 deletions.
51 changes: 30 additions & 21 deletions ACEINNAInclinometer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,8 @@ bool Inclinometer::ACEINNAInclinometer::begin()
CAN::CANBusBaudrate::kbps_250);

#ifdef PROVISION_CAN_ACEINNA_MODULE
// Set Output data rate to 10Hz (10=10Hz; 20=5Hz)
canInterface.write(
CAN::J1939Message(k_sourceAddress, k_aceinnaAddress, PGN_ODR, 10),
k_aceinnaAddress);

// Only use SSI2 (Inclination) data
canInterface.write(CAN::J1939Message(k_sourceAddress, k_aceinnaAddress,
PGN_PERIODIC_DATA_TYPES, 1),
k_aceinnaAddress);

// 2Hz digital low pass filter
canInterface.write(CAN::J1939Message(k_sourceAddress, k_aceinnaAddress,
PGN_LOW_PASS, 2, 2),
k_aceinnaAddress);

// Save config to EEPROM
canInterface.write(CAN::J1939Message(k_sourceAddress, k_aceinnaAddress,
PGN_SAVE_EEPROM, 0, k_aceinnaAddress,
1),
k_aceinnaAddress);
// define PROVISION_CAN_ACEINNA_MODULE to make the aceinna module be set up once
ProvisionACEINNAInclinometer();
#endif

canInterface.flushBuffer();
Expand Down Expand Up @@ -69,7 +51,10 @@ bool Inclinometer::ACEINNAInclinometer::hasData()
roll_adjusted > k_anglePlausibilityRange ||
roll_adjusted < -k_anglePlausibilityRange) {
Fault::Handler::instance()->setFaultCode(
Fault::INCLINOMETER_IMPLAUSIBLE_READING);
Fault::INCL_IMPLAUS_READ);
} else {
Fault::Handler::instance()->unlatchFaultCode(
Fault::INCL_IMPLAUS_READ);
}

cachedAngles = Eigen::Vector2d(pitch_adjusted * PI / 180.0,
Expand All @@ -86,4 +71,28 @@ Eigen::Vector2d Inclinometer::ACEINNAInclinometer::getData()
roll.addPoint(cachedAngles[0]);
pitch.addPoint(cachedAngles[1]);
return Eigen::Vector2d(roll.getAverage(), pitch.getAverage());
}

void Inclinometer::ACEINNAInclinometer::ProvisionACEINNAInclinometer()
{
// Set Output data rate to 10Hz (10=10Hz; 20=5Hz)
canInterface.write(
CAN::J1939Message(k_sourceAddress, k_aceinnaAddress, PGN_ODR, 10),
k_aceinnaAddress);

// Only use SSI2 (Inclination) data
canInterface.write(CAN::J1939Message(k_sourceAddress, k_aceinnaAddress,
PGN_PERIODIC_DATA_TYPES, 1),
k_aceinnaAddress);

// 2Hz digital low pass filter
canInterface.write(CAN::J1939Message(k_sourceAddress, k_aceinnaAddress,
PGN_LOW_PASS, 2, 2),
k_aceinnaAddress);

// Save config to EEPROM
canInterface.write(CAN::J1939Message(k_sourceAddress, k_aceinnaAddress,
PGN_SAVE_EEPROM, 0, k_aceinnaAddress,
1),
k_aceinnaAddress);
}
32 changes: 17 additions & 15 deletions ACEINNAInclinometer.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,28 +51,30 @@ class ACEINNAInclinometer : public InclinometerDataSource {
//! invalid (degrees)
static constexpr double k_anglePlausibilityRange = 5;

/**
* @brief PGNs used by this module
*/
enum PGN {
// Data Messages / Get Messages
PGN_ENABLED_PERIODIC_DATA_TYPES = 61366,
PGN_SSI2DATA = 61481,

// Command Messages
PGN_SAVE_EEPROM = 65361,
PGN_ODR = 65365,
PGN_PERIODIC_DATA_TYPES,
PGN_LOW_PASS,
PGN_ORIENTATION
};
/**
* @brief PGNs used by this module
*/
enum PGN {
// Data Messages / Get Messages
PGN_ENABLED_PERIODIC_DATA_TYPES = 61366,
PGN_SSI2DATA = 61481,

// Command Messages
PGN_SAVE_EEPROM = 65361,
PGN_ODR = 65365,
PGN_PERIODIC_DATA_TYPES,
PGN_LOW_PASS,
PGN_ORIENTATION
};

//! See the InclinometerDataSource interface

bool begin() override;
bool hasData() override;
Eigen::Vector2d getData() override;

void ProvisionACEINNAInclinometer();

private:
CAN::J1939Interface canInterface;

Expand Down
2 changes: 1 addition & 1 deletion ADXL355Inclinometer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Eigen::Vector2d Inclinometer::ADXL355Inclinometer::getData()
pow(measure.z / 16.0, 2));
if (scale > 1.0 + gBand || scale < 1.0 - gBand) {
Fault::Handler::instance()->setFaultCode(
Fault::INCLINOMETER_IMPLAUSIBLE_READING);
Fault::INCL_IMPLAUS_READ);
}

// Apply EWMA filtering
Expand Down
109 changes: 109 additions & 0 deletions DisplayControl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/**
* @file DisplayControl.cpp
* @author Ryan Johnson (ryan@johnsonweb.us)
* @brief Display view models and controllers
* @version 0.1
* @date 2020-06-16
*
* @copyright Copyright (c) 2020
*
*/

#include "DisplayControl.h"

#include <Arduino.h>
#include <cstdio>
#include <cstring>

#define OK_OR_HALT_OR_OFF(corner, enable) \
((enable)) ? (((corner)) ? "HALT" : "OK") : "OFF"

using namespace Display;

void AbstractDisplayView::BlankDisplayableText(DisplayableText *text)
{
memset(text, " ", sizeof(DisplayableText));
}

DisplayableText DisplayViewFault::Render(const SystemDisplayState &dispState)
{
DisplayableText text;
BlankDisplayableText(&text);
strncpy(text.line_struct.line1, "!! Fault Detected !!", 21);
strncpy(text.line_struct.line2, Fault::ecodeName[dispState.faultType], 21);
strncpy(text.line_struct.line3, Fault::ecodeHelpText[dispState.faultType],
21);
if (dispState.faultType > Fault::FATAL_END_SENTINEL) {
strncpy(text.line_struct.line4, " (please try again) ", 21);
}
else {
strncpy(text.line_struct.line4, " (re-boot required) ", 21);
}
return text;
}

DisplayableText DisplayViewNormal::Render(const SystemDisplayState &dispState)
{
DisplayableText text;
BlankDisplayableText(&text);
char pitch[8];
char roll[8];
dtostrf(dispState.pitch, 7, 2, pitch);
dtostrf(dispState.roll, 7, 2, roll);
snprintf(text.line_struct.line1, 21, "%-10s P:%7s",
Motion::k_motionStateNames[dispState.motionState], pitch);
if (dispState.motionState == Motion::MotionStateMachine::STATE_MOVING) {
if (dispState.dirn == Motion::MovementDirection::RAISE) {
snprintf(text.line_struct.line2, 21, "RAISING R:%7s", roll);
} else if (dispState.dirn == Motion::MovementDirection::LOWER) {
snprintf(text.line_struct.line2, 21, "LOWERING R:%7s", roll);
} else {
snprintf(text.line_struct.line2, 21, "OFF R:%7s", roll);
}
} else if (dispState.motionState == Motion::MotionStateMachine::STATE_FAULTED) {
snprintf(text.line_struct.line2, 21, "CAN RESUME R:%7s", roll);
} else {
snprintf(text.line_struct.line2, 21, "SYSTEM OK R:%7s", roll);
}
strncpy(text.line_struct.line3, "-1-- -2-- -3-- -4-- ", 21);
snprintf(text.line_struct.line4, 21, "%-4s %-4s %-4s %-4s ",
OK_OR_HALT_OR_OFF(dispState.ram1, dispState.enable),
OK_OR_HALT_OR_OFF(dispState.ram2, dispState.enable),
OK_OR_HALT_OR_OFF(dispState.ram3, dispState.enable),
OK_OR_HALT_OR_OFF(dispState.ram4, dispState.enable));

return text;
}

bool Controller::begin()
{
lcd.begin(20, 4);
lcd.setBacklight(HIGH);
lcd.setCursor(0, 0);
}

void Controller::update(SystemDisplayState &state)
{
DisplayableText t;
if (state.faultType != Fault::ALL_OK) {
DisplayViewFault faultDisp;
t = faultDisp.Render(state);
}
else {
DisplayViewNormal normalDisp;
t = normalDisp.Render(state);
}
writeRaw(t);
}

void Controller::writeRaw(DisplayableText &t)
{
lcd.setCursor(0, 0);
lcd.print(t.line_struct.line1);
lcd.setCursor(0, 1);
lcd.print(t.line_struct.line2);
lcd.setCursor(0, 2);
lcd.print(t.line_struct.line3);
lcd.setCursor(0, 3);
lcd.print(t.line_struct.line4);
}
127 changes: 127 additions & 0 deletions DisplayControl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/**
* @file DisplayControl.h
* @author Ryan Johnson (ryan@johnsonweb.us)
* @brief Display view models and controllers
* @version 0.1
* @date 2020-06-13
*
* @copyright Copyright (c) 2020
*
*/

#ifndef DISPLAY_CONTROL_H
#define DISPLAY_CONTROL_H

#include "FaultHandling.h"
#include "MotionStateMachine.h"

#include <Adafruit_LiquidCrystal.h>

namespace Display {

/**
* 20x4 display template
*
* +--------------------+
* | |
* | |
* | |
* | |
* +--------------------+
*/

/**
* Normal Operation
*
* +--------------------+
* |LOWERING P:-360.00|
* |SYS OK R:-360.00|
* | 1 2 3 4 |
* | OK OK HALT HALT|
* +--------------------+
*
* +--------------------+
* |STOPPED P:-360.00|
* |SYS OK R:-360.00|
* | 1 2 3 4 |
* | HALT HALT HALT HALT|
* +--------------------+
*
* +--------------------+
* |RAISING P:-360.00|
* |SYS OK R:-360.00|
* | 1 2 3 4 |
* | OK OK OK OK |
* +--------------------+
*/

/**
* FAULT
*
* +--------------------+
* | /!\ Fault Detected | <--- Fault header
* |INCLINOMETER_INIT | <--- error code
* | (re-boot required) | <--- Recoverable or non-recoverable fault
* |Incl. 1 start failed| <--- Short human-readable
* +--------------------+
*
* +--------------------+
* | /!\ Fault Detected | <--- Fault header
* |INCLINOMETER_UNREADY| <--- error code
* | (please try again) | <--- Recoverable or non-recoverable fault
* |Sensor timed out | <--- Short human-readable
* +--------------------+
*/

typedef struct {
Motion::MotionStateMachine::STATE motionState;
double pitch;
double roll;
bool ram1;
bool ram2;
bool ram3;
bool ram4;
bool enable;
Motion::MovementDirection dirn;
Fault::Type faultType;
} SystemDisplayState;

typedef union {
struct __attribute__((packed)) {
char line1[21];
char line2[21];
char line3[21];
char line4[21];
} line_struct;
char array[4][21];
} DisplayableText;

class Controller {
public:
Controller() : lcd{0} {};
bool begin();
void writeRaw(DisplayableText& t);
void update(SystemDisplayState &state);
private:
Adafruit_LiquidCrystal lcd;
};

class AbstractDisplayView {
public:
virtual DisplayableText Render(const SystemDisplayState &dispState) = 0;
void BlankDisplayableText(DisplayableText *text);
};

class DisplayViewFault : public AbstractDisplayView {
public:
DisplayableText Render(const SystemDisplayState &dispState) override;
};

class DisplayViewNormal : public AbstractDisplayView {
public:
DisplayableText Render(const SystemDisplayState &dispState) override;
};

} // namespace Display

#endif // DISPLAY_CONTROL_H
Loading

0 comments on commit bdcb070

Please sign in to comment.