Spectrum Satellite API for Arduino
I was working on a small project to implement the Spectrum Satellite Receiver Protocol on an Arduino. The project should work with any type of board (e.g. Arduinos, ESP32, ESP8266 etc)
- Complete Implementation of the Spektrum Satellite Specification
- Support for sending data e.g. to build a Remote Control Transmitter
- Support for receiving data e.g. to build a Remote Control Receiver
- Support of different data types and automatic scaling of channel values
- Support of logging using a specified Serial pin
- Provides Serialization to and from CSV format
Basic Syntax
The SpektrumSatellite class expects a Stream (HardwareSerial, SoftwareSerial, UDP etc) as parameter. You need to make sure that you set the exected baud rate (e.g. with Serial.begin(SPEKTRUM_SATELLITE_BPS)
if this is necessary. The most important methods are:
setChannelValue(channel, value)
sendData()
getFrame()
getChannelValue(channel)
If you want to work with 16bit unsigned integer numbers you define SpektrumSatellite<uint16_t>
and if you want to use floats instead you can define SpektrumSatellite<float>
.
You can also work with your own value range by calling setChannelValueRange(fromValue, toValue)
;
Example: Implementing a Remote Control
In this Example we use of the SpektrumSatellite class to read the data from analog lines and send it via UDP: With this we can implement a simple custom remote control running on a ESP32 which reads the joystick values and sends them out to a receiver.
Please check and adapt the pin assignments of your Microcontroller.
#include "SpektrumSatellite.h"
#include "SpektrumCSV.h"
#ifdef ESP32
#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiUdp.h>
#else
#error "This demo requires an ESP32 or ESP8266 -> Please convert the sketch to your board"
#endif
char* ssid = "RemoteControl";
char* password = "password123";
IPAddress local_IP(192,168,4,1);
IPAddress gateway(192,168,4,0);
IPAddress subnet(255,255,255,0);
IPAddress target_IP(192,168,4,2);
const int udpPort = 6789;
unsigned long intervall = 500; // send every 500ms (=2 messages per second)
unsigned long intervallTime;
WiFiUDP udp;
SpektrumSatellite<uint16_t> satellite(udp); // Assigning the Sattelite to use UDP
SpektrumCSV<uint16_t> csv;
const int pins = 6; // number of channels for servos
int inPins[] = {16, 5, 4, 0, 10, 9}; // analog input pins
uint8_t buffer[1024];
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println("setup");
//Initiate connection
WiFi.disconnect(true);
WiFi.softAPConfig (local_IP,gateway,subnet);
WiFi.softAP(ssid, password);
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
Serial.println("Access Point started");
// Activate the logging to the console only if SpektrumSatellite is not using Serial
satellite.setLog(Serial);
satellite.setLogMod(0); // do not log records
// setup Input pins
for (int j=0;j<pins; j++){
pinMode(inPins[j],INPUT);
}
}
void loop() {
if (millis()>intervallTime) {
intervallTime = millis()+intervall;
// read values from pins
for (int j=0;j<pins; j++){
int value = analogRead(inPins[j]);
Channel channel = (Channel) (j+1);
satellite.setChannelValue(channel, analogRead(inPins[j]));
}
// send binary data
udp.beginPacket(target_IP, udpPort);
satellite.sendData();
udp.endPacket();
// log data as CSV to console
csv.toString(satellite, buffer, 1024);
satellite.sendData(buffer);
Serial.print((char*)buffer);
}
}
Example: Implementing the Receiver on the RC Airplane
In the following Example we use the SpektrumSatellite class on an ESP32 to receive the data in order to update the servos.
#include "SpektrumSatellite.h"
#include "SpektrumCSV.h"
#include "ESP32_Servo.h"
#ifdef ESP32
#include <WiFi.h>
#include <WiFiUdp.h>
#else
#error "This demo requires an ESP32 or ESP8266 -> Please convert the sketch to your board"
#endif
char* ssid = "RemoteControl"; //Change this to your router SSID.
char* password = "password123"; //Change this to your router password.
const int udpPort = 6789;
IPAddress gateway(192,168,4,0);
IPAddress subnet(255,255,255,0);
IPAddress local_IP(192,168,4,2);
WiFiUDP udp;
SpektrumSatellite<uint16_t> satellite(udp); // Assing satellite to Serial (use Serial1 or Serial2 if available!)
SpektrumCSV<uint16_t> csv;
const int pins = 6; // number of channels for servos
int pwmPins[] = {2, 0, 4, 5, 6, 7}; // servo pins
Servo servos[pins]; // allocate servos for all channels
uint8_t buffer[1024];
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println("setup");
//Initiate WIFI Hostspot connection
WiFi.disconnect(true);
WiFi.config(local_IP, gateway, subnet);
// WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(500);
}
Serial.println("Connected to WIFI");
// Activate the logging to the console only if SpektrumSatellite is not using Serial
satellite.setLog(Serial);
satellite.setLogMod(0);
// setup PWM pins
for (int j=0;j<pins; j++){
//servos[j].attach(pwmPins[j]);
}
// start to listen for data
if (udp.begin(udpPort))
Serial.print("Processing UPD now...");
}
void loop() {
// Start processing the next available incoming packet
if (udp.parsePacket()>0){
if (satellite.getFrame()) {
for (int j=0;j<pins; j++){
Channel ch = static_cast<Channel>(j);
long value = satellite.getChannelValue(ch);
//servos[j].write(value);
}
// log data as CSV to console
csv.toString(satellite, buffer, 1024);
satellite.sendData(buffer);
Serial.print((char*)buffer);
}
}
}
Installation
You can download this project as ZIP and in the Arduino IDE use -> Sketch -> Include Library -> Add ZIP Library.
The recommended way howerver is to clone the project to your libraries directory. E.g. with
cd ~/Documents/Arduino/libraries
git clone https://github.com/pschatzmann/SpektrumSatellite.git
2 Comments
Ed · 17. April 2023 at 23:36
I really want to build a trivial arduino based spektrum transmitter. This looks like an awesome place to start! what rf module do you recommend?
William Lynn · 18. March 2021 at 1:56
This sounds great!
Can you provide more details please?