Browse Source

Initial Version

master
Englebert 1 year ago
commit
395dedf08e
  1. 83
      README.md
  2. 39
      include/README
  3. 46
      lib/README
  4. 15
      platformio.ini
  5. BIN
      src/.main.cpp.swp
  6. BIN
      src/.main.h.swp
  7. 225
      src/i2c_protocols.h
  8. 1063
      src/main.cpp
  9. 256
      src/main.h
  10. 11
      test/README

83
README.md

@ -0,0 +1,83 @@
+-----------------------+
| O | USB | O |
| ------- |
[ OLED VCC ] 3V3 | [ ] [ ] | VIN [ 5V FROM RPi ]
[ Ground From Pi ] GND | [ ] [ ] | GND [ GROUND FROM RPi ]
[ ] Touch3 / HSPI_CS0 / ADC2_3 / GPIO15 | [ ] [ ] | GPIO13 / ADC2_4 / HSPI_ID / Touch4 [ BUTTON8 ]
[ ] CS / Touch2 / HSPI_WP / ADC2_2 / GPIO2 | [ ] [ ] | GPIO12 / ADC2_5 / HSPI_Q / Touch5 [ BUTTON7 ]
[ BUTTON9 ] Touch0 / HSPI_HD / ADC2_0 / GPIO4 | [ ] [ ] | GPIO14 / ADC2_6 / HSPI_CLK / Touch6 [ BUTTON6 ]
[ I2C2_SDA ] U2_RXD / GPIO16 | [ ] [ ] | GPIO27 / ADC2_7 / Touch7 [ BUTTON5 ]
[ I2C2_SCL ] U2_TXD / GPIO17 | [ ] [ ] | GPIO26 / ADC2_9 / DAC2 [ BUTTON4 ]
[ BUTTON10 ] V_SPI_CS0 / GPIO5 | [ ] ___________ [ ] | GPIO25 / ADC2_8 / DAC1 [ BUTTON3 ]
[ BUTTON1 ] SCK / V_SPI_CLK / GPIO18 | [ ] | | [ ] | GPIO33 / ADC1_5 / Touch8 / XTAL32 [ A_SENSE ]
[ BUTTON2 ] U0_CTS / MSIO / V_SPI_Q / GPIO19 | [ ] | | [ ] | GPIO32 / ADC1_4 / Touch9 / XTAL32 [ V_SENSE ]
[ SDA to Pi ] SDA / V_SPI_HD / GPIO21 | [ ] | | [ ] | GPIO35 / ADC1_7 [ ROLL ]
[ ] CLK2 / U0_RXD / GPIO3 | [ ] | | [ ] | GPIO34 / ADC1_6 [ PITCH ]
[ ] CLK3 / U0_TXD / GPIO1 | [ ] | | [ ] | GPIO39 / ADC1_3 / SensVN [ YAW ]
[ SCL to Pi ] SCL / U0_RTS / V_SPI_WP / GPIO22 | [ ] | | [ ] | GPIO36 / ADC1_0 / SensVP [ THROTTLE ]
[ ] MOSI / V_SPI_WP / GPIO23 | [ ] |___________| [ ] | EN
| |
| | | ____ ____ | |
| | | | | | | | |
| |__|__| |__| |__| |
| O O |
+-----------------------+
Power Pins
----------
VIN - VIN pin can be used to directly supply the ESP32 and its peripherals, if you have a regulated 5V voltage source.
3V3 - 3.3V pin is the output of an on-board voltage regulator. This pin can be used to supply power to external components.
GND - Ground pin(s)
GPIO Pins
---------
ESP32 development board has 25 GPIO pins which can be assigned to various functions programmatically.
Each digital enabled GPIO can be configured to internal pull-up or pull-down, or set to high impedance.
When configured as an input, it can also be set to edge-trigger or level-trigger to generate CPU interrupts.
ADC Channels
------------
The board integrates 12-bit SAR ADCs and supports measurements on 15 channels (analog enabled pins).
Some of these pins can be used to build a programmable gain amplifier which is used for the measurement of
small analog signals. The ESP32 is also designed to measure the voltages while operating in the sleep mode.
DAC Channels
------------
he board features two 8-bit DAC channels to convert digital signals into true analog voltages. This dual DAC
can drive other circuits.
Touch Pads
----------
The board offers 9 capacitive sensing GPIOs which detect capacitive variations introduced by the GPIO’s direct
contact or close proximity with a finger or other objects.
UART Pins
---------
ESP32 development board has 2 UART interfaces, i.e. UART0 and UART2, which provide asynchronous communication
(RS232 and RS485) and IrDA support, and communicate at up to 5 Mbps. UART provides hardware management of the
CTS and RTS signals and software flow control (XON and XOFF) as well.
SPI Pins
--------
SPI Pins ESP32 features three SPIs (SPI, HSPI and VSPI) in slave and master modes. These SPIs also support the
following general-purpose SPI features:
- 4 timing modes of the SPI format transfer
- Up to 80 MHz and the divided clocks of 80 MHz
- Up to 64-Byte FIFO
- All SPIs can also be used to connect to the external Flash/SRAM and LCD.
PWM Pins
--------
The board has 25 channels (Nearly All GPIO pins) of PWM pins controlled by Pulse Width Modulation (PWM) controller.
The PWM output can be used for driving digital motors and LEDs. The controller consists of PWM timers and the PWM
operator. Each timer provides timing in synchronous or independent form, and each PWM operator generates the waveform
for one PWM channel.
EN Pin
------
Used to enable ESP32. The chip is enabled when pulled HIGH. When pulled LOW the chip works at minimum power.

39
include/README

@ -0,0 +1,39 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

46
lib/README

@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file.
The source code of each library should be placed in a an own separate directory
("lib/your_library_name/[here are source files]").
For example, see a structure of the following two libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

15
platformio.ini

@ -0,0 +1,15 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
lib_deps = thingpulse/ESP8266 and ESP32 OLED driver for SSD1306 displays@^4.4.0

BIN
src/.main.cpp.swp

BIN
src/.main.h.swp

225
src/i2c_protocols.h

@ -0,0 +1,225 @@
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef unsigned int u32;
typedef unsigned short u16;
typedef unsigned char u8;
#ifdef __cplusplus
}
#endif
// Protocol is:
// 1. * Master sends a command to slave (2...N bytes, depending on command type). First byte of all commands is the command start flag;
// 2. * Slave responds with the right answer based on the command (1...N bytes, depending on command response type);
// 3. * Repeat the steps above;
// That means: slave device (Ruby extension device) just waits on I2C for commands from master (Ruby main controller) and responds to those commands as needed.
// Note!!! All commands and responses have 1 extra byte at the end as the CRC
// Use the example function at the end of file to compute the CRC
// Note!!! Always check the CRC value when you get something. Ignore the commands with bad CRC. There can always be noise or bad I2C devices on the I2C bus.
#define I2C_DEVICE_DEFAULT_ADDRESS 0x60
#define I2C_DEVICE_MIN_ADDRESS_RANGE 0x60
#define I2C_DEVICE_MAX_ADDRESS_RANGE 0x6F
// Note: the address [I2C_DEVICE_MAX_ADDRESS_RANGE-2] is used by the Ruby Pico Extender. If you use one, your plugin should use a different address.
#define I2C_PROTOCOL_STRING_LENGTH 24
// Capabilities flags supported by the slave Ruby device; these capabilities will be queried by the Ruby controller and will be reported back to Ruby controller using the I2C interface;
#define I2C_CAPABILITY_FLAG_SPI ((u16)(((u16)0x01)<<1)) // Set if the slave device does support SPI communication with the Ruby controller (if not, only I2C is used)
#define I2C_CAPABILITY_FLAG_BUTTONS ((u16)(((u16)0x01)<<2)) // Set if the slave device has buttons (for UI navigation in Ruby);
#define I2C_CAPABILITY_FLAG_ROTARY ((u16)(((u16)0x01)<<3)) // Set if the slave device has rotary encoder (for UI navigation/Camera control);
#define I2C_CAPABILITY_FLAG_ROTARY2 ((u16)(((u16)0x01)<<4)) // Set if the slave device has the secondary rotary encoder (for UI navigation/Camera control);
#define I2C_CAPABILITY_FLAG_LEDS ((u16)(((u16)0x01)<<5)) // Set if the slave device has LEDs to be controlled by the Ruby controller;
#define I2C_CAPABILITY_FLAG_RC_INPUT ((u16)(((u16)0x01)<<6)) // Set if the slave device has RC input hardware;
#define I2C_CAPABILITY_FLAG_RC_OUTPUT ((u16)(((u16)0x01)<<7)) // Set if the slave device should output RC frames to the FC;
#define I2C_CAPABILITY_FLAG_FLIGHT_CONTROL ((u16)(((u16)0x01)<<8)) // Set if the slave device wants to send flight commands to the vehicle;
#define I2C_CAPABILITY_FLAG_CAMERA_CONTROL ((u16)(((u16)0x01)<<9)) // Set if the slave device wants to send camera commands (brightness, contrast, etc);
#define I2C_CAPABILITY_FLAG_SOUNDS ((u16)(((u16)0x01)<<10)) // Set if the slave device can play sounds (alarms);
#define I2C_COMMAND_START_FLAG 0xFF
#define I2C_COMMAND_ID_GET_FLAGS 0x01
// Get flags: master asks the slave for the capabilities it supports;
// Master sends: 1 byte: command id (I2C_COMMAND_ID_GET_FLAGS)
// Slave responds: 2 bytes: capabilities (flags as OR-ed bits) supported by the I2C device;
#define I2C_COMMAND_ID_GET_VERSION 0x02
// Get flags: master asks the slave for the version;
// Master sends: 1 byte: command id (I2C_COMMAND_ID_GET_VERSION);
// Slave responds: 1 byte: version of the software on the I2C slave device;
#define I2C_COMMAND_ID_GET_NAME 0x03
// Get name: master asks slave for the device name, to be used in the user interface;
// Master sends: 1 byte: command id;
// Slave responds: I2C_PROTOCOL_STRING_LENGTH bytes: null terminated string, padded with 0 up to I2C_PROTOCOL_STRING_LENGTH bytes;
#define I2C_COMMAND_ID_SET_ADDRESS 0x04
// Set address: master asks slave to set it's address to a custom one, to avoid conflicts
// Master sends: 2 bytes: command id and the new I2C address to be used by slave device;
// Slave responds: 1 byte: 0 - ok, 1 - error
#define I2C_COMMAND_ID_GET_BUTTONS_EVENTS 0x10
// Get buttons: master asks slave if any buttons where pressed;
// Master sends: 1 byte: command id;
// Slave responds: 4 bytes:
// first 2 bytes: each bit represents 1 if a button was pressed, for a possible of 16 buttons on the device;
// last 2 bytes: each bit represents 1 if a button was long pressed, for a possible of 16 buttons on the device;
// bit 0 - Menu/Ok button
// bit 1 - Cancel button
// bit 2 - Plus button
// bit 3 - Minus button
// bit 4 - QA1 button
// bit 5 - QA2 button
// bit 6 - QA3 button
// bit 7 - Action Plus button
// bit 8 - Action Minus button
// bit 9... - future use
#define I2C_COMMAND_ID_GET_ROTARY_EVENTS 0x11
#define I2C_COMMAND_ID_GET_ROTARY_EVENTS2 0x12
// Get rotary encoder events (for main and secondary rotary encoders, if present);
// Master asks slave if any rotary encoder events (first or secondary rotary encoder) took place.
// Master sends: 1 byte: command id;
// Slave responds: 1 byte: each bit represents:
// bit 0: rotary encoder was pressed;
// bit 1: rotary encoder was long pressed;
// bit 2: rotary encoder was rotated CCW;
// bit 3: rotary encoder was rotated CW;
// bit 4: rotary encoder was rotated fast CCW;
// bit 5: rotary encoder was rotated fast CW;
#define I2C_COMMAND_ID_SET_RC_INPUT_FLAGS 0x20
#define I2C_COMMAND_RC_FLAG_SBUS 1
#define I2C_COMMAND_RC_FLAG_IBUS (1<<1)
#define I2C_COMMAND_RC_FLAG_PPM (1<<2)
#define I2C_COMMAND_RC_FLAG_INVERT_UART (1<<4)
// Set RC Input flags: master tells the slave what RC protocol to read and if the RC input UART should be inverted or not (SBUS should be inverted).
// Master sends: 2 bytes: command id and the RC input flags:
// bit 0-4: RC protocol: 1 - parse SBUS RC input; 2 - parse IBUS RC input; 4 - parse PPM RC input;
// bit 4: 0 - non inverted UART, 1 - invert UART;
// Slave responds: 1 byte: 0 - ok, 1 - error
#define I2C_COMMAND_ID_RC_GET_CHANNELS 0x21
// Gets the current RC channels values from the slave device;
// Master sends: 1 byte: command id;
// Slave responds: 26 bytes: 1 byte flags, 1 byte frame number, 24 bytes for RC channels values (16 channels, 12 bits per channel, for 0...4095 posible values).
// byte 0: flags: bit 0 is set if RC input failsafe event occured on the slave device.
// byte 1: frame number: monotonically increasing on each received RC frame
// byte 1-16 - LSBits (8 bits) of each channel, from ch 1 to ch 16;
// byte 17-24 - MSBits (4 bits) of each channel, from ch 1 to ch 16;
// Unused channels should be set to zero.
#define I2C_COMMAND_ID_SET_RC_OUTPUT_FLAGS 0x30
// Set RC Output flags: master tells the slave what RC protocol to generate and if the RC output UART should be inverted or not (SBUS should be inverted).
// Master sends: 2 bytes: command id and the RC output flags (same bits as RC input flags):
// bit 0-4: RC protocol: 1 - SBUS RC output; 2 - IBUS RC output; 4 - PPM RC output;
// bit 4: 0 - non inverted UART, 1 - invert UART;
// Slave responds: 1 byte: 0 - ok, 1 - error
#define I2C_COMMAND_ID_RC_SET_CHANNELS 0x31
// Sets the current RC channels values to the slave device;
// Master sends: 26 bytes: 1 byte command id, 1 byte flags, 24 bytes: RC channels values (16 channels, 12 bits per channel, for 0...4095 posible values).
// byte 0: command id (this one);
// byte 1: flags: bit 0: set if failsafe should be signaled by the slave device; not set otherways;
// byte 2-17 - LSBits (8 bits) of each channel, from ch 1 to ch 16;
// byte 18-25 - MSBits (4 bits) of each channel, from ch 1 to ch 16;
// Unused channels should be set to zero.
#define I2C_COMMAND_ID_FLIGHT_CTRL_QUERY_ARM 0x40
// Ask the slave device if the vehicle should receive the arm or disarm command
// Master sends: 1 byte: command id;
// Slave responds: 1 byte:
// bit 0: 0 - no change; 1 - has new arm state
// bit 1: 0 - disarm; 1 - arm
#define I2C_COMMAND_ID_FLIGHT_CTRL_QUERY_MODE 0x41
// Ask the slave device if the vehicle should receive a new flight mode
// Master sends: 1 byte: command id;
// Slave responds: 1 byte:
// bit 0: 0 - no change; 1 - has new flight mode;
// bit 1..7: new flight mode as defined by ArduPilot;
#define I2C_COMMAND_ID_CAMERA_CTRL_QUERY 0x50
// Ask the slave device if they have any pending camera params changes (or wants to change something);
// Master sends: 1 byte: command id;
// Slave responds: 1 byte:
// bit 0: 0 - no change; 1 - wants to do some changes
#define I2C_COMMAND_ID_CAMERA_CTRL_GET_PARAMS 0x51
// Ask the slave device for the new camera params;
// Master sends: 1 byte: command id;
// Slave responds: 4 bytes:
// byte 0: brightness (0..100)
// byte 1: contrast (0..100)
// byte 2: saturation (0..100)
// byte 3: sharpness (0..100)
#define I2C_COMMAND_ID_VIDEO_GET_QUALITY 0x55
// Ask the slave device if they want to change the video quality
// Master sends: 1 byte: command id;
// Slave responds: 1 byte:
// bit 0: 0 - no (video quality is auto, decided by Ruby), 0-100 sets a custom video quality (0=lowest quality)
#define I2C_COMMAND_ID_PLAY_SOUND_ALARM 0x60
// Ask the slave to play a particular sound
// Master sends: 2 bytes: command id; sound id:
// 1 - battery alarm;
// 2 - arm alarm;
// 3 - disarm alarm;
// Slave responds: 1 byte:
// bit 0: 0 - failed; 1 - succeeded;
// CRC table used for CRC calculations
const u8 s_crc_i2c_table[256] = {
0x00,0x31,0x62,0x53,0xC4,0xF5,0xA6,0x97,0xB9,0x88,0xDB,0xEA,0x7D,0x4C,0x1F,0x2E,
0x43,0x72,0x21,0x10,0x87,0xB6,0xE5,0xD4,0xFA,0xCB,0x98,0xA9,0x3E,0x0F,0x5C,0x6D,
0x86,0xB7,0xE4,0xD5,0x42,0x73,0x20,0x11,0x3F,0x0E,0x5D,0x6C,0xFB,0xCA,0x99,0xA8,
0xC5,0xF4,0xA7,0x96,0x01,0x30,0x63,0x52,0x7C,0x4D,0x1E,0x2F,0xB8,0x89,0xDA,0xEB,
0x3D,0x0C,0x5F,0x6E,0xF9,0xC8,0x9B,0xAA,0x84,0xB5,0xE6,0xD7,0x40,0x71,0x22,0x13,
0x7E,0x4F,0x1C,0x2D,0xBA,0x8B,0xD8,0xE9,0xC7,0xF6,0xA5,0x94,0x03,0x32,0x61,0x50,
0xBB,0x8A,0xD9,0xE8,0x7F,0x4E,0x1D,0x2C,0x02,0x33,0x60,0x51,0xC6,0xF7,0xA4,0x95,
0xF8,0xC9,0x9A,0xAB,0x3C,0x0D,0x5E,0x6F,0x41,0x70,0x23,0x12,0x85,0xB4,0xE7,0xD6,
0x7A,0x4B,0x18,0x29,0xBE,0x8F,0xDC,0xED,0xC3,0xF2,0xA1,0x90,0x07,0x36,0x65,0x54,
0x39,0x08,0x5B,0x6A,0xFD,0xCC,0x9F,0xAE,0x80,0xB1,0xE2,0xD3,0x44,0x75,0x26,0x17,
0xFC,0xCD,0x9E,0xAF,0x38,0x09,0x5A,0x6B,0x45,0x74,0x27,0x16,0x81,0xB0,0xE3,0xD2,
0xBF,0x8E,0xDD,0xEC,0x7B,0x4A,0x19,0x28,0x06,0x37,0x64,0x55,0xC2,0xF3,0xA0,0x91,
0x47,0x76,0x25,0x14,0x83,0xB2,0xE1,0xD0,0xFE,0xCF,0x9C,0xAD,0x3A,0x0B,0x58,0x69,
0x04,0x35,0x66,0x57,0xC0,0xF1,0xA2,0x93,0xBD,0x8C,0xDF,0xEE,0x79,0x48,0x1B,0x2A,
0xC1,0xF0,0xA3,0x92,0x05,0x34,0x67,0x56,0x78,0x49,0x1A,0x2B,0xBC,0x8D,0xDE,0xEF,
0x82,0xB3,0xE0,0xD1,0x46,0x77,0x24,0x15,0x3B,0x0A,0x59,0x68,0xFF,0xCE,0x9D,0xAC };
// CRC-8 function:
/*
u8 calculate_i2c_crc(u8* pData, int iLength)
{
u8 uCrc = 0xFF;
if ( NULL == pData || iLength <= 0 )
return uCrc;
for ( int i = 0; i < iLength; i++)
uCrc = s_crc_i2c_table[pData[i] ^ uCrc];
return uCrc;
}
*/

1063
src/main.cpp
File diff suppressed because it is too large
View File

256
src/main.h

@ -0,0 +1,256 @@
#ifndef MAIN_H
#define MAIN_H
// CPU NAMES
#define CPU_1 1
#define CPU_0 0
// PINS
#define LED_INDICATOR 2 // Default LED light
#define BUTTON_SYNC 0 // Default Push Button
// Mechanical Keyboard Toggle Switches
#define BUTTON1 18
#define BUTTON2 19
#define BUTTON3 25
#define BUTTON4 26
#define BUTTON5 27
#define BUTTON6 14
#define BUTTON7 12
#define BUTTON8 13
#define BUTTON9 4
#define BUTTON10 5
// Gimbal
#define THROTTLE_PIN 36
#define YAW_PIN 39
#define PITCH_PIN 34
#define ROLL_PIN 35
#define RC_DEADBAND 5
// Voltage and Current Sense
#define V_SENSE_PIN 32
#define A_SENSE_PIN 33
// OLED PIN
#define OLED_SDA 16
#define OLED_SCL 17
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// VERSION
#define VERSION_MAJOR 0
#define VERSION_MINOR 0
#define VERSION_BUILD 1
#include <Arduino.h>
// #include <EEPROM.h>
// #include "esp_wifi.h"
// #include <esp_now.h>
// #include <WiFi.h>
// #include "sbus.h"
#include <Wire.h>
#include <dummy.h>
#include "i2c_protocols.h"
#include "SSD1306Wire.h" // legacy include: `#include "SSD1306.h"`
typedef struct struct_data {
uint8_t message_type;
uint16_t throttle;
uint16_t yaw;
uint16_t roll;
uint16_t pitch;
uint16_t aux;
// bool aux[9];
// bool rubybutton[9];
uint16_t rubybutton;
} struct_data;
typedef struct sbus_data {
bool failsafe;
bool ch17;
bool ch18;
uint16_t ch[16];
} struct_sbus;
typedef struct struct_pairing {
uint8_t message_type;
uint8_t channel;
} struct_pairing;
enum PairingStatus {
NOT_PAIRED,
PAIR_REQUEST,
PAIR_REQUESTED,
PAIR_PAIRED
};
enum MessageType {
PAIRING,
DATA,
COMMAND
};
enum ToggleButtonsName {
TOGGLE_A,
TOGGLE_B,
TOGGLE_C,
TOGGLE_D,
TOGGLE_E,
TOGGLE_F
};
enum MedianType {
VOLTAGE_POOL,
AMPERE_POOL,
THROTTLE_POOL,
YAW_POOL,
PITCH_POOL,
ROLL_POOL
};
// For Ground Station Pi via I2C
#define MAX_BUFFER_SIZE 1024
#define I2C_SCL 22
#define I2C_SDA 21
#define I2C_SLAVE_ADDR 0x60
#define BUTTON_MENU 13
#define BUTTON_BACK 12
#define BUTTON_UP 14
#define BUTTON_DOWN 27
bool show_once = false;
bool header_detected = false;
uint8_t i2c_received[MAX_BUFFER_SIZE];
uint8_t i2c_send[MAX_BUFFER_SIZE];
uint16_t i2c_received_length = 0;
uint16_t i2c_send_length = 0;
uint8_t i2c_received_max = 0;
uint8_t frame_count = 0;
uint8_t s_uRCChannelsOut[24];
uint16_t s_iI2CLastCommandReadPosition = 0;
uint16_t s_iI2CLastCommandExpectedLength = 0;
uint8_t s_uI2CLastCommandBuff[MAX_BUFFER_SIZE];
uint8_t s_uI2CLastResponseBuff[MAX_BUFFER_SIZE];
int16_t s_iI2CLastResponseSentPosition = -1;
uint16_t s_iI2CLastResponseLength = 0;
bool rubybutton[16];
uint32_t rubybutton_last[16];
uint16_t rubybutton_delay = 100;
#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, false);
/***
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;
bool i2c_status = false;
uint16_t i2c_counter = 0;
uint16_t i2c_counter_raw = 0;
uint32_t last_sent = 0;
bool sync_mode = false;
struct_data incomingReadings;
struct_pairing pairingData;
struct_sbus sbusData;
/// uint8_t broadcast_address[] = { 0x78, 0x21, 0x84, 0x8d, 0xd9, 0x38 };
uint8_t broadcast_address[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
uint8_t allow_address[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
uint8_t frame_count_raw = 0;
int16_t counter_raw = 0;
int16_t counter = 0;
uint16_t voltage_steps = 0;
uint16_t current_steps = 0;
uint16_t throttle_steps = 0;
uint16_t yaw_steps = 0;
uint16_t roll_steps = 0;
uint16_t pitch_steps = 0;
uint16_t throttle_val = 0;
uint16_t throttle_val_tmp = 0;
uint16_t yaw_val = 0;
uint16_t yaw_val_tmp = 0;
uint16_t pitch_val = 0;
uint16_t pitch_val_tmp = 0;
uint16_t roll_val = 0;
uint16_t roll_val_tmp = 0;
// Active calibration
uint16_t min_throttle = 1000;
uint16_t max_throttle = 1800;
uint16_t min_yaw = 1800;
uint16_t max_yaw = 1000;
uint16_t min_pitch = 1800;
uint16_t max_pitch = 1000;
uint16_t min_roll = 1800;
uint16_t max_roll = 1000;
uint16_t gimbal_rate = 0;
#define MEDIAN_TOTAL 11
#define MEDIAN_POS MEDIAN_TOTAL/2
uint16_t pool_voltage[MEDIAN_TOTAL];
uint16_t median_voltage(uint16_t val);
uint16_t median_get_voltage_steps(void);
#define VOLTAGE_MULTIPLER .0049146189
uint16_t raw_throttle, raw_yaw, raw_pitch, raw_roll;
uint16_t pool_throttle[MEDIAN_TOTAL];
uint16_t pool_yaw[MEDIAN_TOTAL];
uint16_t pool_pitch[MEDIAN_TOTAL];
uint16_t pool_roll[MEDIAN_TOTAL];
uint16_t median_throttle(uint16_t val);
uint16_t median_get_throttle_steps(void);
uint16_t median_yaw(uint16_t val);
uint16_t median_get_yaw_steps(void);
uint16_t median_pitch(uint16_t val);
uint16_t median_get_pitch_steps(void);
uint16_t median_roll(uint16_t val);
uint16_t median_get_roll_steps(void);
uint16_t median(uint8_t median_type);
#define MAX_SAMPLING 5
#define POS_SAMPLING MAX_SAMPLING / 2
uint16_t sampling(uint8_t median_type);
uint16_t sampling_data[MAX_SAMPLING];
uint16_t key;
uint8_t i, j;
uint16_t profile_gimbal_rate;
uint16_t profile_gimbal_rate_raw;
// Controller Toggle Buttons and Gimbal
bool toggle_buttons[6];
// Task Handler
// void taskScreen(void *pvParameters);
// void taskSpeak(void *pvParameters);
void taskButton(void *pvParameters);
void taskCounter(void *pvParameters);
void taskDisplay(void *pvParameters);
void taskSystemStatus(void *pvParameters);
void taskGimbal(void *pvParameters);
// void taskSBUS(void *pvParameters);
// Functions
void printMAC(const uint8_t * mac_addr);
//// void initESP_NOW();
void onI2C0Receive(int len);
void onI2C0Request(void);
void parse_i2c_command(void);
void display_info(void);
#endif

11
test/README

@ -0,0 +1,11 @@
This directory is intended for PlatformIO Test Runner and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PlatformIO Unit Testing:
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
Loading…
Cancel
Save