Browse Source

Added working working SBUS and using hardware serial

master
Englebert 2 years ago
parent
commit
3d6e01bcd0
  1. 4
      platformio.ini
  2. BIN
      src/.main.cpp.swp
  3. BIN
      src/.main.h.swp
  4. 71
      src/main.cpp
  5. 10
      src/main.h
  6. 140
      src/sbus.cpp
  7. 77
      src/sbus.h

4
platformio.ini

@ -12,5 +12,5 @@
platform = espressif32
board = esp32dev
framework = arduino
lib_deps =
plerup/EspSoftwareSerial@^6.16.1
lib_deps =
bolderflight/Bolder Flight Systems SBUS@^8.1.4

BIN
src/.main.cpp.swp

BIN
src/.main.h.swp

71
src/main.cpp

@ -44,8 +44,10 @@ void setup() {
initESP_NOW();
// Setting up SBUS
sbus.sbus_type = true; // True: FAST, False: SLOW
sbus.begin();
//// sbus.sbus_type = true; // True: FAST, False: SLOW
//// sbus.begin();
sbus_tx.Begin(); // SBUS object, writing SBUS
// Task Setup
xTaskCreatePinnedToCore(
@ -78,15 +80,17 @@ void setup() {
CPU_1
);
/**
xTaskCreatePinnedToCore(
taskSBUS,
"TaskSBUS", // Name of the process
"TaskSBUS", // Name of the process
8192, // This stack size can be checked & adjusted by reading the Stack Highwater
NULL,
4, // Priority
1, // Priority
NULL,
CPU_1
);
**/
}
@ -95,8 +99,10 @@ void taskSBUS(void *pvParameters) {
for(;;) {
vTaskDelay(1);
if(!sbus.signalNotOK) {
sbus.writePackets();
if(!signalNotOK) {
/// sbus.writePackets();
sbus_tx.data(sbus_data);
sbus_tx.Write();
}
}
}
@ -125,10 +131,13 @@ void taskDisplay(void *pvParameters) {
} else if(counter > 0) {
pulse_ms = 250;
}
/***
char msg[64];
sprintf(msg, "Total Packets: %d Pulse: %d SBUS: %i", counter, pulse_ms, sbus.sbus_packets_sent);
// sprintf(msg, "Total Packets: %d Pulse: %d SBUS: %i", counter, pulse_ms, sbus.sbus_packets_sent);
sprintf(msg, "Total Packets: %d Pulse: %d", counter, pulse_ms);
Serial.println(msg);
***/
last_display = millis();
}
@ -158,11 +167,11 @@ void taskCounter(void *pvParameters) {
counter = counter_raw;
counter_raw = 0;
sbus.sbus_packets_sent = sbus.sbus_packets_sent_raw;
sbus.sbus_packets_sent_raw = 0;
// sbus.sbus_packets_sent = sbus.sbus_packets_sent_raw;
// sbus.sbus_packets_sent_raw = 0;
if(counter == 0) {
sbus.signalNotOK = true;
signalNotOK = true;
}
last_update = millis();
@ -281,11 +290,20 @@ void OnDataRecv(const uint8_t * mac_addr, const uint8_t *incomingData, int len)
memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));
// Serial.println(incomingReadings.throttle);
sbus.rcCommand[THROTTLE] = incomingReadings.throttle;
sbus.rcCommand[YAW] = incomingReadings.yaw;
sbus.rcCommand[PITCH] = incomingReadings.pitch;
sbus.rcCommand[ROLL] = incomingReadings.roll;
sbus_data.failsafe = true;
sbus_data.ch17 = true;
sbus_data.ch18 = false;
//// sbus.rcCommand[THROTTLE] = incomingReadings.throttle;
sbus_data.ch[0] = incomingReadings.throttle;
//// sbus.rcCommand[YAW] = incomingReadings.yaw;
sbus_data.ch[1] = incomingReadings.yaw;
//// sbus.rcCommand[PITCH] = incomingReadings.pitch;
sbus_data.ch[2] = incomingReadings.pitch;
//// sbus.rcCommand[ROLL] = incomingReadings.roll;
sbus_data.ch[3] = incomingReadings.roll;
/**
sbus.rcCommand[AUX1] = incomingReadings.aux[0] ? 2000 : 1000; // 1
sbus.rcCommand[AUX2] = incomingReadings.aux[1] ? 2000 : 1000; // 1
sbus.rcCommand[AUX3] = incomingReadings.aux[2] ? 2000 : 1000; // 1
@ -295,9 +313,19 @@ void OnDataRecv(const uint8_t * mac_addr, const uint8_t *incomingData, int len)
sbus.rcCommand[AUX7] = incomingReadings.aux[6] ? 2000 : 1000; // 1
sbus.rcCommand[AUX8] = incomingReadings.aux[7] ? 2000 : 1000; // 1
sbus.rcCommand[AUX9] = incomingReadings.aux[8] ? 2000 : 1000; // 1
**/
sbus_data.ch[4] = incomingReadings.aux[0] ? 2000 : 1000; // 1
sbus_data.ch[5] = incomingReadings.aux[1] ? 2000 : 1000; // 1
sbus_data.ch[6] = incomingReadings.aux[2] ? 2000 : 1000; // 1
sbus_data.ch[7] = incomingReadings.aux[3] ? 2000 : 1000; // 1
sbus_data.ch[8] = incomingReadings.aux[4] ? 2000 : 1000; // 1
sbus_data.ch[9] = incomingReadings.aux[5] ? 2000 : 1000; // 1
sbus_data.ch[10] = incomingReadings.aux[6] ? 2000 : 1000; // 1
sbus_data.ch[11] = incomingReadings.aux[7] ? 2000 : 1000; // 1
sbus_data.ch[12] = incomingReadings.aux[8] ? 2000 : 1000; // 1
// Set to false to make the sbus sending to FC or others.
sbus.signalNotOK = false;
signalNotOK = false;
counter_raw++;
break;
@ -374,4 +402,13 @@ void initESP_NOW(){
void loop() {
if(!signalNotOK) {
/// sbus.writePackets();
if((uint32_t)(millis() - last_sbus) > 10) {
sbus_tx.data(sbus_data);
sbus_tx.Write();
last_sbus = millis();
}
}
}

10
src/main.h

@ -50,8 +50,18 @@ enum MessageType {
#define DEFAULT_CHANNEL 1
#define EEPROM_SIZE 7 // define the number of bytes you want to access
/* SBUS data */
bfs::SbusData sbus_data;
bfs::SbusTx sbus_tx(&Serial2, 16, 17, true);
/***
SbusTx(HardwareSerial *bus, const int8_t rxpin, const int8_t txpin,
const bool inv) : uart_(bus), inv_(inv), rxpin_(rxpin), txpin_(txpin)
****/
bool signalNotOK = false;
esp_now_peer_info_t slave;
int channel = 1;
uint32_t last_sbus = 0;
bool sync_mode = false;
struct_data incomingReadings;
struct_pairing pairingData;

140
src/sbus.cpp

@ -1,140 +0,0 @@
// REFERENCES:
// https://www.circuitbasics.com/basics-uart-communication/
// https://www.analog.com/en/analog-dialogue/articles/uart-a-hardware-communication-protocol.html
// https://github.com/uzh-rpg/rpg_quadrotor_control/wiki/SBUS-Protocol
// https://github.com/plerup/espsoftwareserial/blob/main/src/SoftwareSerial.cpp
// https://lucidar.me/en/serialib/most-used-baud-rates-table/
// SBUS data structure
#define RC_CHANS 18
#define RC_CHANNEL_MIN 990
#define RC_CHANNEL_MAX 2010
#include "sbus.h"
uint rcChannels[SBUS_CHANNEL_NUMBER];
uint32_t sbusTime = 0;
SoftwareSerial swSer1;
SBUS::SBUS(void) {
}
void SBUS::begin(void) {
pinMode(SBUS_PORT, OUTPUT);
// ON it first as IDLE
//// GPOS = (1 << SBUS_PORT);
GPIO.out_w1ts = (1 << SBUS_PORT);
// swSer1.begin(200000, SWSERIAL_8E2, SBUS_PORT, SBUS_PORT, false, 264);
// swSer1.begin(100000, SWSERIAL_8E2, SBUS_PORT, SBUS_PORT);
// Default to SBUS FAST protocol
/****
if(sbus_type) {
swSer1.begin(200000, SWSERIAL_8E2, SBUS_PORT, SBUS_PORT);
} else {
swSer1.begin(100000, SWSERIAL_8E2, SBUS_PORT, SBUS_PORT);
}
****/
swSer1.begin(100000, SWSERIAL_8E2, SBUS_PORT, SBUS_PORT);
swSer1.enableTx(true);
// swSer1.enableIntTx(true);
// Initialize to 1000
for(uint8_t i = 0; i < SBUS_CHANNEL_NUMBER; i++) {
rcCommand[i] = 1000;
}
}
void SBUS::run(void) {
}
uint32_t last_profile = 0;
uint32_t total_high = 0;
uint32_t total_low = 0;
// Sending SBUS packets
void SBUS::writePackets(void) {
if(signalNotOK) {
rcCommand[2] = 900;
rcCommand[3] = 900;
rcCommand[1] = 900;
rcCommand[0] = 900;
}
if((uint32_t)millis() - last_sent > SBUS_UPDATE_RATE) {
sbusPreparePacket(rcCommand, signalNotOK, false);
swSer1.write(sbusPacket, SBUS_PACKET_LENGTH);
sbus_packets_sent_raw++;
last_sent = millis();
}
// DEBUG ONLY
// if((uint32_t)(millis() - last_profile) > 1000) {
// Serial.printf("Cmd: %d Signal: %d Sent: %d NRF: %d\r\n", rcCommand[2], signalNotOK, sbus_packets_sent, nrf_packets_received);
// last_profile = millis();
// }
}
// Delay CPU Cycles
void SBUS::delay_cycles(uint16_t cpucycles) {
uint32_t cpucycle_start = ESP.getCycleCount();
while((uint32_t)(ESP.getCycleCount() - cpucycle_start) < cpucycles) {}
}
// Preparing SBUS packets
void SBUS::sbusPreparePacket(uint16_t channels[], bool isSignalLoss, bool isFailsafe){
static int output[SBUS_CHANNEL_NUMBER] = {0};
/*
* Map 1000-2000 with middle at 1500 chanel values to
* 173-1811 with middle at 992 S.BUS protocol requires
*/
for(uint8_t i = 0; i < SBUS_CHANNEL_NUMBER; i++) {
output[i] = map(channels[i], RC_CHANNEL_MIN, RC_CHANNEL_MAX, SBUS_MIN_OFFSET, SBUS_MAX_OFFSET);
}
uint8_t stateByte = 0x00;
if (isSignalLoss) {
stateByte |= SBUS_STATE_SIGNALLOSS;
}
if (isFailsafe) {
stateByte |= SBUS_STATE_FAILSAFE;
}
sbusPacket[0] = SBUS_FRAME_HEADER; //Header
sbusPacket[1] = (uint8_t) (output[0] & 0x07FF);
sbusPacket[2] = (uint8_t) ((output[0] & 0x07FF)>>8 | (output[1] & 0x07FF)<<3);
sbusPacket[3] = (uint8_t) ((output[1] & 0x07FF)>>5 | (output[2] & 0x07FF)<<6);
sbusPacket[4] = (uint8_t) ((output[2] & 0x07FF)>>2);
sbusPacket[5] = (uint8_t) ((output[2] & 0x07FF)>>10 | (output[3] & 0x07FF)<<1);
sbusPacket[6] = (uint8_t) ((output[3] & 0x07FF)>>7 | (output[4] & 0x07FF)<<4);
sbusPacket[7] = (uint8_t) ((output[4] & 0x07FF)>>4 | (output[5] & 0x07FF)<<7);
sbusPacket[8] = (uint8_t) ((output[5] & 0x07FF)>>1);
sbusPacket[9] = (uint8_t) ((output[5] & 0x07FF)>>9 | (output[6] & 0x07FF)<<2);
sbusPacket[10] = (uint8_t) ((output[6] & 0x07FF)>>6 | (output[7] & 0x07FF)<<5);
sbusPacket[11] = (uint8_t) ((output[7] & 0x07FF)>>3);
sbusPacket[12] = (uint8_t) ((output[8] & 0x07FF));
sbusPacket[13] = (uint8_t) ((output[8] & 0x07FF)>>8 | (output[9] & 0x07FF)<<3);
sbusPacket[14] = (uint8_t) ((output[9] & 0x07FF)>>5 | (output[10] & 0x07FF)<<6);
sbusPacket[15] = (uint8_t) ((output[10] & 0x07FF)>>2);
sbusPacket[16] = (uint8_t) ((output[10] & 0x07FF)>>10 | (output[11] & 0x07FF)<<1);
sbusPacket[17] = (uint8_t) ((output[11] & 0x07FF)>>7 | (output[12] & 0x07FF)<<4);
sbusPacket[18] = (uint8_t) ((output[12] & 0x07FF)>>4 | (output[13] & 0x07FF)<<7);
sbusPacket[19] = (uint8_t) ((output[13] & 0x07FF)>>1);
sbusPacket[20] = (uint8_t) ((output[13] & 0x07FF)>>9 | (output[14] & 0x07FF)<<2);
sbusPacket[21] = (uint8_t) ((output[14] & 0x07FF)>>6 | (output[15] & 0x07FF)<<5);
sbusPacket[22] = (uint8_t) ((output[15] & 0x07FF)>>3);
sbusPacket[23] = stateByte; //Flags byte
sbusPacket[24] = SBUS_FRAME_FOOTER; //Footer
}
SBUS sbus;

77
src/sbus.h

@ -1,77 +0,0 @@
#ifndef SBUS_H_
#define SBUS_H_
// #define SBUS_MIN_OFFSET 173
// #define SBUS_MID_OFFSET 992
// #define SBUS_MAX_OFFSET 1811
// #define SBUS_CHANNEL_NUMBER 16
// #define SBUS_PACKET_LENGTH 25
// #define SBUS_FRAME_HEADER 0x0f
// #define SBUS_FRAME_FOOTER 0x00
// #define SBUS_FRAME_FOOTER_V2 0x04
// #define SBUS_STATE_FAILSAFE 0x08
// #define SBUS_STATE_SIGNALLOSS 0x04
// #define SBUS_UPDATE_RATE 15 // ms
// #define SBUS_PORT 16 // Trigger pulse from the port
// FAST SBUS TIMING (Theoritically 50% timing)
#define SBUS_MIN_OFFSET 173
#define SBUS_MID_OFFSET 992
#define SBUS_MAX_OFFSET 1811
#define SBUS_CHANNEL_NUMBER 16
#define SBUS_PACKET_LENGTH 25
#define SBUS_FRAME_HEADER 0x0f
#define SBUS_FRAME_FOOTER 0x00
#define SBUS_FRAME_FOOTER_V2 0x04
#define SBUS_STATE_FAILSAFE 0x08
#define SBUS_STATE_SIGNALLOSS 0x04
#define SBUS_UPDATE_RATE 6 // ms
#define SBUS_PORT 16 // Trigger pulse from the port
// Enumerators - User Defined
enum rc {
ROLL,
PITCH,
THROTTLE,
YAW,
AUX1,
AUX2,
AUX3,
AUX4,
AUX5,
AUX6,
AUX7,
AUX8,
AUX9
};
#include <Arduino.h>
#include <SoftwareSerial.h>
class SBUS {
public:
bool sbus_type = false;
bool signalNotOK = true;
bool invert;
uint16_t rcCommand[18]; // Signal to ESC
uint8_t sbusPacket[SBUS_PACKET_LENGTH];
uint32_t last_sent = 0;
int16_t sbus_packets_sent_raw = 0;
int16_t sbus_packets_sent = 0;
SBUS(void);
void begin(void);
void run(void);
void sbusPreparePacket(uint16_t channels[], bool isSignalLoss, bool isFailsafe);
void writePackets(void);
void delay_cycles(uint16_t cpucycles);
private:
uint32_t last_wifi_check, wifi_check_duration;
};
extern SBUS sbus;
#endif
Loading…
Cancel
Save