Satelitní tachometr pro tchánův veterán Opel Corsa

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

Další podobné články

Test ESC a BLDC motoru

Cílem tohoto Arduino projektu je testování a kalibrace obousměrného regulátoru otáček (ESC) pomocí PWM signálu. Program simuluje sekvenci pohybů: dopředu, neutrální pozici a reverzní chod, což umožňuje ověřit správnou funkci ESC včetně přepínání směru otáčení motoru.

Laserový alarm

Cílem tohoto projektu je vytvořit jednoduchý, ale funkční bezpečnostní systém, který detekuje narušení prostoru pomocí vysílače (laserového paprsku) a přijímače (fotorezistoru). Jakmile je paprsek přerušen, Arduino to vyhodnotí jako narušení a spustí alarm – například zvukový signál pomocí piezo bzučáku.