Sketch zur Servo Ansteuerung hängt sich auf

Hallo zusammen,

ich habe hier ein Sketch zum Ansteuern von einem Servo, welches über ein Poti gesteuert und die Servo Position im Display angezeigt wird.

Das Programm läuft soweit nur friert es in unregelmäßigen abständen immer ein, d.h. das Display verharrt in der letzten angezeigten Position und drehen am Poti bring nichts, das Servos steht still.
Zumeist tritt das innerhalb der ersten Betriebsminute auf.

Ich habe diesen Nano, mit einem Linearen 500k Poti und diesem Display in weiß und einem Standard Servo.

Der Sketch sieht so aus:

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Servo.h>
#include <Fonts/FreeMonoBoldOblique12pt7b.h>

Servo myservo;  // create servo object to control a servo

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

int potpin = A7;  // analog pin used to connect the potentiometer
int val;    // variable to read the value from the analog pin
int val1;   // variable to scale Servo rotation to %

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define NUMFLAKES     10 // Number of snowflakes in the animation example

#define LOGO_HEIGHT   16
#define LOGO_WIDTH    16
static const unsigned char PROGMEM logo_bmp[] =
{ B00000000, B11000000,
  B00000001, B11000000,
  B00000001, B11000000,
  B00000011, B11100000,
  B11110011, B11100000,
  B11111110, B11111000,
  B01111110, B11111111,
  B00110011, B10011111,
  B00011111, B11111100,
  B00001101, B01110000,
  B00011011, B10100000,
  B00111111, B11100000,
  B00111111, B11110000,
  B01111100, B11110000,
  B01110000, B01110000,
  B00000000, B00110000 };

void setup() {
  //Serial.begin(9600);
  //  Serial.println(F("Start"));

  myservo.attach(9);  // attaches the servo on pin 9 to the servo object

  //SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    //Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(2000); // Pause for 2 seconds

  // Clear the buffer
  display.clearDisplay();

  // Draw a single pixel in white
  display.drawPixel(10, 10, SSD1306_WHITE);

  // Show the display buffer on the screen. You MUST call display() after
  // drawing commands to make them visible on screen!
  display.display();
  delay(2000);
  display.setFont(&FreeMonoBoldOblique12pt7b);
  display.clearDisplay();
  display.setTextSize(1);      // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE); // Draw white text
  display.cp437(true);         // Use full 256 char 'Code Page 437' font
}

void loop() {

  // put your main code here, to run repeatedly:
  analogReference(EXTERNAL);
  val = analogRead(potpin);            // reads the value of the potentiometer (value between 0 and 1023)
  val = map(val, 0, 1023, 0, 90);     // scale it to use it with the servo (value between 0 and 180)
  myservo.write(val);                  // sets the servo position according to the scaled value
  display.setCursor(0, 25);     // Start at top-left corner

  // Not all the characters will fit on the display. This is normal.
  // Library will draw what it can and the rest will be clipped.
  display.clearDisplay();
  display.print("Absaugung oben ");
//  display.setCursor(0, 36);     // Start at top-left corner
  val1 = map(val, 0, 90, 0, 100);
  display.print(val1); display.print("%");

  display.display();
  delay(15);   
  }

Woran kann das liegen? Ist da irgendwas mit der Ansteuerung des Displays oder was anderes faul?

Ich bin leider ganz blutiger Anfänger und verstehe wirklich nicht viel davon daher wäre ich um einfach Formulierten Feedback sehr froh :fearful:

Wie sind die einzelnen Komponenten (Nano, Servo, Poti, Display) angeschlossen?
Kannst Du ein Foto vom konkreten Aufbau machen, wo das erkennbar ist (oder eine Handzeichnung).

Falls der Servo seinen Strom direkt vom Nano bekommt: Das geht höhchstens mit einem "sehr kleinen" Servo gut und nur dann, wenn der Servo nicht belastet wird.
Der Servo braucht also praktisch immer eine eigene Stromversorgung.

Hallo

ich habe den Schaltplan mal auf skizziert.
Alle bekommen direkt 5V eingespeist von einem 24VDC Netzteil mit 3 A das über einen 3A DC DC Step Down 5V daraus macht.

Unbenannt.JPG

Unbenannt.JPG

Hallo,

ich tippe auf ein Speicherproblem. Die libs für das Display sind ziemlich speicherhungrig. Lass doch erst mal den überflussigen Kram mit den Schneeflocken weg und nimm den standard Zeichensatz. Minimal Beispiel aus der Lib ausbauen.

So wie ich das sehe willst Du doch nur einen text und einen Wert anzeigen im Loop.

Heinz

Kannst du ein paar serielle Ausgabe auf den seriellen Monitor einbauen, um festzustellen, wo der Sketch hängen bleibt ?

Ist dein Aufbau gesteckt oder gelötet ?
Wenn gesteckt, alle Verbindungen neu stecken. Der I2C-Bus ist sehr anfällig auf Kontaktfehler.

Rentner:
Hallo,

ich tippe auf ein Speicherproblem. Die libs für das Display sind ziemlich speicherhungrig. Lass doch erst mal den überflussigen Kram mit den Schneeflocken weg und nimm den standard Zeichensatz. Minimal Beispiel aus der Lib ausbauen.

So wie ich das sehe willst Du doch nur einen text und einen Wert anzeigen im Loop.

Heinz

Das ist richtig. Was den Speicher angeht da sieht es so aus wie im Bild.
Wie lasse ich den überschüssigen kram weg? ich habe das Sketch nur so bekommen und wie gesagt verstehe ich leider nicht all zu viel davon. Ich wäre froh wenn ihr mir genau sagt was unnötig ist?
Das?

#define NUMFLAKES     10 // Number of snowflakes in the animation example

#define LOGO_HEIGHT   16
#define LOGO_WIDTH    16
static const unsigned char PROGMEM logo_bmp[] =
{ B00000000, B11000000,
  B00000001, B11000000,
  B00000001, B11000000,
  B00000011, B11100000,
  B11110011, B11100000,
  B11111110, B11111000,
  B01111110, B11111111,
  B00110011, B10011111,
  B00011111, B11111100,
  B00001101, B01110000,
  B00011011, B10100000,
  B00111111, B11100000,
  B00111111, B11110000,
  B01111100, B11110000,
  B01110000, B01110000,
  B00000000, B00110000 };

HotSystems:
Kannst du ein paar serielle Ausgabe auf den seriellen Monitor einbauen, um festzustellen, wo der Sketch hängen bleibt ?

Ist dein Aufbau gesteckt oder gelötet ?
Wenn gesteckt, alle Verbindungen neu stecken. Der I2C-Bus ist sehr anfällig auf Kontaktfehler.

Nein das kann ich leider nicht da ich nicht weiß wie das geht...
Der Finale Einbau ist mit Sowas gemacht.

wortmann30:
Nein das kann ich leider nicht da ich nicht weiß wie das geht...
.....

Auch das kann man lernen. Aktuell liest sich das so: Ich weiß es nicht und interessiert mich auch nicht.
Also sieh dir den Sketch an, da stehen schon welche drin. Musst du nur nachmachen.

Edit: Dein Link funktioniert nicht.

Habe den Sketch ein wenig reduziert:

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Servo.h>
#include <Fonts/FreeMonoBoldOblique12pt7b.h>

Servo myservo;  // create servo object to control a servo

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

int potpin = A7;  // analog pin used to connect the potentiometer
int val;    // variable to read the value from the analog pin
int val1;   // variable to scale Servo rotation to %

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);


void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object

  //SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    for (;;); // Don't proceed, loop forever
  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(2000); // Pause for 2 seconds

  // Clear the buffer
  display.clearDisplay();

  display.setFont(&FreeMonoBoldOblique12pt7b);
  display.clearDisplay();
  display.setTextSize(1);      // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE); // Draw white text
  display.cp437(true);         // Use full 256 char 'Code Page 437' font
}


void loop() {
  // analogReference(EXTERNAL);     // <<<---- nicht in loop
  val = analogRead(potpin);            // reads the value of the potentiometer (value between 0 and 1023)
  val = map(val, 0, 1023, 0, 90);     // scale it to use it with the servo (value between 0 and 180)
  myservo.write(val);                  // sets the servo position according to the scaled value
  display.setCursor(0, 25);     // Start at top-left corner

  // Not all the characters will fit on the display. This is normal.
  // Library will draw what it can and the rest will be clipped.
  display.clearDisplay();
  display.print("Absaugung oben ");
  val1 = map(val, 0, 90, 0, 100);
  display.print(val1); display.print("%");

  display.display();
  delay(15);
}

Hinweis:
analogReference(EXTERNAL);
würde ich nicht in Loop ständig aufrufen. Und eigentlich macht das ohnehin wenig Sinn, wenn man als Analog-Reference ohnehin Vcc nimmt...

Mein Nachbau läuft ohne Probleme:

nano_servo_oled_pot01.png

Funktionierender Link aus #6:
https://www.ebay.de/itm/Breakout-Prototype-Proto-Shield-für-Arduino-Nano-mit-Schraubklemmen/254138274774

nano_servo_oled_pot01.png

Kleiner Hinweis:

wortmann30:
Unbenannt.JPG

SCL und SDA sind vertauscht.
SDA .... A4
SCL .... A5

A4 und A5 sind richtig angeschlossen aber falsch von mir gezeichnet :confused:

Irgendwie bin ich Total verwirrt, ich habe eben die Anschlüsse alle nochmals kontrolliert, also Verdrahtet scheint alles richtig zu sein. Wenn ich die Signale messe scheinen die auch ok zu sein.

Es sind bei mir 3 Arduins und 3 Display verbaut. Wenn ich diese einschalte starten alle erst mal aber einer steigt immer gleich aus. Der Erste auch auf dem Bild von Links nach rechts läuft zumeist, der Zweite steigt gerne aus und wenn ich ihn über den Reset Knopf am Nano neu starte steigt der dritte aus wenn ich den dritten neu starte steigt der zweite aus und immer so weiter....

Kann da sein das die sich irgendwie stören???

Ja, bei deiner Verkabelung sind Probleme vorprogrammiert.
Der I2C-Bus ist nur für wenige cm auf einer Platine konzipiert und nicht für mehrere cm oder m in einem Kabelbaum.

Das funktioniert def. nicht.
Du musst die I2C-Verbindung so kurz wie möglich ausführen und es müssen Pullup-Widerstände montiert werden.

Edit:
Du könntest das evtl. mit abgeschirmten Kabeln versuchen. Jedes Display für sich.
Aber optimal und sicher ist das nicht

Ok das heißt einen Wiedererstand von SDA und einer von SCL gegen 5v hängen, oder?
Wie groß sollen die sein? 10kohm? Ist die Position der Pull up Wiederstände egal, also am Nano oder eher am Display selber?

Ich vermute ich muss auch nur die SDA und SCL Kabel so kurz wie möglich halten? Die Spannungsversorgung sollte egal sein oder?

Kann es was helfen wenn ich die beiden Leitungen SDA und SCL in ein geschirmtes Kabel lege? Also ein altes Chinch Kabel bei dem ich den Schirm auf Masse lege? Wobei ich diese Fliegend jeweils Pärchen weise also SDA und SCL, in dem Kasten lasse so das sie sich nicht zu nahe kommen?
Oder kann es schon reichen die Kabel einfach getrennt zu verlegen?

Derzeit habe ich Flachbandkabel verwendet das ca. 90cm lang ist.

wortmann30:
Ok das heißt einen Wiedererstand von SDA und einer von SCL gegen 5v hängen, oder?
Wie groß sollen die sein? 10kohm? Ist die Position der Pull up Wiederstände egal, also am Nano oder eher am Display selber?

Ich vermute ich muss auch nur die SDA und SCL Kabel so kurz wie möglich halten? Die Spannungsversorgung sollte egal sein oder?

Kann es was helfen wenn ich die beiden Leitungen SDA und SCL in ein geschirmtes Kabel lege? Also ein altes Chinch Kabel bei dem ich den Schirm auf Masse lege? Wobei ich diese Fliegend jeweils Pärchen weise also SDA und SCL, in dem Kasten lasse so das sie sich nicht zu nahe kommen?
Oder kann es schon reichen die Kabel einfach getrennt zu verlegen?

Derzeit habe ich Flachbandkabel verwendet das ca. 90cm lang ist.

Dein Kabel ist hier die Fehlerursache, das ist so zu lang.

Und ja, je Display die Kabel (SDA und SCL) einzeln schirmen, die können dann aber nebeneinander laufen.
Den Schirm nur einseitig am Nano anbringen.

Ob das funktioniert ist nicht sicher, da die Kabel deutlich zu lang sind und damit weit außerhalb der Spezifikation sind. Du kannst später dadurch immer wieder Probleme bekommen.
Das ist nicht ausgeschlossen.

Die Pullup-Widerstände (nur ein i) 4,7k können am Nano oder am Display montiert werden. Je Leitung (SDA und SCL) einen gegen +5Volt.

I2C Kabel abschirmen finde ich kontraproduktiv da durch die Abschirmung die parasitäre Kapazität sehr viel größer wird.
Grüße Uwe

uwefed:
I2C Kabel abschirmen finde ich kontraproduktiv da durch die Abschirmung die parasitäre Kapazität sehr viel größer wird.
Grüße Uwe

Grundsätzlich gebe ich dir da Recht. Allerdings besser als Flachbandkabel bei 90cm Länge.
Um dem Problem mit den parasitären Kapazitäten gegenzusteuern, kann man die Pullup-Widerstände verkleinern.

Aber wie ich schon schrieb, ist das keine sichere und optimale Lösung.
Kabellänge auf max. 10cm verringern oder evtl. I2C-Portexpander (PCF8574) einsetzen.

Edit
Äh...son Mist, falscher Type:
Ich wollte I2C-Bus-Extender schreiben, P82B715 heißt der.

Hallo
danke für die tollen Tipps, sind das solche Module? Portexpander

Ich gehe davon aus, dass das eine Art Verstärker der Signale ist?

Und werden die einfach zwischen Nano und Display geschaltet an die SCL und SDA angeschlossen, oder benötigt es da noch eine Änderung im Sketch.

Was würde aber auch bedeuten das ich Drei von diesen Teilen einbauen muss?

Das sind port expander, du brauchst aber range extender

Das bedeutet sowas: P82B715
Gibt's die nicht als Modul oder sind das die Module.