In MultiWii.cpp I've added:
Code: Select all
#include "FrSkySport.h"
and at the end of the annexCode() function I've added:
Code: Select all
frsky_sport();
The frsky_sport() function is just this:
Code: Select all
void frsky_sport() {
if (FrSkySport_timeToSend()) {
FrSkySport_sendData();
}
}
...with the important function being FrSkySport_timeToSend():
Code: Select all
// Note that config.h has: #define FRSKY_SPORT_SERIAL 3
bool FrSkySport_timeToSend() {
static uint8_t lastRx = 0;
// This commented-out way of looping doesn't work either:
// uint8_t c = SerialAvailable(FRSKY_SPORT_SERIAL);
// if (c != 0) { debug[0] = c; }
// while (c--) {
while (SerialAvailable(FRSKY_SPORT_SERIAL)) {
int rx = SerialRead(FRSKY_SPORT_SERIAL);
if (lastRx == 0x7e) {
debug[1] = rx; // This is just here to provide visibility on what MultiWii is seeing
}
if (lastRx == 0x7e && rx == FRSKY_SPORT_SENSOR_ID) { // FRSKY_SPORT_SENSOR_ID == 0x98
// On a regular Arduino (using the default serial lib) this conditional matches *constantly* (once a second maybe?)
// With MultiWii's serial library this conditional only matches about once every 30 seconds or so. No idea why.
lastRx = 0;
debug[2]++; // So I can see how often it matches
return true;
}
lastRx = rx;
}
return false;
}
FrSkySport_sendData() just sends a simulated A2 voltage (full code will be posted once I've got the serial Rx working) but I can have it send the full gamut of FrSky telemetry. In fact, I've got a lot of that ready-to-go except for the issue that I cannot get FrSkySport_timeToSend() working!
Notes about the hardware: The FrSky Smart Port uses an inverted serial signal so I've implemented a simple UART signal inverter using a P2222 NPN transistor with 10k and 4.7k resistors:
I have independently verified that the inverter works using a separate Arduino (Duemilanove) running the following code:
Code: Select all
#include <SoftwareSerial.h>
#define rxPin 4
#define txPin 2
SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin, false);
// Note that with SoftwareSerial you can pass 'true' as the 3rd arg above
// to read the Smart Port without a hardware inverter
void setup() {
Serial.begin(57600);
Serial.println("Serial port monitor starting..");
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
mySerial.begin(57600); // This is the baud rate of the Smart Port
mySerial.listen();
}
void loop() {
if (mySerial.available()>0) {
int val = mySerial.read();
if (val != 0) {
Serial.print(":");
Serial.print(val);
}
else {
Serial.print("\n");
}
}
}
Here's an example of what that outputs while reading the Smart Port:
Code: Select all
:126:161:126:34:126:131:126:228:126:69:126:198:126:103:126:72:126:233:126:106:126:203:126:172:126:13:126:142:126:47:126:208:126:113:126:242:126:83:126:52:126:149:126:22:126:183:126:152:126:57:126:186:126:27:126
The way the protocol works the telemetry data must be sent after detecting "126" (0x7e) immediately followed by the sensor ID that we're simulating which in the code above is "152" (0x98). That would be "126:152" in the output above.
With a separate Ardiuno hooked up to the Smart Port I can successfully send whatever telemetry data I want using this method (detect sensor ID, send payload). It shows up on my Taranis and works great!
Can anyone provide insight as to what's wrong with my FrSkySport_timeToSend() function above? Why can't I read the Smart Port data like I can with a separate Arduino using the regular libraries?