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