Commit 76527c70 authored by Niels Post's avatar Niels Post
Browse files

- Implemented DisplayController

- Implemented SSD1306 boundary using OneBitDisplay library
parent 5349f359
Pipeline #33 failed with stage
......@@ -16,7 +16,9 @@ enum class CommandCategory : uint8_t {
* Commands in the "General" category
*/
enum GeneralCommand {
REBOOT = 0
REBOOT = 0,
DISCOVER = 1,
RESET_ID = 2
};
/**
......
......@@ -2,11 +2,15 @@
#include <core/communication/BaseCommandController.hpp>
#include <core/PMSVSettings.hpp>
#include <core/configuration/ConfigurationValue.hpp>
/**
* Handles commands in the category \refitem{CommandCategory::GENERAL}
*/
class CommandController_General : public BaseCommandController {
PMSVSettings &pmsvSettings;
ConfigurationValue<uint8_t> &configRobotId;
public:
/**
* Handle a General Command
......@@ -17,7 +21,7 @@ public:
uint8_t getCategoryID() override;
CommandController_General();
CommandController_General(PMSVSettings &settings, ConfigurationValue<uint8_t> &robotIdConfig);
std::pair<uint8_t, uint8_t> getParameterLimits(uint8_t command_id) override;
......
#pragma once
#include <cstdint>
struct PMSVSettings {
/// Robot Identifier. Should be set through the Configuration Commands
uint8_t robot_id;
......
......@@ -27,6 +27,8 @@ enum class SuccessCode : uint8_t {
UNKOWN_COMMAND_CATEGORY = 7,
/// The command requested is unknown
UNKNOWN_COMMAND = 8,
/// Do not send a response for this command
NO_RESPONSE = 9
};
......
#pragma once
#include <cstdint>
class BaseDisplayBoundary {
public:
/**
* SetCursor should set the write cursor to the specified position (in characters)
* @param x X position (position within a line)
* @param y Y Position (row number)
*/
virtual void setCursor(uint8_t x, uint8_t y) = 0;
void resetCursor() {
setCursor(0,0);
}
/**
* Write a given string to the display
*
* When called consecutively, strings should appear after each other
* @param str Null terminated string to print
*/
virtual void write(char * str) = 0;
/**
* End the current line and set the cursor to the start of the next line
*/
virtual void newline() = 0;
/**
* Clear the entire display and reset the cursor
*/
virtual void clear() = 0;
/**
* Can be used in case a display needs to be updated continuously
*/
virtual void update() = 0;
};
\ No newline at end of file
#pragma once
#include <core/PMSVSettings.hpp>
#include "BaseDisplayBoundary.hpp"
class DisplayController {
BaseDisplayBoundary &displayBoundary;
PMSVSettings &pmsvSettings;
uint8_t last_robot_id = 255;
public:
DisplayController(BaseDisplayBoundary &displayBoundary, PMSVSettings &pmsvSettings);
void update();
void display();
};
\ No newline at end of file
#pragma once
#include <Arduino.h>
#include <OneBitDisplay.h>
#include <core/PMSVSettings.hpp>
#include <core/display/BaseDisplayBoundary.hpp>
#include "SSD1306Configuration.hpp"
class DisplayBoundary_SSD1306: public BaseDisplayBoundary {
PMSVSettings &settings;
OBDISP obd;
uint8_t ucBackBuffer[512];
int oled_address;
SSD1306Configuration &configuration;
int font_size = FONT_6x8;
int font_width = 6;
int font_height = 8;
int cursor_x = 0;
int cursor_y = 0;
public:
DisplayBoundary_SSD1306(SSD1306Configuration &config, PMSVSettings &settings);
void update();
void clear() override;
void setCursor(uint8_t x, uint8_t y) override;
void write(char *str) override;
void newline() override;
};
#pragma once
#include <cstdint>
struct SSD1306Configuration {
uint8_t width;
uint8_t height;
uint8_t pin_scl;
uint8_t pin_sda;
uint8_t pin_gnd;
uint8_t pin_vcc;
int address;
};
\ No newline at end of file
......@@ -12,8 +12,9 @@
platform = atmelsam
board = due
framework = arduino
lib_deps =
tmrh20/RF24@^1.3.9
teemuatlut/TMCStepper @ ^0.7.1
waspinator/AccelStepper@^1.61.0
sebnil/DueFlashStorage @ ^1.0.0
lib_deps =
tmrh20/RF24@^1.3.9
teemuatlut/TMCStepper @ ^0.7.1
waspinator/AccelStepper@^1.61.0
sebnil/DueFlashStorage @ ^1.0.0
bitbank2/OneBitDisplay@^1.9.0
#include <communication/commandcontroller/CommandController_Action.hpp>
#include <core/communication/CommandRegistry.hpp>
#include <communication/CommandRegistry.hpp>
Response CommandController_Action::handle(const Command &cmd, ResponseCallback callback) {
SuccessCode code = SuccessCode::BAD_PARAMETERS;
......
#include <communication/commandcontroller/CommandController_Configuration.hpp>
#include <core/communication/CommandRegistry.hpp>
#include <communication/CommandRegistry.hpp>
Response
......
#include <communication/commandcontroller/CommandController_General.hpp>
#include <core/communication/CommandRegistry.hpp>
#include <communication/CommandRegistry.hpp>
Response CommandController_General::handle(const Command &cmd, ResponseCallback callback) {
switch(cmd.command_id) {
auto cmd_id = static_cast<GeneralCommand>(cmd.command_id);
switch(cmd_id) {
case REBOOT:
rstc_start_software_reset(RSTC);
break;
case DISCOVER:
if(pmsvSettings.robot_id == 0) {
return {cmd.message_id, SuccessCode::SUCCESS};
}
return {cmd.message_id, SuccessCode::NO_RESPONSE};
case RESET_ID:
pmsvSettings.robot_id = 0;
configRobotId.store();
rstc_start_software_reset(RSTC);
break;
}
return {0, SuccessCode::UNKNOWN_COMMAND};
return {cmd.message_id, SuccessCode::UNKNOWN_COMMAND};
}
uint8_t CommandController_General::getCategoryID() {
return 0;
}
CommandController_General::CommandController_General() {}
CommandController_General::CommandController_General(PMSVSettings &settings, ConfigurationValue<uint8_t> &robotIdConfig)
: pmsvSettings{settings}, configRobotId{robotIdConfig} {}
std::pair<uint8_t, uint8_t> CommandController_General::getParameterLimits(uint8_t command_id) {
switch (command_id) {
auto cmd_id = static_cast<GeneralCommand>(command_id);
switch (cmd_id) {
case REBOOT:
case DISCOVER:
case RESET_ID:
return {0, 0};
default:
return {255, 255};
}
}
#include <communication/commandcontroller/CommandController_Measurement.hpp>
#include <core/communication/CommandRegistry.hpp>
#include <communication/CommandRegistry.hpp>
Response CommandController_Measurement::handle(const Command &cmd, ResponseCallback callback) {
......
......@@ -25,8 +25,9 @@ void CommunicationController::handleQueuedCommand() {
communicationBoundary.sendMessage(msg);
}
);
communicationBoundary.sendMessage(initialResponse);
if(initialResponse.successCode != SuccessCode::NO_RESPONSE) {
communicationBoundary.sendMessage(initialResponse);
}
}
}
......
#include <core/display/DisplayController.hpp>
#include <cstdio>
DisplayController::DisplayController(BaseDisplayBoundary &displayBoundary, PMSVSettings &pmsvSettings)
: displayBoundary(displayBoundary), pmsvSettings(pmsvSettings) {}
void DisplayController::update() {
bool dirty = false;
if (last_robot_id != pmsvSettings.robot_id) {
dirty = true;
last_robot_id = pmsvSettings.robot_id;
}
if (dirty) {
display();
}
displayBoundary.update();
}
void DisplayController::display() {
displayBoundary.clear();
auto robot_id = (char *) "Robot ID:";
char numberstring[4];
sprintf(numberstring, "%d", static_cast<int>(pmsvSettings.robot_id));
displayBoundary.write(robot_id);
displayBoundary.write(numberstring);
displayBoundary.newline();
}
#include <display/DisplayBoundary_SSD1306.hpp>
#include <climits>
#define MY_OLED OLED_128x32
#define OLED_WIDTH 128
#define OLED_HEIGHT 32
DisplayBoundary_SSD1306::DisplayBoundary_SSD1306(SSD1306Configuration &config, PMSVSettings &settings)
: settings{settings}, configuration{config}{
pinMode(config.pin_vcc, OUTPUT);
pinMode(config.pin_gnd, OUTPUT);
digitalWrite(config.pin_gnd, LOW);
digitalWrite(config.pin_vcc, LOW);
delay(50);
digitalWrite(config.pin_vcc, HIGH);
delay(50);
oled_address = obdI2CInit(&obd, MY_OLED, 0x3C, 0, 0, 0, config.pin_sda, config.pin_scl, -1, 800000L); // use standard I2C bus at 400Khz
if (oled_address == OLED_NOT_FOUND)
{
Serial.println("Problem connecting to OLED");
} else {
obdFill(&obd, 0, 1);
obdSetBackBuffer(&obd, ucBackBuffer);
}
}
void DisplayBoundary_SSD1306::update() {
}
void DisplayBoundary_SSD1306::setCursor(uint8_t x, uint8_t y) {
cursor_x = font_width * x;
cursor_y = font_height * y;
}
void DisplayBoundary_SSD1306::write(char *str) {
int size = strlen(str);
obdWriteString(&obd, 0, cursor_x, cursor_y, str, font_size, 0, 1);
cursor_x += size * font_width;
}
void DisplayBoundary_SSD1306::newline() {
cursor_x = 0;
cursor_y += font_height;
}
void DisplayBoundary_SSD1306::clear() {
obdFill(&obd, 0, 1);
resetCursor();
}
......@@ -10,15 +10,15 @@
#include <communication/commandcontroller/CommandController_Measurement.hpp>
#include <communication/commandcontroller/CommandController_Action.hpp>
#include <core/communication/CommunicationController.hpp>
#include <core/display/DisplayController.hpp>
#include <core/util/ArraySize.hpp>
#include <display/DisplayBoundary_SSD1306.hpp>
#include <utility>
#define R_SENSE 0.11f
#include <utility>
//################################################################## Configuration ###################################
////################################################################## Configuration ###################################
PMSVSettings default_settings{
0xE4,
1.434684f,
......@@ -93,6 +93,17 @@ auto c_RIGHTmotor_forward_direction = registerConfig("RIGHTMOTOR_FORWARD_DIRECTI
rightMotorConfig.forward_direction);
SSD1306Configuration displayConfiguration {
128,
32,
53,
59,
49,
51
};
std::reference_wrapper<BaseConfigurationValue> configurationValues[]{
c_robot_id,
c_rot_per_mm,
......@@ -129,7 +140,7 @@ std::reference_wrapper<BaseConfigurationValue> configurationValues[]{
void setup() {
Serial.begin(9600);
// Set up Boundaries
// Set up Boundaries
CommandController_Configuration flashCommandController{configurationValues, lengthof(configurationValues)};
NRF24CommunicationBoundary nrfBoundary{nrf_config, default_settings};
......@@ -140,8 +151,12 @@ void setup() {
MovementController movementController{leftMotor, rightMotor, default_settings};
DisplayBoundary_SSD1306 displayBoundary{displayConfiguration, default_settings};
DisplayController displayController{displayBoundary, default_settings};
CommandController_General generalCommandHandler{};
CommandController_General generalCommandHandler{default_settings, c_robot_id};
CommandController_Action actionCommandHandler{movementController};
CommandController_Measurement measurementCommandHandler{};
......@@ -156,14 +171,16 @@ void setup() {
CommunicationController communicationController{nrfBoundary, commandControllers, lengthof(commandControllers)};
volatile bool _true = true;
while (_true) {
movementController.update();
communicationController.update();
displayController.update();
}
}
void loop() {
}
//
//
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment