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

ROBOTICKÉ RAMENO

Stavebnice obsahuje všechny potřebné díly na sestavení robotnického ramene včetně spojovacího materiálu, pouze je nutné dokoupit čtyři kusy MIKRO SERV SG90. Dále je nutné dokoupit řídící jednotku já jsem použil domácí zásoby ARDUINO NANO a pro něho pak modul ARDUINO NANO IO SHIELD pro jednoduchost zapojení. Díly pro sestavení ramene jdou dobře tzv. vylamovat „vypadávají skoro sami. K servům pokud použijete nové tak doporučuji je před montáží odzkoušet zda jsou funkční v plném rozsahu tj. od 0° do 180°, po namontování a zjištění že servo nefunguje to pak opravdu dost zahýbá s nervy. 

Electronic TiltMaze

Cílem tohoto projektu je vytvoření jednoduchého ovládacího systému, který umožňuje naklápění dvou servomotorů pomocí analogového joysticku. Platforma řízená servomotory může simulovat pohyb například v ose X a Y — tedy naklánění doleva/doprava a dopředu/dozadu. Tento systém může sloužit jako základ pro různé aplikace:

- Manuální ovládání kamery nebo senzoru (např. na pohyblivé konstrukci nebo robotovi)
- Interaktivní ovládací panel pro školní projekty nebo herní ovladač