Browse Source

Final Version

master
Englebert 4 years ago
parent
commit
2448ccd212
  1. 263
      OpenFlightRX.ino
  2. 96
      PriUint64.h
  3. 4
      README.md

263
OpenFlightRX.ino

@ -9,6 +9,7 @@
* 2. Set the:
*/
#include "Arduino.h"
#include <EEPROM.h>
// For NRF24L01 (E01) - EByte
// #include "nRF24L01.h"
@ -24,23 +25,24 @@ const uint64_t pipeIn = 0xE8E8F0F0E1LL; // Must be same as the transmissiona
RF24 radio(NRF24_CE, NRF24_CSN); // Starting up the module on GPIO5 (CE), GPIO4 (CSN)
// Debugging over telnet
#include <WiFi.h>
#define MAX_SRV_CLIENTS 2
// const char* ssid = "Pi3_2G";
// const char* password = "trustno1";
const char* ssid = "M5LoRa";
const char* password = "LetMeIn";
// #include <WiFi.h>
// const char* ssid = "M5LoRa";
// const char* password = "LetMeIn";
// const char* ssid = "OpenFlightTX";
// const char* password = "12345678";
// WiFiServer server(23);
WiFiClient wifiClient; // Socket Handler
// WiFiClient wifiClient; // Socket Handler
#define INDICATOR 2
// LoRa related all on Core 0
TaskHandle_t NRFTask;
// Temporary hardcode Address...
/*
* Only initial starting will check for new settings by connecting to the wifi on OpenFlightTX ssid. Well, you can change it
* to suit you needs. For the 5 seconds frame... if not connected over wifi, it will stop the wifi syncing process.
*/
// TTTT TTTT TTTT ---- YYYY YYYY YYYY ---- PPPP PPPP PPPP ---- RRRR RRRR RRRR ---- SSSS SSSS = 72-bits ( 9 bytes )
// Data Structure
@ -53,6 +55,12 @@ struct RxMessage {
};
RxMessage rxmessage;
struct SyncData {
uint8_t freq_channel;
uint8_t dummy;
uint8_t fixed;
};
SyncData syncdata;
// SBUS data structure
#define RC_CHANNEL_MIN 990
@ -76,7 +84,11 @@ uint32_t sbusTime = 0;
bool signalNotOK = false;
void setup_nrf_rx(void);
void socket_client(void);
void read_settings(void);
void nrf_recv(void);
void write_data(uint16_t addr, uint8_t val);
// void socket_client(void);
void sbusPreparePacket(uint8_t packet[], int channels[], bool isSignalLoss, bool isFailsafe);
void setPPMValuesFromData(void);
void resetData(void);
@ -89,11 +101,14 @@ uint32_t last_telnet_seconds = 0;
bool ip_shown = false;
bool socket_connected = true;
bool nrf_enable = true;
bool nrf_enable = false;
uint32_t uptime = 0;
uint32_t nrf_last_receive = 0;
uint8_t freq_channel = 0;
uint64_t pipe_code = 0;
void setup() {
// For USB Debugging
Serial.begin(115200);
@ -101,21 +116,65 @@ void setup() {
// For SBUS to FC
Serial2.begin(100000, SERIAL_8E2);
// Initialize EEPROM
EEPROM.begin(512);
// Signal...
pinMode(INDICATOR, OUTPUT);
// Read Settings
read_settings();
// Reset Data
resetData();
// NRF Setup
setup_nrf_rx();
// Temporary TX
// setup_lora_tx();
radio.begin();
// WiFi Setup
// WiFi.begin(ssid, password);
WiFi.begin(ssid);
// WiFi.begin(ssid);
// Staring to sync.....mode for 5 seconds...
uint32_t time_start_sync = millis();
bool skip_sync = false;
Serial.println(F("Waiting to Sync from Channel 0"));
setup_nrf_sync();
int i = 0;
while(millis() - time_start_sync < 5000 && skip_sync == false) {
delay(100);
if(radio.available()){
// Getting signals from NRF24L01
radio.read(&syncdata, sizeof(SyncData));
if(i < 20) {
Serial.print(F("Channel:"));
Serial.println(syncdata.freq_channel);
Serial.print(F("Dummy:"));
Serial.println(syncdata.dummy);
Serial.print(F("Fixed:"));
Serial.println(syncdata.fixed);
// Validation....
if(syncdata.dummy == 100)
i++;
radio.flush_rx();
delay(100);
continue;
}
Serial.println(F("New Configuration Found."));
Serial.print(F("Channel:"));
Serial.println(syncdata.freq_channel);
// Trying to save to EEPROM before start....
freq_channel = syncdata.freq_channel;
save_settings();
skip_sync = true;
}
Serial.print(".");
}
// Telnet
// server.begin();
@ -130,6 +189,11 @@ void setup() {
0, /* priority of the task */
&NRFTask, /* Task handle to keep track of created task */
0); /* Pin task to Core 0 */
// NRF Setup
setup_nrf_rx();
}
void loop() {
@ -138,21 +202,23 @@ void loop() {
nrf_received_count = nrf_received_count_raw;
nrf_received_count_raw = 0;
last_seconds = millis() + 1000;
uptime++;
Serial.print(F("NRF:"));
Serial.print("NRF:");
Serial.println(nrf_received_count);
last_seconds = millis() + 1000;
uptime++;
/*
if (WiFi.status() == WL_CONNECTED && ip_shown == false) {
Serial.println(WiFi.localIP());
ip_shown = true;
}
*/
}
nrf_recv();
socket_client();
// socket_client();
// telnet_server();
}
@ -161,45 +227,45 @@ uint32_t last_sent = 0;
const char * host = "192.168.4.1";
const uint16_t port = 1001;
void socket_client(void) {
if(WiFi.status() == WL_CONNECTED) {
if(millis() > last_sent) {
if(wifiClient.connected()) {
Serial.println("Sent Data to Screen");
char post_body[16];
sprintf(post_body, "RATE:%d - %d", nrf_received_count, uptime);
wifiClient.write(post_body);
} else {
if(!wifiClient.connect(host, port, 2000)){
Serial.println("Unable to connect...");
} else {
Serial.println("connected..");
}
}
last_sent = millis() + 1000;
/*** Temporary disable for now
// For command from the server back to client
if(wifiClient.available()) {
line = wifiClient.readStringUntil('\n');
Serial.println(line);
}
*/
}
} else {
if(millis() > last_reconnect) {
// Try to reconnect...
if(wifiClient.connected())
wifiClient.stop();
WiFi.disconnect();
WiFi.begin(ssid);
last_reconnect = millis() + 1000;
}
}
}
// void socket_client(void) {
// if(WiFi.status() == WL_CONNECTED) {
// if(millis() > last_sent) {
// if(wifiClient.connected()) {
// Serial.println("Sent Data to Screen");
// char post_body[16];
// sprintf(post_body, "RATE:%d - %d", nrf_received_count, uptime);
// wifiClient.write(post_body);
// } else {
// if(!wifiClient.connect(host, port, 2000)){
// Serial.println("Unable to connect...");
// } else {
// Serial.println("connected..");
// }
// }
//
//
// last_sent = millis() + 1000;
//
// /*** Temporary disable for now
// // For command from the server back to client
// if(wifiClient.available()) {
// line = wifiClient.readStringUntil('\n');
// Serial.println(line);
// }
// */
// }
// } else {
// if(millis() > last_reconnect) {
// // Try to reconnect...
// if(wifiClient.connected())
// wifiClient.stop();
//
// WiFi.disconnect();
// WiFi.begin(ssid);
// last_reconnect = millis() + 1000;
// }
// }
// }
void nrf_recv(void) {
/***** NRF ***/
@ -215,9 +281,17 @@ void nrf_recv(void) {
nrf_last_receive = millis();
// Turns on.... LED
digitalWrite(INDICATOR, HIGH);
} else {
digitalWrite(INDICATOR, LOW);
// digitalWrite(INDICATOR, HIGH);
// digitalWrite(INDICATOR, LOW);
}
if((uint32_t) (millis() - nrf_last_receive) > 1000) {
// TODO: Set a value that the FC recognized that the signal lost
// resetData();
signalNotOK = true;
} else {
signalNotOK = false;
}
}
@ -226,13 +300,22 @@ void NRFTasker(void *pvParameters) {
// Forever loop in this loop :P
for(;;) {
if(millis() > sbusTime) {
if(signalNotOK) {
rcChannels[2] = 900;
rcChannels[3] = 900;
rcChannels[1] = 900;
rcChannels[0] = 900;
}
sbusPreparePacket(sbusPacket, rcChannels, signalNotOK, false);
Serial2.write(sbusPacket, SBUS_PACKET_LENGTH);
// Prevent overflow. If on for more than 50 days
sbusTime = (uint32_t) (millis() + SBUS_UPDATE_RATE);
}
delay(5);
/*
// Script way for delay....
unsigned long t = millis();
@ -293,6 +376,8 @@ void sbusPreparePacket(uint8_t packet[], int channels[], bool isSignalLoss, bool
}
void setPPMValuesFromData(void) {
static bool firstload = true;
/*
* The values for:
* - throttle
@ -304,7 +389,6 @@ void setPPMValuesFromData(void) {
rcChannels[3] = rxmessage.yaw; // Yaw
rcChannels[1] = rxmessage.pitch; // Pitch
rcChannels[0] = rxmessage.roll; // Roll
rcChannels[4] = 1000; // Channel C
// Misc: (64 * channel_a) | (32 * channel_b) | (16 * channel_d) | (8 * channel_e) | (4 * channel_f) | (2 * channel_g) | (1 * channel_h);
// ch6 reserved for the moment
// Processing switches channel....
@ -317,9 +401,14 @@ void setPPMValuesFromData(void) {
rcChannels[11] = (rxmessage.switches & (1 << 6)) ? 2000 : 1000;
rcChannels[12] = (rxmessage.switches & (1 << 7)) ? 2000 : 1000;
rcChannels[13] = 1000; // Not in use
rcChannels[14] = 1000; // Not in use
rcChannels[15] = 1000; // Not in use
// Static values... so leave it
if(!firstload) {
rcChannels[4] = 1000; // Channel C
rcChannels[13] = 1000; // Not in use
rcChannels[14] = 1000; // Not in use
rcChannels[15] = 1000; // Not in use
firstload = false;
}
}
void resetData(void) {
@ -332,12 +421,48 @@ void resetData(void) {
setPPMValuesFromData();
}
void setup_nrf_sync(void) {
radio.stopListening();
radio.setAutoAck(false);
radio.setChannel(125);
radio.setPayloadSize(sizeof(SyncData));
radio.setDataRate(RF24_250KBPS);
radio.openReadingPipe(1, pipeIn); // Change this too.
radio.startListening();
}
void setup_nrf_rx(void) {
radio.begin();
radio.stopListening();
radio.setAutoAck(false);
radio.setChannel(99); // Temporary at 99. Later read from EEPROM
radio.setChannel(freq_channel); // Temporary at 99. Later read from EEPROM
radio.setPayloadSize(sizeof(RxMessage));
radio.setDataRate(RF24_250KBPS);
radio.openReadingPipe(1, pipeIn); // Change this too.
radio.startListening();
nrf_enable = true;
}
void read_settings(void) {
uint16_t addr = 0x00;
// channel
freq_channel = EEPROM.read(addr);
Serial.println(F("EEPROM configurations"));
Serial.print(F("FREQ:"));
Serial.println(freq_channel, DEC);
}
void save_settings(void) {
uint64_t addr = 0x00;
write_data(addr, freq_channel);
}
void write_data(uint16_t addr, uint8_t val) {
// timerAlarmDisable(timer);
EEPROM.write(addr, val);
EEPROM.commit();
// timerAlarmEnable(timer);
}

96
PriUint64.h

@ -0,0 +1,96 @@
#ifndef PRIUINT64_H
#define PRIUINT64_H
#include <stdint.h>
#include <Print.h>
#include <Printable.h>
/** \brief Allow printing uint64_t value.
* \code
* uint64_t x = 1;
* Serial.print(PriUint64<DEC>(x));
* \endcode
*/
template<int Base>
class PriUint64 : public Printable
{
public:
explicit
PriUint64(uint64_t value, int ignored = 0)
: m_value(value)
{
}
size_t
printTo(Print& p) const override
{
char buf[8 * sizeof(uint64_t) + 1];
char* str = &buf[sizeof(buf) - 1];
*str = '\0';
uint64_t n = m_value;
do {
char c = n % Base;
n /= Base;
*--str = c < 10 ? c + '0' : c + 'A' - 10;
} while (n > 0);
return p.write(str);
}
private:
uint64_t m_value;
};
#if defined(ARDUINO_STREAMING) && defined(STREAMING_LIBRARY_VERSION) && STREAMING_LIBRARY_VERSION == 5
/** \brief Print uint64_t as decimal.
*/
inline Print&
operator<<(Print& p, uint64_t x)
{
return p << PriUint64<DEC>(x);
}
#if defined(ESP8266) || defined(ESP32)
#define PRIUINT64_OVERRIDE_STREAMING_BASED
// <type_traits> is available on ESP8266 and ESP32, but unavailable on AVR.
#endif
#ifdef PRIUINT64_OVERRIDE_STREAMING_BASED
#include <type_traits>
#undef _HEX
#undef _DEC
#undef _OCT
#undef _BIN
class _BASED1 : public _BASED, public Printable
{
public:
using _BASED::_BASED;
size_t
printTo(Print& p) const override
{
return p.print(val, base);
}
};
template<typename V, int Base, typename BaseCls = typename std::conditional<std::is_same<V, uint64_t>::value, PriUint64<Base>, _BASED1>::type>
class _BASED2 : public BaseCls
{
public:
using BaseCls::BaseCls;
};
#define _HEX(a) (_BASED2<decltype(a),HEX>(a, HEX))
#define _DEC(a) (_BASED2<decltype(a),DEC>(a, DEC))
#define _OCT(a) (_BASED2<decltype(a),OCT>(a, OCT))
#define _BIN(a) (_BASED2<decltype(a),BIN>(a, BIN))
#endif // PRIUINT64_OVERRIDE_STREAMING_BASED
#endif // ARDUINO_STREAMING
#endif // PRIUINT64_H

4
README.md

@ -18,3 +18,7 @@ Address: 0x0000 ~ 0xFFFE
Channel: 900MHz ~ 931MHz
TXPower: 19.3dBm ~ 20.0dBm
AirRate: 0.3kbps ~ 19.2kbps (2.4kbps) <--- Testing on 2.4 first. Based on calculation is about 300 Bytes/second.
Loading…
Cancel
Save