Montag, 11. November 2019

ATtiny 85 für Herpa H0 309554 - MB S Schörling Kehrfahrzeug kommunal

In meinem Post Herpa H0 309554 - MB S Schörling Kehrfahrzeug kommunal mit Beleuchtung zeige ich das Herpa H0 Kehrfahrzeug mit Beleuchtungseffekte, die über einen ATtiny 85 gesteuert werden.

Das Modell im Video auf meinem YouTube Kanal!


Die Elektronikbauteile habe ich auf ein Stück Streifenplatine aufgebaut. Neben dem 8pol. IC Sockel mit gesteckten ATtiny 85 befindet sich auf der Platine noch ein 5V Spannungsregler (LM7805), der den ATtiny mit Spannung versorgt. Des weiteren habe ich noch einen 12V Spannungsregler (LM7812) verbaut, der die SMD LED´s für die Scheinwerfer, die Rückleuchten und die Armaturenbeleuchtung direkt versorgt. Auf der Rückseite der Platine habe ich für jeden belegten Pin des ATtiny´s einen 670 Ohm SMD Widerstand (1206) gelötet, an denen die Anoden der SMD LED´s angeschlossen wurden. Am Output vom 12V Spannungsregler habe ich zwei 4,7 kOhm SMD Widerstände gelötet. An einen Widerstand habe ich die Anoden der SMD LED´s für Scheinwerfer und Armaturenbeleuchtung angeschlossen, an den anderen Widerstand die Anoden der SMD LED´s für die Rückleuchten. Die Kathoden der SMD-LED´s habe ich an die auf der Platine vorbereiteten GND Lötpunkte angeschlossen.

Platine - Vorderseite
Platine - Rückseite



Schaltplan ATtiny 85 Herpa Kehrfahrzeug!



Boardansicht ATtiny 85 Herpa Kehrfahrzeug!



Nachfolgend veröffentliche ich den Sketch, gültig für den ATtiny 85, programmiert mit dem Arduino UNO R3.

// ATtiny45 / ATtiny85 Strassenreinigungsfahrzeug
// 2 Rundumleuchten asynchron, LED Monitor, LED Innenraum gedimmt
// Programming by https://meine-modelleisenbahn-digitalisiert.blogspot.com
// © 2019
//
// An dieser Stelle noch der Hinweis:
// der Nachbau geschieht auf eigene Gefahr.
// Ich übernehme keine Haftung für eventuell entstandene Schäden!
//

static byte flimmerHelligkeit;
unsigned long blaustartMillis; //globale Variable für Rundumleuchte
unsigned long int currentMillis; // Merker fuer millis()
enum Phase1 {ON1, OFF1, ON2, OFF2, ON3, OFF3, ON4, OFF4 }; // "Namen" fuer die 
Phasen Rundumleuchte
int d1[] = {60, 60, 60, 150, 60, 60, 60, 150 }; // Dauer der Phasen in ms für 
Rundumleuchte
Phase1 phase1; // Enthaelt die aktuelle Phase Rundumleuchte

const byte blauLED01 = 3; //LED 1 für Rundumleuchte 1
const byte blauLED02 = 4; //LED 2 für Rundumleuchte 2
const byte flimmerLED = 0; //LED für Flimmerleuchte
const byte armaturLED = 1; //LED Armaturbeleuchtung

void setup()
{
  pinMode(blauLED01, OUTPUT); //LED am Ausgang PB2 deklariert
  pinMode(blauLED02, OUTPUT); //LED am Ausgang PB3 deklariert
  pinMode(flimmerLED, OUTPUT); //LED am Ausgang PB0 deklariert
  pinMode(armaturLED, OUTPUT); //LED am Ausgang PB1 deklariert
  blaustartMillis = millis(); //initialisiere Startzeit Rundumleuchte
  phase1 = ON1; //Phase Rundumleuchte Start ON1
  currentMillis = millis(); //Festlegung der aktuellen Zeit (aktuelle Millisekunden seit Programmstart)
}

bool milliSekundenTakt(int dauer, long &alterWert)
{
  // Parameter "dauer": Dauer einer Blinkphase (an bzw. aus)
  // Parameter "alterWert": Variable zum Speichern des millis() Timers
  // Rückgabewert: true wenn die Zeit bis zum nächsten Umschalten abgelaufen ist,
sonst false
  if (millis() - alterWert < dauer) return false;
  while (millis() - alterWert >= dauer) alterWert += dauer;
  return true;
}

void loop()
{
  currentMillis = millis(); //Festlegung der aktuellen Zeit (aktuelle Millisekunden seit Programmstart)
  blau();
  flimmern();
  armatur();
}

void blau()
{ // Anfang Phase Rundumleuchte
  switch (phase1)
  {
    case ON1:
      if (millis() - blaustartMillis < d1[0])
      {
        digitalWrite(blauLED01, HIGH);
      }
      else
      {
        phase1 = OFF1;
      }
      break;

    case OFF1:
      if (millis() - blaustartMillis < d1[0] + d1[1])
      {
        digitalWrite(blauLED01, LOW);
      }
      else
      {
        phase1 = ON2;
      }
      break;

    case ON2:
      if (millis() - blaustartMillis < d1[0] + d1[1] + d1[2])
      {
        digitalWrite(blauLED01, HIGH);
      }
      else
      {
        phase1 = OFF2;
      }
      break;

    case OFF2:
      if (millis() - blaustartMillis < d1[0] + d1[1] + d1[2] + d1[3])
      {
        digitalWrite(blauLED01, LOW);
      }
      else
      {
        phase1 = ON3;
      }
      break;

    case ON3:
      if (millis() - blaustartMillis < d1[0] + d1[1] + d1[2] + d1[3] + d1[4])
      {
        digitalWrite(blauLED02, HIGH);
      }
      else
      {
        phase1 = OFF3;
      }
     break;

    case OFF3:
      if (millis() - blaustartMillis < d1[0] + d1[1] + d1[2] + d1[3] + d1[4] + d1[5])
      {
        digitalWrite(blauLED02, LOW);
      }
      else
      {
        phase1 = ON4;
      }
      break;

    case ON4:
      if (millis() - blaustartMillis < d1[0] + d1[1] + d1[2] + d1[3] + d1[4] + d1[5] + d1[6])
      {
        digitalWrite(blauLED02, HIGH);
      }
      else
      {
        phase1 = OFF4;
      }
      break;

    case OFF4:
      if (millis() - blaustartMillis < d1[0] + d1[1] + d1[2] + d1[3] + d1[4] + d1[5] + d1[6] + d1[7])
      {
        digitalWrite(blauLED02, LOW);
      }
      else
      {
        phase1 = ON1; blaustartMillis = millis();
      }
      break;
  }
}// Ende Phase Rundumleuchte

void flimmern()
{
  static long alterWert;
  static int flimmerDauer = 200;
  static byte flimmerHelligkeit;
  if (milliSekundenTakt(flimmerDauer, alterWert)) // Takt abgelaufen?
  {
    flimmerDauer = 1 + random(200); // neue Flimmerdauer als Zufallswert
    flimmerHelligkeit = random(3, 8); // neue Flimmerhelligkeit als Zufallswert 0-255
    // zwischen (xxx, xxx) oder von 0 bis (xxx)
    analogWrite(flimmerLED, flimmerHelligkeit);
  }
}

void armatur()
 {
  analogWrite(armaturLED, 3); //gedimmte Armaturenbeleuchtung
}

Weiterführende Links zur Programmierung des ATtinys 85 auf meinem Blog:


An dieser Stelle noch der Hinweis:
der Nachbau geschieht auf eigene Gefahr.
Ich übernehme keine Haftung für eventuell entstandene Schäden!

Keine Kommentare:

Kommentar veröffentlichen