Motivace :
Tchán léta jezdí Corsičkou a letos nastala štrapác, tachometr vypověděl službu, rafička splaskla k nule a hotovo. Pokusy nahradit čidlo v bloku motoru opakovaně selhaly a tak nastoupila alternativa satelitního měření rychlosti a analogového zobrazení aktuální rychlosti na tachometru. Vzorkování rychlosti v rozsahu 1 ~ 5 Hz bezpečně vyhoví potřebám analogového sledovače a postačí i bez nutnosti měnit uloženou defaultní konfiguraci GPS přijímače u-blox Neo-6M. Prototypové řešení volně zobrazuje aktuálně poslední přečtený údaj o rychlosti a tento pasivní mód je možné dále rozšiřovat zařazením aktivního filtru a vyhlazováním údajů pomocí modelovaného systému druhého řádu ( rychlost, zrychlení ).

obrázek

BoM ( Bill-of-Material ) :
1x mikrokontrolér Arduino Nano, klon CH340 (+5V)
1x přijímač GPS u-blox Neo-6M (+5V)
1x zobrazovací tachometr na bázi servomotoru SG90 (+5V)
1x USB-napaječ z palubní zásuvky (+5V)
1x USB-USB kabel napájení desky a přijímače GPS
1x sada propojovacích kabelů

Použité knihovny :- standardní knihovna Arduino IDE SoftwareSerial- standardní knihovna Arduino IDE Servo- standardní knihovna Arduino IDE TinyGPS++  viz: [file:TinyGPSPlus-1.0.2b.zip]Zdrojový kód :/* ARDUINO NANO               [doc:https://dratek.cz/arduino/1069-eses-klon-arduino-nano-ch340.html]
   Rx_DATA from u-Blox GPS-6M [doc:https://web.archive.org/web/20200610071942/https://www.u-blox.com/sites/default/files/products/documents/u-blox6_ReceiverDescrProtSpec_(GPS.G6-SW-10018)_Public.pdf]
  -----+5V->     o-Vcc_GPS-6M [+   https://dratek.cz/arduino/1510-gps-neo-6m-gyneo6mv2-modul-s-antenou.html]
  ---TxPin->     o--Rx_GPS-6M
       o-GND_GPS-6M
                 
  PWM_out to SERVO    SG90    [doc:https://www.peckamodel.cz/jix-sg90-1-9g-mini-servo-sg90]
  servoPin-> o--------SG90-PWM-(orange/yellow)--
  -----+5V-> o--------SG90-Vcc-(red)------------
  -----GND-> o--------SG90-GND-(brown)----------  */
//-----------------------------------------------------------
#include <TinyGPS++.h>                            // GPS   toolkit used for NMEA-messages decodes, ref.[doc:Pg.63/210]
#include <Servo.h>                                // SERVO toolkit used to drive SG90
#include <SoftwareSerial.h>                       // UART  RS-232 from the GPS-6M device
//-----------------------------------------------------------
#define  GPSBaud 9600                             // UART                  GPS-6M device default port speed is 9600-8-1-none [doc:Pg.7/210]
#define    RxPin    2                             // UART [2]_Rx  Rx_GPS-6M
#define servoPin    9                             // PWM  [9]_PWM----->    SERVO-SG90_PWM_signal_IN
#define servoOnExit 0                             // 
//-----------------------------------------------------------
TinyGPSPlus    gps;                               // new TinyGPS++ object for DECODEs
SoftwareSerial gpsSerial( RxPin, TxPin );         // new SERIAL instance for connection to the u-blox GPS-6M device
Servo          meTachometroveSERVO;               // new SERVO  instance
int            servoKMH = 0;                      // new int-variable to store GPS-reported speed [km/h].. [ToDo] as aRotatingBUFFER[3] in a 2nd-Order PDE speed-approximator
//-----------------------------------------------------------
void setup() {  Serial.begin(      9600 );        // Start the Arduino hardware TTY port at 9600 baud
             gpsSerial.begin(   GPSBaud );        // Start the software SERIAL port at the GPS's baud (u-blox default value [fine for serving at about ~1 Hz GPS update messages] )
   meTachometroveSERVO.attach( servoPin );        //   Set the Arduino hardware PIN[servoPIN] dedicated to PWM driving SG90-servo
}
//-----------------------------------------------------------
void loop() {
  while (             gpsSerial.available() > 0 ) // every time a new sentence is correctly encoded
    if (  gps.encode( gpsSerial.read() ) ) {      //      READ it
                                displayDATA();    //      TTY report [via USB to PC-host, if present] .... [ToDo] could be removed for a headless, production code
          if ( gps.speed.isValid() ) update();    //      TEST / UPD if  .isValid() ...................... [ToDo] could be extended with a 2nd-Order PDE speed-approximator
          meTachometroveSERVO.write( servoKMH );  //      SET SG90-servo ( Corsa will never fly > 140 )... [ToDo] could be constrain()-fused for non-Corsa vehicles like UL-s
          readGpsWhileInDELAY( 800 );             //      WAIT read-feeding the gps-object for about 800 [ms] (ref. about the 1 Hz GPS-update)
    }
//FUSE/////////////////////////------------------------------------------------------------------------------------- FUSE
  if (              millis() > 5000               // soft-timeout 5[s] ~ if 5000 milliseconds pass and there are no characters coming in
     & gps.charsProcessed() <   10 ) {           //                    and too few CHARs came
        Serial.println("No GPS detected");        //                        show "No GPS detected" on TTY port [via USB to PC, if present]
        meTachometroveSERVO.write( servoOnExit ); //                        SET
                            delay( 1000 );        //
        meTachometroveSERVO.detach();             //                        fuse SERVO out
        while ( true ); // _______________________________________________________________________________________________________________ FOREVER _EndOfGame_STATE_LOCKOUT__
  }
}
//-----------------------------------------------------------
static void update() {                            //      UPD if  .isValid() ............................ [ToDo] could be extended with a 2nd-Order PDE speed-approximator
     servoKMH = map( (int)gps.speed.kmph(),       //      map int( .kmph() )
                       0,                         //          mapFromLo ~   0 km/h ....... (? dead zone around a walking speed ? :o)
                     160,                         //          mapFromHi ~ 160 km/h ....... (a speed Opel Corsa ought never get ;)
                       4,                         //            mapToLo ~   4 of 180 steps
                     176                          //            mapToHi ~ 176 of 180 steps 
                     );                           //
}
//-----------------------------------------------------------
static void displayDATA() {                                           Serial.println();
                                                                      Serial.println();
  if ( gps.location.isValid() ) {  Serial.print(   "Latitude: "  );   Serial.println( gps.location.lat(), 6 );
                                   Serial.print(   "Longitude: " );   Serial.println( gps.location.lng(), 6 );
                                   Serial.print(   "Altitude: "  );   Serial.println( gps.altitude.meters() );
  }
  else                                                                Serial.println( "Location: Not Available" );
  if ( gps.date.isValid() )     {  Serial.print(   "Date: " );        Serial.print(   gps.date.month() ); Serial.print( "/" );
                                                                      Serial.print(   gps.date.day()   ); Serial.print( "/" );
                                                                      Serial.println( gps.date.year()  );
  }
  else                                                                Serial.println( "Date: Not Available" );
  if ( gps.time.isValid() )     {  Serial.print(   "Time: " );
                                   if ( gps.time.hour()   < 10 )      Serial.print(   F( "0" ) );
                                                                      Serial.print(   gps.time.hour()   ); Serial.print( ":" );
                                   if ( gps.time.minute() < 10 )      Serial.print(   F( "0" ) );
                                                                      Serial.print(   gps.time.minute() ); Serial.print( ":" );
                                   if ( gps.time.second() < 10 )      Serial.print(   F( "0" ) );
                                                                      Serial.print(   gps.time.second() ); Serial.print( "." );
                                   if ( gps.time.centisecond() < 10 ) Serial.print(   F( "0" ) );
                                                                      Serial.println( gps.time.centisecond() );
  }
  else                                                                Serial.println( "Time: Not Available" );
}
//-----------------------------------------------------------
static void readGpsWhileInDELAY( unsigned long ms ) {
  unsigned long start = millis();
  do { while ( gpsSerial.available() ) gps.encode( gpsSerial.read() );
  }    while ( millis() - start < ms );
}

a

FB tw

Další podobné články