mirror of
https://github.com/BotChain-Robots/firmware.git
synced 2026-07-08 09:37:21 +02:00
Display control code
This commit is contained in:
@@ -9,7 +9,13 @@
|
|||||||
|
|
||||||
#include "flatbuffers_generated/RobotModule_generated.h"
|
#include "flatbuffers_generated/RobotModule_generated.h"
|
||||||
|
|
||||||
inline std::unordered_map<int, int> MODULE_TO_NUM_CHANNELS_MAP {{ModuleType_SPLITTER, 4}, {ModuleType_SERVO_1, 2}, {ModuleType_DC_MOTOR, 1}, {ModuleType_SERVO_2, 2}};
|
inline std::unordered_map<int, int> MODULE_TO_NUM_CHANNELS_MAP {
|
||||||
|
{ModuleType_SPLITTER, 4},
|
||||||
|
{ModuleType_SERVO_1, 2},
|
||||||
|
{ModuleType_DC_MOTOR, 1},
|
||||||
|
{ModuleType_SERVO_2, 2},
|
||||||
|
{ModuleType_DISPLAY, 1}
|
||||||
|
};
|
||||||
|
|
||||||
#define PC_ADDR 0
|
#define PC_ADDR 0
|
||||||
|
|
||||||
@@ -22,6 +28,9 @@ inline std::unordered_map<int, int> MODULE_TO_NUM_CHANNELS_MAP {{ModuleType_SPLI
|
|||||||
#define DC_ENCODER_A 15
|
#define DC_ENCODER_A 15
|
||||||
#define DC_ENCODER_B 16
|
#define DC_ENCODER_B 16
|
||||||
|
|
||||||
|
#define OLED_SDA 17
|
||||||
|
#define OLED_SCL 18
|
||||||
|
|
||||||
inline std::unordered_map<uint8_t, uint8_t> CHANNEL_TO_0_DEG_MAP{{0, 9} };
|
inline std::unordered_map<uint8_t, uint8_t> CHANNEL_TO_0_DEG_MAP{{0, 9} };
|
||||||
inline std::unordered_map<uint8_t, uint8_t> CHANNEL_TO_90_DEG_MAP{{0, 7} };
|
inline std::unordered_map<uint8_t, uint8_t> CHANNEL_TO_90_DEG_MAP{{0, 7} };
|
||||||
inline std::unordered_map<uint8_t, uint8_t> CHANNEL_TO_180_DEG_MAP{{0, 8} };
|
inline std::unordered_map<uint8_t, uint8_t> CHANNEL_TO_180_DEG_MAP{{0, 8} };
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
idf_component_register(SRCS "MPIMessageBuilder.cpp" "AngleControlMessageBuilder.cpp" "TopologyMessageBuilder.cpp" "SensorMessageBuilder.cpp"
|
idf_component_register(SRCS "MPIMessageBuilder.cpp" "AngleControlMessageBuilder.cpp" "TopologyMessageBuilder.cpp" "SensorMessageBuilder.cpp" "TextControlMessageBuilder.cpp"
|
||||||
INCLUDE_DIRS "include")
|
INCLUDE_DIRS "include")
|
||||||
|
|||||||
@@ -26,6 +26,11 @@ SerializedMessage SensorMessageBuilder::build_sensor_message(std::vector<sensor_
|
|||||||
values_vec.push_back(Messaging::CreateCurrentAngle(builder_, a.angle).Union());
|
values_vec.push_back(Messaging::CreateCurrentAngle(builder_, a.angle).Union());
|
||||||
sensor_values_vec.push_back(Messaging::SensorValue_CurrentAngle);
|
sensor_values_vec.push_back(Messaging::SensorValue_CurrentAngle);
|
||||||
},
|
},
|
||||||
|
[&](target_text t) {
|
||||||
|
auto text_offset = builder_.CreateString(t.text);
|
||||||
|
values_vec.push_back(Messaging::CreateCurrentText(builder_, text_offset).Union());
|
||||||
|
sensor_values_vec.push_back(Messaging::SensorValue_CurrentText);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
v);
|
v);
|
||||||
}
|
}
|
||||||
|
|||||||
11
components/flatbuffers/TextControlMessageBuilder.cpp
Normal file
11
components/flatbuffers/TextControlMessageBuilder.cpp
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
//
|
||||||
|
// Created by Johnathon Slightham on 2025-06-30.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "TextControlMessageBuilder.h"
|
||||||
|
|
||||||
|
namespace Flatbuffers {
|
||||||
|
const Messaging::TextControlMessage* TextControlMessageBuilder::parse_text_control_message(const uint8_t* buffer) {
|
||||||
|
return flatbuffers::GetRoot<Messaging::TextControlMessage>(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,11 +15,15 @@ struct current_angle {
|
|||||||
int16_t angle;
|
int16_t angle;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::variant<target_angle, current_angle> sensor_value;
|
struct target_text {
|
||||||
|
std::string text;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::variant<target_angle, current_angle, target_text> sensor_value;
|
||||||
|
|
||||||
class SensorMessageBuilder {
|
class SensorMessageBuilder {
|
||||||
public:
|
public:
|
||||||
SensorMessageBuilder() : builder_(128) {
|
SensorMessageBuilder() : builder_(256) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SerializedMessage build_sensor_message(std::vector<sensor_value> &values);
|
SerializedMessage build_sensor_message(std::vector<sensor_value> &values);
|
||||||
|
|||||||
18
components/flatbuffers/include/TextControlMessageBuilder.h
Normal file
18
components/flatbuffers/include/TextControlMessageBuilder.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// Created by Johnathon Slightham on 2025-06-30.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef TEXTCONTROLMESSAGEBUILDER_H_
|
||||||
|
#define TEXTCONTROLMESSAGEBUILDER_H_
|
||||||
|
|
||||||
|
#include "flatbuffers_generated/TextControlMessage_generated.h"
|
||||||
|
#include "flatbuffers/flatbuffers.h"
|
||||||
|
|
||||||
|
namespace Flatbuffers {
|
||||||
|
class TextControlMessageBuilder {
|
||||||
|
public:
|
||||||
|
static const Messaging::TextControlMessage* parse_text_control_message(const uint8_t* buffer);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
#include "flatbuffers/flatbuffers.h"
|
#include "flatbuffers/flatbuffers.h"
|
||||||
|
|
||||||
// Ensure the included flatbuffers.h is the same version as when this file was
|
// Ensure the included flatbuffers.h is the same version as when this file was
|
||||||
// // generated, otherwise it may not be compatible.
|
// generated, otherwise it may not be compatible.
|
||||||
// static_assert(FLATBUFFERS_VERSION_MAJOR == 25 &&
|
// static_assert(FLATBUFFERS_VERSION_MAJOR == 25 &&
|
||||||
// FLATBUFFERS_VERSION_MINOR == 2 &&
|
// FLATBUFFERS_VERSION_MINOR == 2 &&
|
||||||
// FLATBUFFERS_VERSION_REVISION == 10,
|
// FLATBUFFERS_VERSION_REVISION == 10,
|
||||||
@@ -25,35 +25,71 @@ enum ModuleType : int8_t {
|
|||||||
ModuleType_DC_MOTOR = 2,
|
ModuleType_DC_MOTOR = 2,
|
||||||
ModuleType_BATTERY = 3,
|
ModuleType_BATTERY = 3,
|
||||||
ModuleType_SERVO_2 = 4,
|
ModuleType_SERVO_2 = 4,
|
||||||
|
ModuleType_DISPLAY = 5,
|
||||||
|
ModuleType_GRIPPER = 6,
|
||||||
|
ModuleType_SPEAKER = 7,
|
||||||
|
ModuleType_IMU = 8,
|
||||||
|
ModuleType_DISTANCE_SENSOR = 9,
|
||||||
|
ModuleType_SPLITTER_2 = 10,
|
||||||
|
ModuleType_SPLITTER_3 = 11,
|
||||||
|
ModuleType_SPLITTER_4 = 12,
|
||||||
|
ModuleType_SPLITTER_5 = 13,
|
||||||
|
ModuleType_SPLITTER_6 = 14,
|
||||||
|
ModuleType_SPLITTER_7 = 15,
|
||||||
|
ModuleType_SPLITTER_8 = 16,
|
||||||
ModuleType_MIN = ModuleType_SPLITTER,
|
ModuleType_MIN = ModuleType_SPLITTER,
|
||||||
ModuleType_MAX = ModuleType_SERVO_2
|
ModuleType_MAX = ModuleType_SPLITTER_8
|
||||||
};
|
};
|
||||||
|
|
||||||
inline const ModuleType (&EnumValuesModuleType())[5] {
|
inline const ModuleType (&EnumValuesModuleType())[17] {
|
||||||
static const ModuleType values[] = {
|
static const ModuleType values[] = {
|
||||||
ModuleType_SPLITTER,
|
ModuleType_SPLITTER,
|
||||||
ModuleType_SERVO_1,
|
ModuleType_SERVO_1,
|
||||||
ModuleType_DC_MOTOR,
|
ModuleType_DC_MOTOR,
|
||||||
ModuleType_BATTERY,
|
ModuleType_BATTERY,
|
||||||
ModuleType_SERVO_2
|
ModuleType_SERVO_2,
|
||||||
|
ModuleType_DISPLAY,
|
||||||
|
ModuleType_GRIPPER,
|
||||||
|
ModuleType_SPEAKER,
|
||||||
|
ModuleType_IMU,
|
||||||
|
ModuleType_DISTANCE_SENSOR,
|
||||||
|
ModuleType_SPLITTER_2,
|
||||||
|
ModuleType_SPLITTER_3,
|
||||||
|
ModuleType_SPLITTER_4,
|
||||||
|
ModuleType_SPLITTER_5,
|
||||||
|
ModuleType_SPLITTER_6,
|
||||||
|
ModuleType_SPLITTER_7,
|
||||||
|
ModuleType_SPLITTER_8
|
||||||
};
|
};
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const char * const *EnumNamesModuleType() {
|
inline const char * const *EnumNamesModuleType() {
|
||||||
static const char * const names[6] = {
|
static const char * const names[18] = {
|
||||||
"SPLITTER",
|
"SPLITTER",
|
||||||
"SERVO_1",
|
"SERVO_1",
|
||||||
"DC_MOTOR",
|
"DC_MOTOR",
|
||||||
"BATTERY",
|
"BATTERY",
|
||||||
"SERVO_2",
|
"SERVO_2",
|
||||||
|
"DISPLAY",
|
||||||
|
"GRIPPER",
|
||||||
|
"SPEAKER",
|
||||||
|
"IMU",
|
||||||
|
"DISTANCE_SENSOR",
|
||||||
|
"SPLITTER_2",
|
||||||
|
"SPLITTER_3",
|
||||||
|
"SPLITTER_4",
|
||||||
|
"SPLITTER_5",
|
||||||
|
"SPLITTER_6",
|
||||||
|
"SPLITTER_7",
|
||||||
|
"SPLITTER_8",
|
||||||
nullptr
|
nullptr
|
||||||
};
|
};
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const char *EnumNameModuleType(ModuleType e) {
|
inline const char *EnumNameModuleType(ModuleType e) {
|
||||||
if (::flatbuffers::IsOutRange(e, ModuleType_SPLITTER, ModuleType_SERVO_2)) return "";
|
if (::flatbuffers::IsOutRange(e, ModuleType_SPLITTER, ModuleType_SPLITTER_8)) return "";
|
||||||
const size_t index = static_cast<size_t>(e);
|
const size_t index = static_cast<size_t>(e);
|
||||||
return EnumNamesModuleType()[index];
|
return EnumNamesModuleType()[index];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// automatically generated by the FlatBuffers compiler, do not modify
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
|
||||||
#ifndef FLATBUFFERS_GENERATED_SENSORMESSAGE_MESSAGING_H_
|
#ifndef FLATBUFFERS_GENERATED_SENSORMESSAGE_MESSAGING_H_
|
||||||
#define FLATBUFFERS_GENERATED_SENSORMESSAGE_MESSAGING_H_
|
#define FLATBUFFERS_GENERATED_SENSORMESSAGE_MESSAGING_H_
|
||||||
|
|
||||||
@@ -17,6 +18,9 @@ namespace Messaging {
|
|||||||
struct TargetAngle;
|
struct TargetAngle;
|
||||||
struct TargetAngleBuilder;
|
struct TargetAngleBuilder;
|
||||||
|
|
||||||
|
struct CurrentText;
|
||||||
|
struct CurrentTextBuilder;
|
||||||
|
|
||||||
struct CurrentAngle;
|
struct CurrentAngle;
|
||||||
struct CurrentAngleBuilder;
|
struct CurrentAngleBuilder;
|
||||||
|
|
||||||
@@ -27,57 +31,69 @@ enum SensorValue : uint8_t {
|
|||||||
SensorValue_NONE = 0,
|
SensorValue_NONE = 0,
|
||||||
SensorValue_TargetAngle = 1,
|
SensorValue_TargetAngle = 1,
|
||||||
SensorValue_CurrentAngle = 2,
|
SensorValue_CurrentAngle = 2,
|
||||||
|
SensorValue_CurrentText = 3,
|
||||||
SensorValue_MIN = SensorValue_NONE,
|
SensorValue_MIN = SensorValue_NONE,
|
||||||
SensorValue_MAX = SensorValue_CurrentAngle
|
SensorValue_MAX = SensorValue_CurrentText
|
||||||
};
|
};
|
||||||
|
|
||||||
inline const SensorValue (&EnumValuesSensorValue())[3] {
|
inline const SensorValue (&EnumValuesSensorValue())[4] {
|
||||||
static const SensorValue values[] = {
|
static const SensorValue values[] = {
|
||||||
SensorValue_NONE, SensorValue_TargetAngle, SensorValue_CurrentAngle};
|
SensorValue_NONE,
|
||||||
|
SensorValue_TargetAngle,
|
||||||
|
SensorValue_CurrentAngle,
|
||||||
|
SensorValue_CurrentText
|
||||||
|
};
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const char *const *EnumNamesSensorValue() {
|
inline const char * const *EnumNamesSensorValue() {
|
||||||
static const char *const names[4] = {"NONE", "TargetAngle", "CurrentAngle",
|
static const char * const names[5] = {
|
||||||
nullptr};
|
"NONE",
|
||||||
|
"TargetAngle",
|
||||||
|
"CurrentAngle",
|
||||||
|
"CurrentText",
|
||||||
|
nullptr
|
||||||
|
};
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const char *EnumNameSensorValue(SensorValue e) {
|
inline const char *EnumNameSensorValue(SensorValue e) {
|
||||||
if (::flatbuffers::IsOutRange(e, SensorValue_NONE, SensorValue_CurrentAngle))
|
if (::flatbuffers::IsOutRange(e, SensorValue_NONE, SensorValue_CurrentText)) return "";
|
||||||
return "";
|
|
||||||
const size_t index = static_cast<size_t>(e);
|
const size_t index = static_cast<size_t>(e);
|
||||||
return EnumNamesSensorValue()[index];
|
return EnumNamesSensorValue()[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> struct SensorValueTraits {
|
template<typename T> struct SensorValueTraits {
|
||||||
static const SensorValue enum_value = SensorValue_NONE;
|
static const SensorValue enum_value = SensorValue_NONE;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct SensorValueTraits<Messaging::TargetAngle> {
|
template<> struct SensorValueTraits<Messaging::TargetAngle> {
|
||||||
static const SensorValue enum_value = SensorValue_TargetAngle;
|
static const SensorValue enum_value = SensorValue_TargetAngle;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct SensorValueTraits<Messaging::CurrentAngle> {
|
template<> struct SensorValueTraits<Messaging::CurrentAngle> {
|
||||||
static const SensorValue enum_value = SensorValue_CurrentAngle;
|
static const SensorValue enum_value = SensorValue_CurrentAngle;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool VerifySensorValue(::flatbuffers::Verifier &verifier, const void *obj,
|
template<> struct SensorValueTraits<Messaging::CurrentText> {
|
||||||
SensorValue type);
|
static const SensorValue enum_value = SensorValue_CurrentText;
|
||||||
bool VerifySensorValueVector(
|
};
|
||||||
::flatbuffers::Verifier &verifier,
|
|
||||||
const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values,
|
bool VerifySensorValue(::flatbuffers::Verifier &verifier, const void *obj, SensorValue type);
|
||||||
const ::flatbuffers::Vector<uint8_t> *types);
|
bool VerifySensorValueVector(::flatbuffers::Verifier &verifier, const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values, const ::flatbuffers::Vector<uint8_t> *types);
|
||||||
|
|
||||||
struct TargetAngle FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
|
struct TargetAngle FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
|
||||||
typedef TargetAngleBuilder Builder;
|
typedef TargetAngleBuilder Builder;
|
||||||
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
||||||
VT_VALUE = 4
|
VT_VALUE = 4
|
||||||
};
|
};
|
||||||
int16_t value() const { return GetField<int16_t>(VT_VALUE, 0); }
|
int16_t value() const {
|
||||||
|
return GetField<int16_t>(VT_VALUE, 0);
|
||||||
|
}
|
||||||
bool Verify(::flatbuffers::Verifier &verifier) const {
|
bool Verify(::flatbuffers::Verifier &verifier) const {
|
||||||
return VerifyTableStart(verifier) &&
|
return VerifyTableStart(verifier) &&
|
||||||
VerifyField<int16_t>(verifier, VT_VALUE, 2) && verifier.EndTable();
|
VerifyField<int16_t>(verifier, VT_VALUE, 2) &&
|
||||||
|
verifier.EndTable();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -99,22 +115,77 @@ struct TargetAngleBuilder {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline ::flatbuffers::Offset<TargetAngle>
|
inline ::flatbuffers::Offset<TargetAngle> CreateTargetAngle(
|
||||||
CreateTargetAngle(::flatbuffers::FlatBufferBuilder &_fbb, int16_t value = 0) {
|
::flatbuffers::FlatBufferBuilder &_fbb,
|
||||||
|
int16_t value = 0) {
|
||||||
TargetAngleBuilder builder_(_fbb);
|
TargetAngleBuilder builder_(_fbb);
|
||||||
builder_.add_value(value);
|
builder_.add_value(value);
|
||||||
return builder_.Finish();
|
return builder_.Finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CurrentText FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
|
||||||
|
typedef CurrentTextBuilder Builder;
|
||||||
|
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
||||||
|
VT_VALUE = 4
|
||||||
|
};
|
||||||
|
const ::flatbuffers::String *value() const {
|
||||||
|
return GetPointer<const ::flatbuffers::String *>(VT_VALUE);
|
||||||
|
}
|
||||||
|
bool Verify(::flatbuffers::Verifier &verifier) const {
|
||||||
|
return VerifyTableStart(verifier) &&
|
||||||
|
VerifyOffset(verifier, VT_VALUE) &&
|
||||||
|
verifier.VerifyString(value()) &&
|
||||||
|
verifier.EndTable();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CurrentTextBuilder {
|
||||||
|
typedef CurrentText Table;
|
||||||
|
::flatbuffers::FlatBufferBuilder &fbb_;
|
||||||
|
::flatbuffers::uoffset_t start_;
|
||||||
|
void add_value(::flatbuffers::Offset<::flatbuffers::String> value) {
|
||||||
|
fbb_.AddOffset(CurrentText::VT_VALUE, value);
|
||||||
|
}
|
||||||
|
explicit CurrentTextBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
|
||||||
|
: fbb_(_fbb) {
|
||||||
|
start_ = fbb_.StartTable();
|
||||||
|
}
|
||||||
|
::flatbuffers::Offset<CurrentText> Finish() {
|
||||||
|
const auto end = fbb_.EndTable(start_);
|
||||||
|
auto o = ::flatbuffers::Offset<CurrentText>(end);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline ::flatbuffers::Offset<CurrentText> CreateCurrentText(
|
||||||
|
::flatbuffers::FlatBufferBuilder &_fbb,
|
||||||
|
::flatbuffers::Offset<::flatbuffers::String> value = 0) {
|
||||||
|
CurrentTextBuilder builder_(_fbb);
|
||||||
|
builder_.add_value(value);
|
||||||
|
return builder_.Finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ::flatbuffers::Offset<CurrentText> CreateCurrentTextDirect(
|
||||||
|
::flatbuffers::FlatBufferBuilder &_fbb,
|
||||||
|
const char *value = nullptr) {
|
||||||
|
auto value__ = value ? _fbb.CreateString(value) : 0;
|
||||||
|
return Messaging::CreateCurrentText(
|
||||||
|
_fbb,
|
||||||
|
value__);
|
||||||
|
}
|
||||||
|
|
||||||
struct CurrentAngle FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
|
struct CurrentAngle FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
|
||||||
typedef CurrentAngleBuilder Builder;
|
typedef CurrentAngleBuilder Builder;
|
||||||
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
||||||
VT_VALUE = 4
|
VT_VALUE = 4
|
||||||
};
|
};
|
||||||
int16_t value() const { return GetField<int16_t>(VT_VALUE, 0); }
|
int16_t value() const {
|
||||||
|
return GetField<int16_t>(VT_VALUE, 0);
|
||||||
|
}
|
||||||
bool Verify(::flatbuffers::Verifier &verifier) const {
|
bool Verify(::flatbuffers::Verifier &verifier) const {
|
||||||
return VerifyTableStart(verifier) &&
|
return VerifyTableStart(verifier) &&
|
||||||
VerifyField<int16_t>(verifier, VT_VALUE, 2) && verifier.EndTable();
|
VerifyField<int16_t>(verifier, VT_VALUE, 2) &&
|
||||||
|
verifier.EndTable();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -136,8 +207,9 @@ struct CurrentAngleBuilder {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline ::flatbuffers::Offset<CurrentAngle>
|
inline ::flatbuffers::Offset<CurrentAngle> CreateCurrentAngle(
|
||||||
CreateCurrentAngle(::flatbuffers::FlatBufferBuilder &_fbb, int16_t value = 0) {
|
::flatbuffers::FlatBufferBuilder &_fbb,
|
||||||
|
int16_t value = 0) {
|
||||||
CurrentAngleBuilder builder_(_fbb);
|
CurrentAngleBuilder builder_(_fbb);
|
||||||
builder_.add_value(value);
|
builder_.add_value(value);
|
||||||
return builder_.Finish();
|
return builder_.Finish();
|
||||||
@@ -153,8 +225,7 @@ struct SensorMessage FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
|
|||||||
return GetPointer<const ::flatbuffers::Vector<uint8_t> *>(VT_VALUES_TYPE);
|
return GetPointer<const ::flatbuffers::Vector<uint8_t> *>(VT_VALUES_TYPE);
|
||||||
}
|
}
|
||||||
const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values() const {
|
const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values() const {
|
||||||
return GetPointer<
|
return GetPointer<const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *>(VT_VALUES);
|
||||||
const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *>(VT_VALUES);
|
|
||||||
}
|
}
|
||||||
bool Verify(::flatbuffers::Verifier &verifier) const {
|
bool Verify(::flatbuffers::Verifier &verifier) const {
|
||||||
return VerifyTableStart(verifier) &&
|
return VerifyTableStart(verifier) &&
|
||||||
@@ -171,13 +242,10 @@ struct SensorMessageBuilder {
|
|||||||
typedef SensorMessage Table;
|
typedef SensorMessage Table;
|
||||||
::flatbuffers::FlatBufferBuilder &fbb_;
|
::flatbuffers::FlatBufferBuilder &fbb_;
|
||||||
::flatbuffers::uoffset_t start_;
|
::flatbuffers::uoffset_t start_;
|
||||||
void add_values_type(
|
void add_values_type(::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> values_type) {
|
||||||
::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> values_type) {
|
|
||||||
fbb_.AddOffset(SensorMessage::VT_VALUES_TYPE, values_type);
|
fbb_.AddOffset(SensorMessage::VT_VALUES_TYPE, values_type);
|
||||||
}
|
}
|
||||||
void add_values(
|
void add_values(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<void>>> values) {
|
||||||
::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<void>>>
|
|
||||||
values) {
|
|
||||||
fbb_.AddOffset(SensorMessage::VT_VALUES, values);
|
fbb_.AddOffset(SensorMessage::VT_VALUES, values);
|
||||||
}
|
}
|
||||||
explicit SensorMessageBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
|
explicit SensorMessageBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
|
||||||
@@ -194,8 +262,7 @@ struct SensorMessageBuilder {
|
|||||||
inline ::flatbuffers::Offset<SensorMessage> CreateSensorMessage(
|
inline ::flatbuffers::Offset<SensorMessage> CreateSensorMessage(
|
||||||
::flatbuffers::FlatBufferBuilder &_fbb,
|
::flatbuffers::FlatBufferBuilder &_fbb,
|
||||||
::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> values_type = 0,
|
::flatbuffers::Offset<::flatbuffers::Vector<uint8_t>> values_type = 0,
|
||||||
::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<void>>>
|
::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<void>>> values = 0) {
|
||||||
values = 0) {
|
|
||||||
SensorMessageBuilder builder_(_fbb);
|
SensorMessageBuilder builder_(_fbb);
|
||||||
builder_.add_values(values);
|
builder_.add_values(values);
|
||||||
builder_.add_values_type(values_type);
|
builder_.add_values_type(values_type);
|
||||||
@@ -206,15 +273,15 @@ inline ::flatbuffers::Offset<SensorMessage> CreateSensorMessageDirect(
|
|||||||
::flatbuffers::FlatBufferBuilder &_fbb,
|
::flatbuffers::FlatBufferBuilder &_fbb,
|
||||||
const std::vector<uint8_t> *values_type = nullptr,
|
const std::vector<uint8_t> *values_type = nullptr,
|
||||||
const std::vector<::flatbuffers::Offset<void>> *values = nullptr) {
|
const std::vector<::flatbuffers::Offset<void>> *values = nullptr) {
|
||||||
auto values_type__ =
|
auto values_type__ = values_type ? _fbb.CreateVector<uint8_t>(*values_type) : 0;
|
||||||
values_type ? _fbb.CreateVector<uint8_t>(*values_type) : 0;
|
auto values__ = values ? _fbb.CreateVector<::flatbuffers::Offset<void>>(*values) : 0;
|
||||||
auto values__ =
|
return Messaging::CreateSensorMessage(
|
||||||
values ? _fbb.CreateVector<::flatbuffers::Offset<void>>(*values) : 0;
|
_fbb,
|
||||||
return Messaging::CreateSensorMessage(_fbb, values_type__, values__);
|
values_type__,
|
||||||
|
values__);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool VerifySensorValue(::flatbuffers::Verifier &verifier,
|
inline bool VerifySensorValue(::flatbuffers::Verifier &verifier, const void *obj, SensorValue type) {
|
||||||
const void *obj, SensorValue type) {
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SensorValue_NONE: {
|
case SensorValue_NONE: {
|
||||||
return true;
|
return true;
|
||||||
@@ -227,22 +294,20 @@ inline bool VerifySensorValue(::flatbuffers::Verifier &verifier,
|
|||||||
auto ptr = reinterpret_cast<const Messaging::CurrentAngle *>(obj);
|
auto ptr = reinterpret_cast<const Messaging::CurrentAngle *>(obj);
|
||||||
return verifier.VerifyTable(ptr);
|
return verifier.VerifyTable(ptr);
|
||||||
}
|
}
|
||||||
default:
|
case SensorValue_CurrentText: {
|
||||||
return true;
|
auto ptr = reinterpret_cast<const Messaging::CurrentText *>(obj);
|
||||||
|
return verifier.VerifyTable(ptr);
|
||||||
|
}
|
||||||
|
default: return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool VerifySensorValueVector(
|
inline bool VerifySensorValueVector(::flatbuffers::Verifier &verifier, const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values, const ::flatbuffers::Vector<uint8_t> *types) {
|
||||||
::flatbuffers::Verifier &verifier,
|
if (!values || !types) return !values && !types;
|
||||||
const ::flatbuffers::Vector<::flatbuffers::Offset<void>> *values,
|
if (values->size() != types->size()) return false;
|
||||||
const ::flatbuffers::Vector<uint8_t> *types) {
|
|
||||||
if (!values || !types)
|
|
||||||
return !values && !types;
|
|
||||||
if (values->size() != types->size())
|
|
||||||
return false;
|
|
||||||
for (::flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
|
for (::flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
|
||||||
if (!VerifySensorValue(verifier, values->Get(i),
|
if (!VerifySensorValue(
|
||||||
types->GetEnum<SensorValue>(i))) {
|
verifier, values->Get(i), types->GetEnum<SensorValue>(i))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -253,17 +318,17 @@ inline const Messaging::SensorMessage *GetSensorMessage(const void *buf) {
|
|||||||
return ::flatbuffers::GetRoot<Messaging::SensorMessage>(buf);
|
return ::flatbuffers::GetRoot<Messaging::SensorMessage>(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const Messaging::SensorMessage *
|
inline const Messaging::SensorMessage *GetSizePrefixedSensorMessage(const void *buf) {
|
||||||
GetSizePrefixedSensorMessage(const void *buf) {
|
|
||||||
return ::flatbuffers::GetSizePrefixedRoot<Messaging::SensorMessage>(buf);
|
return ::flatbuffers::GetSizePrefixedRoot<Messaging::SensorMessage>(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool VerifySensorMessageBuffer(::flatbuffers::Verifier &verifier) {
|
inline bool VerifySensorMessageBuffer(
|
||||||
|
::flatbuffers::Verifier &verifier) {
|
||||||
return verifier.VerifyBuffer<Messaging::SensorMessage>(nullptr);
|
return verifier.VerifyBuffer<Messaging::SensorMessage>(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool VerifySizePrefixedSensorMessageBuffer(
|
||||||
VerifySizePrefixedSensorMessageBuffer(::flatbuffers::Verifier &verifier) {
|
::flatbuffers::Verifier &verifier) {
|
||||||
return verifier.VerifySizePrefixedBuffer<Messaging::SensorMessage>(nullptr);
|
return verifier.VerifySizePrefixedBuffer<Messaging::SensorMessage>(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef FLATBUFFERS_GENERATED_TEXTCONTROLMESSAGE_MESSAGING_H_
|
||||||
|
#define FLATBUFFERS_GENERATED_TEXTCONTROLMESSAGE_MESSAGING_H_
|
||||||
|
|
||||||
|
#include "flatbuffers/flatbuffers.h"
|
||||||
|
|
||||||
|
// Ensure the included flatbuffers.h is the same version as when this file was
|
||||||
|
// generated, otherwise it may not be compatible.
|
||||||
|
// static_assert(FLATBUFFERS_VERSION_MAJOR == 25 &&
|
||||||
|
// FLATBUFFERS_VERSION_MINOR == 2 &&
|
||||||
|
// FLATBUFFERS_VERSION_REVISION == 10,
|
||||||
|
// "Non-compatible flatbuffers version included");
|
||||||
|
|
||||||
|
namespace Messaging {
|
||||||
|
|
||||||
|
struct TextControlMessage;
|
||||||
|
struct TextControlMessageBuilder;
|
||||||
|
|
||||||
|
struct TextControlMessage FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
|
||||||
|
typedef TextControlMessageBuilder Builder;
|
||||||
|
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
||||||
|
VT_MESSAGE = 4
|
||||||
|
};
|
||||||
|
const ::flatbuffers::String *message() const {
|
||||||
|
return GetPointer<const ::flatbuffers::String *>(VT_MESSAGE);
|
||||||
|
}
|
||||||
|
bool Verify(::flatbuffers::Verifier &verifier) const {
|
||||||
|
return VerifyTableStart(verifier) &&
|
||||||
|
VerifyOffset(verifier, VT_MESSAGE) &&
|
||||||
|
verifier.VerifyString(message()) &&
|
||||||
|
verifier.EndTable();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TextControlMessageBuilder {
|
||||||
|
typedef TextControlMessage Table;
|
||||||
|
::flatbuffers::FlatBufferBuilder &fbb_;
|
||||||
|
::flatbuffers::uoffset_t start_;
|
||||||
|
void add_message(::flatbuffers::Offset<::flatbuffers::String> message) {
|
||||||
|
fbb_.AddOffset(TextControlMessage::VT_MESSAGE, message);
|
||||||
|
}
|
||||||
|
explicit TextControlMessageBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
|
||||||
|
: fbb_(_fbb) {
|
||||||
|
start_ = fbb_.StartTable();
|
||||||
|
}
|
||||||
|
::flatbuffers::Offset<TextControlMessage> Finish() {
|
||||||
|
const auto end = fbb_.EndTable(start_);
|
||||||
|
auto o = ::flatbuffers::Offset<TextControlMessage>(end);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline ::flatbuffers::Offset<TextControlMessage> CreateTextControlMessage(
|
||||||
|
::flatbuffers::FlatBufferBuilder &_fbb,
|
||||||
|
::flatbuffers::Offset<::flatbuffers::String> message = 0) {
|
||||||
|
TextControlMessageBuilder builder_(_fbb);
|
||||||
|
builder_.add_message(message);
|
||||||
|
return builder_.Finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ::flatbuffers::Offset<TextControlMessage> CreateTextControlMessageDirect(
|
||||||
|
::flatbuffers::FlatBufferBuilder &_fbb,
|
||||||
|
const char *message = nullptr) {
|
||||||
|
auto message__ = message ? _fbb.CreateString(message) : 0;
|
||||||
|
return Messaging::CreateTextControlMessage(
|
||||||
|
_fbb,
|
||||||
|
message__);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Messaging::TextControlMessage *GetTextControlMessage(const void *buf) {
|
||||||
|
return ::flatbuffers::GetRoot<Messaging::TextControlMessage>(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Messaging::TextControlMessage *GetSizePrefixedTextControlMessage(const void *buf) {
|
||||||
|
return ::flatbuffers::GetSizePrefixedRoot<Messaging::TextControlMessage>(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool VerifyTextControlMessageBuffer(
|
||||||
|
::flatbuffers::Verifier &verifier) {
|
||||||
|
return verifier.VerifyBuffer<Messaging::TextControlMessage>(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool VerifySizePrefixedTextControlMessageBuffer(
|
||||||
|
::flatbuffers::Verifier &verifier) {
|
||||||
|
return verifier.VerifySizePrefixedBuffer<Messaging::TextControlMessage>(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void FinishTextControlMessageBuffer(
|
||||||
|
::flatbuffers::FlatBufferBuilder &fbb,
|
||||||
|
::flatbuffers::Offset<Messaging::TextControlMessage> root) {
|
||||||
|
fbb.Finish(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void FinishSizePrefixedTextControlMessageBuffer(
|
||||||
|
::flatbuffers::FlatBufferBuilder &fbb,
|
||||||
|
::flatbuffers::Offset<Messaging::TextControlMessage> root) {
|
||||||
|
fbb.FinishSizePrefixed(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Messaging
|
||||||
|
|
||||||
|
#endif // FLATBUFFERS_GENERATED_TEXTCONTROLMESSAGE_MESSAGING_H_
|
||||||
3
components/oled/CMakeLists.txt
Normal file
3
components/oled/CMakeLists.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
idf_component_register(INCLUDE_DIRS "include"
|
||||||
|
PRIV_REQUIRES driver
|
||||||
|
SRCS "Oled.cpp")
|
||||||
159
components/oled/Oled.cpp
Normal file
159
components/oled/Oled.cpp
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
#include "driver/i2c.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "Oled.h"
|
||||||
|
#include "font8x8_basic.h"
|
||||||
|
#include "ssd1306.h"
|
||||||
|
|
||||||
|
#define TAG "OLED"
|
||||||
|
|
||||||
|
// 128x64 pixels
|
||||||
|
// 8 pixels per byte
|
||||||
|
// 128 bytes per page -> ((128*64)/8)/128 = 8 pages.
|
||||||
|
#define DISPLAY_WIDTH 128
|
||||||
|
#define DISPLAY_HEIGHT 64
|
||||||
|
#define PAGE_SIZE 128
|
||||||
|
#define PAGE_COUNT 8
|
||||||
|
#define I2C_PORT I2C_NUM_0
|
||||||
|
|
||||||
|
void Oled::init(uint8_t sda_pin, uint8_t scl_pin) {
|
||||||
|
i2c_config_t i2c_config = {
|
||||||
|
.mode = I2C_MODE_MASTER,
|
||||||
|
.sda_io_num = sda_pin,
|
||||||
|
.scl_io_num = scl_pin,
|
||||||
|
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
||||||
|
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
||||||
|
.master = {
|
||||||
|
.clk_speed = 1000000
|
||||||
|
},
|
||||||
|
.clk_flags = 0,
|
||||||
|
};
|
||||||
|
i2c_param_config(I2C_PORT, &i2c_config);
|
||||||
|
|
||||||
|
i2c_driver_install(I2C_PORT, I2C_MODE_MASTER, 0, 0, 0);
|
||||||
|
|
||||||
|
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||||
|
i2c_master_start(cmd);
|
||||||
|
i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
||||||
|
i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true);
|
||||||
|
i2c_master_write_byte(cmd, OLED_CMD_SET_CHARGE_PUMP, true);
|
||||||
|
i2c_master_write_byte(cmd, 0x14, true);
|
||||||
|
i2c_master_write_byte(cmd, OLED_CMD_SET_SEGMENT_REMAP, true);
|
||||||
|
i2c_master_write_byte(cmd, OLED_CMD_SET_COM_SCAN_MODE, true);
|
||||||
|
i2c_master_write_byte(cmd, OLED_CMD_DISPLAY_ON, true);
|
||||||
|
i2c_master_stop(cmd);
|
||||||
|
|
||||||
|
if (ESP_OK != i2c_master_cmd_begin(I2C_PORT, cmd, 10 / portTICK_PERIOD_MS)) {
|
||||||
|
ESP_LOGE(TAG, "configuration failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
i2c_cmd_link_delete(cmd);
|
||||||
|
|
||||||
|
clear_display();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oled::clear_display() {
|
||||||
|
ESP_LOGI(TAG, "clear_display");
|
||||||
|
i2c_cmd_handle_t cmd;
|
||||||
|
|
||||||
|
uint8_t page[PAGE_SIZE] = {0};
|
||||||
|
for (uint8_t i = 0; i < PAGE_COUNT; i++) {
|
||||||
|
cmd = i2c_cmd_link_create();
|
||||||
|
i2c_master_start(cmd);
|
||||||
|
i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
||||||
|
i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_SINGLE, true);
|
||||||
|
i2c_master_write_byte(cmd, 0xB0 | i, true);
|
||||||
|
|
||||||
|
i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_DATA_STREAM, true);
|
||||||
|
i2c_master_write(cmd, page, PAGE_SIZE, true);
|
||||||
|
i2c_master_stop(cmd);
|
||||||
|
i2c_master_cmd_begin(I2C_PORT, cmd, 10 / portTICK_PERIOD_MS);
|
||||||
|
i2c_cmd_link_delete(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oled::set_contrast(uint8_t contrast) {
|
||||||
|
i2c_cmd_handle_t cmd;
|
||||||
|
cmd = i2c_cmd_link_create();
|
||||||
|
i2c_master_start(cmd);
|
||||||
|
i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
||||||
|
i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true);
|
||||||
|
i2c_master_write_byte(cmd, OLED_CMD_SET_CONTRAST, true);
|
||||||
|
i2c_master_write_byte(cmd, contrast, true);
|
||||||
|
i2c_master_stop(cmd);
|
||||||
|
i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS);
|
||||||
|
i2c_cmd_link_delete(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oled::display_text(const std::string& text) {
|
||||||
|
ESP_LOGI(TAG, "display_text %s", text.c_str());
|
||||||
|
i2c_cmd_handle_t cmd;
|
||||||
|
|
||||||
|
uint8_t cur_page = 0;
|
||||||
|
uint8_t col = 0;
|
||||||
|
auto col_width = DISPLAY_WIDTH / 8; // using an 8x8 font
|
||||||
|
auto num_rows = DISPLAY_HEIGHT / 8; // using an 8x8 font
|
||||||
|
auto max_size = col_width * num_rows;
|
||||||
|
|
||||||
|
cmd = i2c_cmd_link_create();
|
||||||
|
i2c_master_start(cmd);
|
||||||
|
i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
||||||
|
|
||||||
|
i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true);
|
||||||
|
i2c_master_write_byte(cmd, 0x00, true); // reset column
|
||||||
|
i2c_master_write_byte(cmd, 0x10, true);
|
||||||
|
i2c_master_write_byte(cmd, 0xB0 | cur_page, true); // reset page
|
||||||
|
|
||||||
|
i2c_master_stop(cmd);
|
||||||
|
i2c_master_cmd_begin(I2C_NUM_0, cmd, 10 / portTICK_PERIOD_MS);
|
||||||
|
i2c_cmd_link_delete(cmd);
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < text.size() && i < max_size; i++) {
|
||||||
|
ESP_LOGI(TAG, "%d: %c", i, text[i]);
|
||||||
|
if (text[i] == '\n' || col >= col_width) {
|
||||||
|
ESP_LOGI(TAG, "new line");
|
||||||
|
cmd = i2c_cmd_link_create();
|
||||||
|
i2c_master_start(cmd);
|
||||||
|
i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
||||||
|
|
||||||
|
i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_CMD_STREAM, true);
|
||||||
|
i2c_master_write_byte(cmd, 0x00, true); // reset column
|
||||||
|
i2c_master_write_byte(cmd, 0x10, true);
|
||||||
|
i2c_master_write_byte(cmd, 0xB0 | ++cur_page, true); // increment page
|
||||||
|
|
||||||
|
i2c_master_stop(cmd);
|
||||||
|
i2c_master_cmd_begin(I2C_NUM_0, cmd, 10/portTICK_PERIOD_MS);
|
||||||
|
i2c_cmd_link_delete(cmd);
|
||||||
|
col = 0;
|
||||||
|
} else {
|
||||||
|
cmd = i2c_cmd_link_create();
|
||||||
|
i2c_master_start(cmd);
|
||||||
|
i2c_master_write_byte(cmd, (OLED_I2C_ADDRESS << 1) | I2C_MASTER_WRITE, true);
|
||||||
|
|
||||||
|
i2c_master_write_byte(cmd, OLED_CONTROL_BYTE_DATA_STREAM, true);
|
||||||
|
uint8_t rotated[8];
|
||||||
|
rotate8x8((uint8_t*)font8x8_basic[(uint8_t)text[i]], rotated);
|
||||||
|
i2c_master_write(cmd, rotated, 8, true);
|
||||||
|
|
||||||
|
i2c_master_stop(cmd);
|
||||||
|
i2c_master_cmd_begin(I2C_NUM_0, cmd, 10/portTICK_PERIOD_MS);
|
||||||
|
i2c_cmd_link_delete(cmd);
|
||||||
|
col++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oled::rotate8x8(uint8_t in[8], uint8_t out[8]) {
|
||||||
|
for (int x = 0; x < 8; x++) {
|
||||||
|
out[x] = 0;
|
||||||
|
for (int y = 0; y < 8; y++) {
|
||||||
|
if (in[y] & (1 << x)) {
|
||||||
|
out[x] |= (1 << (7 - y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
23
components/oled/include/Oled.h
Normal file
23
components/oled/include/Oled.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#ifndef OLED_H
|
||||||
|
#define OLED_H
|
||||||
|
|
||||||
|
class Oled {
|
||||||
|
public:
|
||||||
|
Oled(uint8_t sda_pin, uint8_t scl_pin) {
|
||||||
|
init(sda_pin, scl_pin);
|
||||||
|
};
|
||||||
|
void clear_display();
|
||||||
|
void set_contrast(uint8_t contrast);
|
||||||
|
void display_text(const std::string& text);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void init(uint8_t sda_pin, uint8_t scl_pin);
|
||||||
|
void rotate8x8(uint8_t in[8], uint8_t out[8]);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // OLED_H
|
||||||
163
components/oled/include/font8x8_basic.h
Normal file
163
components/oled/include/font8x8_basic.h
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
#ifndef FONT_H
|
||||||
|
#define FONT_H
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
// Adapted from https://github.com/dhepper/font8x8/blob/master/font8x8_basic.h
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 8x8 monochrome bitmap fonts for rendering
|
||||||
|
* Author: Daniel Hepper <daniel@hepper.net>
|
||||||
|
*
|
||||||
|
* License: Public Domain
|
||||||
|
*
|
||||||
|
* Based on:
|
||||||
|
* // Summary: font8x8.h
|
||||||
|
* // 8x8 monochrome bitmap fonts for rendering
|
||||||
|
* //
|
||||||
|
* // Author:
|
||||||
|
* // Marcel Sondaar
|
||||||
|
* // International Business Machines (public domain VGA fonts)
|
||||||
|
* //
|
||||||
|
* // License:
|
||||||
|
* // Public Domain
|
||||||
|
*
|
||||||
|
* Fetched from: http://dimensionalrift.homelinux.net/combuster/mos3/?p=viewsource&file=/modules/gfx/font8_8.asm
|
||||||
|
**/
|
||||||
|
|
||||||
|
// Constant: font8x8_basic
|
||||||
|
// Contains an 8x8 font map for unicode points U+0000 - U+007F (basic latin)
|
||||||
|
uint8_t font8x8_basic[128][8] = {
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x18, 0x00, 0x18, 0x18, 0x3C, 0x3C, 0x18 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36 },
|
||||||
|
{ 0x00, 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36 },
|
||||||
|
{ 0x00, 0x0C, 0x1F, 0x30, 0x1E, 0x03, 0x3E, 0x0C },
|
||||||
|
{ 0x00, 0x63, 0x66, 0x0C, 0x18, 0x33, 0x63, 0x00 },
|
||||||
|
{ 0x00, 0x6E, 0x33, 0x3B, 0x6E, 0x1C, 0x36, 0x1C },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x06 },
|
||||||
|
{ 0x00, 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18 },
|
||||||
|
{ 0x00, 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06 },
|
||||||
|
{ 0x00, 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00 },
|
||||||
|
{ 0x06, 0x0C, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x01, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60 },
|
||||||
|
{ 0x00, 0x3E, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x3E },
|
||||||
|
{ 0x00, 0x3F, 0x0C, 0x0C, 0x0C, 0x0C, 0x0E, 0x0C },
|
||||||
|
{ 0x00, 0x3F, 0x33, 0x06, 0x1C, 0x30, 0x33, 0x1E },
|
||||||
|
{ 0x00, 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E },
|
||||||
|
{ 0x00, 0x78, 0x30, 0x7F, 0x33, 0x36, 0x3C, 0x38 },
|
||||||
|
{ 0x00, 0x1E, 0x33, 0x30, 0x30, 0x1F, 0x03, 0x3F },
|
||||||
|
{ 0x00, 0x1E, 0x33, 0x33, 0x1F, 0x03, 0x06, 0x1C },
|
||||||
|
{ 0x00, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x33, 0x3F },
|
||||||
|
{ 0x00, 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E },
|
||||||
|
{ 0x00, 0x0E, 0x18, 0x30, 0x3E, 0x33, 0x33, 0x1E },
|
||||||
|
{ 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00 },
|
||||||
|
{ 0x06, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00 },
|
||||||
|
{ 0x00, 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18 },
|
||||||
|
{ 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06 },
|
||||||
|
{ 0x00, 0x0C, 0x00, 0x0C, 0x18, 0x30, 0x33, 0x1E },
|
||||||
|
{ 0x00, 0x1E, 0x03, 0x7B, 0x7B, 0x7B, 0x63, 0x3E },
|
||||||
|
{ 0x00, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x1E, 0x0C },
|
||||||
|
{ 0x00, 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F },
|
||||||
|
{ 0x00, 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C },
|
||||||
|
{ 0x00, 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F },
|
||||||
|
{ 0x00, 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F },
|
||||||
|
{ 0x00, 0x0F, 0x06, 0x16, 0x1E, 0x16, 0x46, 0x7F },
|
||||||
|
{ 0x00, 0x7C, 0x66, 0x73, 0x03, 0x03, 0x66, 0x3C },
|
||||||
|
{ 0x00, 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33 },
|
||||||
|
{ 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E },
|
||||||
|
{ 0x00, 0x1E, 0x33, 0x33, 0x30, 0x30, 0x30, 0x78 },
|
||||||
|
{ 0x00, 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67 },
|
||||||
|
{ 0x00, 0x7F, 0x66, 0x46, 0x06, 0x06, 0x06, 0x0F },
|
||||||
|
{ 0x00, 0x63, 0x63, 0x6B, 0x7F, 0x7F, 0x77, 0x63 },
|
||||||
|
{ 0x00, 0x63, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x63 },
|
||||||
|
|
||||||
|
{ 0x00, 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C },
|
||||||
|
{ 0x00, 0x0F, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3F },
|
||||||
|
{ 0x00, 0x38, 0x1E, 0x3B, 0x33, 0x33, 0x33, 0x1E },
|
||||||
|
{ 0x00, 0x67, 0x66, 0x36, 0x3E, 0x66, 0x66, 0x3F },
|
||||||
|
{ 0x00, 0x1E, 0x33, 0x38, 0x0E, 0x07, 0x33, 0x1E },
|
||||||
|
{ 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x2D, 0x3F },
|
||||||
|
{ 0x00, 0x3F, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33 },
|
||||||
|
{ 0x00, 0x0C, 0x1E, 0x33, 0x33, 0x33, 0x33, 0x33 },
|
||||||
|
{ 0x00, 0x63, 0x77, 0x7F, 0x6B, 0x63, 0x63, 0x63 },
|
||||||
|
{ 0x00, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x63 },
|
||||||
|
{ 0x00, 0x1E, 0x0C, 0x0C, 0x1E, 0x33, 0x33, 0x33 },
|
||||||
|
{ 0x00, 0x7F, 0x66, 0x4C, 0x18, 0x31, 0x63, 0x7F },
|
||||||
|
{ 0x00, 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E },
|
||||||
|
{ 0x00, 0x40, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03 },
|
||||||
|
{ 0x00, 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x63, 0x36, 0x1C, 0x08 },
|
||||||
|
{ 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0C, 0x0C },
|
||||||
|
{ 0x00, 0x6E, 0x33, 0x3E, 0x30, 0x1E, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x07 },
|
||||||
|
{ 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x30, 0x38 },
|
||||||
|
{ 0x00, 0x1E, 0x03, 0x3F, 0x33, 0x1E, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x0F, 0x06, 0x06, 0x0F, 0x06, 0x36, 0x1C },
|
||||||
|
{ 0x1F, 0x30, 0x3E, 0x33, 0x33, 0x6E, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x67, 0x66, 0x66, 0x6E, 0x36, 0x06, 0x07 },
|
||||||
|
{ 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x0E, 0x00, 0x0C },
|
||||||
|
{ 0x1E, 0x33, 0x33, 0x30, 0x30, 0x30, 0x00, 0x30 },
|
||||||
|
{ 0x00, 0x67, 0x36, 0x1E, 0x36, 0x66, 0x06, 0x07 },
|
||||||
|
{ 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0E },
|
||||||
|
{ 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x33, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x33, 0x33, 0x33, 0x33, 0x1F, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00, 0x00 },
|
||||||
|
{ 0x0F, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00, 0x00 },
|
||||||
|
{ 0x78, 0x30, 0x3E, 0x33, 0x33, 0x6E, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x0F, 0x06, 0x66, 0x6E, 0x3B, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x1F, 0x30, 0x1E, 0x03, 0x3E, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x18, 0x2C, 0x0C, 0x0C, 0x3E, 0x0C, 0x08 },
|
||||||
|
{ 0x00, 0x6E, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x0C, 0x1E, 0x33, 0x33, 0x33, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x36, 0x7F, 0x7F, 0x6B, 0x63, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00, 0x00 },
|
||||||
|
{ 0x1F, 0x30, 0x3E, 0x33, 0x33, 0x33, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x3F, 0x26, 0x0C, 0x19, 0x3F, 0x00, 0x00 },
|
||||||
|
{ 0x00, 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38 },
|
||||||
|
{ 0x00, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18 },
|
||||||
|
{ 0x00, 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07 },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3B, 0x6E },
|
||||||
|
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // FONT_H
|
||||||
45
components/oled/include/ssd1306.h
Normal file
45
components/oled/include/ssd1306.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#ifndef SSD_1306_H
|
||||||
|
#define SSD_1306_H
|
||||||
|
|
||||||
|
// From http://robotcantalk.blogspot.com/2015/03/interfacing-arduino-with-ssd1306-driven.html
|
||||||
|
|
||||||
|
// SLA (0x3C) + WRITE_MODE (0x00) = 0x78 (0b01111000)
|
||||||
|
#define OLED_I2C_ADDRESS 0x3C
|
||||||
|
|
||||||
|
// Control byte
|
||||||
|
#define OLED_CONTROL_BYTE_CMD_SINGLE 0x80
|
||||||
|
#define OLED_CONTROL_BYTE_CMD_STREAM 0x00
|
||||||
|
#define OLED_CONTROL_BYTE_DATA_STREAM 0x40
|
||||||
|
|
||||||
|
// Fundamental commands (pg.28)
|
||||||
|
#define OLED_CMD_SET_CONTRAST 0x81 // follow with 0x7F
|
||||||
|
#define OLED_CMD_DISPLAY_RAM 0xA4
|
||||||
|
#define OLED_CMD_DISPLAY_ALLON 0xA5
|
||||||
|
#define OLED_CMD_DISPLAY_NORMAL 0xA6
|
||||||
|
#define OLED_CMD_DISPLAY_INVERTED 0xA7
|
||||||
|
#define OLED_CMD_DISPLAY_OFF 0xAE
|
||||||
|
#define OLED_CMD_DISPLAY_ON 0xAF
|
||||||
|
|
||||||
|
// Addressing Command Table (pg.30)
|
||||||
|
#define OLED_CMD_SET_MEMORY_ADDR_MODE 0x20 // follow with 0x00 = HORZ mode = Behave like a KS108 graphic LCD
|
||||||
|
#define OLED_CMD_SET_COLUMN_RANGE 0x21 // can be used only in HORZ/VERT mode - follow with 0x00 and 0x7F = COL127
|
||||||
|
#define OLED_CMD_SET_PAGE_RANGE 0x22 // can be used only in HORZ/VERT mode - follow with 0x00 and 0x07 = PAGE7
|
||||||
|
|
||||||
|
// Hardware Config (pg.31)
|
||||||
|
#define OLED_CMD_SET_DISPLAY_START_LINE 0x40
|
||||||
|
#define OLED_CMD_SET_SEGMENT_REMAP 0xA1
|
||||||
|
#define OLED_CMD_SET_MUX_RATIO 0xA8 // follow with 0x3F = 64 MUX
|
||||||
|
#define OLED_CMD_SET_COM_SCAN_MODE 0xC8
|
||||||
|
#define OLED_CMD_SET_DISPLAY_OFFSET 0xD3 // follow with 0x00
|
||||||
|
#define OLED_CMD_SET_COM_PIN_MAP 0xDA // follow with 0x12
|
||||||
|
#define OLED_CMD_NOP 0xE3 // NOP
|
||||||
|
|
||||||
|
// Timing and Driving Scheme (pg.32)
|
||||||
|
#define OLED_CMD_SET_DISPLAY_CLK_DIV 0xD5 // follow with 0x80
|
||||||
|
#define OLED_CMD_SET_PRECHARGE 0xD9 // follow with 0xF1
|
||||||
|
#define OLED_CMD_SET_VCOMH_DESELCT 0xDB // follow with 0x30
|
||||||
|
|
||||||
|
// Charge Pump (pg.62)
|
||||||
|
#define OLED_CMD_SET_CHARGE_PUMP 0x8D // follow with 0x14
|
||||||
|
|
||||||
|
#endif // SSD_1306_H
|
||||||
@@ -17,7 +17,7 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
idf_component_register(SRCS ${ALL_SRCS}
|
idf_component_register(SRCS ${ALL_SRCS}
|
||||||
PRIV_REQUIRES esp_psram spi_flash nvs_flash esp_event rpc constants config rmt esp_driver_gptimer dataLink flatbuffers esp_driver_ledc
|
PRIV_REQUIRES esp_psram spi_flash nvs_flash esp_event rpc constants config rmt esp_driver_gptimer dataLink flatbuffers esp_driver_ledc oled
|
||||||
INCLUDE_DIRS "include")
|
INCLUDE_DIRS "include")
|
||||||
|
|
||||||
if(DEFINED SRC_BOARD AND SRC_BOARD)
|
if(DEFINED SRC_BOARD AND SRC_BOARD)
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "control/ActuatorFactory.h"
|
#include "control/ActuatorFactory.h"
|
||||||
#include "control/DCMotorActuator.h"
|
#include "control/DCMotorActuator.h"
|
||||||
#include "control/Servo1Actuator.h"
|
#include "control/Servo1Actuator.h"
|
||||||
|
#include "control/OledActuator.h"
|
||||||
#include "flatbuffers_generated/RobotModule_generated.h"
|
#include "flatbuffers_generated/RobotModule_generated.h"
|
||||||
|
|
||||||
std::unique_ptr<IActuator>
|
std::unique_ptr<IActuator>
|
||||||
@@ -18,6 +19,8 @@ ActuatorFactory::create_actuator(const ModuleType type) {
|
|||||||
return std::make_unique<Servo1Actuator>();
|
return std::make_unique<Servo1Actuator>();
|
||||||
case ModuleType_DC_MOTOR:
|
case ModuleType_DC_MOTOR:
|
||||||
return std::make_unique<DCMotorActuator>();
|
return std::make_unique<DCMotorActuator>();
|
||||||
|
case ModuleType_DISPLAY:
|
||||||
|
return std::make_unique<OledActuator>();
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,6 +101,8 @@ void DCMotorActuator::setup_encoder() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DCMotorActuator::actuate(uint8_t *cmd) {
|
void DCMotorActuator::actuate(uint8_t *cmd) {
|
||||||
|
// todo: Do we want to verify flatbuffers here?
|
||||||
|
// Will introduce latency, and means that we need to also send the size to the actuate function.
|
||||||
const auto *angleControlCmd =
|
const auto *angleControlCmd =
|
||||||
Flatbuffers::AngleControlMessageBuilder::parse_angle_control_message(cmd);
|
Flatbuffers::AngleControlMessageBuilder::parse_angle_control_message(cmd);
|
||||||
this->m_target_angle = angleControlCmd->angle();
|
this->m_target_angle = angleControlCmd->angle();
|
||||||
|
|||||||
33
main/control/OledActuator.cpp
Normal file
33
main/control/OledActuator.cpp
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
//
|
||||||
|
// Created by Johnathon Slightham on 2025-07-15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "control/OledActuator.h"
|
||||||
|
#include "TextControlMessageBuilder.h"
|
||||||
|
#include "SensorMessageBuilder.h"
|
||||||
|
#include "constants/module.h"
|
||||||
|
#include "driver/ledc.h"
|
||||||
|
#include "flatbuffers_generated/SensorMessage_generated.h"
|
||||||
|
#include "util/number_utils.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
|
||||||
|
void OledActuator::actuate(uint8_t *cmd) {
|
||||||
|
// todo: Do we want to verify flatbuffers here?
|
||||||
|
// Will introduce latency, and means that we need to also send the size to the actuate function.
|
||||||
|
|
||||||
|
const auto *text_control_message = Flatbuffers::TextControlMessageBuilder::parse_text_control_message(cmd);
|
||||||
|
const auto new_str = text_control_message->message()->str();
|
||||||
|
|
||||||
|
if (m_display_str != new_str) {
|
||||||
|
m_display_str = new_str;
|
||||||
|
|
||||||
|
m_oled->clear_display();
|
||||||
|
if (m_display_str != "") {
|
||||||
|
m_oled->display_text(m_display_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Flatbuffers::sensor_value> OledActuator::get_sensor_data() {
|
||||||
|
return {Flatbuffers::target_text{m_display_str}};
|
||||||
|
}
|
||||||
@@ -39,6 +39,8 @@ Servo1Actuator::Servo1Actuator() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Servo1Actuator::actuate(uint8_t *cmd) {
|
void Servo1Actuator::actuate(uint8_t *cmd) {
|
||||||
|
// todo: Do we want to verify flatbuffers here?
|
||||||
|
// Will introduce latency, and means that we need to also send the size to the actuate function.
|
||||||
const auto *angleControlCmd =
|
const auto *angleControlCmd =
|
||||||
Flatbuffers::AngleControlMessageBuilder::parse_angle_control_message(cmd);
|
Flatbuffers::AngleControlMessageBuilder::parse_angle_control_message(cmd);
|
||||||
const auto newDuty =
|
const auto newDuty =
|
||||||
|
|||||||
24
main/include/control/OledActuator.h
Normal file
24
main/include/control/OledActuator.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
// Oled module
|
||||||
|
|
||||||
|
#ifndef OLED_ACTUATOR_H
|
||||||
|
#define OLED_ACTUATOR_H
|
||||||
|
|
||||||
|
#include "IActuator.h"
|
||||||
|
#include "ISensor.h"
|
||||||
|
#include "Oled.h"
|
||||||
|
#include "constants/module.h"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
class OledActuator final : public IActuator {
|
||||||
|
public:
|
||||||
|
OledActuator() : m_oled(std::make_unique<Oled>(OLED_SDA, OLED_SCL)) {};
|
||||||
|
~OledActuator() override = default;
|
||||||
|
void actuate(std::uint8_t *cmd) override;
|
||||||
|
std::vector<Flatbuffers::sensor_value> get_sensor_data() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_display_str = "";
|
||||||
|
std::unique_ptr<Oled> m_oled;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //OLED_ACTUATOR_H
|
||||||
Reference in New Issue
Block a user