Arduino Uno Fehler - stürzt in void setup() ab

Ich habe leider ein Problem mit dem Arduino Uno. Programmieren mache ich mit PlatformIO und das klappt auch ganz gut. Von Arduino programmieren habe ich jetzt nicht viel schimmer, weswegen mir schon ein paar Fehler unterlaufen sind. Unter anderem, dass die Inputs wie aktiv auf low oder mit dem internen PullUp Widerstand verwendet werden müssen.

Jedenfalls habe ich an dem Arduino zwei Potis, drei Schalter, einen 128x64 Display, eine Batterie Anzeige über TM1651 und 16 Leds angesteuert über zwei 74HC595.

Es funktioniert eigentlich alles ganz prima, aber jetzt an einer Stelle wurde es sehr kniffelig. Ich habe gemerkt, dass der Eingang rauscht und wollte ihn mit einem PT1 Glied glätten. Deswegen kurz eine Klasse PT1 geschrieben und den Eingang eines Potis damit geglättet. Jetzt wollte ich noch den zweiten Poti damit glätten und der Arduino verabschiedet sich. Jetzt habe ich ein wenig rumprobiert und mir ist aufgefallen, dass der Arduino sich nur verabschiedet wenn ich zwei PT1 Objekte erzeuge. Bei einem PT1 Objekt funktioniert alles Klasse. Es geht sogar soweit, dass wirklich nur das erzeugen ausreicht, dass der Arduino sich irgendwo in der setup() Funktion aufhängt. Irgendwo unter "Battery_display.soc(50);" Ich hab keinen Schimmer wieso und hoffe hier auf Hilfe. Mir geht es auch wirklich darum zu diesem Thema Hilfe zu bekommen, um das Verhalten nachvollziehen zu können.

die main.cpp:

#include <Arduino.h>
#include "LedLightStateMachine.h"
#include "Battery.h"
#include "Disp.h"
#include "PT1.h"
#include "TM1651.h"

const int PIN_SHIFT = 3;   // connected to SHCP
const int PIN_STORE = 4;   // connected to STCP
const int PIN_DATA  = 5;  // connected to DS
const int LED_LIGHTS_SWITCH = 2; // on off led lights
const int LED_LIGHTS_SWITCH1 = 6; // on off led lights
const int LED_LIGHTS_SWITCH2 = 7; // on off led lights
const int LED_LIGHTS_DELAY = A0; // on off led lights
unsigned long  Led_interval = 10;
unsigned long  Led_last_change = 0;

const int PIN_BATTERY_CLK = 9;
const int PIN_BATTERY_DIO = 8;
const int PIN_BATTERY_STATE = A1;


LedLightStateMachine Leds(PIN_SHIFT,PIN_STORE,PIN_DATA);
Battery Battery_display(PIN_BATTERY_CLK,PIN_BATTERY_DIO);
//PT1 Pt1_Battery(1.0);
PT1 Pt1_Led_speed(50.0);

#include <SPI.h>
#include <Wire.h>
Disp Display(-1, &Wire);

void setup()
{
  pinMode(PIN_STORE, OUTPUT);
  pinMode(PIN_SHIFT, OUTPUT);
  pinMode(PIN_DATA, OUTPUT);
  pinMode(LED_LIGHTS_SWITCH, INPUT_PULLUP);
  pinMode(LED_LIGHTS_SWITCH1, INPUT_PULLUP);
  pinMode(LED_LIGHTS_SWITCH2, INPUT_PULLUP);
  pinMode(LED_LIGHTS_DELAY, INPUT);
  pinMode(PIN_BATTERY_CLK, OUTPUT);
  pinMode(PIN_BATTERY_DIO, OUTPUT);
  pinMode(PIN_BATTERY_STATE, INPUT);

  Battery_display.on();
  Battery_display.soc(50);

  Led_last_change = millis();
  Leds.set_mode(RUNNING);
  Leds.start();

   Display.init();
   delay(500);

   //Serial.begin(9600);
}

void loop ()
{
  //Serial.println("start into loop");

  // LED STATUS

  Display.update_led_status(digitalRead(LED_LIGHTS_SWITCH));
  Display.update_led_mode(digitalRead(LED_LIGHTS_SWITCH1), digitalRead(LED_LIGHTS_SWITCH2));

  int Led_interval_read = analogRead(LED_LIGHTS_DELAY);
  int Led_interval_read_PT1 = Pt1_Led_speed.get(Led_interval_read); //Led_interval_read; 
  int Led_interval_temp = (map(Led_interval_read_PT1,0,1023,0,1000) * map(Led_interval_read_PT1,0,1023,0,1000))/(1000); // nihct lineare Kurve
  Led_interval = min(30 + Led_interval_temp,999);
  Display.update_led_speed(Led_interval);
  if (millis() - Led_last_change > Led_interval){
    Leds.update();
    Led_last_change = millis();
  } 


  // BATTERIE STATUS
  int level = analogRead(PIN_BATTERY_STATE);
  int level2 = level; //Pt1_Battery.get(level);
  Battery_display.soc(map(level2,0,1023,100,0));
  Display.update_battery_level(map(level2,0,1023,100,0));

  //Display.on();
}

Die PT1.h

// PT1.h
#ifndef PT1_H
#define PT1_H

class PT1{
    public:
        PT1(double T1);
        int get(int u);

    private:
        double tau;
        int y;
        unsigned long delta_t;
};

#endif

Die PT1.cpp

#include "PT1.h"
#include <Arduino.h>

PT1::PT1(double T1) : tau(T1)
{
    delta_t = millis();
    y = 0;
}

int PT1::get(int u)
{
    if (millis() - delta_t < 10)
        return y;
    
    double delta = double(millis() - delta_t);
    double val = double(y) + double(u - y) * delta/(tau + delta);
    y = int(val);
    delta_t = millis();
    return y;
}

Würde ich jetzt //PT1 Pt1_Battery(1.0); in der main.cpp auskommentieren, dann schmiert das Programm ab. Nur das auskommentieren reicht schon.

Vielen Dank für eure Hilfe

Mir ist jetzt auch aufgefallen, dass wenn ich den Code wie oben lasse, aber den Serial Monitor hinzufüge um mir die Methode setup() aufzuzeigen, dann schmiert mir der Arduino ebenfalls ab. Die Methode sieht jetzt so aus:

void setup()
{
  Serial.begin(9600);
  delay(500);
  Serial.println("Set pin modes");
  pinMode(PIN_STORE, OUTPUT);
  pinMode(PIN_SHIFT, OUTPUT);
  pinMode(PIN_DATA, OUTPUT);
  pinMode(LED_LIGHTS_SWITCH, INPUT_PULLUP);
  pinMode(LED_LIGHTS_SWITCH1, INPUT_PULLUP);
  pinMode(LED_LIGHTS_SWITCH2, INPUT_PULLUP);
  pinMode(LED_LIGHTS_DELAY, INPUT);
  pinMode(PIN_BATTERY_CLK, OUTPUT);
  pinMode(PIN_BATTERY_DIO, OUTPUT);
  pinMode(PIN_BATTERY_STATE, INPUT);

  delay(500);
  Serial.println("Init Battery");
  Battery_display.on();
  Battery_display.soc(50);

  delay(500);
  Serial.println("Init LEDs");
  Led_last_change = millis();
  Leds.set_mode(RUNNING);
  Leds.start();

  delay(500);
  Serial.println("Init Display");
  Display.init();
  delay(500);

  //Serial.begin(9600);
}

Und die Ausgabe ist:

---- Opened the serial port COM3 ----
Set pin modes
Init Battery
Init LEDs
In�Set pin modes
Init Battery
Init LEDs
In�Set pin modes
Init Battery
Init LEDs
In�Set pin modes
Init Battery
Init LEDs
In�Set pin modes
Init Battery

Ist der Arduino eventuell überlastet? PlatformIO sieht noch viele Ressourcen:
RAM: [==== ] 36.2% (used 741 bytes from 2048 bytes)
Flash: [====== ] 57.8% (used 18644 bytes from 32256 bytes)

Dein Problem könntest du sicher lösen, wenn du an geeigneter Stelle serielle Ausgaben einbaust, an der du erkennen kannst, wo ein tatsächlicher Ausstieg erfolgt.

Aktuell sieht es danach aus, dass er hiernach:
Serial.println("Init LEDs");

abstürzt.

---- Opened the serial port COM3 ----
Set pin modes
Init Battery
Init LEDs
In�Set pin modes
Init Battery
Init LEDs
In�Set pin modes
Init Battery

Ich würde vermuten bei der Initialisierung vom Display. Da wird aber nicht viel gemacht. Die funktion hat den folgenden Rumpf:

display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS );
   
    display.clearDisplay();
    display.setTextColor(WHITE);
    display.setTextSize(1);
    display.setCursor(23,0);
    display.println("OLED - Display");
    display.setCursor(23,12);
    display.println("www.joy-it.net");
    display.setCursor(36,24);
    display.println("SBC-OLED01");
    display.display();

In den Funktionen

  Led_last_change = millis();
  Leds.set_mode(RUNNING);
  Leds.start();

werden nur die Variablen gesetzt. Das heißt, dass auch die Funktion start() eigentlich eher "Bereitschaft" oder so ähnlich heißen müsste. Die LEDs bzw. der 74HC595 werden noch nicht angesteuert.

Könnte es ein Speicherproblem sein?

Nein, ich meinte nach der Anweisung.
Die Anweisung führt er noch aus.

Er startet ja danach neu.
Und in einer Anweisung nachdem er die Leds initialisiert, stürzt er ab.

Setze mal serielle Ausgaben nach

Init LEDs

Zeige mal die

Okay. Meinst du so?

void setup()
  ...

  delay(500);
  Serial.println("Init Battery");
  Battery_display.on();
  Battery_display.soc(50);

  delay(500);
  Serial.println("Init LEDs");
  Led_last_change = millis();
  delay(100);
  Serial.println("- LEDs set mode");
  Leds.set_mode(RUNNING);
  delay(100);
  Serial.println("- LEDs reset and standby");
  Leds.start();
  delay(100);
  Serial.println("Init LEDs completed");

  delay(500);
  Serial.println("Init Display");
  Display.init();
  delay(500);

Dann kommt das:

---- Opened the serial port COM3 ----
Set pin modes
Init Battery
Init LEDs
- LEDs set mode
- LEDs reset and standby
Init LEDs completed
In�Set pin modes
Init Battery
Init LEDs
- LEDs set mode
- LEDs reset and standby
Init LEDs completed
In�Set pin modes
Init Battery
Init LEDs

Die LedLightStateMachine.h sieht folgend aus @wwerner :


// LedLightStateMachine.h
#ifndef LEDLIGHTSTATEMACHINE_H
#define LEDLIGHTSTATEMACHINE_H

enum LED_LIGHT_MODE {
  INIT,
  RUNNING,
  NIGHTRIDER,
  AGAINST,
  RANDOM
};

enum LED_LIGHT_COLOR {
  GREEN,
  BLUE
};

class LedLightStateMachine {
  public: 
    LedLightStateMachine(int SHIFT, int STORE, int DATA);
    void set_mode(LED_LIGHT_MODE mode);
    void set_state(int newstate[16]);
    int* get_state();
    void set_color(LED_LIGHT_COLOR newcolor);
    void start();
    void stop();
    void reset();
    bool update();
    void show();
    void ledupdown();
    void nightrider();
    void running();
    void randomstate(unsigned long millis);
    
  private:
    int shift;
    int store;
    int data;
    int led_light_state;
    LED_LIGHT_MODE mode;
    LED_LIGHT_COLOR color;
    int actualstate[16];
    bool nightrider_direction;
    bool is_running;
};

#endif

Danke für eure Hilfe :+1:

Wie viele LEDs sind angeschlossen und welche Stromversorgung hast du?

16 LEDs. Strom kommt kommt vom Arduino der seinen Strom vom USB erhält.

Dann kommentiere doch die einzelnen Funktionen mal nacheinander raus.
Hier angefangen:

Dann sollte sich der Fehler zeigen.

Ich habe jetzt alles einzeln aus und einkommentiert und bemerkt, dass er beim Display abschmiert. Ohne Display läuft es.
Es scheint in der setup die Funktion Display.init() zu sein, die den Absturz verursacht. ABER nur wenn ich den Serial Monitor initialisiere oder zwei Objekte vom Typ

PT1 

erzeuge. Ich hab zwar keine Ahnung von einem Arduino aber ich vermute, dass er entweder ein Problem mit der Spannungsversorgung hat oder noch eher, dass ihm der Speicher nicht ausreicht... kann man das irgendwie eingrenzen?

Nimm für Display
GitHub - olikraus/u8g2: U8glib library for monochrome displays, version 2

und die u8x8. Deine Lib wurde auf der Basis gebaut. Die u8x8 ist in den Beispielen, ist sehr sparsam.
Sind Vorwiderstände eingebaut für die LED?
Der UnoR3 kann gesamt nur 200mA, also rechnen was die LED dürfen verbraten.

Habe übersehen den LED Treiber

Dann solltest du den Fehler in deiner Display Ansteuerung suchen und beseitigen.

Dumme Frage.

Wie wird das Display angesteuert. ?? Spi // i2c // Normal mit vielen Pins. Und was für ein Display ist es.

Und messe mal nach wie viel Saft am Display ankommt und was es braucht.

Was für ein Display ist das überhaupt. Link ?!?

Gruß

Pucki

Hi @pucki007 , es wird über i2c angesteuert. Also 4 Kabel. Strom geht vom Arduino aufs Breadboard und von dort zum Display. Ich habe das hier: Joy-it SBC-OLED01 Display-Modul 2.4 cm (0.96 Zoll) 128 x 64 Pixel kaufen

In der Doku steht leider nichts zum Stromverbrauch. Ich frag mich, ob ich was falsch mache mit dem Wire übergeben. Aber das erschließt sich mir nicht warum es in manchen Situationen geht und in anderen im setup hängen bleibt.

Die lib ist adafruit und in der init wird das Beispiel aus der adafruit ausgeführt.

Das ist ein SSD1306 Display.

Dafür gibt es spezielle Treiber = Libs.

Lies mal dieses Beispiel.

Ich würde mal die Libs austauschen und dann den Code anpassen.

Ach und scanne mal die Adressen des Teils (internes Beispiel : i2c_scanner).

Die höchste Wahrscheinlichkeit für ein Absturz ist (wie beim PC) ein falscher "Treiber".

bzw. das zuweisen der falschen Adresse (oder eine doppelte Adresse).

Alternativ hilft dir vielleicht diese Zauberseite :wink: LCD wiki

Ich habe die Erfahrung gemacht das ein Austausch der Libs sehr oft das Problem löst.

Gruß

Pucki

Mein 1,3" braucht 45mA, dann ein 0,96 um die 30mA.

Wurde raten u8x8 nehmen braucht viel weniger RAM als LCD Wicki, dazu noch ein paar Schriftarten

Den Stromverbrauch kannst du nachmessen.

Zeig doch mal einen Link deiner Display-Library.
Und ja, wenn am I2C-Bus etwas falsch ist, kann das System abstürzen.
Wie hast du das Display angeschlossen ?
Verlötet oder mit Kabel ?
Hat das Diaplay am I2C Pullup-Widerstände, oder hast du welche eingebaut ?