Tim S has asked me to put his latest coding on here to keep it safe.
For those of you following this, mostly on SubPirates, Tim is working on Telemetry for subs.
I can testify to the the fact that (an early version of this ) is working very well on my subs. Giving temperature and current draw and battery voltage.
This is the latest version (still under development by Tim) now incorporating a depth sensor. (And yes - it works!)
Tim's code follows: (You need to use it with Arduino IDE version 1.6.7 or above and the FrSkyTelemetryLRS library installed)
/*
FrSky Telemetry library LRS test
(c) Pawelsky 20150724.
Not for commercial use
FrSkyTelemetry library modified to deal with LRS format (TTL level serial instead of FrSky format...
renamed to FrSkyTelemetryLRS
modifications by tim senecal
*/
#include "FrSkyTelemetryLRS.h"
#define minraw 272.0
#define maxraw 1015.0
#define minreal 9.0
#define maxreal 158.0
//#define voltsdiv 84.81
//#define voltsdiv 102.40
#define voltsdiv 104.2839
//explanation of some math...
// arduino analog pins return values from 0 to 1023...
// which represent voltages from 0 to 5
// pressure transducer returns 0.5 to 4.5 volts,
// for the 5psi model, 4.5 volts represents 11.5 feet, or 138 inches, or 350 cm, or 3500 mm
// if 1023 = 5 volts, then 921 = 4.5 volts, then 921 = 3500 mm
// however, we need to establish what "zero" is.
// we start with 102, which should be 0.5 volts...
// but because we converted our sensor to a sealed sensor, it might not be 102...
// so we have some variables and math to handle that.
#define maxP 921
#define milli 3514.344
#define centi 351.434
#define inches 138.36
FrSkyTelemetryLRS telemetry; // Create telemetry object
const int analogTemp1 = A0;
const int analogTemp2 = A1;
const int analogAmp = A2;
const int analogVolt = A3;
const int analogPressure = A6;
int mVperAmp = 66; // use 185 for 5A, 100 for 20A, and 66 for 30A
int ACSoffset = 2500; // offset to remove negative side of range
int baseline = 102; // this should be the zero psi baseline for 0.5 volts, but may not be
int init_counter = 0;
float calc_milli = 0;
float calc_centi = 0;
float calc_inches = 0;
float amperes = 0;
float voltage = 0;
float actual_rpm = 0;
float calc_speed = 0;
float Temp1 = 0;
float Temp2 = 0;
float depth = 0;
void setup()
{
// Configure the telemetry serial port
telemetry.begin(SERIAL_1);
Serial.begin(9600);
}
void loop()
{
actual_rpm = 3000;
calc_speed = 2.258;
amperes = calc_amperage_val();
voltage = calc_voltage_val();
telemetry.setFasData(amperes, // Current consumption in amps
voltage); // Battery voltage in volts
depth = calc_pressure_val();
telemetry.setFgsData(depth); // Fuel level in percent - unsigned int16 - any value between 0 and 65535
// Set LiPo voltage sensor (FLVS) data (we use two sensors to simulate 8S battery
// (set Voltage source to Cells in menu to use this data for battery voltage)
float v1 = voltage/2;
float v2 = voltage/2;
telemetry.setFlvsData(v1, v2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // Cell voltages in volts (cells 1-8). Cells 9-12 are not used in this example
// Set variometer sensor (FVAS) data
telemetry.setFvasData(depth); // Altitude in m (can be nevative)
// Set GPS data
float heading = 125.22;
telemetry.setGpsData(39.847993, -105.104269, // Latitude and longitude in degrees decimal (positive for N/E, negative for S/W)
depth, // Altitude in m (can be negative)
calc_speed, // Speed in m/s
heading, // Course over ground in degrees
15, 2, 19, // Date (year - 2000, month, day)
12, 00, 00); // Time (hour, minute, second) - will be affected by timezone setings in your radio
float accel_angle_x = 2.35;
float accel_angle_y = 4.25;
float accel_angle_z = 3.15;
telemetry.setTasData(accel_angle_x, // calculated x angle
accel_angle_y, // calculated y angle
accel_angle_z); // calculated z angle
// Set temperature sensor (TEMS) data, two temperatures T1 & T2
// Set temperature sensor (TEMS) data, two temperatures T1 & T2
Temp1 = calc_temp_val(analogTemp1);
Temp2 = calc_temp_val(analogTemp2);
telemetry.setTemsData(Temp1, // Temperature #1 in degrees Celsuis (can be negative)
Temp2); // Temperature #2 in degrees Celsuis (can be negative)
// Set RPM sensor (RPMS) data
// (set number of blades to 2 in telemetry menu to get correct rpm value)
telemetry.setRpmsData(actual_rpm); // Rotations per minute
// Send the telemetry data, note that the data will only be sent for sensors
// that had their data set at least once. Also it will only be set in defined
// time intervals, so not necessarily at every call to send() method.
telemetry.send();
delay(100); //delay for 1/10 of a second
}
float fmap (float x, float in_min, float in_max, float out_min, float out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
float calc_temp_val(int analog_pin){
uint16_t raw_val;
float temp, raw_float;
temp = 0;
raw_val = analogRead(analog_pin);
// raw_val = 1023 - raw_val;
raw_float = raw_val;
temp = fmap(raw_val, minraw, maxraw, minreal, maxreal);
// Serial.print("raw temp: ");
// Serial.print(analog_pin);
// Serial.print(" ");
// Serial.println(raw_val);
return temp;
}
float calc_voltage_val(){
int RawValue = analogRead(analogVolt);
voltage = RawValue;
// Serial.print("raw volt: ");
// Serial.println(RawValue);
voltage = voltage / voltsdiv; // Gets you adjusted Volts
return voltage;
}
float calc_amperage_val(){
int RawValue = analogRead(analogAmp);
Serial.print("raw amps: ");
Serial.println(RawValue);
float mVoltage = RawValue;
mVoltage = mVoltage / 1024.0;
mVoltage = mVoltage * 5000; // Gets you mV 5000 is VCC for 5v arduino
Serial.print("mVolts: ");
Serial.println(mVoltage);
amperes = abs(((mVoltage - ACSoffset) / mVperAmp));
Serial.print("amps: ");
Serial.println(amperes);
return amperes;
}
float calc_pressure_val(){
// read the input on analog pin 0:
int RawValue = analogRead(analogPressure);
// here is code where we establish what the real zero baseline is
// we read the sensor ten times in the first second of running,
// and take the average of those ten readings as the baseline
if (init_counter < 10)
{
baseline = baseline + RawValue;
baseline = baseline / 2;
init_counter = init_counter + 1;
// we then calculate what each discrete value for an analog
// result would need to be multiplied by to reach max depth at 921
calc_milli = (maxP - baseline) / milli;
calc_centi = (maxP - baseline) / centi;
calc_inches = (maxP - baseline) / inches;
}
int fixed_sensor = RawValue - baseline;
Serial.print("raw depth: ");
Serial.println(fixed_sensor);
if (fixed_sensor < 0)
{
fixed_sensor = 0;
}
// float depth = fixed_sensor / calc_inches;
// float depth = fixed_sensor / calc_centi;
float depth = fixed_sensor / calc_milli;
Serial.print("calced depth: ");
Serial.println(depth);
return depth;
}
Later Edit: Good point, John. I will do it once I have worked out how to do it! We can't just store a zip file but we can include a link to SubPirates.
Later Edit: Well, I have managed to lock myself out of SubPirates (I tried changing my password!)
So I can't download the zip file!
Perhaps (John or Tim or any other person signed on with SubPirates) you could download the zip and keep it safe.
It is on this page:
http://www.subpirates.com/showthread.php?5271-Custom-Frsky-Telemetry-Hub/page3
The link is labelled:
FrSkyTelemetryLRS.zip
Later Later Edit: I have a copy of the library zip files now. (Retrieved from my waste paper basket!) Now to get a password working on SubPirates again.
For those of you following this, mostly on SubPirates, Tim is working on Telemetry for subs.
I can testify to the the fact that (an early version of this ) is working very well on my subs. Giving temperature and current draw and battery voltage.
This is the latest version (still under development by Tim) now incorporating a depth sensor. (And yes - it works!)
Tim's code follows: (You need to use it with Arduino IDE version 1.6.7 or above and the FrSkyTelemetryLRS library installed)
/*
FrSky Telemetry library LRS test
(c) Pawelsky 20150724.
Not for commercial use
FrSkyTelemetry library modified to deal with LRS format (TTL level serial instead of FrSky format...
renamed to FrSkyTelemetryLRS
modifications by tim senecal
*/
#include "FrSkyTelemetryLRS.h"
#define minraw 272.0
#define maxraw 1015.0
#define minreal 9.0
#define maxreal 158.0
//#define voltsdiv 84.81
//#define voltsdiv 102.40
#define voltsdiv 104.2839
//explanation of some math...
// arduino analog pins return values from 0 to 1023...
// which represent voltages from 0 to 5
// pressure transducer returns 0.5 to 4.5 volts,
// for the 5psi model, 4.5 volts represents 11.5 feet, or 138 inches, or 350 cm, or 3500 mm
// if 1023 = 5 volts, then 921 = 4.5 volts, then 921 = 3500 mm
// however, we need to establish what "zero" is.
// we start with 102, which should be 0.5 volts...
// but because we converted our sensor to a sealed sensor, it might not be 102...
// so we have some variables and math to handle that.
#define maxP 921
#define milli 3514.344
#define centi 351.434
#define inches 138.36
FrSkyTelemetryLRS telemetry; // Create telemetry object
const int analogTemp1 = A0;
const int analogTemp2 = A1;
const int analogAmp = A2;
const int analogVolt = A3;
const int analogPressure = A6;
int mVperAmp = 66; // use 185 for 5A, 100 for 20A, and 66 for 30A
int ACSoffset = 2500; // offset to remove negative side of range
int baseline = 102; // this should be the zero psi baseline for 0.5 volts, but may not be
int init_counter = 0;
float calc_milli = 0;
float calc_centi = 0;
float calc_inches = 0;
float amperes = 0;
float voltage = 0;
float actual_rpm = 0;
float calc_speed = 0;
float Temp1 = 0;
float Temp2 = 0;
float depth = 0;
void setup()
{
// Configure the telemetry serial port
telemetry.begin(SERIAL_1);
Serial.begin(9600);
}
void loop()
{
actual_rpm = 3000;
calc_speed = 2.258;
amperes = calc_amperage_val();
voltage = calc_voltage_val();
telemetry.setFasData(amperes, // Current consumption in amps
voltage); // Battery voltage in volts
depth = calc_pressure_val();
telemetry.setFgsData(depth); // Fuel level in percent - unsigned int16 - any value between 0 and 65535
// Set LiPo voltage sensor (FLVS) data (we use two sensors to simulate 8S battery
// (set Voltage source to Cells in menu to use this data for battery voltage)
float v1 = voltage/2;
float v2 = voltage/2;
telemetry.setFlvsData(v1, v2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // Cell voltages in volts (cells 1-8). Cells 9-12 are not used in this example
// Set variometer sensor (FVAS) data
telemetry.setFvasData(depth); // Altitude in m (can be nevative)
// Set GPS data
float heading = 125.22;
telemetry.setGpsData(39.847993, -105.104269, // Latitude and longitude in degrees decimal (positive for N/E, negative for S/W)
depth, // Altitude in m (can be negative)
calc_speed, // Speed in m/s
heading, // Course over ground in degrees
15, 2, 19, // Date (year - 2000, month, day)
12, 00, 00); // Time (hour, minute, second) - will be affected by timezone setings in your radio
float accel_angle_x = 2.35;
float accel_angle_y = 4.25;
float accel_angle_z = 3.15;
telemetry.setTasData(accel_angle_x, // calculated x angle
accel_angle_y, // calculated y angle
accel_angle_z); // calculated z angle
// Set temperature sensor (TEMS) data, two temperatures T1 & T2
// Set temperature sensor (TEMS) data, two temperatures T1 & T2
Temp1 = calc_temp_val(analogTemp1);
Temp2 = calc_temp_val(analogTemp2);
telemetry.setTemsData(Temp1, // Temperature #1 in degrees Celsuis (can be negative)
Temp2); // Temperature #2 in degrees Celsuis (can be negative)
// Set RPM sensor (RPMS) data
// (set number of blades to 2 in telemetry menu to get correct rpm value)
telemetry.setRpmsData(actual_rpm); // Rotations per minute
// Send the telemetry data, note that the data will only be sent for sensors
// that had their data set at least once. Also it will only be set in defined
// time intervals, so not necessarily at every call to send() method.
telemetry.send();
delay(100); //delay for 1/10 of a second
}
float fmap (float x, float in_min, float in_max, float out_min, float out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
float calc_temp_val(int analog_pin){
uint16_t raw_val;
float temp, raw_float;
temp = 0;
raw_val = analogRead(analog_pin);
// raw_val = 1023 - raw_val;
raw_float = raw_val;
temp = fmap(raw_val, minraw, maxraw, minreal, maxreal);
// Serial.print("raw temp: ");
// Serial.print(analog_pin);
// Serial.print(" ");
// Serial.println(raw_val);
return temp;
}
float calc_voltage_val(){
int RawValue = analogRead(analogVolt);
voltage = RawValue;
// Serial.print("raw volt: ");
// Serial.println(RawValue);
voltage = voltage / voltsdiv; // Gets you adjusted Volts
return voltage;
}
float calc_amperage_val(){
int RawValue = analogRead(analogAmp);
Serial.print("raw amps: ");
Serial.println(RawValue);
float mVoltage = RawValue;
mVoltage = mVoltage / 1024.0;
mVoltage = mVoltage * 5000; // Gets you mV 5000 is VCC for 5v arduino
Serial.print("mVolts: ");
Serial.println(mVoltage);
amperes = abs(((mVoltage - ACSoffset) / mVperAmp));
Serial.print("amps: ");
Serial.println(amperes);
return amperes;
}
float calc_pressure_val(){
// read the input on analog pin 0:
int RawValue = analogRead(analogPressure);
// here is code where we establish what the real zero baseline is
// we read the sensor ten times in the first second of running,
// and take the average of those ten readings as the baseline
if (init_counter < 10)
{
baseline = baseline + RawValue;
baseline = baseline / 2;
init_counter = init_counter + 1;
// we then calculate what each discrete value for an analog
// result would need to be multiplied by to reach max depth at 921
calc_milli = (maxP - baseline) / milli;
calc_centi = (maxP - baseline) / centi;
calc_inches = (maxP - baseline) / inches;
}
int fixed_sensor = RawValue - baseline;
Serial.print("raw depth: ");
Serial.println(fixed_sensor);
if (fixed_sensor < 0)
{
fixed_sensor = 0;
}
// float depth = fixed_sensor / calc_inches;
// float depth = fixed_sensor / calc_centi;
float depth = fixed_sensor / calc_milli;
Serial.print("calced depth: ");
Serial.println(depth);
return depth;
}
Later Edit: Good point, John. I will do it once I have worked out how to do it! We can't just store a zip file but we can include a link to SubPirates.
Later Edit: Well, I have managed to lock myself out of SubPirates (I tried changing my password!)
So I can't download the zip file!
Perhaps (John or Tim or any other person signed on with SubPirates) you could download the zip and keep it safe.
It is on this page:
http://www.subpirates.com/showthread.php?5271-Custom-Frsky-Telemetry-Hub/page3
The link is labelled:
FrSkyTelemetryLRS.zip
Later Later Edit: I have a copy of the library zip files now. (Retrieved from my waste paper basket!) Now to get a password working on SubPirates again.
Last edited by david f on Tue Feb 16, 2016 2:48 pm; edited 7 times in total
Tue Oct 29, 2024 4:46 pm by tsenecal
» RC Drift Gyro for pitch control
Sun Oct 20, 2024 2:04 pm by geofrancis
» WW2 mini sub build
Thu Oct 17, 2024 2:34 pm by geofrancis
» sonar data link
Mon Oct 14, 2024 4:31 pm by geofrancis
» Robbe Seawolf V2
Sat Oct 12, 2024 3:52 pm by geofrancis
» ExpressLRS - 868/915 Mhz equipment
Fri Oct 11, 2024 8:58 pm by Marylandradiosailor
» Flight controllers as sub levelers
Fri Oct 11, 2024 8:14 pm by geofrancis
» 868/915 Mhz as a viable frequency for submarines.
Thu Oct 10, 2024 3:21 am by tsenecal
» Microgyro pitch controller corrosion
Wed Oct 02, 2024 11:32 am by geofrancis