Hi,
I’m trying to do the following, half working but the other half not and wondering why...
Input: mwv (relative wind) sentence from wind sensor
Input: gprmc sentence from gps
Output: mwv (relative wind) as is ==>working
Output: vwr sentence (converted from mwv) ==>working
Output: mwv (true wind, calculated with gprmc and relative wind)==>not working, seeing only 2 sentences above continuously but no true wind sentence
Confirmed that gprmc is coming out from gps
Below is the code. Appreciate your help and guidance.
Cheers,
z
#include <PString.h>
#include <nmea.h>
NMEA nmeaDecoder(ALL);
// calculate checksum function (thanks to https://mechinations.wordpress.com)
byte checksum(char*str)
{
byte cs = 0;
for (unsigned int n=1; n < strlen(str) - 1; n++)
{
cs ^= str[n];
}
return cs;
}
//true wind functions defined below
double calc_twa(double bs, double aws, double awa)
{
double y = 3.141592 * (90 - awa) / 180;
double a = aws * cos(y);
double bb = aws * sin(y); //MZ: unnecessary?
double b = bb - bs;
double twa = 90 - 180 * atan2(b, a) / 3.141592;
if (twa < 0) twa += 360;
if (bs == 0 && aws == 0) return awa;
else return twa;
}
double calc_tws(double bs, double aws, double awa)
{
double y = 3.141592 * (90 - awa) / 180;
double a = aws * cos(y);
double bb = aws * sin(y);
double b = bb - bs;
double tws = sqrt((a * a) + (b *b )); //MZ: originally(b*)??
return tws;
}
void setup() {
Serial.begin(4800);
Serial1.begin(4800);
Serial3.begin(4800);
}
void loop()
{
if(Serial1.available())
{
if (nmeaDecoder.decode(Serial1.read()))
{
char*title=nmeaDecoder.term(0);
if (strcmp(title,"WIMWV")==0)
{ // only run the following code if the incoming sentence is MWV
Serial1.println(nmeaDecoder.sentence()); // prints the original MWV(R)
Serial.println(nmeaDecoder.sentence()); // Same above. Just to see if this is working with IDE serial monitor
int awa1=atoi(nmeaDecoder.term(1)); // declares a integer from a string
float aws1=atof(nmeaDecoder.term(3)); // declares a float from a string
int x;
if(awa1>180){int x=180;}
else{int x=0;}
int vdir=awa1-x; // convert 360 degrees to 180 for VWR
float vveln=aws1; // wind speed in knots
float vvelm=aws1*1852/3600; // wind speed in m/s
float vvelk=aws1*1.852; // wind speed in kh
// Time to assemble VWR sentence
char vwrSentence [36]; // the VWR sentence can be up to 36 characters long
byte cst;
PString strt(vwrSentence, sizeof(vwrSentence));
strt.print("$XXVWR,");
strt.print(vdir);
strt.print(",");
if(awa1>180) // R if 0-180 degrees L if 180~360 degrees
{strt.print("L");}
else{strt.print("R");}
strt.print(",");
strt.print(vveln,1);
strt.print(",N,");
strt.print(vvelm,1);
strt.print(",M,");
strt.print(vvelk,1);
strt.print(",K*");
cst = checksum(vwrSentence);
if (cst < 0x10) strt.print('0'); // Arduino prints 0x007 as 7, 0x02B as 2B, so we add it now
strt.print(cst, HEX);
Serial1.println(vwrSentence); // Output VWR Sentence
Serial.println(vwrSentence); // Same above. Just to see if this is working with IDE serial monitor
if(Serial3.available())
{
if(nmeaDecoder.decode(Serial3.read()))
{
char*title=nmeaDecoder.term(0);
if(strcmp(title,"GPRMC")==0)
{
Serial.println(nmeaDecoder.sentence()); //Output GPRMC to IDE serial monitor to check
float bs1=atof(nmeaDecoder.term(7));
double twa1;
double tws1;
twa1=calc_twa(bs1, aws1, awa1);
tws1=calc_tws(bs1, aws1, awa1);
// Time to assemble the MWV(T) sentence
char mwvtrueSentence [36]; // the MWV sentence can be up to 36 characters long
byte cst;
PString strt(mwvtrueSentence, sizeof(mwvtrueSentence));
strt.print("$XXMWV,");
strt.print(twa1,0);
strt.print(",");
strt.print("T");
strt.print(",");
strt.print(tws1,1);
strt.print(",K,A*");
cst = checksum(mwvtrueSentence);
if (cst < 0x10) strt.print('0'); // Arduino prints 0x007 as 7, 0x02B as 2B, so we add it now
strt.print(cst, HEX);
Serial1.println(mwvtrueSentence); // Output MWV(T) sentence
Serial.println(mwvtrueSentence); // Same above. Just to see if this is working with IDE serial monitor
} // } for strcmp
} // } for nmeadecoder
} // } for gpsserial
}
}
}
}