9 Commits

Author SHA1 Message Date
Oleg Kalachev
c3b818c2ae Try using installable Preferences library 2025-11-18 18:19:02 +03:00
Oleg Kalachev
531b3f4d04 Use analogWrite api instead of ledc 2025-11-18 16:54:51 +03:00
Oleg Kalachev
795b248b94 Adapt firmware for non-esp32 boards 2025-11-04 13:47:41 +03:00
Oleg Kalachev
77c4b5fc5b Test build for STM32 2025-11-04 13:42:05 +03:00
Oleg Kalachev
1a017ccb97 Keep only one floating point version of map function
Two variants are redundant
2025-11-02 00:02:28 +03:00
Oleg Kalachev
7170b20d1d Simplify command for command handling 2025-10-21 19:41:10 +03:00
Oleg Kalachev
dc9aed113b Minor code fixes 2025-10-21 19:41:05 +03:00
Oleg Kalachev
08b6123eb7 Fixes to troubleshooting 2025-10-21 19:40:54 +03:00
Oleg Kalachev
1a8b63ee04 Send only mavlink heartbeats until connected 2025-10-21 19:39:17 +03:00
8 changed files with 33 additions and 21 deletions

View File

@@ -29,6 +29,13 @@ jobs:
run: sed -i 's/^#define WIFI_ENABLED 1$/#define WIFI_ENABLED 0/' flix/flix.ino && make
- name: Check c_cpp_properties.json
run: tools/check_c_cpp_properties.py
- name: Build for Black Pill F411CE (STM32)
run: |
arduino-cli config set board_manager.additional_urls https://github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectronics_index.json
arduino-cli core install STMicroelectronics:stm32
arduino-cli board listall STMicroelectronics:stm32
arduino-cli lib install "Preferences"
make BOARD=STMicroelectronics:stm32:GenF4:pnum=BLACKPILL_F411CE
build_macos:
runs-on: macos-latest

View File

@@ -32,6 +32,6 @@ Do the following:
* `mfl` — should rotate front left motor (clockwise).
* `mrl` — should rotate rear left motor (counter-clockwise).
* `mrr` — should rotate rear right motor (clockwise).
* **Calibrate the RC** if you use it. Type `cr` command in Serial Monitor and follow the instructions.
* **Check the RC data** if you use it. Use `rc` command, `Control` should show correct values between -1 and 1, and between 0 and 1 for the throttle.
* **Check the remote control**. Using `rc` command, check the control values reflect your sticks movement. All the controls should change between -1 and 1, and throttle between 0 and 1.
* If using SBUS receiver, **calibrate the RC**. Type `cr` command in Serial Monitor and follow the instructions.
* **Check the IMU output using QGroundControl**. Connect to the drone using QGroundControl on your computer. Go to the *Analyze* tab, *MAVLINK Inspector*. Plot the data from the `SCALED_IMU` message. The gyroscope and accelerometer data should change according to the drone movement.

View File

@@ -74,9 +74,10 @@ void doCommand(String str, bool echo = false) {
// parse command
String command, arg0, arg1;
splitString(str, command, arg0, arg1);
if (command.isEmpty()) return;
// echo command
if (echo && !command.isEmpty()) {
if (echo) {
print("> %s\n", str.c_str());
}
@@ -170,8 +171,6 @@ void doCommand(String str, bool echo = false) {
attitude = Quaternion();
} else if (command == "reboot") {
ESP.restart();
} else if (command == "") {
// do nothing
} else {
print("Invalid command: %s\n", command.c_str());
}

View File

@@ -5,6 +5,7 @@
#include <SPI.h>
#include <FlixPeriph.h>
#include "vector.h"
#include "lpf.h"
#include "util.h"

View File

@@ -12,6 +12,7 @@
#define PERIOD_FAST 0.1
#define MAVLINK_CONTROL_YAW_DEAD_ZONE 0.1f
bool mavlinkConnected = false;
String mavlinkPrintBuffer;
extern float controlTime;
@@ -41,12 +42,14 @@ void sendMavlink() {
mode, MAV_STATE_STANDBY);
sendMessage(&msg);
if (!mavlinkConnected) return; // send only heartbeat until connected
mavlink_msg_extended_sys_state_pack(SYSTEM_ID, MAV_COMP_ID_AUTOPILOT1, &msg,
MAV_VTOL_STATE_UNDEFINED, landed ? MAV_LANDED_STATE_ON_GROUND : MAV_LANDED_STATE_IN_AIR);
sendMessage(&msg);
}
if (t - lastFast >= PERIOD_FAST) {
if (t - lastFast >= PERIOD_FAST && mavlinkConnected) {
lastFast = t;
const float zeroQuat[] = {0, 0, 0, 0};
@@ -80,6 +83,7 @@ void sendMessage(const void *msg) {
void receiveMavlink() {
uint8_t buf[MAVLINK_MAX_PACKET_LEN];
int len = receiveWiFi(buf, MAVLINK_MAX_PACKET_LEN);
if (len) mavlinkConnected = true;
// New packet, parse it
mavlink_message_t msg;

View File

@@ -25,30 +25,32 @@ const int MOTOR_FRONT_LEFT = 3;
void setupMotors() {
print("Setup Motors\n");
// configure pins
#ifdef ESP32
ledcAttach(MOTOR_0_PIN, PWM_FREQUENCY, PWM_RESOLUTION);
ledcAttach(MOTOR_1_PIN, PWM_FREQUENCY, PWM_RESOLUTION);
ledcAttach(MOTOR_2_PIN, PWM_FREQUENCY, PWM_RESOLUTION);
ledcAttach(MOTOR_3_PIN, PWM_FREQUENCY, PWM_RESOLUTION);
#else
analogWriteResolution(PWM_RESOLUTION);
analogWriteFrequency(PWM_FREQUENCY);
#endif
sendMotors();
print("Motors initialized\n");
}
int getDutyCycle(float value) {
value = constrain(value, 0, 1);
float pwm = mapff(value, 0, 1, PWM_MIN, PWM_MAX);
float pwm = mapf(value, 0, 1, PWM_MIN, PWM_MAX);
if (value == 0) pwm = PWM_STOP;
float duty = mapff(pwm, 0, 1000000 / PWM_FREQUENCY, 0, (1 << PWM_RESOLUTION) - 1);
float duty = mapf(pwm, 0, 1000000 / PWM_FREQUENCY, 0, (1 << PWM_RESOLUTION) - 1);
return round(duty);
}
void sendMotors() {
ledcWrite(MOTOR_0_PIN, getDutyCycle(motors[0]));
ledcWrite(MOTOR_1_PIN, getDutyCycle(motors[1]));
ledcWrite(MOTOR_2_PIN, getDutyCycle(motors[2]));
ledcWrite(MOTOR_3_PIN, getDutyCycle(motors[3]));
analogWrite(MOTOR_0_PIN, getDutyCycle(motors[0]));
analogWrite(MOTOR_1_PIN, getDutyCycle(motors[1]));
analogWrite(MOTOR_2_PIN, getDutyCycle(motors[2]));
analogWrite(MOTOR_3_PIN, getDutyCycle(motors[3]));
}
bool motorsActive() {

View File

@@ -8,7 +8,6 @@
extern float channelZero[16];
extern float channelMax[16];
extern float rollChannel, pitchChannel, throttleChannel, yawChannel, armedChannel, modeChannel;
extern float mavlinkControlScale;
Preferences storage;

View File

@@ -6,17 +6,15 @@
#pragma once
#include <math.h>
#ifdef ESP32
#include <soc/soc.h>
#include <soc/rtc_cntl_reg.h>
#endif
const float ONE_G = 9.80665;
extern float t;
float mapf(long x, long in_min, long in_max, float out_min, float out_max) {
return (float)(x - in_min) * (out_max - out_min) / (float)(in_max - in_min) + out_min;
}
float mapff(float x, float in_min, float in_max, float out_min, float out_max) {
float mapf(float x, float in_min, float in_max, float out_min, float out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
@@ -41,7 +39,9 @@ float wrapAngle(float angle) {
// Disable reset on low voltage
void disableBrownOut() {
#ifdef ESP32
REG_CLR_BIT(RTC_CNTL_BROWN_OUT_REG, RTC_CNTL_BROWN_OUT_ENA);
#endif
}
// Trim and split string by spaces