Zeigt her eure geilen Projekte!

780 Einträge (Stand 02.03.2021): Das Thema hat ja ein extrem großes Interesse und schreit eigentlich nach einem eigenen Forum! Auch die Vielfalt spricht dafür. Super!!

Hallo allerseits,

wie immer, wenn was fertig und in Nutzung gibt es Kleinigkeiten, die so nicht richtig gefallen. Wenn aller 5 bis 6 Sekunden nur ein Korn fällt, dann ist das fast langweilig. Deshalb habe ich das Programm etwas (fast neu) verändert.
Außerdem ist jetzt die Füllgeschwindigkeit der einzelnen Reihen von ihrer Breite abhängig. Die Kommentierung habe ich auch etwas ausführlicher geschrieben.

M.f.G.

Hans-Ulrich

#include <MD_MAX72xx.h >

#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 2 // Anzahl Segmente

#define CLK_PIN 13  // or SCK
#define DATA_PIN 11 // or MOSI
#define CS_PIN 10   // or SS

MD_MAX72XX su = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

// Adressen für die Koerner
byte zeile1 = 0; byte reihe1 = 0;
byte zeile2 = 0; byte reihe2 = 0;

int pause_5 = 136; int pause_5_5 = 149; int pause_6 = 162; // Zeiten Ablauf
int pause_1 = pause_5_5;
byte beep_1 = 50; byte beep_2 = 44; byte beep_3 = 50; // Zwischenzeiten 5 bei 5:30, 5 bei 6, 5:30 bei 6

byte ton_ausgang = 9; 
byte schalter1 = 8; byte schalter2 = 7; // Schalter fuer zeiteinstellung

int zw_unten = 0;     // Zaelwert unten, Position unten
int zw_oben = 0;      // Zaelwert oben, Zaelwert hauptschleife und Position oben
byte zw_laenge = 0;   // Waeglaenge des Korn
byte zw_anzahl = 0;   // Anzahl der Koerner
byte zw_laenge_1 = 0; // Weglaenge des Korn in der Schleife
byte zw_anzahl_1 = 0; // Anzahl der Koerner in der Schleife
byte zw_position = 7; // Position Korn

// Unterer Rombus, 9 -> Stererelement, X -> Fallhöhe, Y -> Anzahl Koerner, Z... -> Positionen
// X und Y gelten immer bis zum naechste Steuerelement.

byte unten [] = {9, 8, 01, 00,                                     //1   Zeile 01
                 9, 07, 02, 01, 10,                                //2   Zeile 02
                 9, 07, 01, 11, 9, 06, 02, 20, 02,                 //1+2 Zeile 03
                 9, 06, 04, 12, 21, 30, 03,                        //4   Zeile 04
                 9, 06, 01, 22, 9, 05, 04, 13, 31, 40, 04,         //1+4 Zeile 05     
                 9, 05, 06, 23, 32, 14, 41, 05, 50,                //6   Zeile 06
                 9, 05, 01, 33, 9, 04, 06, 24, 42, 15, 51, 06, 60, //1+6 Zeile 07
                 9, 04, 06, 34, 43, 25, 52, 16, 61, 07, 70,        //6   Zeile 08
                 9, 04, 01, 44, 9, 03, 04, 35, 53, 26, 62, 17, 71, //1+4 Zeile 09
                 9, 03, 04, 45, 54, 36, 63, 27, 72,                //4   Zeile 10
                 9, 03, 01, 55, 9, 02, 03, 46, 64, 37, 73,         //1+3 Zeile 11 
                 9, 02, 03, 56, 65, 74, 47,                        //3   Zeile 12
                 9, 02, 01, 66, 9, 01, 01, 75, 57,                 //1+1 Zeile 13
                 9, 01, 01, 67, 76,                                //1   Zeile 14
                 9, 0, 0, 77                                       //0   Zeile 14    
                };

// Oberer Rombus, Positionen

byte oben [] = {77,                              // Zeile 01
                67, 76,                          // Zeile 02
                66, 75, 57,                      // Zeile 03
                56, 65, 74, 47,                  // Zeile 04
                55, 46, 64, 37, 73,              // Zeile 05
                45, 54, 36, 63, 27, 72,          // Zeile 06
                44, 35, 53, 26, 62, 17, 71,      // Zeile 07
                34, 43, 25, 52, 16, 61, 07, 70,  // Zeile 08
                33, 24, 42, 15, 51, 06, 60,      // Zeile 09
                23, 32, 14, 41, 05, 50,          // Zeile 10
                22, 13, 31, 40, 04,              // Zeile 11
                12, 21, 30, 03,                  // Zeile 12
                11, 20, 02,                      // Zeile 13
                01, 10,                          // Zeile 14
                00                               // Zeile 15
               };

void setup() {
  su.begin(); su.control(MD_MAX72XX::INTENSITY, 0); // Start MD_MAX72xx.h; Helligkeit Minimum

  // Benoetigte Ports
  pinMode (ton_ausgang, OUTPUT);
  pinMode (schalter1, INPUT); digitalWrite (schalter1, HIGH);
  pinMode (schalter2, INPUT); digitalWrite (schalter2, HIGH);

}

void loop() {

  su.clear();  delay (100);  su.clear(); // Loeschen Anzeige

  // Zuordnung der Verzoegerungszeiten

  if (digitalRead (schalter1 ) == 0) {
    pause_1 = pause_5;
  };
  if (digitalRead (schalter2) == 0) {
    pause_1 = pause_6;
  }

  // Tonsignal für eingestellte Zeit

  if (pause_1 == pause_5 ) {
    tone(ton_ausgang, 500); delay (1000); noTone(ton_ausgang);
  };

  if (pause_1 == pause_5_5) {
    tone(ton_ausgang, 500); delay (1000); noTone(ton_ausgang); delay (1000);
    tone(ton_ausgang, 500); delay (1000); noTone(ton_ausgang);
  };

  if (pause_1 == pause_6) {
    tone(ton_ausgang, 500); delay (1000); noTone(ton_ausgang); delay (1000);
    tone(ton_ausgang, 500); delay (1000); noTone(ton_ausgang); delay (1000);
    tone(ton_ausgang, 500); delay (1000); noTone(ton_ausgang);
  };

  //Fuellen oberer Rombus

  zw_oben = 0;

  do {
    zeile2 = oben [zw_oben] / 10; reihe2 = (oben [zw_oben] % 10) + 8;
    su.setPoint(zeile2, reihe2, 1);
    zw_oben++;
  }
  while (zw_oben != 64);

  // Lesen Steuerzeichen und Ausgabe der Koerner

  zw_unten = 0; zw_oben = 0;

  do {
    if (unten [zw_unten] == 9) {
      zw_unten++; zw_laenge = unten [zw_unten]; zw_unten++; zw_anzahl = unten [zw_unten]; zw_unten++;
    };

    zw_anzahl_1 = zw_anzahl;// Uebernahme der Daten fuer aeußeren Zyklus (Anzahl der Ketten)

    do {

      zw_laenge_1 = zw_laenge; zw_position = 7;  // Uebernahme der Daten fuer inneren Zyklus (Anzahl Koerner der Kette und Ausgabe)

      do {
        if (zw_laenge_1 != 0) {
          su.setPoint (zw_position, zw_position, 1); delay (pause_1);
          su.setPoint (zw_position, zw_position, 0); zw_position--;
          zw_laenge_1--;
        }
      }
      while (zw_laenge_1 != 0);

      if (zw_anzahl_1 != 0) {
        zw_anzahl_1--;
      };
      delay (pause_1 * 5);
    }
    while (zw_anzahl_1 != 0);

    // Ausgabe der gefallenen Koerner

    zeile1 = unten [zw_unten] / 10; reihe1 = unten [zw_unten] % 10;
    su.setPoint(zeile1, reihe1, 1);
    zw_unten++;
    zeile2 = oben [zw_oben] / 10; reihe2 = (oben [zw_oben] % 10) + 8;
    su.setPoint(zeile2, reihe2, 0);
    zw_oben++;

    // Ausgabe Signal Zwischenzeiten

    if (zw_oben == beep_1 && pause_1 == pause_5_5) {
      tone(ton_ausgang, 500);
      delay (1000);
      noTone(ton_ausgang);
    }

    if (zw_oben == beep_2 && pause_1 == pause_6) {
      tone(ton_ausgang, 500);
      delay (1000);
      noTone(ton_ausgang);
    }
    if (zw_oben == beep_3 && pause_1 == pause_6) {
      tone(ton_ausgang, 500);
      delay (1000);
      noTone(ton_ausgang);
    }
  }
  while (zw_oben != 64);

  // Ausgabe Endsignal

  tone(ton_ausgang, 500); delay (1000);
  noTone(ton_ausgang); delay (500);
  tone(ton_ausgang, 800); delay (1000);
  noTone(ton_ausgang); delay (500);
  tone(ton_ausgang, 500); delay (1000);
  noTone(ton_ausgang); delay (500);

  su.clear();

  // "Bildschirm und Batterieschoner" do while wird nicht verlassen.

  do {
    zeile1 = random(8); reihe1 = random (16);
    su.setPoint(zeile1, reihe1, 1); delay (100);
    su.setPoint(zeile1, reihe1, 0);
  }
  while (zw_oben != 0);
}

// HUK Sanduhr V2-2 06.03.2021

Keine Angst vor dem ESP8266-01 bzw. ESP-01

In zahlreichen Diskussionen hier oder in anderen Foren wird gern vom ESP-01 (bisher auch von mir) abgeraten, da dieser sehr viel umständlicher zu verwenden ist. Das "Umständlich" bezieht sich auf das Flashen des Sketches.

Damit es mit dem ESP-01 weniger Probleme gibt, empfehle ich immer einen eigenen Sketch zu Flashen und nicht mit der vorhandenen Firmware und den AT-Befehlen zu arbeiten. Mit 1MByte Flash hat der ESP-01 erst mal genug Platz für umfangreiche Projekte. Eine kleine Einschränkung gibt es, wenn das Projekt mit einer Webseite auf Spiffs oder LittleFS ausgestattet wird.
Dann wird es für eine komfortable Programmierung über OTA eng bis geht nicht.

Aber auch hier gibt es eine Lösung, dazu später mehr.

Auch wenn der ESP-01 nur 4 nutzbare GPIO's hat, kann dieser mit passender Erweiterung per I2C auch für
komplexere Projekte eingesetzt werden.
Der Reiz für mich war es, "minimalistisch" meine Projekte umzusetzen.
So entstanden in kurzer Zeit folgende kleine Projekte.

  1. Gaszähler auslesen (nach Fips) nur eben mit dem ESP-01
  2. Anzeige Drainagepumpe, auf Webseite der Pumpenzahl
  3. Komplette Drainagepumpensteuerung inkl. Punkt 2.
  4. Weitere Projekte werden sicher folgen

In meinen Projekten spielt der I2C-Bus eine große Rolle und dank dessen lassen sich zahlreiche Erweiterungen
am ESP-01 betreiben.

Aktuell teste ich eine kleine Wetterstation, mit div. Sensoren am I2C-Bus sowie einem OLED die diese Daten
auf einer Webseite sowie dem OLED visualisiert. Weiterhin werden von einem anderen System per UART Daten
an die serielle Schnittstelle des ESP-01 gesendet, die auch auf der Webseite und dem OLED angezeigt werden.

Nach dem ersten Flashen (per FTDI-USB-Adapter) wird die UART freigeschaltet und jedes weitere Update per OTA geflasht. Damit dies auch sicher funktioniert, habe ich den ESP-01 mit 4MByte Flash bestückt.
Die Umbauanweisung dazu wurde freundlicherweise von combie hier bereit gestellt.

Um den ESP-01 zu flashen gibt es im Netz sehr viele Anregungen. Diese haben mir alle nicht gefallen, sodass
ich mir einen eigenen Programmer zusammen gelötet habe.
Schaltung dazu folgt im Anschluss.

Damit macht das Flashen (fast) genau so viel Spaß, wie bei einem Wemos D1 mini oder NodeMCU. Nur dass ich aktuell noch zuvor 2 Tasten drücken muss. Evtl. nehme ich noch eine kleine Erweiterung (2 zusätzliche Transistoren) vor, um den Flashvorgang ähnlich wie am Wemos/NodeMCU zu "automatisieren".

  1. Schaltung des Programmers

  1. Foto des Programmers inkl. Testprojekt

1 Like

Hallo allerseits,

das Alter bringt es mit sich, dass es mit dem Sehen und dem Hören nicht mehr so richtig funktionieren will. So geht es meinem Schwiegervater.
Eine normale Uhr kann er in der Nacht nicht erkennen, die sprechende Uhr geht ohne Hörgerät auch nicht so richtig. Also durfte ich mir was einfallen lassen.
Um eine möglichst große Anzeige zu erhalten, habe ich zwei MAX7219 8x32 4 in 1 Dot Matrix LED übereinander gesetzt. Als Uhr diente eine Real Time Clock RTC DS3231 I2C.
Die Schaltung weist keine Besonderheiten auf.

Das Programm dazu:

//Benötigte libraries
#include <MD_MAX72xx.h > // Anzeige
#include <Wire.h>        // I2C Schnittstelle
#include "RTClib.h"      // Real Time Clock ZS-042,

// Einbinder Anzeige
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 8 // Anzahl Segmente

#define CLK_PIN 13  // or SCK
#define DATA_PIN 11 // or MOSI
#define CS_PIN 10   // or SS

MD_MAX72XX uhr = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

// Einbinden Uhr

// SDA an A4
// SCL an A5

bool syncOnFirstStart = false; // true mit Pc synchronisieren, ansonsten false
RTC_DS3231 rtc;

// Variable Ausgabe Ziffern
byte offset = 0; int zahl = 0; byte minute_1 = 0; byte stunde_1 = 0; byte minute_2 = 0;
byte ziffer_1 = 0; byte ziffer_2 = 0; byte ziffer_3 = 0;  byte ziffer_4 = 0;

void setup() {

  // Daten Anzeige
  uhr.begin(); uhr.control(MD_MAX72XX::INTENSITY, 0); // Start MD_MAX72xx.h; Helligkeit Minimum
  uhr.clear();  delay (100);  uhr.clear(); // Loeschen Anzeige

  // Daten Uhr
  pinMode(LED_BUILTIN, OUTPUT);

#ifndef ESP8266
  while (!Serial); // fuer Leonardo/Micro/Zero relevant
#endif

  delay(3000); // Warte auf Terminal

  if (! rtc.begin()) {
    while (1);
  }

  if (rtc.lostPower() || syncOnFirstStart) {
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }

  uhr.clear();
  uhr.setPoint(6 , 16, 1); uhr.setPoint(2 , 48, 1);
}

void loop() {

  DateTime now = rtc.now();

  if (now.second() % 10 == 0) {
    digitalWrite(LED_BUILTIN, HIGH);

    minute_1 = now.minute(), DEC;
    stunde_1 = now.hour(), DEC;

    if ( stunde_1 == 24) {
      stunde_1 = 0;
    };
    if ( stunde_1 == 25) {
      stunde_1 = 1;
    };

    // Bearbeitung Ziffern // 1 und 2 Minuten, 3 und 4 Stunden, Ausgabe erfolgt nur beim Wechseln der Minute  
    if (minute_1 != minute_2) {
      minute_2 = minute_1;
      ziffer_1 = minute_1 % 10; ziffer_2 = minute_1 / 10;
      ziffer_3 = stunde_1 % 10; ziffer_4 = stunde_1 / 10;

      uhr.clear(); uhr.setPoint(6 , 16, 1); uhr.setPoint(2 , 48, 1); // Ausgabe Trennungszeichen

      offset = 0; zahl = ziffer_1;
      if (zahl == 1) {
        offset = 3;
      };
      ziffer ();

      zahl = ziffer_2;
      if (zahl == 1) {
        offset = 10;
      } else {
        offset = 7;
      }; ziffer ();

      offset = 18; zahl = ziffer_3;

      if (zahl == 1) {
        offset = 19;
      };
      ziffer ();

      zahl = ziffer_4;
      offset = 25;
      if (zahl == 1) {
        offset = 26;
      };

      if (zahl != 0) {
        ziffer ();
      };
    };
  };
}

// Zuordnung der Segmente zu den einzelnen Ziffern
//
//         **** 1 ****
//         *         * 
//         6         2
//         *         *
//         **** 7 ****
//         *         *
//         5         3
//         *         *
//         **** 4 ****       

void ziffer () {
  if (zahl == 0) {
    balken_1 (); balken_2 (); balken_3 (); balken_4 (); balken_5 (); balken_6 ();
  };

  if (zahl == 1) {
    balken_2 (); balken_3 ();
  };

  if (zahl == 2) {
    balken_1 (); balken_2 (); balken_7 (); balken_5 (); balken_4 ();
  };

  if (zahl == 3) {
    balken_1 (); balken_2 (); balken_7 (); balken_3 (); balken_4 ();
  };

  if (zahl == 4) {
    balken_6 (); balken_2 (); balken_7 (); balken_3 ();
  };

  if (zahl == 5) {
    balken_1 (); balken_6 (); balken_7 (); balken_3 (); balken_4 ();
  };

  if (zahl == 6) {
    balken_1 (); balken_6 (); balken_7 (); balken_3 (); balken_4 (); balken_5 ();
  };

  if (zahl == 7) {
    balken_1 (); balken_2 (); balken_3 ();
  };

  if (zahl == 8) {
    balken_6 (); balken_1 (); balken_2 (); balken_7 (); balken_5 (); balken_4 (); balken_3 ();
  };

  if (zahl == 9) {
    balken_7 (); balken_6 (); balken_1 (); balken_2 (); balken_3 (); balken_4 ();
  };
}

// Ausgabe der aufgerufenen Segmente

void balken_1 () {
  uhr.setPoint(1 , 6 + offset, 1); uhr.setPoint(1 , 5 + offset, 1); uhr.setPoint(1 , 4 + offset, 1);
  uhr.setPoint(1 , 3 + offset, 1); uhr.setPoint(1 , 2 + offset, 1); uhr.setPoint(1 , 1 + offset, 1);
}
void balken_2 () {
  uhr.setPoint(1 , 1 + offset, 1); uhr.setPoint(2 , 1 + offset, 1); uhr.setPoint(3 , 1 + offset, 1);
  uhr.setPoint(4 , 1 + offset, 1); uhr.setPoint(5 , 1 + offset, 1); uhr.setPoint(6 , 1 + offset, 1);
  uhr.setPoint(7 , 1 + offset, 1);
}
void balken_3 () {
  uhr.setPoint(7 , 1 + offset, 1); uhr.setPoint(0, 33 + offset, 1); uhr.setPoint(1 , 33 + offset, 1);
  uhr.setPoint(2 , 33 + offset, 1); uhr.setPoint(3 , 33 + offset, 1); uhr.setPoint(4 , 33 + offset, 1);
  uhr.setPoint(5 , 33 + offset, 1); uhr.setPoint(6 , 33 + offset, 1);
}
void balken_4 () {
  uhr.setPoint(6 , 38 + offset, 1); uhr.setPoint(6 , 37 + offset, 1); uhr.setPoint(6 , 36 + offset, 1);
  uhr.setPoint(6 , 35 + offset, 1); uhr.setPoint(6 , 34 + offset, 1); uhr.setPoint(6 , 33 + offset, 1);
}
void balken_5 () {
  uhr.setPoint(7 , 6 + offset, 1); uhr.setPoint(0 , 38 + offset, 1); uhr.setPoint(1 , 38 + offset, 1);
  uhr.setPoint(2 , 38 + offset, 1); uhr.setPoint(3 , 38 + offset, 1); uhr.setPoint(4 , 38 + offset, 1);
  uhr.setPoint(5 , 38 + offset, 1); uhr.setPoint(6 , 38 + offset, 1);
}
void balken_6 () {
  uhr.setPoint(1 , 6 + offset, 1); uhr.setPoint(2 , 6 + offset, 1); uhr.setPoint(3 , 6 + offset, 1);
  uhr.setPoint(4 , 6 + offset, 1); uhr.setPoint(5 , 6 + offset, 1); uhr.setPoint(6 , 6 + offset, 1);
  uhr.setPoint(7 , 6 + offset, 1);
}
void balken_7 () {
  uhr.setPoint(7 , 6 + offset, 1); uhr.setPoint(7 , 5 + offset, 1); uhr.setPoint(7 , 4 + offset, 1);
  uhr.setPoint(7 , 3 + offset, 1); uhr.setPoint(7 , 2 + offset, 1); uhr.setPoint(7 , 1 + offset, 1);
}

HUK V-4-17 31.03.2021

M.f.G.
Hans-Ulrich

Erstmal Applaus, Applaus :grinning:

Du würdest uns aber auch Dir einen Gefallen tun, wenn Du die Quellen der verwendeten Bibliotheken mit angibst.

EDIT: Danke für die Ergänzung!

Die RTC

https://github.com/StephanFink/RTClib/archive/master.zip

Den entpackten Ordner "RTClib-master" in "RTClib" umbenennen und in den Ordner „libraries“ einfügen.

Quelle AZ-Delivery „Kostenlose eBooks“.

Anzeige MD_MAX72xx.h

Library Manager; MD_MAX72XX von „majicDesigns“ suchen und installieren.

Es scheinen nur die Anschlüsse D10, D11 und D13 zu funktionieren.

Wire.h sollte schon da sein.

Auf Wunsch verlinke ich zu meiner Anleitung: ESP32 mit ESP-NOW als Sender und Webserver als Access Point

Im originalen Thema geht es um eine Modellautorennbahn, deren Ergebnisse des Renn-PCs an mehrere Stationen zur Anzeige per Funk übertragen werden sollen. Tatsächlich verwendet werden soll wohl NRF24. Aus einer 1. April Laune heraus habe ich das dann mal mit dem ESP32 versucht, da ich NRF24 nicht habe. Die Datenübertragung von einem ESP32 zu vier ESP32 (one-to-many) war kein Problem, zusätzlich sollten die Rundenzeiten aber auch noch ohne Router auf einem Händi sichtbar werden.

Spannend war, ob WiFi.mode(WIFI_AP_STA); tut, was ich mir vorgestellt hatte. “STA” für ESP-NOW und “AP” für die Anbindung an Läppi oder Händi. Genau so ein Beispiel mit “WIFI_AP_STA” und one-to-many konnte ich im WWW nicht finden, was für mich Motivation war, etwas darüber zu schreiben.

Ausgereift sind meine Programme noch nicht, aber grundsätzlich funktioniert es auf meinem Schreibtisch.

2 Likes

Ich hatte Anfangs des Jahres mal ein Netzteil gebaut - finde aber erst jetz wieder mal Zeit darüber zu
berichten.
In diesen Beitrag ging es um die richtige Ansteuerung des Displays:

https://forum.arduino.cc/t/gelost-anzeige-tft-flimmerfrei-nachtrag-netzteil-ist-fertig/697281/41

Hier im Anhang noch zwei Fotos für einen groben Überblick:

Alles nur "Quick & Dirty" verkabelt - aber es funktioniert.
In diesen Netzteil ist noch die "Beta - Platine" - daher auch die blaue Dratbrücken rechts hinten.
Mitlerweile habe ich für Bekannte eine neue Version die diesen Fehler nicht mehr hat.
Die Netzteilplatine ist ein Nachbau des ELV Bausatzes Universalnetzteil (im Web suchen).
Den Bausatz gibt es nicht mehr - daher musste ich eine neue Platine selbst entwerfen und anfertigen lassen.
Platinen selber zu ätzen lohnt sich nicht mehr - bei meinen Hersteller hat diese Platine ca. 15 Euro gekostet
(geht u.U. in China noch billiger).
Eine 5V Hilfsspannung für das "Arduinogedöns" brauchte ich auch noch - daher die Lochrasterplatine mit
Printtrafo usw.
Das Netzteil ist rein analog und ist bis max. 15V bei ca. 1,0A - 1,5A dimensoniert.
Mehr würde vom Trafo her gehen - mir reicht es aber und ich brauche keinen zu großen Kühlkörper.
Heut zu Tage sind die Schaltungen von der Stromaufnahme sowieso eher genügsam.
Alles passt daher in ein Bopla Ultramas Gehäuse UM52011L.
Die Frontplatte(n) habe ich anfertigen lassen - sieht besser aus als was "dahin gefeiltes".
Ich hatte vor vielen Jahren noch eines mit Siebensegment aufgebaut (gleicher Bausatz) -
da war von Arduino & Co. noch nicht die Rede:

Jetzt habe ich zwei und der "technische Forschritt" ist deutlich erkennbar:

Über die Materialkosten möchte ich nicht reden - deutlichen teurer als ein China Netzteil aber
man gönnt sich ja sonst nix.
Der Vorteil ist auch,man hat was eigenes hat welches man zur Not auch mal selbst reparieren und
updaten kann.
Wenn Interesse an weiteren Infos besteht - einfach mich kontaktieren oder auf meinen o.g.
Thread im Forum antworten.

Hier würde mich das verbaute Display und der Code für die Spritabfrage interessieren.

Er hat doch darauf zitiert.

Habe für die MoBa ein Mini-Projekt geschrieben und endlich auch mit millis() hantiert. Alles funktioniert: 2 Kreise, in jedem ein Hallsensor. Beim Auslösen des 1. bremst Lok 1 bis zum Halt, kurze Pause, bevor Lok 2 langsam beschleunigt. Mit Auslösen vom 2. Hallsensor umgekehrt, Lok 2 bremst langsam, kurze Pause, Lok 1 beschleunigt. Ich würde gern Eure Meinung hören (lesen), ob das noch eleganter geht, was zweckmäßiger ist und ob ihr ähnliche Projekte habt. Ich habe das "Werkeln" der Hallsensoren in eigene Funktionen gepackt.
Schon mal danke und frohe Pfingsten

/*
  DC-Motorsteuerung mit L298N zum Regeln
  von Anfahr- und Bremsverhalten mit 2 Hallsensoren,
  mit Pause  zwischen dem Brems- und Anfahrstart
  von Schorsch für ZFI
  23.05.21
*/

// Definition Hallpins und Hallstatus
const int hallSensorPin = 2;
const int hallSensorPin2 =3;
int hallStatus = LOW;     // 1. Hall aktiv
int hallStatus2=HIGH;  // 2. Hall paasiv

// Gleichstrommotor 1
int GSM1 = 10;
int in1 = 9;
int in2 = 8;

// Gleichstrommotor 2
int GSM2 = 5; //IN B
int in3 = 7; // IN 3
int in4 = 6;  // IN 4
unsigned long anfang = 0;
const long warte = 2000; //Pause zwische M1 und M2 im Loop
void setup()
{
  Serial.begin(9600);
  pinMode(GSM1, OUTPUT);    
  pinMode(GSM2, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
pinMode(hallSensorPin, INPUT);
pinMode(hallSensorPin2, INPUT);
if (hallStatus ==LOW) 
  {                        // Beschleunigen M1 als Zustand nach Einschalten
  for (int i = 0; i <=240; i += 20) //in 40-iger Schritten bis Maximalgeschwindigkeit
    { 
    digitalWrite(in1, HIGH);  
    digitalWrite(in2, LOW);   // Motor 1 beginnt zu rotieren
    analogWrite(GSM1, i); // Motor 1 beschleunigt 
    delay(100);
    }
  }
}
void HALL1A() // Funktion für Hallsensor1
{
// Bremsen M2
  if (hallStatus ==LOW) 
  {
  for (int i = 240; i >=0; i -= 40) //in 40-iger Schritten bis Maximalgeschwindigkeit
    { 
    digitalWrite(in3, HIGH);  
    digitalWrite(in4, LOW);   // Motor 2 beginnt zu rotieren
    analogWrite(GSM2, i); // Motor 2 bremst
    delay(500);
    }
  }
// Beschleunigen M1
   if (hallStatus ==LOW) 
   {
    anfang =millis();
    while (millis()-anfang < warte); //nach dem Bremsen M1 warten=Halt, dann 
    for (int i = 0; i <=240; i += 40) //in 40-iger Schritten bis Maximalgeschwindigkeit
      { 
    digitalWrite(in1, HIGH);  
    digitalWrite(in2, LOW);   // Motor 1 beginnt zu rotieren
    analogWrite(GSM1, i); // Motor 1 beschleunigt 
    delay(100);
      }
   }
}
void HALL1B() //Funktion für Hallsensor 2
{
// Bremsen M1
 if (hallStatus2 ==LOW) 
 {
  for (int i = 240; i >=0; i -= 40) //in 40-iger Schritten bis Maximalgeschwindigkeit
    { 
    digitalWrite(in1, HIGH);  
    digitalWrite(in2, LOW);   // Motor 1 beginnt zu rotieren
    analogWrite(GSM1, i); // Motor 1 bremst
    delay(500);
    }
  }
  anfang =millis();
  while (millis()- anfang < warte);
// Beschleunigen M2
  if (hallStatus2 ==LOW) 
  {
  for (int i = 0; i <=240; i += 40) 
    { //in 40-iger Schritten bis Maximalgeschwindigkeit
    digitalWrite(in3, HIGH);  
    digitalWrite(in4, LOW);   // Motor 2 beginnt zu rotieren
    analogWrite(GSM2, i); // Motor 2 beschleunigt 
    delay(100);
    }
  } 
}
 //=============================
void loop()
{
  hallStatus=digitalRead(hallSensorPin);
  hallStatus2=digitalRead(hallSensorPin2);
 HALL1A();
 HALL1B(); 
}

Danke für die Vorstellung, immer wieder spannend, wer was so treibt :slightly_smiling_face:

Da fände ich ein eigenes Thema besser geeignet als dieses, denn ich sehe doch einigen "Gesprächsbedarf" :wink:

Hallo agmue,
ich wollte nicht gleich eine Lawine lostreten, nur wissen, ob ich da in etwa richtig liege.

Hallo,

ja die Richtung stimmt, aber man kann Dinge zusammenfassen die zusammen gehören. Um den Thread hier nicht weiter zu strapazieren, weil das kein Frage Antwort Thread ist, mach einen eigenen Thread auf, wenn du mehr wissen möchtest, weil das ist speziell.

Hallo Freunde,
da das Thema doch sehr speziell ist, wird es hier fortgesetzt:

Modellbahn-Basteleien

1 Like

16Seg-Disp.ino (5.1 KB)
TWI-Sender.ino (4.3 KB)
Moin, ich hab auch mal ein kleines Projekt; ich hatte noch eine handvoll 16-Segment LEDs und einen ATMEGA32 denen langweilig war. Aus diesen habe ich ein 8-stelliges alphanumerisches Display gebastelt. Beim Nachbau ist zu beachten, dass die Anoden (+) der Displays über einen BD139 an Port A geschaltet werden, und die Segmente LOW-Active sind. Die Zuordnungen befinden sich im Script 16Seg-Disp, das Script TWI-Sender dient nur zu Demozwecken. Die Datenübertragung läuft über TWI, die ersten 8 Byte entsprechen dem Inhalt der jeweiligen Stelle, Byte 9 ist für den Dezimalpunkt. Ich hab mal ca 70 Zeichen definiert (ziemlich langweilige Angelegenheit).
Das Ganze soll mal die Anzeigeeinheit für ein Multimeter auf ADS1220 /55 /56 -Basis werden. (kennt sich einer mit den Dingern aus?)

Edith will wissen, ob man Bilder (nachträglich) drehen kann.



1 Like

Sieht recht schöh aus. "Starburst" Anzeigen gefallen mir !

1 Like

Ich auch gerade, danke

Platine mit Atmega1284 - ohne USB Interface nur ISP.
Da ich mit den China Nano Platinen immer Probleme habe, habe ich mir eine eigene Platine entworfen.
Die Größe ist ca. 20mm x 46mm - Programmierung nur über ISP (zum Vergleich die 40 polige DIL Fassung).
Aber man kann ja seine Projekte vorher Testen und dann Final auf eine Platine ohne USB per ISP
übertragen.
Kern der Platine ist ein AtMega1284 QFN - die abgebildete Platine ist nur teilbestückt.
Programmiert wird über MightyCore:
https://github.com/MCUdude/MightyCore
Wenn Interesse besteht, gern weiteres per Anfrage.

1 Like

Roll-a-Ball Autorennen

Alle Details direkt im Thread :passport_control: