Go Down

Topic: GPS - NMEA decoder $GPGSV (Read 10435 times) previous topic - next topic

neutrinos

Hello,

With Excell, from 1976 to 2037, I calculate all values and after many tests, reflections, comparisons and verifications I have simplified the calculations to this :

Code: [Select]


lp = leap_year(year);
dw = day_week("01/01/"+year);

// spring is day in march
spring = dw + lp > 1 ? 33 : 26;
spring -= dw + lp;

// fall is day in october
fall =  dw + lp > 3 ? 36 : 29;
fall -=  dw + lp;



I do not search for USA because I have not mathematical formulas...as given :
 byte s = (31 - (5 * y /4 + 4) % 7);  // spring
 byte a = (31 - (5 * y /4 + 1) % 7);  // autumn

I don't know if my formulas are faster

Greatjob !
I understand what you write and not
byte s = (31 - (5 * y /4 + 4) % 7);  // spring
byte a = (31 - (5 * y /4 + 1) % 7);  // autumn

 
But ...
You need more calculations !

neutrinos

I think the RTC should be in UTC.  The GPS time can be used to set the RTC time, without adjusting. Then the time read from both GPS and the RTC should be adjusted for local and DST time.   It wouldn't matter when you set the RTC, because you would always recalculate sprint and fall from the current RTC year (in UTC).  That would fix the RTC issues.
I do not know yet how I will organize, because I still have not received DS3231 + AT24C32 IIC RTC shield.
I tried DS1307 but too much drift on time.

At power up, it takes me many minutes to get the GPS time, I need a RTC to get the exact time right away.
When I receive the GPS time, I will only calculate the next DST that I will store in the EEPROM and update the RTC time.

After I do not know if I keep the local time or UTC in the RTC.

To display the time, I do not know if I keep in memory the next DST or if I read it from the EEPROM.
Is it useful if momentarily I do not display the date and time ?

Every second shwing date and time, I should check DST.

Is it faster to read and adapt the time  and date (DDDD DD MMMM YYYY hh:mm:ss) from RTC or GPS ?

But about RTC GPS DST UTC I think I'll open another TOPIC because it's a bit outside of it, isn't it ?

Anyway I will open another one about the speed, the slope and the distance calculated by the GPS ...

neutrinos

I am fully satisfied with the work done.

With static bool operator < satellites are classified and displayed by
lastSatellites.tracked  (tracked in first)
lastSatellites.snr        (signal hight to low)
lastSatellites.id          (id low to hight)

Code: [Select]
static bool operator <
  ( NMEAGPS::satellite_view_t const & l, NMEAGPS::satellite_view_t const & r )
{
  //   This operator compares two satellites views.  It returns true if
  //   the left satellite view is less than the right satellite view.
  //   This determines how the satellite array is sorted.

  return
     (!l.tracked &&  r.tracked) ||
    (( l.tracked &&  r.tracked) && (l.snr < r.snr))   ||
    ((!l.tracked && !r.tracked) && (l.id  < r.id));
}

I do not understand when lastSatellites.tracked === FALSE satellite are not ordered. But it is not important.
Code: [Select]
different = (nbsat != gps.sat_count);      // Compare satellite count
      if (!different)
      {  for (uint8_t i=0; i < nbsat; i++)  // Same number of satellites, compare IDs
         {  bool found = false;
            for (uint8_t j=0; j < nbsat; j++)
            {  if (lastSatellites[i].id == gps.satellites[j].id)
               {  found = true;
                  if (  (lastSatellites[i].tracked != gps.satellites[j].tracked)
                        ||
                        (lastSatellites[i].snr     != gps.satellites[j].snr)
                     )
                  {  different = true;
                  }
                  break;
               }
            }
            if (!found)
            {  different = true;
            }
            if (different)
            {  break;
            }
         }
      }
      if (different)
      {  nbsat = gps.sat_count;
         for(uint8_t i = 0; i < nbsat; i++)        // Save the new satellites array
         { 
            uint8_t j = i;
            while ( (j > 0) &&
                    (lastSatellites[j-1] < gps.satellites[i]) // <-- "operator <" used
                  )
           {
              lastSatellites[j] = lastSatellites[j-1];  // move element forward
              j--;
           }
           lastSatellites[j] = gps.satellites[i];  // store element here
         }
        }
      }
   }


Now I would also like to be able to display the 10 best signal in other order :
lastSatellites.tracked  (tracked in first)
lastSatellites.id          (id low to hight)


I tried several changes in sketch, but this is not the desired result.


Maybe you can help me ?

neutrinos

Now I would also like to be able to display the 10 best signal in other order :
lastSatellites.tracked  (tracked in first)
lastSatellites.id          (id low to hight)


I tried several changes in sketch, but this is not the desired result.


Maybe you can help me ?
I said 10 best signal, but it can be the 12 best signal.

-dev

I think you are saying that you don't want to sort by SNR, just ID.  If that's the case, operator < should do this:

Code: [Select]
 return
     (!l.tracked &&  r.tracked) ||
    (( l.tracked &&  r.tracked) && (l.id < r.id))   ||
    ((!l.tracked && !r.tracked) && (l.id  < r.id));

This will sort the satellites into 2 sections: a tracked section (sorted by ID), and an untracked section (sorted by ID).

Limiting the display to 10 (or 12) satellites should be performed in signal_block.  Just set the variable maxbar to whatever you want.  You could use a constant

    const int maxbar = 10;

...or you can play with the other screen variables (tece, lgch and hich) to force the maxbar calculation result in 10 or 12.

Is this what you are trying to do?
Really, I used to be /dev.  :(

neutrinos

#65
Oct 03, 2017, 07:15 am Last Edit: Oct 03, 2017, 08:19 pm by neutrinos
Thank you for your answer. I should want :

* one list sort by :
- tracked            (true in first, false in last)
- signal              (hight in first, low in last)
- id sat              (low in first, hight in last)

* one list with X (parameter) best signal order by :
- tracked           (true in first, false in last)
- id sat             (low in first, hight in last)


Some month ago you give me something about first list, work fine when tracked is true, but when traked is false, signal and id are not sorted.

In this picture, it is first list :



10 sat in view

7 sat used

0 sat very hight signal
4 sat hight signal : 23(39), 5(35), 26(32), 2(31)
1 sat medium signal : 16(25)
1 sat low signal : 25(13)
1 sat very low signal : 21(10)

3 sat unused (unsorted):

20(32) 14(0) 12(17)


     id sat(snr)


about  3 sat unused I would like sorted as  


10 sat in view

7 sat used

0 sat very hight signal
4 sat hight signal : 23(39), 5(35), 26(32), 2(31)
1 sat medium signal : 16(25)
1 sat low signal : 25(13)
1 sat very low signal : 21(10)

3 sat unused (sorted):

20(32) 14(0) 12(17)


     id sat(snr)



In second list if I want display only 6 best signal I should want display this order :
,



2(31)
5(35)
16(25)
23(39)
25(13)
26(32)
----      empty place
----      empty place
----      empty place
----      empty place
----      empty place
----      empty place
----      empty place

     id sat(snr)



the other sat are not displayed.


Other example about second list, if I want display 11 best signal I should want display this order :
,



2(31)
5(35)
16(25)
21(10)  not in 6 best
23(39)
25(13)
26(32)
12(17)  not in 6 best
14(0)    not in 6 best
20(32)  not in 6 best
----      empty place
----      empty place
----      empty place

     id sat(snr)



-dev

Ok, the comparison needs to be operator >, not <:

Code: [Select]
//-----------------

static bool operator >
  ( NMEAGPS::satellite_view_t const & l, NMEAGPS::satellite_view_t const & r )
{
  // This operator compares two satellites views.  It returns true if
  //   the left satellite view is less than the right satellite view.
  //   This determines how the satellite array is sorted.

  return
     (!l.tracked &&  r.tracked) ||
    (( l.tracked &&  r.tracked) && (l.id > r.id))   ||
    ((!l.tracked && !r.tracked) && (l.id > r.id));
}

Then the insertion sort uses >:

Code: [Select]
   // Save the new satellites array (insertion sort)
    nbsat = gps.sat_count;
    for (uint8_t i=0; i < nbsat; i++) {
      uint8_t j = i;
      while ( (j > 0) &&
              (lastSatellites[j-1] > gps.satellites[i]) // <-- "operator >" used
            )
      {
        lastSatellites[j] = lastSatellites[j-1];  // move element forward
        j--;
      }
      lastSatellites[j] = gps.satellites[i];  // store element here
    }

This creates the first list you wanted.

To create the second list, you need a slightly different comparison operator.  But since you can't have two of the same operators defined, just use a function name:

Code: [Select]
//-----------------

static bool betterSNR
  ( NMEAGPS::satellite_view_t const & l, NMEAGPS::satellite_view_t const & r )
{
  // This function compares two satellites' SNRs

  return
     (!l.tracked &&  r.tracked) ||
    (( l.tracked &&  r.tracked) && (l.snr > r.snr))   ||
    ((!l.tracked && !r.tracked) && (l.snr > r.snr);
}

I'm not sure if this is correct.  I'll leave that as an exercise for the reader... :)

Then a different insertion sort loop will use this function:

Code: [Select]
   for (uint8_t i=0; i < nbsat; i++) {
      uint8_t j = i;
      while ( (j > 0) &&
              (betterSNR( lastSatellites[j-1], gps.satellites[i] ) // <-- comparison function
            )
      {
        lastSatellites[j] = lastSatellites[j-1];  // move element forward
        j--;
      }
      lastSatellites[j] = gps.satellites[i];  // store element here
    }
Really, I used to be /dev.  :(

neutrinos

Thank you very, much !
Now it is too late for testing.

I do not want both list in same time.

mybrain_iq55

Maybe you can order every time for firt list with <

tracked signal id

and for second list select X best in first list and order then by id with >

neutrinos

Maybe you can order every time for first list with <

tracked signal id

and for second list select X best in first list and order then by id with >
this is a good idea, and I use it for this solution :

lastSatellites is allways sorted for first list.

If I want second list, I create a new object then for N  0 to X, search for each element of gps.satellites if it is the  N element in lastSatellites and add current element of gps.satellites in the new object.
I do not need an other operator.

Maybe is it faster to display directly without create a new object and better for memory ?

Because I do not sort again all lastSatellites but only X element, I think it is faster or better, but I am not sure !

I await -dev's pertinent answer...

-dev

Quote
I await -dev's pertinent answer...
Most of my answers are impertinent.  And I'm not sure I see a question.

If you are asking "Is it faster and uses less memory to not have a second list?", the answer is "no".  It is very rarely "yes".  That is the traditional speed vs. memory trade-off.  It may be faster, but it probably uses more memory.

Because you said, "I do not want both list in same time", I think you only need one list.  Just sort it two different ways.  I *assume* that you are displaying two different screens at different times, so you only need to sort the list one way at a time.

You could have a "sorting mode" that is used by the operator >:

Code: [Select]
enum list_order_t { TRACKED_THEN_SNR,  TRACKED_THEN_ID };
static list_order_t list_order = TRACKED_THEN_SNR;

static bool operator >
  ( NMEAGPS::satellite_view_t const & l, NMEAGPS::satellite_view_t const & r )
{
  // This operator compares two satellites views.  It returns true if
  //   the left satellite view is less than the right satellite view.
  //   This determines how the satellite array is sorted.

  switch (list_order) {
    case TRACKED_THEN_SNR:
      return
         (!l.tracked &&  r.tracked) ||
        (( l.tracked &&  r.tracked) && (l.snr > r.snr))   ||
        ((!l.tracked && !r.tracked) && (l.snr > r.snr));

    case TRACKED_THEN_ID:
      return
         (!l.tracked &&  r.tracked) ||
        (( l.tracked &&  r.tracked) && (l.id > r.id))   ||
        ((!l.tracked && !r.tracked) && (l.id > r.id));
  }
}

(Not tested.)  Just set the sorting mode according to which page is displayed:

Code: [Select]
void showPage3()
{
  displaySatellites( TRACKED_THEN_SNR, 12 );
}

void showPage5()
  displaySatellites( TRACKED_THEN_ID, 6 );
}

void displaySatellites( list_order_t lo, uint8_t max_blocks )
{
     ...

  if (different) {
    // Save the new satellites array (insertion sort)
    list_order = lo; // controls "operator >"
    nbsat = gps.sat_count;
    for (uint8_t i=0; i < nbsat; i++) {
      uint8_t j = i;
      while ( (j > 0) &&
              (lastSatellites[j-1] > gps.satellites[i]) // <-- "operator <" used
            )
      {
        lastSatellites[j] = lastSatellites[j-1];  // move element forward
        j--;
      }
      lastSatellites[j] = gps.satellites[i];  // store element here
    }

    //TableSatellitesInView(); // print new satellites to Serial Monitor window
    signal_block( max_blocks );          // print new satellites to TFT
       ...
}

void signal_block( uint8_t max_blocks )
{

Or just call a function with extra arguments instead of using "operator >" and a global variable:

Code: [Select]
      while ( (j > 0) &&
              compare( lastSatellites[j-1], gps.satellites[i], lo ) // <-- pass in sorting order
            )

This makes it easy to add new sorting modes.
Really, I used to be /dev.  :(

rsneha

google translate :
Of course, as I begin, I am much less structured and thoughtful than you are. I miss a step back.
Without knowing the extent of the arduino's capabilities, I started with a UNO and a TFT display and simply display figures, with a delay (1000).
Conscious of the lack of precision, I used a RTC module.
Then, wishing for an automatic change of time, I hesitated between GSM (SIM disabled) and DCF77, then I opted for GPS.
With the GPS new possibilities come to me. I progress slowly. As my sketch evolved and expanded in functions according to my personal needs and my research on the web.
I planned to look at optimization, speed of execution, memory management, etc ...
The UNO becoming too small, I ordered a MEGA.
With your bookstore, I am a bit unsettled because I do not understand how it works and I have difficulty using it well.
Your example will allow other people (as novice as me) to adapt NeoGPS to his country, for example: australia http://www.timetemperature.com/australia/australia_time_zones.shtml
Thanks again for your listening, your curiosity, your availability and your work.
Also try this Time zone converter.

iamnotgenius

I am looking for a screen like this

and I love your


but I have an error :  declaration of 'operator<' as non-function
static bool operator <




PS:
Time zone converter : https://timely.is/ and its pages will be unavailable due to technical maintenance.



Go Up