mirror of
https://github.com/scottbez1/smartknob.git
synced 2025-09-26 23:09:27 +08:00
SPIFFS persistent storage for motor calibration (#122)
- New Configuration class for managing persistent configuration - New proto messages for serialized configuration, with flexibility for expansion - Load persistent configuration at startup, if available, use for default motor calibration - Save motor calibration to persistent configuration file
This commit is contained in:
parent
2afc38f7f9
commit
1d73af17cc
125
firmware/src/configuration.cpp
Normal file
125
firmware/src/configuration.cpp
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
#include <SPIFFS.h>
|
||||||
|
|
||||||
|
#include "pb_decode.h"
|
||||||
|
#include "pb_encode.h"
|
||||||
|
|
||||||
|
#include "proto_gen/smartknob.pb.h"
|
||||||
|
#include "semaphore_guard.h"
|
||||||
|
|
||||||
|
#include "configuration.h"
|
||||||
|
|
||||||
|
static const char* CONFIG_PATH = "/config.pb";
|
||||||
|
|
||||||
|
Configuration::Configuration() {
|
||||||
|
mutex_ = xSemaphoreCreateMutex();
|
||||||
|
assert(mutex_ != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
Configuration::~Configuration() {
|
||||||
|
vSemaphoreDelete(mutex_);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Configuration::loadFromDisk() {
|
||||||
|
SemaphoreGuard lock(mutex_);
|
||||||
|
if (!SPIFFS.begin(true)) {
|
||||||
|
log("Failed to mount SPIFFS");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
File f = SPIFFS.open(CONFIG_PATH);
|
||||||
|
if (!f) {
|
||||||
|
log("Failed to read config file");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t read = f.readBytes((char*)buffer_, sizeof(buffer_));
|
||||||
|
f.close();
|
||||||
|
|
||||||
|
pb_istream_t stream = pb_istream_from_buffer(buffer_, read);
|
||||||
|
if (!pb_decode(&stream, PB_PersistentConfiguration_fields, &pb_buffer_)) {
|
||||||
|
char buf[200];
|
||||||
|
snprintf(buf, sizeof(buf), "Decoding failed: %s", PB_GET_ERROR(&stream));
|
||||||
|
log(buf);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pb_buffer_.version != PERSISTENT_CONFIGURATION_VERSION) {
|
||||||
|
char buf[200];
|
||||||
|
snprintf(buf, sizeof(buf), "Invalid config version. Expected %u, received %u", PERSISTENT_CONFIGURATION_VERSION, pb_buffer_.version);
|
||||||
|
log(buf);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
loaded_ = true;
|
||||||
|
|
||||||
|
char buf[200];
|
||||||
|
snprintf(
|
||||||
|
buf,
|
||||||
|
sizeof(buf),
|
||||||
|
"Motor calibration: calib=%u, pole_pairs=%u, zero_offset=%.2f, cw=%u",
|
||||||
|
pb_buffer_.motor.calibrated,
|
||||||
|
pb_buffer_.motor.pole_pairs,
|
||||||
|
pb_buffer_.motor.zero_electrical_offset,
|
||||||
|
pb_buffer_.motor.direction_cw
|
||||||
|
);
|
||||||
|
log(buf);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Configuration::saveToDisk() {
|
||||||
|
SemaphoreGuard lock(mutex_);
|
||||||
|
|
||||||
|
pb_ostream_t stream = pb_ostream_from_buffer(buffer_, sizeof(buffer_));
|
||||||
|
pb_buffer_.version = PERSISTENT_CONFIGURATION_VERSION;
|
||||||
|
if (!pb_encode(&stream, PB_PersistentConfiguration_fields, &pb_buffer_)) {
|
||||||
|
char buf[200];
|
||||||
|
snprintf(buf, sizeof(buf), "Encoding failed: %s", PB_GET_ERROR(&stream));
|
||||||
|
log(buf);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
File f = SPIFFS.open(CONFIG_PATH, FILE_WRITE);
|
||||||
|
if (!f) {
|
||||||
|
log("Failed to read config file");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
size_t written = f.write(buffer_, stream.bytes_written);
|
||||||
|
f.close();
|
||||||
|
|
||||||
|
char buf[20];
|
||||||
|
snprintf(buf, sizeof(buf), "Wrote %d bytes", written);
|
||||||
|
log(buf);
|
||||||
|
|
||||||
|
if (written != stream.bytes_written) {
|
||||||
|
log("Failed to write all bytes to file");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
PB_PersistentConfiguration Configuration::get() {
|
||||||
|
SemaphoreGuard lock(mutex_);
|
||||||
|
if (!loaded_) {
|
||||||
|
return PB_PersistentConfiguration();
|
||||||
|
}
|
||||||
|
return pb_buffer_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Configuration::setMotorCalibrationAndSave(PB_MotorCalibration& motor_calibration) {
|
||||||
|
{
|
||||||
|
SemaphoreGuard lock(mutex_);
|
||||||
|
pb_buffer_.motor = motor_calibration;
|
||||||
|
pb_buffer_.has_motor = true;
|
||||||
|
}
|
||||||
|
return saveToDisk();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Configuration::setLogger(Logger* logger) {
|
||||||
|
logger_ = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Configuration::log(const char* msg) {
|
||||||
|
if (logger_ != nullptr) {
|
||||||
|
logger_->log(msg);
|
||||||
|
}
|
||||||
|
}
|
33
firmware/src/configuration.h
Normal file
33
firmware/src/configuration.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <SPIFFS.h>
|
||||||
|
#include <PacketSerial.h>
|
||||||
|
|
||||||
|
#include "proto_gen/smartknob.pb.h"
|
||||||
|
|
||||||
|
#include "logger.h"
|
||||||
|
|
||||||
|
const uint32_t PERSISTENT_CONFIGURATION_VERSION = 1;
|
||||||
|
|
||||||
|
class Configuration {
|
||||||
|
public:
|
||||||
|
Configuration();
|
||||||
|
~Configuration();
|
||||||
|
|
||||||
|
void setLogger(Logger* logger);
|
||||||
|
bool loadFromDisk();
|
||||||
|
bool saveToDisk();
|
||||||
|
PB_PersistentConfiguration get();
|
||||||
|
bool setMotorCalibrationAndSave(PB_MotorCalibration& motor_calibration);
|
||||||
|
|
||||||
|
private:
|
||||||
|
SemaphoreHandle_t mutex_;
|
||||||
|
|
||||||
|
Logger* logger_ = nullptr;
|
||||||
|
bool loaded_ = false;
|
||||||
|
PB_PersistentConfiguration pb_buffer_ = {};
|
||||||
|
|
||||||
|
uint8_t buffer_[PB_PersistentConfiguration_size];
|
||||||
|
|
||||||
|
void log(const char* msg);
|
||||||
|
};
|
@ -1,16 +1,19 @@
|
|||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#include "configuration.h"
|
||||||
#include "display_task.h"
|
#include "display_task.h"
|
||||||
#include "interface_task.h"
|
#include "interface_task.h"
|
||||||
#include "motor_task.h"
|
#include "motor_task.h"
|
||||||
|
|
||||||
|
Configuration config;
|
||||||
|
|
||||||
#if SK_DISPLAY
|
#if SK_DISPLAY
|
||||||
static DisplayTask display_task(0);
|
static DisplayTask display_task(0);
|
||||||
static DisplayTask* display_task_p = &display_task;
|
static DisplayTask* display_task_p = &display_task;
|
||||||
#else
|
#else
|
||||||
static DisplayTask* display_task_p = nullptr;
|
static DisplayTask* display_task_p = nullptr;
|
||||||
#endif
|
#endif
|
||||||
static MotorTask motor_task(1);
|
static MotorTask motor_task(1, config);
|
||||||
|
|
||||||
|
|
||||||
InterfaceTask interface_task(0, motor_task, display_task_p);
|
InterfaceTask interface_task(0, motor_task, display_task_p);
|
||||||
@ -24,9 +27,13 @@ void setup() {
|
|||||||
motor_task.addListener(display_task.getKnobStateQueue());
|
motor_task.addListener(display_task.getKnobStateQueue());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
interface_task.begin();
|
||||||
|
|
||||||
|
config.setLogger(&interface_task);
|
||||||
|
config.loadFromDisk();
|
||||||
|
|
||||||
motor_task.setLogger(&interface_task);
|
motor_task.setLogger(&interface_task);
|
||||||
motor_task.begin();
|
motor_task.begin();
|
||||||
interface_task.begin();
|
|
||||||
|
|
||||||
// Free up the Arduino loop task
|
// Free up the Arduino loop task
|
||||||
vTaskDelete(NULL);
|
vTaskDelete(NULL);
|
||||||
|
@ -12,15 +12,6 @@
|
|||||||
#include "motors/motor_config.h"
|
#include "motors/motor_config.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
// ####
|
|
||||||
// Hardware-specific motor calibration constants.
|
|
||||||
// Run calibration once at startup, then update these constants with the calibration results.
|
|
||||||
static const float ZERO_ELECTRICAL_OFFSET = 7.61;
|
|
||||||
static const Direction FOC_DIRECTION = Direction::CW;
|
|
||||||
static const int MOTOR_POLE_PAIRS = 7;
|
|
||||||
// ####
|
|
||||||
|
|
||||||
|
|
||||||
static const float DEAD_ZONE_DETENT_PERCENT = 0.2;
|
static const float DEAD_ZONE_DETENT_PERCENT = 0.2;
|
||||||
static const float DEAD_ZONE_RAD = 1 * _PI / 180;
|
static const float DEAD_ZONE_RAD = 1 * _PI / 180;
|
||||||
|
|
||||||
@ -31,7 +22,7 @@ static const float IDLE_CORRECTION_MAX_ANGLE_RAD = 5 * PI / 180;
|
|||||||
static const float IDLE_CORRECTION_RATE_ALPHA = 0.0005;
|
static const float IDLE_CORRECTION_RATE_ALPHA = 0.0005;
|
||||||
|
|
||||||
|
|
||||||
MotorTask::MotorTask(const uint8_t task_core) : Task("Motor", 2500, 1, task_core) {
|
MotorTask::MotorTask(const uint8_t task_core, Configuration& configuration) : Task("Motor", 3200, 1, task_core), configuration_(configuration) {
|
||||||
queue_ = xQueueCreate(5, sizeof(Command));
|
queue_ = xQueueCreate(5, sizeof(Command));
|
||||||
assert(queue_ != NULL);
|
assert(queue_ != NULL);
|
||||||
}
|
}
|
||||||
@ -86,8 +77,9 @@ void MotorTask::run() {
|
|||||||
encoder.update();
|
encoder.update();
|
||||||
delay(10);
|
delay(10);
|
||||||
|
|
||||||
motor.pole_pairs = MOTOR_POLE_PAIRS;
|
PB_PersistentConfiguration c = configuration_.get();
|
||||||
motor.initFOC(ZERO_ELECTRICAL_OFFSET, FOC_DIRECTION);
|
motor.pole_pairs = c.motor.calibrated ? c.motor.pole_pairs : 7;
|
||||||
|
motor.initFOC(c.motor.zero_electrical_offset, c.motor.direction_cw ? Direction::CW : Direction::CCW);
|
||||||
|
|
||||||
motor.monitor_downsample = 0; // disable monitor at first - optional
|
motor.monitor_downsample = 0; // disable monitor at first - optional
|
||||||
|
|
||||||
@ -524,13 +516,13 @@ void MotorTask::calibrate() {
|
|||||||
|
|
||||||
|
|
||||||
// #### Apply settings
|
// #### Apply settings
|
||||||
// TODO: save to non-volatile storage
|
|
||||||
motor.pole_pairs = measured_pole_pairs;
|
motor.pole_pairs = measured_pole_pairs;
|
||||||
motor.zero_electric_angle = avg_offset_angle + _3PI_2;
|
motor.zero_electric_angle = avg_offset_angle + _3PI_2;
|
||||||
motor.voltage_limit = FOC_VOLTAGE_LIMIT;
|
motor.voltage_limit = FOC_VOLTAGE_LIMIT;
|
||||||
motor.controller = MotionControlType::torque;
|
motor.controller = MotionControlType::torque;
|
||||||
|
|
||||||
log("\n\nRESULTS:\n Update these constants at the top of " __FILE__);
|
log("");
|
||||||
|
log("RESULTS:");
|
||||||
snprintf(buf_, sizeof(buf_), " ZERO_ELECTRICAL_OFFSET: %.2f", motor.zero_electric_angle);
|
snprintf(buf_, sizeof(buf_), " ZERO_ELECTRICAL_OFFSET: %.2f", motor.zero_electric_angle);
|
||||||
log(buf_);
|
log(buf_);
|
||||||
if (motor.sensor_direction == Direction::CW) {
|
if (motor.sensor_direction == Direction::CW) {
|
||||||
@ -540,7 +532,18 @@ void MotorTask::calibrate() {
|
|||||||
}
|
}
|
||||||
snprintf(buf_, sizeof(buf_), " MOTOR_POLE_PAIRS: %d", motor.pole_pairs);
|
snprintf(buf_, sizeof(buf_), " MOTOR_POLE_PAIRS: %d", motor.pole_pairs);
|
||||||
log(buf_);
|
log(buf_);
|
||||||
delay(2000);
|
|
||||||
|
log("");
|
||||||
|
log("Saving to persistent configuration...");
|
||||||
|
PB_MotorCalibration calibration = {
|
||||||
|
.calibrated = true,
|
||||||
|
.zero_electrical_offset = motor.zero_electric_angle,
|
||||||
|
.direction_cw = motor.sensor_direction == Direction::CW,
|
||||||
|
.pole_pairs = motor.pole_pairs,
|
||||||
|
};
|
||||||
|
if (configuration_.setMotorCalibrationAndSave(calibration)) {
|
||||||
|
log("Success!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MotorTask::checkSensorError() {
|
void MotorTask::checkSensorError() {
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <SimpleFOC.h>
|
#include <SimpleFOC.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "configuration.h"
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "proto_gen/smartknob.pb.h"
|
#include "proto_gen/smartknob.pb.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
@ -33,7 +34,7 @@ class MotorTask : public Task<MotorTask> {
|
|||||||
friend class Task<MotorTask>; // Allow base Task to invoke protected run()
|
friend class Task<MotorTask>; // Allow base Task to invoke protected run()
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MotorTask(const uint8_t task_core);
|
MotorTask(const uint8_t task_core, Configuration& configuration);
|
||||||
~MotorTask();
|
~MotorTask();
|
||||||
|
|
||||||
void setConfig(const PB_SmartKnobConfig& config);
|
void setConfig(const PB_SmartKnobConfig& config);
|
||||||
@ -47,6 +48,7 @@ class MotorTask : public Task<MotorTask> {
|
|||||||
void run();
|
void run();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Configuration& configuration_;
|
||||||
QueueHandle_t queue_;
|
QueueHandle_t queue_;
|
||||||
Logger* logger_;
|
Logger* logger_;
|
||||||
std::vector<QueueHandle_t> listeners_;
|
std::vector<QueueHandle_t> listeners_;
|
||||||
|
@ -27,4 +27,10 @@ PB_BIND(PB_SmartKnobConfig, PB_SmartKnobConfig, AUTO)
|
|||||||
PB_BIND(PB_RequestState, PB_RequestState, AUTO)
|
PB_BIND(PB_RequestState, PB_RequestState, AUTO)
|
||||||
|
|
||||||
|
|
||||||
|
PB_BIND(PB_PersistentConfiguration, PB_PersistentConfiguration, AUTO)
|
||||||
|
|
||||||
|
|
||||||
|
PB_BIND(PB_MotorCalibration, PB_MotorCalibration, AUTO)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,6 +73,19 @@ typedef struct _PB_ToSmartknob {
|
|||||||
} payload;
|
} payload;
|
||||||
} PB_ToSmartknob;
|
} PB_ToSmartknob;
|
||||||
|
|
||||||
|
typedef struct _PB_MotorCalibration {
|
||||||
|
bool calibrated;
|
||||||
|
float zero_electrical_offset;
|
||||||
|
bool direction_cw;
|
||||||
|
uint32_t pole_pairs;
|
||||||
|
} PB_MotorCalibration;
|
||||||
|
|
||||||
|
typedef struct _PB_PersistentConfiguration {
|
||||||
|
uint32_t version;
|
||||||
|
bool has_motor;
|
||||||
|
PB_MotorCalibration motor;
|
||||||
|
} PB_PersistentConfiguration;
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -86,6 +99,8 @@ extern "C" {
|
|||||||
#define PB_SmartKnobState_init_default {0, 0, false, PB_SmartKnobConfig_init_default}
|
#define PB_SmartKnobState_init_default {0, 0, false, PB_SmartKnobConfig_init_default}
|
||||||
#define PB_SmartKnobConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, "", 0, {0, 0, 0, 0, 0}, 0}
|
#define PB_SmartKnobConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, "", 0, {0, 0, 0, 0, 0}, 0}
|
||||||
#define PB_RequestState_init_default {0}
|
#define PB_RequestState_init_default {0}
|
||||||
|
#define PB_PersistentConfiguration_init_default {0, false, PB_MotorCalibration_init_default}
|
||||||
|
#define PB_MotorCalibration_init_default {0, 0, 0, 0}
|
||||||
#define PB_FromSmartKnob_init_zero {0, 0, {PB_Ack_init_zero}}
|
#define PB_FromSmartKnob_init_zero {0, 0, {PB_Ack_init_zero}}
|
||||||
#define PB_ToSmartknob_init_zero {0, 0, 0, {PB_RequestState_init_zero}}
|
#define PB_ToSmartknob_init_zero {0, 0, 0, {PB_RequestState_init_zero}}
|
||||||
#define PB_Ack_init_zero {0}
|
#define PB_Ack_init_zero {0}
|
||||||
@ -93,6 +108,8 @@ extern "C" {
|
|||||||
#define PB_SmartKnobState_init_zero {0, 0, false, PB_SmartKnobConfig_init_zero}
|
#define PB_SmartKnobState_init_zero {0, 0, false, PB_SmartKnobConfig_init_zero}
|
||||||
#define PB_SmartKnobConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, "", 0, {0, 0, 0, 0, 0}, 0}
|
#define PB_SmartKnobConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, "", 0, {0, 0, 0, 0, 0}, 0}
|
||||||
#define PB_RequestState_init_zero {0}
|
#define PB_RequestState_init_zero {0}
|
||||||
|
#define PB_PersistentConfiguration_init_zero {0, false, PB_MotorCalibration_init_zero}
|
||||||
|
#define PB_MotorCalibration_init_zero {0, 0, 0, 0}
|
||||||
|
|
||||||
/* Field tags (for use in manual encoding/decoding) */
|
/* Field tags (for use in manual encoding/decoding) */
|
||||||
#define PB_Ack_nonce_tag 1
|
#define PB_Ack_nonce_tag 1
|
||||||
@ -120,6 +137,12 @@ extern "C" {
|
|||||||
#define PB_ToSmartknob_nonce_tag 2
|
#define PB_ToSmartknob_nonce_tag 2
|
||||||
#define PB_ToSmartknob_request_state_tag 3
|
#define PB_ToSmartknob_request_state_tag 3
|
||||||
#define PB_ToSmartknob_smartknob_config_tag 4
|
#define PB_ToSmartknob_smartknob_config_tag 4
|
||||||
|
#define PB_MotorCalibration_calibrated_tag 1
|
||||||
|
#define PB_MotorCalibration_zero_electrical_offset_tag 2
|
||||||
|
#define PB_MotorCalibration_direction_cw_tag 3
|
||||||
|
#define PB_MotorCalibration_pole_pairs_tag 4
|
||||||
|
#define PB_PersistentConfiguration_version_tag 1
|
||||||
|
#define PB_PersistentConfiguration_motor_tag 2
|
||||||
|
|
||||||
/* Struct field encoding specification for nanopb */
|
/* Struct field encoding specification for nanopb */
|
||||||
#define PB_FromSmartKnob_FIELDLIST(X, a) \
|
#define PB_FromSmartKnob_FIELDLIST(X, a) \
|
||||||
@ -182,6 +205,21 @@ X(a, STATIC, SINGULAR, FLOAT, snap_point_bias, 12)
|
|||||||
#define PB_RequestState_CALLBACK NULL
|
#define PB_RequestState_CALLBACK NULL
|
||||||
#define PB_RequestState_DEFAULT NULL
|
#define PB_RequestState_DEFAULT NULL
|
||||||
|
|
||||||
|
#define PB_PersistentConfiguration_FIELDLIST(X, a) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, version, 1) \
|
||||||
|
X(a, STATIC, OPTIONAL, MESSAGE, motor, 2)
|
||||||
|
#define PB_PersistentConfiguration_CALLBACK NULL
|
||||||
|
#define PB_PersistentConfiguration_DEFAULT NULL
|
||||||
|
#define PB_PersistentConfiguration_motor_MSGTYPE PB_MotorCalibration
|
||||||
|
|
||||||
|
#define PB_MotorCalibration_FIELDLIST(X, a) \
|
||||||
|
X(a, STATIC, SINGULAR, BOOL, calibrated, 1) \
|
||||||
|
X(a, STATIC, SINGULAR, FLOAT, zero_electrical_offset, 2) \
|
||||||
|
X(a, STATIC, SINGULAR, BOOL, direction_cw, 3) \
|
||||||
|
X(a, STATIC, SINGULAR, UINT32, pole_pairs, 4)
|
||||||
|
#define PB_MotorCalibration_CALLBACK NULL
|
||||||
|
#define PB_MotorCalibration_DEFAULT NULL
|
||||||
|
|
||||||
extern const pb_msgdesc_t PB_FromSmartKnob_msg;
|
extern const pb_msgdesc_t PB_FromSmartKnob_msg;
|
||||||
extern const pb_msgdesc_t PB_ToSmartknob_msg;
|
extern const pb_msgdesc_t PB_ToSmartknob_msg;
|
||||||
extern const pb_msgdesc_t PB_Ack_msg;
|
extern const pb_msgdesc_t PB_Ack_msg;
|
||||||
@ -189,6 +227,8 @@ extern const pb_msgdesc_t PB_Log_msg;
|
|||||||
extern const pb_msgdesc_t PB_SmartKnobState_msg;
|
extern const pb_msgdesc_t PB_SmartKnobState_msg;
|
||||||
extern const pb_msgdesc_t PB_SmartKnobConfig_msg;
|
extern const pb_msgdesc_t PB_SmartKnobConfig_msg;
|
||||||
extern const pb_msgdesc_t PB_RequestState_msg;
|
extern const pb_msgdesc_t PB_RequestState_msg;
|
||||||
|
extern const pb_msgdesc_t PB_PersistentConfiguration_msg;
|
||||||
|
extern const pb_msgdesc_t PB_MotorCalibration_msg;
|
||||||
|
|
||||||
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
||||||
#define PB_FromSmartKnob_fields &PB_FromSmartKnob_msg
|
#define PB_FromSmartKnob_fields &PB_FromSmartKnob_msg
|
||||||
@ -198,11 +238,15 @@ extern const pb_msgdesc_t PB_RequestState_msg;
|
|||||||
#define PB_SmartKnobState_fields &PB_SmartKnobState_msg
|
#define PB_SmartKnobState_fields &PB_SmartKnobState_msg
|
||||||
#define PB_SmartKnobConfig_fields &PB_SmartKnobConfig_msg
|
#define PB_SmartKnobConfig_fields &PB_SmartKnobConfig_msg
|
||||||
#define PB_RequestState_fields &PB_RequestState_msg
|
#define PB_RequestState_fields &PB_RequestState_msg
|
||||||
|
#define PB_PersistentConfiguration_fields &PB_PersistentConfiguration_msg
|
||||||
|
#define PB_MotorCalibration_fields &PB_MotorCalibration_msg
|
||||||
|
|
||||||
/* Maximum encoded size of messages (where known) */
|
/* Maximum encoded size of messages (where known) */
|
||||||
#define PB_Ack_size 6
|
#define PB_Ack_size 6
|
||||||
#define PB_FromSmartKnob_size 264
|
#define PB_FromSmartKnob_size 264
|
||||||
#define PB_Log_size 258
|
#define PB_Log_size 258
|
||||||
|
#define PB_MotorCalibration_size 15
|
||||||
|
#define PB_PersistentConfiguration_size 23
|
||||||
#define PB_RequestState_size 0
|
#define PB_RequestState_size 0
|
||||||
#define PB_SmartKnobConfig_size 173
|
#define PB_SmartKnobConfig_size 173
|
||||||
#define PB_SmartKnobState_size 192
|
#define PB_SmartKnobState_size 192
|
||||||
|
@ -128,8 +128,9 @@ build_flags =
|
|||||||
|
|
||||||
[env:nanofoc]
|
[env:nanofoc]
|
||||||
extends = base_config
|
extends = base_config
|
||||||
platform = espressif32
|
platform = espressif32@6.3.1
|
||||||
board = adafruit_feather_esp32s3
|
board = adafruit_feather_esp32s3
|
||||||
|
board_build.partitions = firmware/partitions-4MB-spiffs.csv
|
||||||
lib_deps =
|
lib_deps =
|
||||||
${base_config.lib_deps}
|
${base_config.lib_deps}
|
||||||
askuric/Simple FOC@^2.3.0
|
askuric/Simple FOC@^2.3.0
|
||||||
|
@ -70,3 +70,14 @@ message SmartKnobConfig {
|
|||||||
|
|
||||||
message RequestState {}
|
message RequestState {}
|
||||||
|
|
||||||
|
message PersistentConfiguration {
|
||||||
|
uint32 version = 1;
|
||||||
|
MotorCalibration motor = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message MotorCalibration {
|
||||||
|
bool calibrated = 1;
|
||||||
|
float zero_electrical_offset = 2;
|
||||||
|
bool direction_cw = 3;
|
||||||
|
uint32 pole_pairs = 4;
|
||||||
|
}
|
||||||
|
@ -15,7 +15,7 @@ _sym_db = _symbol_database.Default()
|
|||||||
import nanopb_pb2 as nanopb__pb2
|
import nanopb_pb2 as nanopb__pb2
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0fsmartknob.proto\x12\x02PB\x1a\x0cnanopb.proto\"\x9a\x01\n\rFromSmartKnob\x12\x1f\n\x10protocol_version\x18\x01 \x01(\rB\x05\x92?\x02\x38\x08\x12\x16\n\x03\x61\x63k\x18\x02 \x01(\x0b\x32\x07.PB.AckH\x00\x12\x16\n\x03log\x18\x03 \x01(\x0b\x32\x07.PB.LogH\x00\x12-\n\x0fsmartknob_state\x18\x04 \x01(\x0b\x32\x12.PB.SmartKnobStateH\x00\x42\t\n\x07payload\"\xa4\x01\n\x0bToSmartknob\x12\x1f\n\x10protocol_version\x18\x01 \x01(\rB\x05\x92?\x02\x38\x08\x12\r\n\x05nonce\x18\x02 \x01(\r\x12)\n\rrequest_state\x18\x03 \x01(\x0b\x32\x10.PB.RequestStateH\x00\x12/\n\x10smartknob_config\x18\x04 \x01(\x0b\x32\x13.PB.SmartKnobConfigH\x00\x42\t\n\x07payload\"\x14\n\x03\x41\x63k\x12\r\n\x05nonce\x18\x01 \x01(\r\"\x1a\n\x03Log\x12\x13\n\x03msg\x18\x01 \x01(\tB\x06\x92?\x03p\xff\x01\"j\n\x0eSmartKnobState\x12\x18\n\x10\x63urrent_position\x18\x01 \x01(\x05\x12\x19\n\x11sub_position_unit\x18\x02 \x01(\x02\x12#\n\x06\x63onfig\x18\x03 \x01(\x0b\x32\x13.PB.SmartKnobConfig\"\xc9\x02\n\x0fSmartKnobConfig\x12\x10\n\x08position\x18\x01 \x01(\x05\x12\x19\n\x11sub_position_unit\x18\x02 \x01(\x02\x12\x1d\n\x0eposition_nonce\x18\x03 \x01(\rB\x05\x92?\x02\x38\x08\x12\x14\n\x0cmin_position\x18\x04 \x01(\x05\x12\x14\n\x0cmax_position\x18\x05 \x01(\x05\x12\x1e\n\x16position_width_radians\x18\x06 \x01(\x02\x12\x1c\n\x14\x64\x65tent_strength_unit\x18\x07 \x01(\x02\x12\x1d\n\x15\x65ndstop_strength_unit\x18\x08 \x01(\x02\x12\x12\n\nsnap_point\x18\t \x01(\x02\x12\x13\n\x04text\x18\n \x01(\tB\x05\x92?\x02p2\x12\x1f\n\x10\x64\x65tent_positions\x18\x0b \x03(\x05\x42\x05\x92?\x02\x10\x05\x12\x17\n\x0fsnap_point_bias\x18\x0c \x01(\x02\"\x0e\n\x0cRequestStateb\x06proto3')
|
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0fsmartknob.proto\x12\x02PB\x1a\x0cnanopb.proto\"\x9a\x01\n\rFromSmartKnob\x12\x1f\n\x10protocol_version\x18\x01 \x01(\rB\x05\x92?\x02\x38\x08\x12\x16\n\x03\x61\x63k\x18\x02 \x01(\x0b\x32\x07.PB.AckH\x00\x12\x16\n\x03log\x18\x03 \x01(\x0b\x32\x07.PB.LogH\x00\x12-\n\x0fsmartknob_state\x18\x04 \x01(\x0b\x32\x12.PB.SmartKnobStateH\x00\x42\t\n\x07payload\"\xa4\x01\n\x0bToSmartknob\x12\x1f\n\x10protocol_version\x18\x01 \x01(\rB\x05\x92?\x02\x38\x08\x12\r\n\x05nonce\x18\x02 \x01(\r\x12)\n\rrequest_state\x18\x03 \x01(\x0b\x32\x10.PB.RequestStateH\x00\x12/\n\x10smartknob_config\x18\x04 \x01(\x0b\x32\x13.PB.SmartKnobConfigH\x00\x42\t\n\x07payload\"\x14\n\x03\x41\x63k\x12\r\n\x05nonce\x18\x01 \x01(\r\"\x1a\n\x03Log\x12\x13\n\x03msg\x18\x01 \x01(\tB\x06\x92?\x03p\xff\x01\"j\n\x0eSmartKnobState\x12\x18\n\x10\x63urrent_position\x18\x01 \x01(\x05\x12\x19\n\x11sub_position_unit\x18\x02 \x01(\x02\x12#\n\x06\x63onfig\x18\x03 \x01(\x0b\x32\x13.PB.SmartKnobConfig\"\xc9\x02\n\x0fSmartKnobConfig\x12\x10\n\x08position\x18\x01 \x01(\x05\x12\x19\n\x11sub_position_unit\x18\x02 \x01(\x02\x12\x1d\n\x0eposition_nonce\x18\x03 \x01(\rB\x05\x92?\x02\x38\x08\x12\x14\n\x0cmin_position\x18\x04 \x01(\x05\x12\x14\n\x0cmax_position\x18\x05 \x01(\x05\x12\x1e\n\x16position_width_radians\x18\x06 \x01(\x02\x12\x1c\n\x14\x64\x65tent_strength_unit\x18\x07 \x01(\x02\x12\x1d\n\x15\x65ndstop_strength_unit\x18\x08 \x01(\x02\x12\x12\n\nsnap_point\x18\t \x01(\x02\x12\x13\n\x04text\x18\n \x01(\tB\x05\x92?\x02p2\x12\x1f\n\x10\x64\x65tent_positions\x18\x0b \x03(\x05\x42\x05\x92?\x02\x10\x05\x12\x17\n\x0fsnap_point_bias\x18\x0c \x01(\x02\"\x0e\n\x0cRequestState\"O\n\x17PersistentConfiguration\x12\x0f\n\x07version\x18\x01 \x01(\r\x12#\n\x05motor\x18\x02 \x01(\x0b\x32\x14.PB.MotorCalibration\"p\n\x10MotorCalibration\x12\x12\n\ncalibrated\x18\x01 \x01(\x08\x12\x1e\n\x16zero_electrical_offset\x18\x02 \x01(\x02\x12\x14\n\x0c\x64irection_cw\x18\x03 \x01(\x08\x12\x12\n\npole_pairs\x18\x04 \x01(\rb\x06proto3')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -26,6 +26,8 @@ _LOG = DESCRIPTOR.message_types_by_name['Log']
|
|||||||
_SMARTKNOBSTATE = DESCRIPTOR.message_types_by_name['SmartKnobState']
|
_SMARTKNOBSTATE = DESCRIPTOR.message_types_by_name['SmartKnobState']
|
||||||
_SMARTKNOBCONFIG = DESCRIPTOR.message_types_by_name['SmartKnobConfig']
|
_SMARTKNOBCONFIG = DESCRIPTOR.message_types_by_name['SmartKnobConfig']
|
||||||
_REQUESTSTATE = DESCRIPTOR.message_types_by_name['RequestState']
|
_REQUESTSTATE = DESCRIPTOR.message_types_by_name['RequestState']
|
||||||
|
_PERSISTENTCONFIGURATION = DESCRIPTOR.message_types_by_name['PersistentConfiguration']
|
||||||
|
_MOTORCALIBRATION = DESCRIPTOR.message_types_by_name['MotorCalibration']
|
||||||
FromSmartKnob = _reflection.GeneratedProtocolMessageType('FromSmartKnob', (_message.Message,), {
|
FromSmartKnob = _reflection.GeneratedProtocolMessageType('FromSmartKnob', (_message.Message,), {
|
||||||
'DESCRIPTOR' : _FROMSMARTKNOB,
|
'DESCRIPTOR' : _FROMSMARTKNOB,
|
||||||
'__module__' : 'smartknob_pb2'
|
'__module__' : 'smartknob_pb2'
|
||||||
@ -75,6 +77,20 @@ RequestState = _reflection.GeneratedProtocolMessageType('RequestState', (_messag
|
|||||||
})
|
})
|
||||||
_sym_db.RegisterMessage(RequestState)
|
_sym_db.RegisterMessage(RequestState)
|
||||||
|
|
||||||
|
PersistentConfiguration = _reflection.GeneratedProtocolMessageType('PersistentConfiguration', (_message.Message,), {
|
||||||
|
'DESCRIPTOR' : _PERSISTENTCONFIGURATION,
|
||||||
|
'__module__' : 'smartknob_pb2'
|
||||||
|
# @@protoc_insertion_point(class_scope:PB.PersistentConfiguration)
|
||||||
|
})
|
||||||
|
_sym_db.RegisterMessage(PersistentConfiguration)
|
||||||
|
|
||||||
|
MotorCalibration = _reflection.GeneratedProtocolMessageType('MotorCalibration', (_message.Message,), {
|
||||||
|
'DESCRIPTOR' : _MOTORCALIBRATION,
|
||||||
|
'__module__' : 'smartknob_pb2'
|
||||||
|
# @@protoc_insertion_point(class_scope:PB.MotorCalibration)
|
||||||
|
})
|
||||||
|
_sym_db.RegisterMessage(MotorCalibration)
|
||||||
|
|
||||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||||
|
|
||||||
DESCRIPTOR._options = None
|
DESCRIPTOR._options = None
|
||||||
@ -104,4 +120,8 @@ if _descriptor._USE_C_DESCRIPTORS == False:
|
|||||||
_SMARTKNOBCONFIG._serialized_end=849
|
_SMARTKNOBCONFIG._serialized_end=849
|
||||||
_REQUESTSTATE._serialized_start=851
|
_REQUESTSTATE._serialized_start=851
|
||||||
_REQUESTSTATE._serialized_end=865
|
_REQUESTSTATE._serialized_end=865
|
||||||
|
_PERSISTENTCONFIGURATION._serialized_start=867
|
||||||
|
_PERSISTENTCONFIGURATION._serialized_end=946
|
||||||
|
_MOTORCALIBRATION._serialized_start=948
|
||||||
|
_MOTORCALIBRATION._serialized_end=1060
|
||||||
# @@protoc_insertion_point(module_scope)
|
# @@protoc_insertion_point(module_scope)
|
||||||
|
Loading…
Reference in New Issue
Block a user