Mahlzeit,
Bauteilliste ist relativ klein:
Arduino Pro Mini
Speicher
Display
Spannungswandler
Zum Programieren des ProMini benötigt man noch ein 
FTDI-Adapter oder man nimmt gleich einen kleinen Arduino mit USB-Anschluss.
Hier noch der Code, den ich gerade benutze, aber noch nicht fertig ist. Es fehlen noch die Temperaturwerte.
Ich bin kein Programmierer, wenn jemand Verbesserungspotential findet, dann bitte 

.
Code: Alles auswählen
#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
#include <RunningAverage.h>
#include "Adafruit_FRAM_I2C.h"
#include <Bounce2.h>
#define pinTacho 3
uint32_t aktMillis, altMillis, drueckMillis = 3000;
bool status;
Bounce debouncer = Bounce();
/* Connect SCL    to analog 5
   Connect SDA    to analog 4
   Connect VDD    to 5.0V DC
   Connect GROUND to common ground */
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ SCL, /* data=*/ SDA);  //Mein Display (OLED 182x32)
Adafruit_FRAM_I2C fram = Adafruit_FRAM_I2C();
RunningAverage myRA(5);
volatile unsigned long dauer = 0;             // microsekunden seit dem letzten Interrupt
volatile unsigned long last = 0;              // Zählerwert beim letzten Interrup
volatile short geschwindigkeit;               // selbstredend
volatile int counter = 0;
int aktuell = 0;
int VAnzeige;
unsigned long Gesamtmeter;
unsigned long Tagesmillimeter;
int Gesamtmeter_ADDR = 0;
int Tagesmillimeter_ADDR = 4;
int Tageshunderter = 0;
int Tripkilometer = 0;
char Trip[10];
char Speed[10];
char Gesamtkilometer[10];
void setup(void) {
  Serial.begin(9600);
  pinMode(2, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(2), readmillis, RISING);
  myRA.clear();
  u8g2.begin();
  fram.begin();
  pinMode(pinTacho, INPUT_PULLUP);
  debouncer.attach(pinTacho);
  debouncer.interval(30);
  Gesamtmeter = eepromReadLong(Gesamtmeter_ADDR);
  Tagesmillimeter = eepromReadLong(Tagesmillimeter_ADDR);
  Tripkilometer = (Tagesmillimeter / 1000000);
  Tageshunderter = (Tagesmillimeter / 100000) % 10;
  u8g2.setFont(u8g2_font_profont22_tr);
  u8g2.drawStr(20, 20 , "READY :)");
  u8g2.sendBuffer();
  delay(2000);
  u8g2.clearDisplay();
}
void loop(void) {
  debouncer.update();
  aktMillis = millis();
  if (last > 0) {
    if (millis() - last > 4000) {                         // Nach 4 Sekunden stillstand Display löschen
      u8g2.clearDisplay();
      myRA.clear();
      if ( debouncer.fell()  ) {    // Taste gedrückt
        altMillis = aktMillis;
        status = true;
      }
      if ( debouncer.rose()  ) {    // Taste losgelassen
        status = false;
        if (aktMillis - altMillis < drueckMillis) {
          Serial.println("Kurz");
          Gesamtmeter = eepromReadLong(Gesamtmeter_ADDR);
          Serial.print("Gesamtkilometer:");
          Serial.println(Gesamtkilometer);
          sprintf(Gesamtkilometer, "%6d" , Gesamtmeter / 1000);
          status = false;
          u8g2.setFont(u8g2_font_t0_13b_tf);
          u8g2.drawStr(10, 14, "Gesamtkilometer:");
          u8g2.setFont(u8g2_font_profont22_tr);
          u8g2.drawStr(0, 32, Gesamtkilometer);
          u8g2.sendBuffer();
          delay(2000);
          u8g2.clearDisplay();
        }
      }
      if (status && (aktMillis - altMillis >= drueckMillis)) {
        status = false;
        Serial.println("Lang");
        eepromWriteLong(0, Tagesmillimeter_ADDR);
        Tagesmillimeter = eepromReadLong(Tagesmillimeter_ADDR);
        Tripkilometer = (Tagesmillimeter / 1000000);
        Tageshunderter = (Tagesmillimeter / 100000) % 10;
        u8g2.setFont(u8g2_font_profont22_tr);
        u8g2.drawStr(0, 23, "Trip reset");
        u8g2.sendBuffer();
        delay(2000);
        u8g2.clearDisplay();
      }
    }
    else {
      VAnzeige = myRA.getAverage();
      if (aktuell < counter) {       // eine Umdrehung -> Interrupt durchlaufen
        aktuell = counter;
        Serial.print("Counter:");
        Serial.println(counter);
        Tagesmillimeter += 714;
        Serial.print("Tagesmillimeter:");
        Serial.println(Tagesmillimeter);
        Tripkilometer = (Tagesmillimeter / 1000000);
        if (Tripkilometer > 999) {
          Tripkilometer = 0;
        }
        Tageshunderter = (Tagesmillimeter / 100000) % 10;
        Serial.print("Tageshunderter:");
        Serial.println(Tageshunderter);
        if (counter % 100 == 0) {
          eepromWriteLong(Tagesmillimeter, Tagesmillimeter_ADDR);
        }
        if (counter >= 500) {
          counter = 0;
          aktuell = 0;
          Gesamtmeter += 357;
          eepromWriteLong(Gesamtmeter, Gesamtmeter_ADDR);
          Serial.print("Gesamtmeter in Speicher:");
          Serial.println(Gesamtmeter);
        }
      }
      sprintf(Trip, "%5d.%d" , Tripkilometer, Tageshunderter);
      sprintf(Speed, "%3u", VAnzeige);
      u8g2.clearBuffer();
      u8g2.setFont(u8g2_font_logisoso32_tn);
      u8g2.drawStr(0, 32, Speed);
      u8g2.setFont(u8g2_font_logisoso16_tf);
      u8g2.drawStr(70, 32, "km/h");
      u8g2.setFont(u8g2_font_synchronizer_nbp_tf);
      u8g2.drawStr(70, 10, "T:");
      u8g2.drawStr(70, 10, Trip);
      u8g2.sendBuffer();
    }
  }
}
void readmillis() {                           // Interrupt-Routine
  detachInterrupt(2);                         // Interrupt ausschalten damit er uns nicht beißt
  volatile unsigned long m = millis();          // Microsekundenzähler auslesen
  volatile unsigned long v = m - last;          // Differenz zum letzten Durchlauf berechnen
  if (v > 10) {                               // ignorieren wenn <= 10ms (Kontaktpreller)
    dauer = v;                                // Wert in dauer übernehmen
    last = m;                                 // und wieder den letzten Wert merken
    geschwindigkeit = 2572 / dauer;           // Geschwindigkeit ausrechnen mit k-Wert 1,4 (1 Umdrehung/s = 0,714m/s = 2,570km/h)
    myRA.addValue(geschwindigkeit);           // Wert zur Mittelwerberechnung hinzufügen
    counter += 1;
  }
  attachInterrupt(digitalPinToInterrupt(2), readmillis, RISING);    // Interrupt wieder einschalten.
}
void eepromWriteLong(unsigned long lo, int adr) {
  // long Wert in das EEPROM schreiben
  // Eingabe : adr Speicherplatz
  // Eingabe : lo Zahl, Wertebereich -2.147.483.648 bis 2.147.483.647
  //
  // Matthias Busse 23.5.2014 Version 1.0 -> RS Geändert von EEprom auf Fram und ULong
  byte by;
  for (int i = 0; i < 4; i++) {
    by = (lo >> ((3 - i) * 8)) & 0x000000ff;
    fram.write8(adr + i, by);
  }
} // eepromWriteLong
long eepromReadLong(int adr) {
  // long int Wert aus 4 Byte EEPROM lesen
  // Eingabe : adr bis adr+3
  // Ausgabe : long Wert
  //
  // Matthias Busse 23.5.2014 Version 1.0 -> RS Geändert von EEprom auf Fram und ULong
  unsigned long lo = 0;
  for (int i = 0; i < 3; i++) {
    lo += fram.read8(adr + i);
    lo = lo << 8;
  }
  lo += fram.read8(adr + 3);
  return lo;
} // eepromReadLong
Die Verlinkungen oben sind nur Bauteilbeispiele und können vom Händler des geringstren Misstrauens erworben werden. Ich verdiene an den Links kein Geld. Tachosignal habe ich von einem el. Adapter für die Tachoschnecke, wird bei anderen Mopeds sicher anders sein.
Ich habe einen K-Wert von 1,4: (geschwindigkeit = 2572 / dauer;           // Geschwindigkeit ausrechnen mit k-Wert 1,4 (1 Umdrehung/s = 0,714m/s = 2,570km/h)
Bei Fragen gerne fragen. Anschluss der einzelnen Bauteile miteinander sollte klar sein.
LG Roland