Problemas de programation con ATTINY85 + Registro de desplazamiento 74HC595

Ante de todo Un feliz año nuevo a todos,

Espero que alguien que es bueno en la programación arduino puede ayudar, Primero voy a explicar y luego hago una pregunta o dos y ver si alguien por ahí puede ayudar, Comienza; Un buen amigo alemán y colega arduino me ha ayudado a modificar un antigua Proyecto Arduino alemán llamado "Blebetus House" donde usamos un arduino UNO para programar un integrat ATTINY85 para que en su turno controla 5 luces de casa (Leds) y el parpadeo simulado de un televisor (6to LED) usando PWM, en una casa o tienda en un maqueta ferroviaria.
Como he dicho, ahora hemos modificado el sketch para hacer que el parpadeo de la TV, es un televisor de color con 3 Leds en lugar de la 1 Led original, para que todavia tenemos las 5 luces de la casa (LED) hemos logrado eso usando un Registro de Desplazamiento 74HC595 (o más bien mi amigo alemán ha re-escrito el sketch), como se puede ver en el código que a dejado aquí abajo hizo esto diciendo al registro de desplazamiento que:

unsigned int dataPin = 0;   // Pin D0 verbunden mit DS von 74HC595 Pin14 SI
unsigned int clockPin = 1;  // Pin D1 verbunden mit SH_CP von 74HC595 Pin11 SCK
unsigned int latchPin = 2;  // Pin D2 verbunden mit ST_CP von 74HC595 Pin12 RCK

DataPin 14, ClockPin 11 y LatchPin 12 del registro de desplazamiento provienen de los pines 0, 1 y 2 del ATTINY85.

Dejando así los pins 3, 4 y 5 del ATTINY85 Libre.

Aquí Comienza mis problemas, Le pregunté a mi amigo si podíamos usar estos pins que a quedado libre en el ATTINY85 para aleatoriamente encender y apagar otras tres luces en la casa como lo hacemos con los pins 3,4,5,6 y 7 del Registro de desplazamiento 74HC595.

const byte leds[] = {3, 4, 5, 6, 7};    // LED Pins für das normale Blinken deklarieren

A continuación, mi amigo alemán respondió que sería mejor utilizar los pines 3 y 4 de la ATTINY85 para el registro de desplazamiento ya que els Pins 0 y 1 de la ATTINY85 son pins PWM de veredad y que sería mejor para los Leds. Así dejándonos ahora con pins 0,1 y 5 del ATTINY85 libre, también me dijo que pin 5 no se puede utilizar (no entiendo por qué no ..?)

Así que aquí están mis preguntas que no pude conseguir aclararar con nuestro amigo alemán Simplamente debido a la barrera del lenguaje y mierd......Traductor de Google ... :frowning: :frowning:

En primer lugar para cambiar el sketch para que el DataPin, LatchPin y Clockpin del registro de desplazamiento 74HC595 son como mi amigo alemán sugerido sería este el código correcto.

unsigned int dataPin = 3;   // Pin D3 verbunden mit DS von 74HC595 Pin14 SI
unsigned int clockPin = 4;  // Pin D4 verbunden mit SH_CP von 74HC595 Pin11 SCK
unsigned int latchPin = 2;  // Pin D2 verbunden mit ST_CP von 74HC595 Pin12 RCK

Y más importantemente ¿Puede alguien explicarme cómo tengo que escribir el codigo para que el ATTINY85 comprenda qué pins están en el registro de cambios 74HC595 y qué pins están en el ATTINY85 ya que ahora tenemos los pins 0 y 1 en el 74HC595 y los pins 0 y 1 en el ATTINY85 para utilizar. ??

Después tengo más preguntas Pero vamos a ir uno por uno

Saludos cordiales a todos y gracias de antemano

Carlos

Que confusa explicación por favor!! al menos para mi.
Veamos tu ATTINY85

Usas pines 3, 2 y 4 indicados como Analog input 1 a 3.
Los demas los veo disponibles a menos que me pierda de algo que no sepa. Es como todo ATMEL.
El problema es al momento de programarlo pero eso lo haras fuera del esquema que tienes.

Luego trabajar con el 595 es simplemente manejo de bits.
No pones código asi que poco puedo ayudarte pero yo a priorio y a riesgo de equivocarme no veo problema en usar el resto de los pines disponibles sea en el ATTiny85 como en el 595.

Como esta página hay muchas, tal vez sirva, tal vez sea algo que ya sepas.

Uhhhhhhhh Uhhhhh Surbyte,

Creo que el mejor sera postear todo el sketch original y intento a explicar.

/*  Simulation "belebtes Haus für die Modellbahn" */
// ATMEL ATTINY85 / ARDUINO
//
//                  +-\/-+
// Ain0 (D 5) PB5  1|    |8  Vcc
// Ain3 (D 3) PB3  2|    |7  PB2 (D 2)  Ain1
// Ain2 (D 4) PB4  3|    |6  PB1 (D 1) pwm1
//            GND  4|    |5  PB0 (D 0) pwm0
//                  +----+

unsigned int dataPin = 0;   // Pin D0 verbunden mit DS von 74HC595 Pin14 SI
unsigned int clockPin = 1;  // Pin D1 verbunden mit SH_CP von 74HC595 Pin11 SCK
unsigned int latchPin = 2;  // Pin D2 verbunden mit ST_CP von 74HC595 Pin12 RCK

const byte pwmFlimmerPins[] = {0, 1, 2}; // PWM Pin für das "analoge" Flimmern
uint32_t flimmerStart, flimmerEnd;      // Anfangs- und Endzeiten für das Flimmern
const uint32_t flimmerZeit = 10;        // PWM-Zeit in ms
const byte leds[] = {3, 4, 5, 6, 7};    // LED Pins für das normale Blinken deklarieren
const uint32_t ledtakt[] = {9000, 1500, 2200, 3333, 5000};  // LED Blinktakt in Millisekunden für diese Pins
uint32_t ledtime[sizeof(leds)];   // Variablen zum Merken von millis()-Zeiten beim Schalten/Blinken
byte muster;

void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
}

void blinkenImTakt() {
  // Alle gleichmäßig blinkenden LEDs in ihrem eigenen Takt blinken lassen
  for (byte i = 0; i < sizeof(leds); i++) // alle LEDs in einer Schleife durchgehen
  {
    if (millis() - ledtime[i] >= ledtakt[i]) // Takt für diese LED abgelaufen?
    {
      ledtime[i] = millis();
      digitalWrite(leds[i], !digitalRead(leds[i])); // wenn ja ==> Umschalten
      if (bitRead(muster, leds[i])) {
        bitWrite(muster, leds[i], LOW);
      } else {
        bitWrite(muster, leds[i], HIGH);
      }
      if (leds[i] == leds[0] && bitRead(muster, leds[i])) // Pin-0 LED wurde gerade eingeschaltet
      {
        flimmerStart = millis() + 2000; // Anfangszeit für das Flimmern setzen
        flimmerEnd = millis() + 8000; // Endzeit für das Flimmern setzen
      }
    }
  }
}

void flimmernPwmPins() {
  // Die flimmernde LED im Zufallsmodus flimmern lassen
  static uint32_t alterWert[sizeof(pwmFlimmerPins)];
  static uint32_t flimmerDauer[sizeof(pwmFlimmerPins)] = {5, 5, 5};
  static uint32_t fS[sizeof(pwmFlimmerPins)];
  static byte flimmerHelligkeit[sizeof(pwmFlimmerPins)];
  for (byte i = 0; i < sizeof(pwmFlimmerPins); i++) {
    if (millis() - alterWert[i] >= flimmerDauer[i]) // Takt abgelaufen?
    {
      alterWert[i] = millis();
      flimmerDauer[i] = 1 + random(100); // neue Flimmerdauer als Zufallswert
      if (millis() > flimmerStart && millis() < flimmerEnd)
        flimmerHelligkeit[i] = random(flimmerZeit); // neue Flimmerhelligkeit als Zufallswert
      else
        flimmerHelligkeit[i] = 0; // Flimmern aus wenn falsche Zeit zum Flimmern
    }
    if (flimmerHelligkeit[i]) {
      if (millis() - fS[i] >= flimmerHelligkeit[i]) {
        bitWrite(muster, pwmFlimmerPins[i], HIGH);
      } else {
        bitWrite(muster, pwmFlimmerPins[i], LOW);
      }
      if (millis() - fS[i] >= flimmerZeit) {
        fS[i] = millis();
      }
    } else {
      bitWrite(muster, pwmFlimmerPins[i], LOW);
      fS[i] = millis();
    }
  }
}

void updateShiftRegister(byte bitfolge)
{
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, bitfolge);
  digitalWrite(latchPin, HIGH);
}

void loop() {
  blinkenImTakt();
  flimmernPwmPins();
  updateShiftRegister(muster);
}

Ok Como seguramente puedes ver lo que hacemos basicamente aqui es decir a el Registro de desplazamiento 74HC595 que el pins 11, 12 y 14, Shift Register DataPin, ClockPin y LatchPin viene dels Pins D0, D1 y D2 del ATTINY85 como el pin 8 y 4 del ATTINY85 son el VCC y GND esto nos deja els pins D3, D4, y D5 Libre.

Despues como puedes ver En El 74HC595 utilizamos els Pins 0, 1 y 2 Como Leds con un "Flicker" Effect Simulando las Luces que Parpadeo en un TV de Color Cuando por example estas mirrando una pelicula y Els Pins 3,4,5,6 y 7 Como Leds Que se enciende y Apaga con Tiempos Aletoria a Intervalos Aletoria, contando que els pins 8 y 13 enviamos a GND, Els Pins 16 y 10 enviamos a VCC y els pins 14, 11 y 12 recibe els commands del ATTINY85 en el registro de dezplazamiento solo nos queda libre el pin 9 que corrigeme si estoy equivocado pero creo que no puedamos utilizar.

Lo que quiero hacer es como a sugerido mi amigo aleman cambiar els pins D0 y D1 del salida del ATTINY85 Para els Pins D3 y D4 asi Dejando Els Pins D0, D1 y D5 en el ATTINY85 Libre, en estas pins Igual que en els Pins 3,4,5,6 y 7 Del Registro de desplazamiento quiero posar 3 Leds Mas que enciende y apaga con Tiempos Aletoria a Intervalos Aletoria. Despues quiero ampliar el sketch a un seconda registro de dezplazamiento asi dejando mi controlar un total de 16 Leds que s'enciende y apaga y els 3 leds que simula el TV.

Esperando que asi tienes un millor idea de lo que estoy intentando a hacer, y sera mas facil de prestarme su ayuda

un saludo cordial y gracias por adelantado

Carlos

Una primera parte resuelta, el cambio de los pines para liberar otros.

/*  Simulation "Animación de Ferrocarril" */
// ATMEL ATTINY85 / ARDUINO
//
//                  +-\/-+
// Ain0 (D 5) PB5  1|    |8  Vcc
// Ain3 (D 3) PB3  2|    |7  PB2 (D 2)  Ain1
// Ain2 (D 4) PB4  3|    |6  PB1 (D 1) pwm1
//            GND  4|    |5  PB0 (D 0) pwm0
//                  +----+

unsigned int dataPin  = 3;  // Pin D0 unido a DS de 74HC595 Pin14 SI
unsigned int clockPin = 4;  // Pin D1 verbunden mit SH_CP de 74HC595 Pin11 SCK
unsigned int latchPin = 2;  // Pin D2 verbunden mit ST_CP de 74HC595 Pin12 RCK

const byte pwmFlimmerPins[] = {0, 1, 2}; // PWM Pin para la "analoge" parpadeo
uint32_t StartParpadeo, FinalParpadeo;       // Anfangs- und Endtiempoen para la parpadeo
const uint32_t flimmertiempo = 10;       // PWM-tiempo in ms
const byte leds[] = {3, 4, 5, 6, 7};     // LED Pins para la Animación Normal
const uint32_t ledtakt[] = {900, 150, 220, 333, 500};  // LED Blinktakt in milisegundos für diese Pins
uint32_t ledtime[sizeof(leds)];   // Variable para recordar de millis()-tiempos en la Animación de parpadeo
byte muster;

void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
}

void blinkenImTakt() {
  // Alle gleichmäßig blinkenden LEDs in ihrem eigenen Takt blinken lassen
  for (byte i = 0; i < sizeof(leds); i++) { // alle LEDs in einer Schleife durchgehen
  
    if (millis() - ledtime[i] >= ledtakt[i]) {  // Takt für diese LED abgelaufen?
        ledtime[i] = millis();
        digitalWrite(leds[i], !digitalRead(leds[i])); // wenn ja ==> Umschalten
      if (bitRead(muster, leds[i])) {
          bitWrite(muster, leds[i], LOW);
      } else {
          bitWrite(muster, leds[i], HIGH);
      }
    
      if (leds[i] == leds[0] && bitRead(muster, leds[i])) { // Pin-0 LED wurde gerade eingeschaltet
        StartParpadeo = millis() + 2000; // Inicialmente Tiempo para la parpadeo conjunto
        FinalParpadeo = millis() + 8000; // Tiempo final para la parpadeo conjunto
      }
    }
  }
}

void parpadeoPwmPins() {
  // Die parpadeode LED im Zufallsmodus parpadeo lassen
  static uint32_t alterWert[sizeof(pwmFlimmerPins)];
  static uint32_t flimmerDauer[sizeof(pwmFlimmerPins)] = {5, 5, 5};
  static uint32_t fS[sizeof(pwmFlimmerPins)];
  static byte flimmerHelligkeit[sizeof(pwmFlimmerPins)];
  for (byte i = 0; i < sizeof(pwmFlimmerPins); i++) {
    if (millis() - alterWert[i] >= flimmerDauer[i]) // Tiempo expirado?
    {
      alterWert[i] = millis();
      flimmerDauer[i] = 1 + random(100); // nueva Animación de parpadeo aleatorio
      if (millis() > StartParpadeo && millis() < FinalParpadeo)
        flimmerHelligkeit[i] = random(flimmertiempo); // El brillo del parpadeo como un valor aleatorio
      else
        flimmerHelligkeit[i] = 0; // parpadeo desde cuando es falso Tiempo de parpadeo
    }
    if (flimmerHelligkeit[i]) {
      if (millis() - fS[i] >= flimmerHelligkeit[i]) {
        bitWrite(muster, pwmFlimmerPins[i], HIGH);
      } else {
        bitWrite(muster, pwmFlimmerPins[i], LOW);
      }
      if (millis() - fS[i] >= flimmertiempo) {
        fS[i] = millis();
      }
    } else {
      bitWrite(muster, pwmFlimmerPins[i], LOW);
      fS[i] = millis();
    }
  }
}

void updateShiftRegister(byte bitfolge)
{
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, bitfolge);
  digitalWrite(latchPin, HIGH);
}

void loop() {
  blinkenImTakt();
  parpadeoPwmPins();
  updateShiftRegister(muster);
}

Cambié esta linea para que la simulación sea rápida

const uint32_t ledtakt[] = {900, 150, 220, 333, 500};  // LED Blinktakt in milisegundos für diese Pins

corrige a sus valores por defecto

const uint32_t ledtakt[] = {9000, 1500, 2200, 3333, 5000};  // LED Blinktakt in milisegundos für diese Pins

Y el segundo 595 conectado, ahora te dejo a ti el código.

Hola, disculpen mi curiosidad, pero ¿ a que frecuencia trabaja el ATtiny85 en ese montaje ?

Me falta el dato para poder ver los timer y demás.

Problema del autor. Lo puse a 8Mhz

Ahora mismo iba a editar el post, porque al final logré encontarlo.
Gracias.

Por cierto yo me plantearia usar modulos expansores I/O con interfaz I2C (viejos conocidos PCF8574) que solo tan solo usan dos pines: PB0 y PB2 (pin0 y pin2)

Eso implica cambiar todo el código que ya esta hecho.
Cual es el beneficio?

Si es por el código,... ninguno.
Si es por el hardware,... habria que analizarlo.

Tan solo era una observación intrascendente.

Surbyte,

Mil Gracias por el tiempo tomado en ayudar, durante els proximas dias escribo de nuevo para pedir unas ultimas consejos ya que estas dias estoy muy liado en el trabajo, basicamente lo que no entiendo es el codigo que debe escribir para differenciar els pins del ATTINY85, Registro Desplazamiento 74HC595 (1) y el Registro de Desplazamiento 74HC595 (2) ya que yo soy mas tecnical que programador.

Un Saludo Cordial Y Disculpar el tiempo tomado en responder

Carlos

P.S. Alfaville tambien gracias por sus commentarios como bien dices tengo el ATTINY85 funcionando a 8mhz tambien de aqui a unas dias hablo contigo ya que tambien quiere que mi amplias sobre el dicho.

Buenas días Surbyte,

En final tengo tiempo para hablar contigo y contar ti els problemas que tengo, como a dicho en mi respuesta rápida del otra dia en cuanto a programación aun que intento entender els básicos, no soy programader soy mas bien el hombre técnico.

En cuanto concierna el problema que nos afronta hoy a ver si puede explicar mi bien, entiendo que en esta parte del sketch definamos los different variables y arrays y también aquí es donde definamos els pins que utilizamos tanto de salida del ATTINY85 como los del premier y hasta hora unique registro de desplazamiento 74HC595 que utilizamos:

unsigned int dataPin = 0;   // Pin D0 verbunden mit DS von 74HC595 Pin14 SI
unsigned int clockPin = 1;  // Pin D1 verbunden mit SH_CP von 74HC595 Pin11 SCK
unsigned int latchPin = 2;  // Pin D2 verbunden mit ST_CP von 74HC595 Pin12 RCK

const byte pwmFlimmerPins[] = {0, 1, 2}; // PWM Pin für das "analoge" Flimmern
uint32_t flimmerStart, flimmerEnd;      // Anfangs- und Endzeiten für das Flimmern
const uint32_t flimmerZeit = 10;        // PWM-Zeit in ms
const byte leds[] = {3, 4, 5, 6, 7};    // LED Pins für das normale Blinken deklarieren
const uint32_t ledtakt[] = {9000, 1500, 2200, 3333, 5000};  // LED Blinktakt in Millisekunden für diese Pins
uint32_t ledtime[sizeof(leds)];   // Variablen zum Merken von millis()-Zeiten beim Schalten/Blinken
byte muster;

También entiendo que en estas linias definamos el mode dels pins DataPin,LatchPin, y ClockPin

void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
}

aparte de esto creo que aquí es donde enviamos als pins pertiniente els resultats dels diferentes operaciones efectuado anteriormente, als diferentes pins del registro de desplazamiento, en cuanto concierna els leds que simula el encendiendo y apagado dels leds normal del casa (Pins 3,4,5,6 y 7)

void updateShiftRegister(byte bitfolge)
{
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, bitfolge);
  digitalWrite(latchPin, HIGH);
}

Hora en cuanto a el problema, no entiendo como definamos si quieramos escribir al ATTINY85, el premier registro de despazamiento 74HC595 o al seconda Registro de desplazamiento 74HC595 ya que por example en el attiny85 y registro de desplazamiento 74HC595 los dos tiene pins 0,1, y 2, en cuanto a el seconda registro será suficiente de hacer esto en el siguente linia de código..????

const byte leds[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};    // LED Pins für das normale Blinken 
deklarieren

o tengo hacer otra cosa?

como siempre agradiciendo de ante mano tu ayuda

un saludo cordial

Carlos

P.S. Si alguien mas que surbyte pueden ayudar por supuesto será mas que agradecido ya que estoy consciente que nuestra amigo surbyte tiene trabajo de sobre y no siempre puede ayudar nos todos rápidamente.

como siempre gracias por adelantado a todos

un saludo

carlos

Hola ocnalops,

que pasó al agregar esta linea?

const byte leds[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};

El sistema está preparado para solo 8 bits de modo que los segundos 8 no van a actuar.

este llamdo en el loop se encarga de hacerlo con 8 bits

updateShiftRegister(muster);

Tendrás que transformar updaShiftRegister para que envie dos bytes y no uno.

void updateShiftRegister(int bitfolge)
{
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, bitfolge & 0x00ff);
  shiftOut(dataPin, clockPin, LSBFIRST, ((bitfolge & 0xFF00)>>8));
  digitalWrite(latchPin, HIGH);
}

x lo que todo queda en armar correctamente la variable muster que no puede ser mas del tipo byte sino int (entera).

Subyte buenas días,

Y como siempre muchas gracias para estar siempre aquí para ayudar por supuesto esta agradecimiento queda extento a todos los compañeros arduino de esta foro.

Surbyte si a entendido correctamente tiendra a modificar el:

void updateShiftRegister(byte bitfolge)
{
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, bitfolge);
  digitalWrite(latchPin, HIGH);
}

a:

void updateShiftRegister(int bitfolge)
{
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, bitfolge & 0x00ff);
  shiftOut(dataPin, clockPin, LSBFIRST, ((bitfolge & 0xFF00)>>8));
  digitalWrite(latchPin, HIGH);
}

Obviamente también tiendra a modificar el síguente código:

const byte pwmFlimmerPins[] = {0, 1, 2}; // PWM Pin für das "analoge" Flimmern
uint32_t flimmerStart, flimmerEnd;      // Anfangs- und Endzeiten für das Flimmern
const uint32_t flimmerZeit = 10;        // PWM-Zeit in ms
const byte leds[] = {3, 4, 5, 6, 7};    // LED Pins für das normale Blinken deklarieren
const uint32_t ledtakt[] = {9000, 1500, 2200, 3333, 5000};  // LED Blinktakt in Millisekunden für diese Pins
uint32_t ledtime[sizeof(leds)];   // Variablen zum Merken von millis()-Zeiten beim Schalten/Blinken
byte muster;

Para el siguente:

const byte pwmFlimmerPins[] = {0, 1, 2}; // PWM Pin für das "analoge" Flimmern
uint32_t flimmerStart, flimmerEnd;      // Anfangs- und Endzeiten für das Flimmern
const uint32_t flimmerZeit = 10;        // PWM-Zeit in ms
const byte leds[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};    // LED Pins für das normale Blinken deklarieren
const uint32_t ledtakt[] = {21000, 1500, 2200, 3333, 5000, 7000, 8400, 9500, 11111, 15000, 16666, 18500};  // LED Blinktakt in Millisekunden für diese Pins
uint32_t ledtime[sizeof(leds)];   // Variablen zum Merken von millis()-Zeiten beim Schalten/Blinken
byte muster;

si esto es correcto ya tiendra solucionado como utiliza el seconda registro de desplazamiento pero todavía no entiendo como diferencia els pins libre del ATTINY85 de los del mismo numero en el premier registro de desplazamiento 74HC595.

Como siempre mil gracias por adelantado para su ayuda

un saludo cordial

Carlos

Si pero olvidaste esto, ya no puedes usar

byte muster;

sino

unsigned int muster;

porque hay que desdoblarlo en dos bytes.
He traducido el código para que me resulte mas ameno. El alemán no es mi fuerte.

EDITO: bueno fue otro el error y no lo que te estaba poniendo.
Este código a continuación funciona con los dos 595's
Pruébalo a ver si es lo que esperabas.

/*  Simulation "Animación de Ferrocarril" */
// ATMEL ATTINY85 / ARDUINO
//
//                  +-\/-+
// Ain0 (D 5) PB5  1|    |8  Vcc
// Ain3 (D 3) PB3  2|    |7  PB2 (D 2)  Ain1
// Ain2 (D 4) PB4  3|    |6  PB1 (D 1) pwm1
//            GND  4|    |5  PB0 (D 0) pwm0
//                  +----+

unsigned int dataPin  = 3;  // Pin D0 unido a DS de 74HC595 Pin14 SI
unsigned int clockPin = 4;  // Pin D1 verbunden mit SH_CP de 74HC595 Pin11 SCK
unsigned int latchPin = 2;  // Pin D2 verbunden mit ST_CP de 74HC595 Pin12 RCK

const byte pwmParpadeoPins[] = {0, 1, 2}; // PWM Pin para el parpadeo analógico
uint32_t StartParpadeo, EndParpadeo;      // Tiempos de inicio y fin para el parpadeo
const uint32_t TiempoParpadeo = 10;        // PWM-Zeit in ms
const byte leds[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};    // LED Pins für das normale Blinken deklarieren
const uint32_t relojLed[] = {21000, 1500, 2200, 3333, 5000, 7000, 8400, 9500, 11111, 15000, 16666, 18500};  // LED Blinktakt in Millisekunden für diese Pins
//const uint32_t relojLed[] = {2100, 150, 220, 333, 500, 700, 840, 950, 1111, 1500, 1666, 1850};  // LED Blinktakt in Millisekunden für diese Pins
uint32_t ledtime[sizeof(leds)];   // Variables para la memorización de millis (-) veces al cambiar / intermitente
unsigned int pattern;

void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
}

void parpadeoTarea() {
  // Permitir que enciendan LEDs parapadeando con su propio reloj
  for (byte i = 0; i < sizeof(leds); i++) { // pasar por todos los LEDs en un bucle
    if (millis() - ledtime[i] >= relojLed[i]) {  // el relojLed ha terminado?
        ledtime[i] = millis();
        digitalWrite(leds[i], !digitalRead(leds[i])); // en caso afirmativo ==> Cambiar
      if (bitRead(pattern, leds[i])) {
          bitWrite(pattern, leds[i], LOW);
      } else {
          bitWrite(pattern, leds[i], HIGH);
      }
    
      if (leds[i] == leds[0] && bitRead(pattern, leds[i])) { // Pin-0 LED se acaba de encender
          StartParpadeo = millis() + 2000; // Inicialmente Tiempo para la parpadeo conjunto
          EndParpadeo = millis() + 8000; // Tiempo final para la parpadeo conjunto
      }
    }
  }
}

void parpadeoPwmPins() {
  // Die parpadeode LED im Zufallsmodus parpadeo lassen
  static uint32_t valorAnterior[sizeof(pwmParpadeoPins)];
  static uint32_t duracionParpadeo[sizeof(pwmParpadeoPins)] = {5, 5, 5};
  static uint32_t fS[sizeof(pwmParpadeoPins)];
  static byte ParpadeoBrillo[sizeof(pwmParpadeoPins)];
  for (byte i = 0; i < sizeof(pwmParpadeoPins); i++) {
    if (millis() - valorAnterior[i] >= duracionParpadeo[i]) { // Tiempo expirado?
        valorAnterior[i] = millis();
        duracionParpadeo[i] = 1 + random(100); // nueva Animación de parpadeo aleatorio
        if (millis() > StartParpadeo && millis() < EndParpadeo)
            ParpadeoBrillo[i] = random(TiempoParpadeo); // El brillo del parpadeo como un valor aleatorio
        else
            ParpadeoBrillo[i] = 0; // parpadeo desde cuando es falso Tiempo de parpadeo
    }
    if (ParpadeoBrillo[i]) {
      if (millis() - fS[i] >= ParpadeoBrillo[i]) {
        bitWrite(pattern, pwmParpadeoPins[i], HIGH);
      } else {
        bitWrite(pattern, pwmParpadeoPins[i], LOW);
      }
      if (millis() - fS[i] >= TiempoParpadeo) {
        fS[i] = millis();
      }
    } else {
      bitWrite(pattern, pwmParpadeoPins[i], LOW);
      fS[i] = millis();
    }
  }
}

void updateShiftRegister(unsigned int bitsequence) {
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST,  bitsequence & 0x00ff);
  shiftOut(dataPin, clockPin, LSBFIRST, (bitsequence & 0xFF00)>>8);
  digitalWrite(latchPin, HIGH);
}

void loop() {
  parpadeoTarea();
  parpadeoPwmPins();
  updateShiftRegister(pattern);
}

Se me escapó algún comentario (aún en Alemán) pero esta todo traducido al espanenglish como me gusta al menos a mi.

Buenas noches amigo Surbyte,

Que puede decir, eres un crack como mínimum, como ya a dicho mil veces ya solo puede dar ti el gracias.
yo a pasado un rato esta tarde añadiendo el seconda registro de desplazamiento a el circuit y conectado todo para tenir 8 leds mas y como todavía no había visto vuestra post modificado a cargado el siguente sketch y vola todo funcionando correctamente (Esto si mi gusta todavía hacer un par de cambios).

/*  Simulation "belebtes Haus für die Modellbahn" by jurs */
/*  Version "Flimmern nur wenn die Pin-3 LED an ist */
/*  getestet mit ATtiny85 */
// ATMEL ATTINY85 / ARDUINO
//
//                  +-\/-+
// Ain0 (D 5) PB5  1|    |8  Vcc
// Ain3 (D 3) PB3  2|    |7  PB2 (D 2)  Ain1
// Ain2 (D 4) PB4  3|    |6  PB1 (D 1) pwm1
//            GND  4|    |5  PB0 (D 0) pwm0
//                  +----+

unsigned int dataPin = 0;   // Pin D0 verbunden mit DS von 74HC595 Pin14 SI
unsigned int clockPin = 1;  // Pin D1 verbunden mit SH_CP von 74HC595 Pin11 SCK
unsigned int latchPin = 2;  // Pin D2 verbunden mit ST_CP von 74HC595 Pin12 RCK

const byte pwmFlimmerPins[] = {0, 1, 2}; // PWM Pin für das "analoge" Flimmern
uint32_t flimmerStart, flimmerEnd;      // Anfangs- und Endzeiten für das Flimmern
const uint32_t flimmerZeit = 10;        // PWM-Zeit in ms
const byte leds[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};    // LED Pins für das normale Blinken deklarieren
const uint32_t ledtakt[] = {21000, 1500, 2200, 3333, 5000, 7000, 8400, 9500, 11111, 15000, 16666, 18500};  // LED Blinktakt in Millisekunden für diese Pins
uint32_t ledtime[sizeof(leds)];   // Variablen zum Merken von millis()-Zeiten beim Schalten/Blinken
unsigned int muster;

void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
}

void blinkenImTakt() {
  // Alle gleichmäßig blinkenden LEDs in ihrem eigenen Takt blinken lassen
  for (byte i = 0; i < sizeof(leds); i++) // alle LEDs in einer Schleife durchgehen
  {
    if (millis() - ledtime[i] >= ledtakt[i]) // Takt für diese LED abgelaufen?
    {
      ledtime[i] = millis();
      digitalWrite(leds[i], !digitalRead(leds[i])); // wenn ja ==> Umschalten
      if (bitRead(muster, leds[i])) {
        bitWrite(muster, leds[i], LOW);
      } else {
        bitWrite(muster, leds[i], HIGH);
      }
      if (leds[i] == leds[0] && bitRead(muster, leds[i])) // Pin-0 LED wurde gerade eingeschaltet
      {
        flimmerStart = millis() + 2000; // Anfangszeit für das Flimmern setzen
        flimmerEnd = millis() + 8000; // Endzeit für das Flimmern setzen
      }
    }
  }
}

void flimmernPwmPins() {
  // Die flimmernde LED im Zufallsmodus flimmern lassen
  static uint32_t alterWert[sizeof(pwmFlimmerPins)];
  static uint32_t flimmerDauer[sizeof(pwmFlimmerPins)] = {5, 5, 5};
  static uint32_t fS[sizeof(pwmFlimmerPins)];
  static byte flimmerHelligkeit[sizeof(pwmFlimmerPins)];
  for (byte i = 0; i < sizeof(pwmFlimmerPins); i++) {
    if (millis() - alterWert[i] >= flimmerDauer[i]) // Takt abgelaufen?
    {
      alterWert[i] = millis();
      flimmerDauer[i] = 1 + random(100); // neue Flimmerdauer als Zufallswert
      if (millis() > flimmerStart && millis() < flimmerEnd)
        flimmerHelligkeit[i] = random(flimmerZeit); // neue Flimmerhelligkeit als Zufallswert
      else
        flimmerHelligkeit[i] = 0; // Flimmern aus wenn falsche Zeit zum Flimmern
    }
    if (flimmerHelligkeit[i]) {
      if (millis() - fS[i] >= flimmerHelligkeit[i]) {
        bitWrite(muster, pwmFlimmerPins[i], HIGH);
      } else {
        bitWrite(muster, pwmFlimmerPins[i], LOW);
      }
      if (millis() - fS[i] >= flimmerZeit) {
        fS[i] = millis();
      }
    } else {
      bitWrite(muster, pwmFlimmerPins[i], LOW);
      fS[i] = millis();
    }
  }
}

void updateShiftRegister(int bitfolge)
{
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, bitfolge & 0x00ff);
  shiftOut(dataPin, clockPin, LSBFIRST, ((bitfolge & 0xFF00)>>8));
  digitalWrite(latchPin, HIGH);
}

void loop() {
  blinkenImTakt();
  flimmernPwmPins();
  updateShiftRegister(muster);
}

Ok como a dicho mi gusteria saber si es posible de hacer un par de cambios, a visto que cada vez el luces siguen el mismo patrón ante de todo mi gusteria saber si es posible de hacer que els diferentes leds enciende y apaga de forma totalmente aletorio y no siempre con el mismo patrón y después si es posible que también encienden y apagan con un tiempo aletoria asi dando un efecto mas realistic al edificio el tiempo de enciendido y apagando si posible con un tiempo mínimum y máximum, no se si esto será un task muy difícil o no..?

Despres mi gusteria saber si es posible de commienzar todo el animation con apretar un pulsador que en su turno enciende un led que queda enciendido todo el tiempo que dura el animation y con otra pulso del pulsador termina el animation y apaga el led que esta enciendido desde el animation empiezo.

Por ultima todavía no mi a contestado en cuanto concierna utilizar els 3 leds que queda libre en el ATTINY85

como siempre gracias por adelanto

un saludo cordial

Carlos

Si me preguntas si es posible te digo Claro, pero ahora creo que te toca ponerte a programar un poco jajaja

Si me preguntas si es posible te digo Claro, pero ahora creo que te toca ponerte a programar un poco jajaja

Para lo aleatorio debes usar random() asi que ve viendo como se usa, corre el ejemplo, entiendelo y luego debatimos como usarlo, te parece?

Amigo Surbyte,

Por supuesto que si hora mismo mi ponga a documentar mi y por supuesto hacer algunas pruebas y después vuelvo contigo

como siempre gracias

hablamos pronto

Carlos