INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Motorrad-Tacho (Nano) robust gegen Störungen machen
29.07.2020, 18:31
Beitrag #1
Motorrad-Tacho (Nano) robust gegen Störungen machen
Guten Abend,
ich habe mir über die letzten Wochen / Monate einen kleinen Tacho für mein Motorrad gebaut. Der Tacho besteht aus einem 0,96" Bildschirm, einer DS3231 RTC sowie einem Nano. Die Geschwindigkeit lese ich per Interrupt über einen Reedschalter plus Magneten an der Felge ein.
Soweit so gut - am Fahrrad funktioniert das ganz ausgezeichnet, allerdings fange ich mir am Motorrad massive Störungen ein. Sobald der Motor läuft, springt die angezeigte Geschwindigkeit auch im Stand auf irgendwelche Werte über 300km/h.
Vermutlich spuckt mir hier die Zündanlage in die Suppe.

Den "Fehler" konnte ich auf die Leitung zum Reed-Schalter eingrenzen; entferne ich diese Strippe dann zeigt der Tacho stabile "0 km/h" an.

Meine nächsten Schritte wären jetzt ein geschirmtes Kabel zu bestellen (derzeit ist es nur eine verdrillte "Klingelleitung") sowie den internen Pullup-Widerstand an Pin3 durch einen externen, deutlich kleineren Widerstand zu ersetzen (ich dachte an 560 Ohm in der Richtung).
Den Schirm der Leitung würde ich an GND vom Nano anschlagen.
Denkt ihr dass ich damit Aussicht auf Erfolg habe? Oder fallen euch noch weitere Maßnahmen ein? EMV ist leider nicht meine Stärke, daher bin ich auf Hilfe angewiesen..

Danke im Voraus
Basti

PS: Anbei der Code falls es relevant sein sollte..

Code:
#include <EEPROM.h>
#include <RunningAverage.h>
#include <Wire.h>
#include "OneButton.h"
#include <U8g2lib.h>
#include "RTClib.h"

U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 16, /* data=*/ 17);   // ESP32 Thing, HW I2C with pin remapping
RTC_DS3231 rtc;


const uint16_t Entprellzeit = 15; // in ms
volatile uint32_t lastMillis = 0;
RunningAverage myRA(7);
volatile short geschwindigkeit;
const int buttonPin = 4;
const int reedPin = 3;
int screen = 0;
volatile int RotationCounter = 0;
OneButton button(buttonPin, true);
const int RadUmfang = 1862;
char Speed[10];

uint64_t GesamtMillimeter;
uint32_t TripMillimeter;
int GesamtMillimeter_ADDR = 0;
int TripMillimeter_ADDR = GesamtMillimeter_ADDR + 8;    //Gesamtmillimeter ist 64bit Zahl --> braucht 8 Byte im EEPROM
char TripKm[10];
char GesamtKm[10];
boolean reset = false;
boolean MotorradFaehrt = false;
boolean ShowLogo = false;
boolean beimNaechstenStopDatenSichern = false;

#define logo_width 128
#define logo_height 62
const unsigned char logo[] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};



#define tachoSymbol_width 48
#define tachoSymbol_height 30
const unsigned char tachoSymbol[] PROGMEM = {
  0x70, 0x00, 0x0e, 0xe0, 0xc3, 0x07, 0x80, 0xff, 0x01, 0x00, 0x7e, 0x00
};


#define route_width 34
#define route_height 34
const unsigned char route_bits[] PROGMEM = {
  0x00, 0x06, 0x00, 0x00, 0x20, 0xff, 0x07, 0x00, 0x00, 0x80, 0x1f, 0x00
};


void setup()   {
  //  Serial.begin(9600);      // open the serial port at 9600 bps:

  if (reset) {
    resetEEPROM();  //alles auf 0 setzen
  }

  pinMode(reedPin, INPUT_PULLUP); // Reed-Sensor an Pin 3
  pinMode(buttonPin, INPUT_PULLUP); // Taster an Pin 2
  EIFR = (1 << INTF1);                                        //verhindert fälschliches Aufrufen der ISR revs() bei Startup --> https://github.com/arduino/Arduino/issues/510
  attachInterrupt(digitalPinToInterrupt(reedPin), revs, FALLING);

  getMileage();                                   //gespeicherten Tachostand abrufen (eeprom-adresse mit höchstem Zählerstand suchen)
  myRA.clear();
  button.attachClick(klick);
  button.attachLongPressStop(langDruck);
  u8g2.begin();
  u8g2_prepare();
  u8g2.clearBuffer();
  u8g2.drawXBMP( 0, 0, logo_width, logo_height, logo);
  u8g2.sendBuffer();
  delay(2000);
}



void loop() {
  button.tick();
  u8g2.clearBuffer();
  if (MotorradFaehrt) {
    myRA.addValue(geschwindigkeit);           // Wert zur Mittelwerberechnung hinzufügen
    GesamtMillimeter += RadUmfang;
    TripMillimeter += RadUmfang;
    MotorradFaehrt = false;
    if (geschwindigkeit > 30) beimNaechstenStopDatenSichern = true;   //Flag setzen um Tachostand beim nächsten Stop wegzuschreiben

  }

  if (millis() - lastMillis >= 10000) {               //wenn keine Radumdrehung innerhalb von 10 Sek stattgefunden hat --> Logo zeigen
    u8g2.drawXBMP( 0, 0, logo_width, logo_height, logo);
    ShowLogo = true;
    if (beimNaechstenStopDatenSichern) {            //Tachostand nur dann ins EEPROM schreiben, wenn vorher über 30km/h gefahren wurde
      saveMileage();
      beimNaechstenStopDatenSichern = false;
    }
  } else {
    draw();
  }
  u8g2.sendBuffer();

  if (millis() - lastMillis >= 2000) {
    myRA.clear();                                   //wenn keine Radumdrehung innerhalb von 2 Sek stattgefunden hat --> Geschwindigkeit nullen
  }

  if (RotationCounter >= 10) {          //Tachostand ca. alle 500m sichern (260 umdrehungen);
    RotationCounter = 0;
    saveMileage();
  }
}


void draw() {

  short VAnzeige = myRA.getAverage();        // Mittelwert errechnen
  DateTime now = rtc.now();
  int hunderter = (TripMillimeter / 100000) % 10;
  int tausender = TripMillimeter / 1000000;
  sprintf(GesamtKm, "%6lukm", (uint32_t)(GesamtMillimeter / 1000000));
  sprintf(TripKm, "%5d.%dkm", tausender, hunderter);
  sprintf(Speed, "%3d", VAnzeige);
  switch (screen) {
    case 0:
      u8g2.drawXBMP( 80, 0, tachoSymbol_width, tachoSymbol_height, tachoSymbol);
      u8g2.setFont(u8g2_font_logisoso38_tn);
      u8g2.drawStr( 0, 15, Speed);
      u8g2.setFont(u8g2_font_logisoso20_tr);
      u8g2.drawStr( 75, 32, "kmh");
      break;
    case 1:
      u8g2.setFont(u8g2_font_logisoso38_tn);
      u8g2.setCursor(5, 15);
      if (now.hour() < 10) u8g2.print("0");
      u8g2.print(now.hour());
      u8g2.print(":");
      if (now.minute() < 10) u8g2.print("0");
      u8g2.print(now.minute());
      break;
    case 2:
      u8g2.setFont(u8g2_font_logisoso20_tr);
      u8g2.drawStr( 0, 10, "Trip:");
      u8g2.drawStr( 0, 40, TripKm);
      u8g2.drawXBMP( 80, 0, route_width, route_height, route_bits);
      break;
    case 3:
      u8g2.drawStr( 0, 40, TripKm);
      u8g2.drawStr( 5, 10, GesamtKm);
      break;
    case 4:
      u8g2.setFont(u8g2_font_logisoso38_tn);
      u8g2.setCursor(0, 15);
      u8g2.print(tempDS3231(), 1);
      u8g2.drawCircle(98, 20, 5, U8G2_DRAW_ALL);  //nicht besonders schön, aber speicher-optimalste Veriante ??
      u8g2.drawCircle(98, 20, 4, U8G2_DRAW_ALL);
      u8g2.drawXBMP( 105, 0, thermometer_width, thermometer_height, thermometer_Symbol);
      break;
  }
}


void u8g2_prepare(void) {
  u8g2.setFontRefHeightExtendedText();
  u8g2.setDrawColor(1);
  u8g2.setFontPosTop();
  u8g2.setFontDirection(0);
}



void revs() {                           // Interrupt-Routine
  uint32_t jetztMillis = millis();
  if (jetztMillis - lastMillis >= Entprellzeit) {                               // ignorieren wenn <= 10ms (Kontaktpreller)
    geschwindigkeit = RadUmfang * 3.6 / (jetztMillis - lastMillis);       // Geschwindigkeit: 1 Interrupt alle 1861mm (Radumfang)

    lastMillis = millis();                                 // und wieder den neuen Wert merken
    //    myRA.addValue(geschwindigkeit);           // Wert zur Mittelwerberechnung hinzufügen
    //    TripMillimeter += RadUmfang;                    //pro Umdrehung 1861mm gefahren
    //    GesamtMillimeter += RadUmfang;
    RotationCounter += 1;
    MotorradFaehrt = true;
  }
}

void klick() {   //durchtoggeln der Screens
  screen++;
  if (screen > 4) screen = 0;
  if (ShowLogo) {  //falls Logo angezeigt und Knopf gedrückt wird --> Logo-Timer wieder auf 10sek setzen und Geschwindigkeit anzeigen
    ShowLogo = false;
    lastMillis = millis();
    screen = 0;
  }
}

void langDruck() {
  if (screen == 2)  {
    TripMillimeter = 0;   //Trip zurücksetzen
    EEPROM.put(TripMillimeter_ADDR, TripMillimeter);
  }
}


float tempDS3231() {    // Die Temperatur des DS3231 auslesen
  float temp;
  int msb, lsb;
  Wire.beginTransmission(0x68);
  Wire.write(0x11);
  Wire.endTransmission();
  Wire.requestFrom(0x68, 2);
  msb = Wire.read();
  lsb = Wire.read();
  temp = ((msb << 2) + (lsb >> 6) ) / 4.0;
  return temp;
}

void getMileage() {     //EEPROM-Adresse mit dem höchsten Tachostand suchen
  uint64_t GesamtMillimeter_vgl;
  EEPROM.get(GesamtMillimeter_ADDR, GesamtMillimeter);    //Absprungbasis bei Adresse=0

  for (int pos = 0; pos <= 1008; pos = pos + 12) { //EEProm.length = 0-1023
    EEPROM.get(pos, GesamtMillimeter_vgl);
    if (GesamtMillimeter_vgl > GesamtMillimeter) {  //falls höherer KM-Stand gefunden wurde, diesen übernehmen und weitersuchen
      GesamtMillimeter = GesamtMillimeter_vgl;
      GesamtMillimeter_ADDR =  pos;
    }
  }

  TripMillimeter_ADDR = GesamtMillimeter_ADDR + 8;
  EEPROM.get(GesamtMillimeter_ADDR, GesamtMillimeter);
  EEPROM.get(TripMillimeter_ADDR, TripMillimeter);
}

void saveMileage() {
  GesamtMillimeter_ADDR += 12;                  //immer in neue Zelle schreiben --> verlängert EEPROM Lebensdauer (Gesamtmillimeter 8 Byte, TripMillimeter 4 Byte -> Sprung um 12Byte
  if (GesamtMillimeter_ADDR > 1008) {
    GesamtMillimeter_ADDR = 0;
  }
  TripMillimeter_ADDR = GesamtMillimeter_ADDR + 8;              //Gesamtmillimeter ist 64bit Zahl --> braucht 8 Byte im EEPROM
  EEPROM.put(GesamtMillimeter_ADDR, GesamtMillimeter);
  EEPROM.put(TripMillimeter_ADDR, TripMillimeter);
}

void resetEEPROM() {
  for (unsigned int i = 0 ; i < EEPROM.length() ; i++) {
    EEPROM.write(i, 0);
  }
  GesamtMillimeter = 0;
  TripMillimeter = 0;
  //Serial.println(F("FACTORY-RESET"));
}
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
29.07.2020, 21:47
Beitrag #2
RE: Motorrad-Tacho (Nano) robust gegen Störungen machen
(29.07.2020 18:31)SebastianM schrieb:  Denkt ihr dass ich damit Aussicht auf Erfolg habe? Oder fallen euch noch weitere Maßnahmen ein? EMV ist leider nicht meine Stärke, daher bin ich auf Hilfe angewiesen..
Das ist sehr schwer zu beantworten. In jedem Projekt mit Verbrennungsmotor reagiert das anders. Da muss man einfach mal probieren.

Aber der Wek mit abgeschirmtem Kabel ist der Richtige.
Auch mit einem kleineren Pullup liegst du richtig.

Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. Cool
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
30.07.2020, 17:08 (Dieser Beitrag wurde zuletzt bearbeitet: 30.07.2020 17:57 von Chopp.)
Beitrag #3
RE: Motorrad-Tacho (Nano) robust gegen Störungen machen
Hallo,

Hast du einen Bekannten, der ein Oszilloskope hat ?
Wenn nicht, dann einen Bekannten in einer Werkstatt mit Bosch Tester ?

Nur wenn man die Störimpulse kennt, kann man sie mit einen Filter geziehlt aussperren.

Aber ein Versuch mit einen RC Tiefpass 4,8 KHz - 5,89 KHz ( 330 Ω - 270 Ω , 100nF ) könnte schon helfen.

Da ich ja nicht weiß, wie schnell sich dein Rad ( Impulse ) drehen kann,
kannst du ja hier dein Filter selbst berechnen.

Sehr nützlich ist auch ein Filter in der Zuleitung zum Nano.
( Im einfachsten Fall ein billiges für Autoradios )

Edit: Habe mal bei mir nachgerechnet ( nur Theoretisch );
Also, meine Virago 3LP hat einen 100/90-19 Vorderreifen.
Der hat einen Abrollumfang von 201,4 cm.
Die gefahrene Strecke ist ja: Km/h : 3,6 = Meter pro sec.
bei 100 Km/h = 27,78 m/sec. mein Rad dreht 13,79 U/sec.
bei 200 Km/h = 55,56 m/sec. mein Rad dreht 27,58 U/sec.
Also würde ja ein Tiefpass von 100Hz locker bei mir reichen ( 1 Impuls pro Umdrehung ),
da mein Motor eine Leehrlaufdrehzahl von 950 U/min. hat.
Bei einen Widerstand von 1,5 KΩ und 1 µF ergibt das einen Tiefpass von 106,1 Hz.
Soviel zur Theorie, aber praktisch kann das anders aussehen.
Wenn das nicht funktionieren sollte, hilft wie geschrieben nur ausmessen mit einen Ozzi.

Gruß, Markus

Noch ein Nachtrag; Habe überlesen das du einen 560 Ω Widerstand nehmen wolltest.
Da würde in zusammenhang mit einen 1µF Kondensator ca: 285 Hz rauskommen.
Also auch locker weit unter Leerlaufdrehzahl, also alles im grünen Bereich.

Gruß, Markus

Immer in Stress
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
30.07.2020, 20:59
Beitrag #4
RE: Motorrad-Tacho (Nano) robust gegen Störungen machen
Danke Markus für deinen Input.

Allerdings bin ich mir nicht sicher, ob ich mit einem (HW) Filter ans Ziel komme, da ich glaube dass die Frequenzen vom "Nutzsignal" und "Störsignal" recht nah bei einander liegen.

Meine boldor cb900 hat ne Leerlaufdrehzahl von ca. 1200upm. Pro Umdrehung werden zwei Zündfunken gesetzt. Das macht dann 40 Funken pro Sekunde, also 40Hz.

Bei 200km/h dreht sich mein Rad (Umfang 1840mm) ca. 30 mal pro Sekunde, also mit 30Hz.

Oder hab ich hier einen Denkfehler?

Eine weitere Frage hätte ich auch noch - du hast meinen 560Ohm Widerstand aufgegriffen. Allerdings müsste der Widerstand für einen Tiefpass doch in "Reihe" zur Sensorleitung geschaltet werden, oder? Ich hätte den 560er als Pullup, also auf +5V gelegt...

mfg und Danke nochmals...

Basti
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
31.07.2020, 15:33 (Dieser Beitrag wurde zuletzt bearbeitet: 31.07.2020 15:34 von Chopp.)
Beitrag #5
RE: Motorrad-Tacho (Nano) robust gegen Störungen machen
Ja, hast Recht.
Hab einen Denkfehler drinn.
Ich muss die Drehzahl ja noch durch 60 teilen um auf sec. Zu kommen.
Aber dann würde ein tiefpass mit 40 Hz ja gehen.
Gruß, Markus

Immer in Stress
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
01.08.2020, 09:50
Beitrag #6
RE: Motorrad-Tacho (Nano) robust gegen Störungen machen
(29.07.2020 18:31)SebastianM schrieb:  Vermutlich spuckt mir hier die Zündanlage in die Suppe.
Für gewöhnlich wird bei der Entstörung eines Fahrzeuges der Störer entstört. In diesem Fall würde ich mit entstörten Zündkerzen (die mit dem "R") mal anfangen...

(29.07.2020 18:31)SebastianM schrieb:  Den "Fehler" konnte ich auf die Leitung zum Reed-Schalter eingrenzen;
Vermutlich hat Du einen Schließer montiert, der -solange der Magnet nicht über ihm steht- offen ist. Die Leitung wird in dieser Zeit zur Antenne.
Was spricht dagegen, einen Öffner zu nehmen und die steigenden Flanken zu zählen?
Den Rest der Umdrehung schließt der Reed-Kontakt die Störungen gegen Masse kurz (wg. Pullup gehe ich davon aus, daß Du gegen Masse schaltest).
Grundsätzlich würde ich für solche Anwendungen einen Hall-Geber vorsehen (ich weiß, das auch professionell manchmal Reeds verwendet werden).

Just my 2 Cents
Gruß

Elux
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
01.08.2020, 18:30
Beitrag #7
RE: Motorrad-Tacho (Nano) robust gegen Störungen machen
@ Elux,

Beides in meinen Augen ein Guter Vorschlag.

Bei mir sind entstörte Kerzen und Stecker Serienmäßig dran.
Ich habe auch damals beim Umbau meiner Gegensprechanlage ( vor 18 Jahren ),
und Einbau der CB Funkanlage mit MiniDisc Walkman nie mit so Problemen gekämft.
Einzig ein Filter für Autoradios hatte ich damals in der Zuleitung verbaut.
Aber nicht weil Störungen waren, sondern ich hatte es noch übrig, & etwas Platz.
Meine Maschine ist jedoch aus Zeitgründen und anderen Gründen seit ein paar Jahren abgemeldet.
Der Wohnwagen ist jetzt erst mal wichtiger bei mir, und Arbeiten an der Hütte.
Villeicht mach ich das Moped nächstes oder übernächstes Jahr wieder fit.
Fehlt mir schon noch das Fahren....

Mal sehn, was der TO sagt, und ob er seine Störungen beseitigen konnte.
Gruß, Markus

Immer in Stress
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
01.08.2020, 20:37
Beitrag #8
RE: Motorrad-Tacho (Nano) robust gegen Störungen machen
(01.08.2020 18:30)Chopp schrieb:  Bei mir sind entstörte Kerzen und Stecker Serienmäßig dran.

@Markus
Klar, theoretisch sollte das Moppet serienmäßig nahentstört sein, "...aber grau ist alle Theorie..."; vielleicht hat er ja auch das Kabel vom Reed an der/den Primärleitung(en) der Zündung entlang verlegt. Keine Ahnung.
Ich habe mit Zwiebacksägen nur eher selten zu tun und die Beschreibung desTO gibt solche Details nicht her.
Er schreibt ja auch nur rudimentär darüber, ob und wenn ja wie er den Eingang verblockt hat.
Man weiß so wenig...

(01.08.2020 18:30)Chopp schrieb:  ...und Arbeiten an der Hütte.
Ja, der deutsche Volkssport => mache ich auch grade ;-) Zwar nicht direkt an der Hütte, aber ich baue derzeit Garage und pflastere.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  Outputs vom Nano Reinhard112 9 811 18.07.2020 19:31
Letzter Beitrag: hotsystems
  Arduino Nano Funktioniert nicht? acca500 7 1.582 10.05.2020 10:22
Letzter Beitrag: hotsystems
  Nano nur mit CH340 USB ?? Franz54 23 4.406 18.04.2020 21:16
Letzter Beitrag: Franz54
  Nano und 12Volt für Weichensteuerung Jan99 2 1.074 13.04.2020 12:30
Letzter Beitrag: hotsystems
  Stand-alone-Nano an USB leuchtet nicht AnFi 5 1.153 23.03.2020 10:08
Letzter Beitrag: SOFTHARD
Photo der NANO will nicht sensor 8 2.131 02.03.2020 17:26
Letzter Beitrag: hotsystems
  Suche gegen Bezahlung Hilfe bei Programmierung und LED-Technik baerenboldi 40 6.720 17.02.2020 22:34
Letzter Beitrag: Tommy56
  Stromversorgung Nano + Servos turold 13 2.760 04.02.2020 23:40
Letzter Beitrag: Chopp
  Sketch auf Arduino Nano laden berny46 5 1.663 05.01.2020 11:05
Letzter Beitrag: berny46
  Arduino Nano keine Verbindung zu nRF24L01 Modul Jonaz2 9 2.490 26.11.2019 21:38
Letzter Beitrag: hotsystems

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste