Arduino hängt sich weg .........bitte um Hilfe

Moin,
ich habe mir einen Km/h Begrenzer gebastelt nach dem Prinzip:
Bei einer über ein Poti einstellbaren max Km/h schaltet ein Relais einen Stellmotor in meinem Fahrzeug welcher dann die Luftzufuhr drosselt und das Fahrzeug die Leistung/Geschwindigkeit reduziert.

Funktioniert auch soweit alles gut.

ABER: folgendes Problem
wenn ich an dem Relais ( 5v ) den Stellmotor anschließe ( wird über Masse geschaltet als Schließer, hat ca. 6A )
hängt sich der Arduino nach ein paar mal einwandfreier Funktion einfach "auf" . Auf dem LCD erscheinen komische Symbole oder er wird einfach blank ohne irgendwelche Symbole.
Die Funktion ist dann manchmal trotzdem noch da.
Manchmal friert auch das LCD ein und die Funktion ist weg.

Ich dachte schon das es evt. an einen "Spannungszusammenbruch" durch die höhere Stromaufnahme vom Stellmotor liegen könnte, aber das Relais schaltet doch nur einen Durchgang und ist bis 10A belastbar.

Auch habe ich den Arduino an eine seperate Stromquelle angeschlossen.

Kann es evt an meinem Code liegen: siehe (bin Ratlos, würde mich über Hilfe freuen)

Anlage: Bild der Verdrahtung

Code nur bis Arduino 1.5 !!!

//Anzahl Spalten des Display (16)
#define LCD_WIDTH 16

//Anzahl Zeilen des Display (2)
#define LCD_HEIGHT 2

// Pin fuer Reed-Kontakt, Digital-2 fuer Interrupt 0
#define REEDPIN 2

// Hardware-Interrupt fuer den Reed-Pin
#define REEDINTERRUPT 0

// Radumfang in mm
#define RADUMFANG 1900


#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int Relais = 11; // Relais an Pin 11
int potiWert = 0;

// build 2-line digit font data array
// Digits are 3 characters wide.
byte bignums[10][2][3] = {
// Define which characters to use for each number. 255 is a solid block; 254 is a space 
// The format is { {TopLeft, TopMiddle, TopRight}, {BottomLeft, BottomMiddle, BottomRight} }
{ {255, 0, 255}, {255, 1, 255} },        // data to display "0"
{ {0, 255, 254}, {1, 255, 1} },          // data to display "1"
{ {0, 5, 255}, {255, 1, 1} },            // data to display "2"
{ {0, 5, 255}, {1, 1, 255} },            // data to display "3"
{ {255, 1, 255}, {254, 254, 255} },      // data to display "4"
{ {255, 5, 5}, {1, 1, 255} },            // data to display "5"
{ {255, 5, 5}, {255, 1, 255} },          // data to display "6"
{ {0, 0, 255}, {254, 255, 254} },        // data to display "7"
{ {255, 5, 255}, {255, 1, 255} },        // data to display "8"
{ {255, 5, 255}, {254, 254, 255} }       // data to display "9"
};

void loadchars() {                        // This subroutine programs the custom character data into the LCD
  lcd.command(64);
// Custom character 0
  lcd.write(byte(B11111));
  lcd.write(byte(B11111));
  lcd.write(byte(B11111));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
 
// Custom character 1
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B11111));
  lcd.write(byte(B11111));
  lcd.write(byte(B11111));
 
// Custom character 2
  lcd.write(byte(B11111));
  lcd.write(byte(B11111));
  lcd.write(byte(B11111));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B11111));
  lcd.write(byte(B11111));
  lcd.write(byte(B11111));
 
// Custom character 3
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B01110));
  lcd.write(byte(B01110));
  lcd.write(byte(B01110));
 
// Custom character 4
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B01110));
  lcd.write(byte(B01110));
  lcd.write(byte(B01110));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
 
// Custom character 5
  lcd.write(byte(B11111));
  lcd.write(byte(B11111));
  lcd.write(byte(B11111));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B11111));
  lcd.write(byte(B11111));
 
// Custom character 6
  lcd.write(byte(B11111));
  lcd.write(byte(B11111));
  lcd.write(byte(B11111));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B11110));
  lcd.write(byte(B11111));
 
// Custom character 7
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));
  lcd.write(byte(B00000));

  lcd.home();
}

void printbigchar(byte digit, byte col) { // This subroutine prints the big font characters on the LCD screen
if (digit > 9) return;                   // reject anything above 9
for (int i = 0; i < 2; i++) {            // count i from 0 to 1
   lcd.setCursor(col*4 , i);              // set LCD cursor at correct point
   for (int j = 0; j < 3; j++) {          // count j from 0 to 2
     lcd.write(bignums[digit][i][j]);     // write proper block to LCD from array
   }
   lcd.write(254);                        // write an empty space
}
lcd.setCursor(col + 4, 0);               // move the cursor to the top line, col + 4
}


void setup(){
   Serial.begin(9600);
  pinMode(Relais, OUTPUT); // Pin 11 Ausgang
  pinMode(REEDPIN, INPUT_PULLUP); // Reedkontakt direkt und ohne Widerstand angeschlossen 
  lcd.begin(LCD_WIDTH, LCD_HEIGHT);
  loadchars();
  attachInterrupt(REEDINTERRUPT, reedISR, FALLING);
}

volatile byte reedCountSum;
volatile long reedMillisSum;

unsigned long lastReedMillis;

void reedISR()
{
  if (millis()-lastReedMillis>=25)  // 25ms entspricht max. 40 Radumdrehungen pro Sekunde
  {
    reedCountSum++;                 // eine Radumdrehung zaehlen
    reedMillisSum+=millis()-lastReedMillis;   // Zeit addieren
    lastReedMillis=millis();       // Zeit merken
  }
}

unsigned long gesamtUmdrehungen;

void tachoAnzeige()
{
  byte umdrehungen;
  unsigned long zeit;
  float kph, kilometer;
  int kphRounded;
  char buffer[10];
  noInterrupts();            // Interrupts sperren
    umdrehungen=reedCountSum;// Zaehlvariable umkopieren
    reedCountSum=0;          // Zaehlvariable auf 0 zuruecksetzen
    zeit=reedMillisSum;      // Zeitzaehler umkopieren
    reedMillisSum=0;         // Zeitzaehler auf 0 zuruecksetzen
  interrupts();              // Interrupts wieder zulassen
  gesamtUmdrehungen+= umdrehungen; // Aufsummieren aller Radumdrehungen
  kilometer=(float)gesamtUmdrehungen*(float)RADUMFANG/1000000.0; // Fahrtkilometerzaehler
  if (umdrehungen>0)
    kph=float(RADUMFANG)*(float)umdrehungen/(float)zeit*3.6;
  else
    kph=0.0;
   
    
  if(kph>potiWert/7) digitalWrite(Relais, HIGH);
  else       digitalWrite(Relais, LOW);
  
 
  lcd.setCursor(12, 0);
  dtostrf(kilometer,3, 1, buffer);
  

  
  if (potiWert/7<1000) lcd.print(' ');  // loescht die ueberfuessigen Zeichen beim runterregeln
  if (potiWert/7<100)  lcd.print(' ');
  if (potiWert/7<10)   lcd.print(' ');
  
  lcd.print(potiWert/7); // zeigt den PotiWert geteilt durch 7 also 1024 durch 7
  
  /* 
  lcd.setCursor(0, 0);
  dtostrf(kilometer,9,3,buffer);
  lcd.print(buffer);
  lcd.print(" km");
  lcd.setCursor(0, 1);
  lcd.print("KM/H ");
  dtostrf(kph,5,1,buffer);
  */
  kphRounded=int(kph+0.5); // auf ganze kph gerundet
  // Ausgabe kph in grossen Ziffern
  kphRounded = kphRounded % 1000;       // drop any digits above 999
  printbigchar(kphRounded / 100,0);     // print the speed hundreds
  kphRounded = kphRounded % 100;        // drop any digits above 99
  printbigchar(kphRounded/10,1);        // print the speed tens
  kphRounded = kphRounded % 10;         // drop any digits above 9
  printbigchar(kphRounded,2);           // print the speed ones
  lcd.setCursor(13, 1);
  lcd.print("max");
}


unsigned long letzteSekunde=0;
void loop()
{
 
  
  potiWert = analogRead(A0);
  Serial.println(potiWert/7);
  
  unsigned long dieseSekunde=millis()/500;
  // Tachoanzeige wird genau einmal pro Sekunde aktualisiert
  if (letzteSekunde != dieseSekunde)
  {
    tachoAnzeige();
    letzteSekunde=dieseSekunde;
  }
}

Ohne den Code auf Fehler oder Unstimmigkeiten überprüft zu haben, vermute ich eher ein Problem in der Hardware. Kannst du dazu mal einen Schaltplan erstellen bzw. die Schaltung (erkennbar) fotografieren?

Du hast banale EMV-Störungen. Deine Autoelektronik erzeugt einfach zuviele Störungen. Du musst deinen Aufbau EMV-fest machen.

Aber wie man das genau macht, lässt sich kaum erklären. Manchmal reicht es Kondensatoren zu setzen, Erdung, Spulen, Ferrite auf die Zuleitungen etc.

Grundsätzlich würde ich auf jedenfall die Elektronik in ein Gehäuse aus Blech bauen und das großflächig mit Minus/Chassis verbinden. Großflächig heist, nicht einfach ein Draht mit ner 3mm Blechtreibschraube dran tüfteln, sondern Kupfergeflecht zb von Antennenkabelabschirmung dran löten möglichst breitflächig und das dann auf kurzem Weg ans Gehäuse. Das ist normalerweise 50% der Miete. Nun können Störungen nur noch via Leitungen eindringen. Legst du das Relais nach Aussen, würde zumindest diese Störung auch wegbleiben. Deine Ansteuerung ist DC, folglich kannst du über die Relaisspule auch noch kleine Kondensatoren löten, 100nF ist da schon viel. Aber obs was bringt, könnte man nur in unserem Messlabor sehen. Wir können solche Prüfungen machen und glaub mir, da wirst du viele Entwickler treffen die bald heulen, weil ihnen EMV ihr ganzes Design zerstört. Müssen Platinen komplett neu entwerfen, weil die Entstörung einfach nicht hinhauen will.

Vermeide auch Lastkabel und Sensorig zusammen im selben Kabelbaum zu verlegen, wenn ja, verdrille es gut. Einfach nur parallel zusammenfassen wirkt quasi wie ein Trafo. Überträgt Hochfrequenz fast perfekt.

Eventuell helfen auch Klappferrite, das sind die Bollen zb an USB-Kabel oder Netzteile. Manchmal braucht man es, manchmal nicht. Wie unser Laborspezialist immer sagt: EMV ist Schätzen, aber auf hohem Niveau. Wirklich messen kann man nicht, nur Messen, etwas ändern und schauen obs besser oder schlechter wurde und daraus ableiten wohin der Weg gehen muss.

PS: Daimler hatte vor 20 Jahren ähnliche Probleme in seiner S-Klasse als sie CAN-Bussysteme verstärkt nutzen wollten und der Bus permanent durch Störungen abgekotzt hat. Bis hin zu Dauerreset weil irgendwo eine Massevebindung unsauber war. War sehr teuer für Daimler, vor 20 Jahren wusste man noch recht wenig über EMV und seine Wirkungen.

Das liegt vermutlich an der fehlenden "Freilaufdiode". Die musst du noch parallel zum Verbraucher schalten.

Im Anhang da ist der Verdrahtungsplan und das Relais.

Komisch nur das alles gut funktioniert wenn man nichts am Relais anschließt.
Ich habe es auch testweise auf dem Schreibtisch aufgebaut, gleiche Problem.

Mit der Freilaufdiode werde ich es versuchen. Sollte ich eine Freilaufdiode NUR am Stellmotor anbringen oder auch zwischen Vin-GND vom Arduino ?

Juergen-BWH:
Im Anhang da ist der Verdrahtungsplan und das Relais.

Komisch nur das alles gut funktioniert wenn man nichts am Relais anschließt.
Ich habe es auch testweise auf dem Schreibtisch aufgebaut, gleiche Problem.

Mit der Freilaufdiode werde ich es versuchen. Sollte ich eine Freilaufdiode NUR am Stellmotor anbringen oder auch zwischen Vin-GND vom Arduino ?

Am Relais ist schon eine Freilaufdiode vorhanden. daher funktioniert es auch mit dem Relais allein.

Auf die Größe (A) der Diode achten. Die muss schon einiges verkraften können.

Hast den Anhang vergessen... Freilauf- oder Löschdiode gehört antiparallel zur Relaisspule.
EMV könnte im eingebauten Zustand aber durchaus auch zum Problem werden, wie chefin bereits ausführte.

Anhang siehe unten:

Habe nun eine Freilaufdiode zwischen Spule Relais und Stellmotor gemacht.
Klappt aber immer noch nicht.

ich verstehe nicht das es keine Probleme gibt wenn ich am Relais (Schließer) nichts anklemme. Das sind doch zwei völlig unabhängige Stromkreise.

Ich habe den Arduino zum testen einen zweiten genommen und ihn mit einem USB Netzteil über 220V Steckdose versorgt.
Und den Stellmotor über eine eigene 12V Batterie nur über den Schließer des Relais schalten lassen.

Kapiere ich nicht :confused: :confused:

Juergen-BWH:
Habe nun eine Freilaufdiode zwischen Spule Relais und Stellmotor gemacht.
Klappt aber immer noch nicht.

Die Freilaufdiode gehört an den Verbraucher, deinen Stellmotor.

Wie liegen deine Kabel zum Motor ?
Evtl. musst du an die Relaiskontakte auch einen Snubber einsetzen.

Edit:
Die Freilaufdiode soll Spannungen kurzschließen, die beim Ausschalten der Verbraucher (Spulen) entstehen. Diese können Bauteile zerstören oder eben Controller außer Takt bringen.

es ist noch gar nicht im Motor verbaut, ich teste auf dem Schreibtisch ( keine EMV)

An den Verbraucher habe ich ebenfalls ein Freilaufdiode angebracht, trotzdem gleiche Problem.

das sind doch zweit Stromkreise die nicht miteinander verbunden sind.

Juergen-BWH:
es ist noch gar nicht im Motor verbaut, ich teste auf dem Schreibtisch ( keine EMV)

An den Verbraucher habe ich ebenfalls ein Freilaufdiode angebracht, trotzdem gleiche Problem.

das sind doch zweit Stromkreise die nicht miteinander verbunden sind.

Leider ist es doch EMV.

Was für ein Verbraucher ist denn jetzt dran ?

Ein 12V 6A Stellmotor, siehe Anhang. Mit Drosselklappe.

Ich würde es mit einem Snubber probieren.
Wichtig auch, Relais weit weg von Arduino.
Und evtl. den 10k-Pullup-Widerstand am Sensor kleiner machen.

Jetzt habe ich mal als Verbraucher am Relais eine 55Watt Glühlampe angeschlossen und habe keinerlei Probleme.
Scheinbar erzeugt der Stellmotor doch ein sehr starkes Magnetfeld ??

Juergen-BWH:
Jetzt habe ich mal als Verbraucher am Relais eine 55Watt Glühlampe angeschlossen und habe keinerlei Probleme.
Scheinbar erzeugt der Stellmotor doch ein sehr starkes Magnetfeld ??

das Magnetfeld ist nicht das Problem, sondern die Spannungen, die zurückfließen (Gegen-EMK).

Nochmal: Alles weit auseinander oder Snubber einsetzen.

ich werde es weiter auseinander bauen und berichten

HotSystems:
das Magnetfeld ist nicht das Problem, sondern die Spannungen, die zurückfließen (Gegen-EMK).

Nochmal: Alles weit auseinander oder Snubber einsetzen.

Danke, der Tip mit dem zurückfließen der Spannung hat mich auf eine "Test" Idee gebracht.
Ich habe einfach eine 12V 35Watt Glühlampe in Reihe der Minus-Leitung zum Relais gemacht und es läuft so wie es soll.
Aber ich werde mir einen Snubber besorgen.

siehe Anhang :o

Juergen-BWH:
Danke, der Tip mit dem zurückfließen der Spannung hat mich auf eine "Test" Idee gebracht.
Ich habe einfach eine 12V 35Watt Glühlampe in Reihe der Minus-Leitung zum Relais gemacht und es läuft so wie es soll.
Aber ich werde mir einen Snubber besorgen.

siehe Anhang :o

Das ist allerdings eine sehr eigenwillige Art der Entstörung.
Damit begrenzt du den Einschaltstrom für den Motor, was in deinem Fall offensichtlich auch hilft.

Kurze Frage noch.
Ich dachte daran mir einen Snubber selbst zu basteln mit einem Kondensator 0,7µF und einen Widerstand mit 12Ω ( Nach Faustformel 1Ω/V und 0,1µF/A)
Passt das ?

Hat der Motor eigentlich wirklich 6A? Ein Motor mit 72Watt erscheint mir für den Zweck stark überdimensioniert. Bei deiner Schaltung mit der Glühlampe können maximal 3A fließen. Was heißen die 53Ohm, die auf der Klappe stehen?