Neuling hat ne Frage Projekt Leuchtturm-Karte

Hallo jurs,

danke für die schnelle Antwort. Gedacht war z.B. folgenden Sketch aus dem ShiftOut Tutorial zu nehmen.
Diesen habe ich mal auf 6 Reihen erweitert und verschiedene 0b, 0x Werte oder Variablen eingetragen. Teilweise negiert weil ich die LED’s an den SH Register von 5V zum SH Ausgang gelegt habe.

Diese Bytes müßten dann wohl halt mit den Blinkergebnissen gefüllt werden. Nur halt die Frage wie? Mit Byte read oder einem Array?

//**************************************************************//
//  Name    : shiftOutCode, Dual Binary Counters                 //
//  Author  : Carlyn Maw, Tom Igoe                               //
//  Date    : 25 Oct, 2006                                       //
//  Version : 1.0                                                //
//  Notes   : Code for using a 74HC595 Shift Register            //
//          : to count from 0 to 255                             //
//**************************************************************//



//Pin connected to ST_CP of 74HC595 Pin 12
int latchPin = 8;
//Pin connected to SH_CP of 74HC595 Pin 11
int clockPin = 12;
////Pin connected to DS of 74HC595 Pin 14
int dataPin = 11;



void setup() {
  //Start Serial for debuging purposes	
  Serial.begin(9600);
  //set pins to output because they are addressed in the main loop
  pinMode(latchPin, OUTPUT);

}

void loop() { 
  
  //count up routine
  for (int j = 0; j < 256; j++) {
    //ground latchPin and hold low for as long as you are transmitting
    digitalWrite(latchPin, 0);

    shiftOut(dataPin, clockPin, LSBFIRST, 0x55);           //6. Reihe links nach rechts
    
    shiftOut(dataPin, clockPin, LSBFIRST, ~0b00110011);    //5. Reihe links nach rechts
    
    shiftOut(dataPin, clockPin, LSBFIRST, ~0b00001111);    //4. Reihe links nach rechts
    
    shiftOut(dataPin, clockPin, LSBFIRST, ~0xFF);          //3. Reihe links nach rechts
    
    shiftOut(dataPin, clockPin, ~j);                       //2. Reihe 
    
    shiftOut(dataPin, clockPin, LSBFIRST, ~0b00110111);    //1. Reihe links nach rechts
    //return the latch pin high to signal chip that it 
    //no longer needs to listen for information
    digitalWrite(latchPin, 1);
    delay(100);
  }
}


void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
  // This shifts 8 bits out MSB first, 
  //on the rising edge of the clock,
  //clock idles low

//internal function setup
  int i=0;
  int pinState;
  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, OUTPUT);

//clear everything out just in case to
//prepare shift register for bit shifting
  digitalWrite(myDataPin, 0);
  digitalWrite(myClockPin, 0);

  //for each bit in the byte myDataOut?
  //NOTICE THAT WE ARE COUNTING DOWN in our for loop
  //This means that %00000001 or "1" will go through such
  //that it will be pin Q0 that lights. 
  for (i=7; i>=0; i--)  {
    digitalWrite(myClockPin, 0);

    //if the value passed to myDataOut and a bitmask result 
    // true then... so if we are at i=6 and our value is
    // %11010100 it would the code compares it to %01000000 
    // and proceeds to set pinState to 1.
    if ( myDataOut & (1<<i) ) {
      pinState= 1;
    }
    else {	
      pinState= 0;
    }

    //Sets the pin to HIGH or LOW depending on pinState
    digitalWrite(myDataPin, pinState);
    //register shifts bits on upstroke of clock pin  
    digitalWrite(myClockPin, 1);
    //zero the data pin after shift to prevent bleed through
    digitalWrite(myDataPin, 0);
  }

  //stop shifting
  digitalWrite(myClockPin, 0);
}

Entweder mit Shift Registern oder Du kaufst Dir zwei billige Megas in der Bucht. Die kosten pro Stück eh nur noch so um die 16-17 Euro mit Versand und haben jeweils 54 IO Pins. Das ist zwar teurer, aber dafür ist der Code einfacher und Du must nicht mit Schieberegistern basteln.

MKy_KB: Diese Bytes müßten dann wohl halt mit den Blinkergebnissen gefüllt werden. Nur halt die Frage wie? Mit Byte read oder einem Array?

Wie gesagt, ich habe keine praktischen Erfahrungen mit den Shift-Registern und kenne auch nur das Shiftout-Tutorial.

Wenn es so ist, dass die Werte byteweise rausgeschiftet werden müssen, also mit der Funktion void shiftOut(int myDataPin, int myClockPin, byte myDataOut) über das gesetzte byte "myDataOut", dann muß dieses Byte natürlich vor dem Funktionsaufruf aus dem Status von je 8 Türmen zusammengebastelt werden.

Codeausschnitt zum Setzen der 8 Bits mit anschließendem Shiftout:

bitWrite(myDataOut, 0, Norderney_timing[0]);
bitWrite(myDataOut, 1, Pilsum_timing[0]);
bitWrite(myDataOut, 2, Campen_timing[0]);
bitWrite(myDataOut, 3, Schillig_timing[0]);
bitWrite(myDataOut, 4, Voslapp_timing[0]);
bitWrite(myDataOut, 5, Tossens_timing[0]);
bitWrite(myDataOut, 6, Turm_XXX_timing[0]);
bitWrite(myDataOut, 7, Turm_YYY_timing[0]);
shiftOut(dataPin, clockPin, myDataOut);

Und das dann für immer acht Türme wiederholen.

Obwohl ich mir nicht sicher bin: Kann man durch eine Reihe kaskadierter Shiftregister nicht gleich alle Bits in einem Rutsch durchshiften, muß das wirklich immer 8-bitweise gemacht werden wie es die Beispiele im Shiftout-Tutorial zeigen?

Zu Udos Vorschlag ist natürlich zu sagen: Ein MEGA hat zwar 54 Pins, aber das Board darf trotzdem an allen Pins zusammen nicht zu viel Strom ziehen:

Absolute Maximum ratings: DC Current VCC and GND Pins......... 200.0 mA Selbst wenn man den Eigenverbrauch des Board mal außen vor läßt: Schließt man 54 LEDs an, die wenigstens kurzfristig mal alle zusammen leuchten können, dann ist die maximal pro LED erlaubte Stromstärke nur 200/54= 3,7mA.

Das ergibt natürlich recht flau blinkende LEDs. Also kommt man um das Basteln nicht herum.

Die einfachen 74HC595 Schieberegister dürfen wohl mit 70 mA belastet werden, das wären 70/8 = 8,75 mA. Auch noch nicht viel. Irgendwo habe ich mal was von einer Trickschaltung gelesen, dass man mit inverser Anschaltung am Schieberegister auch den doppelten Strom in der Summe bekommen kann, ohne einzelne Pins zu überlasten, das wären ja immerhin 17,5 mA.

Ich persönlich würde für so eine interaktive Landkarte wohl die Lösung mit den zwei MEGA Arduinos machen, und dann in entsprechender Anzahl ULN2803 Treiber hinter die Arduino-Pins schalten, damit jede LED auch ihre 20 mA bekommen kann, ohne dass Bauteile oberhalb ihres Max-Ratings betrieben werden. Man will sich mit sowas ja auch nicht die Bude abfackeln oder riskieren, dass es schon nach kurzer Betriebszeit die ersten Ausfallerscheinungen gibt.

Nachtrag: Auch beim MEGA kann man doch die Analog-Pins als Digital-Pins verwenden? Wenn man sonst nichts anderes an Hardware anschließen möchte, beträgt die Anzahl der ohne Verwendung von Shiftregistern maximal gleichzeitig blinkenden Türme 54+16= 70, weil man insgesamt 70 Pins pro MEGA zur Verfügung hat.

Ich denke mit SH Register ist wohl die elegantere Lösung, da ja ein paar LED's setzen einen µC nicht gerade voll auslastet. Sicherlich 2 mal den Mega genommen ist evtl. am Anfang einfacher. Strom der LED's ist normalerweise auch kein Problem, man braucht die nicht mit den vollen 20mA ansteuern, sind dann immer noch hell genug, sonst evtl. wie gesagt einen 2803. Die SH Platine wir sowieso separat mit 5V versorgt, ist mit dem UNO nur über die 3 SH Leitungen und GND verbunden.

Ich werde auf jedenfall die nächste Tage das mit dem bitWrite versuchen. Evtl. klapp es ja.

Danke

MKy_KB: Ich werde auf jedenfall die nächste Tage das mit dem bitWrite versuchen. Evtl. klapp es ja.

Na dann auf gutes Gelingen!

Ich sehe da softwaretechnisch eigentlich keine größeren Probleme. Außer vielleicht das Problem der LED-Verkabelung und der exakten Zuordnung zwischen einem bestimmten ShiftRegister-Ausgang und einem bestimmten Leuchtturm, da gibt es natürlich diverse Verwechslungsmöglichkeiten beim Schieben der Bits. Und es muß beim Verkabeln dann gut aufgepaßt werden, sonst blinkt leicht ein Turm so wie eigentlich ein anderer blinken sollte.

Anyway, bevor Du jetzt alles fix mit Daten füllst, würde ich auch nochmal prüfen, ob die Datenstruktur und der RAM-Speicherbedarf insgesamt passend ist. Ich hatte meinen Sketch gemacht, da standen die Daten der Türme zuerst fest und RAM-Speicher war wegen der wenigen Daten kein Thema.

Zu prüfen wäre: 1. Reicht eine maximale Zyklusdauer von 32,7 Sekunden, d.h. ist sichergestellt, dass sich das Blinkmuster jedes Turms innerhalb dieser Zeit exakt wiederholt? Wenn nein, wie lang ist die längste vorkommende Zyklus-Gesamtdauer aus Ein- und Aus-Zyklen?

  1. Soll das Programm auf einem UNO laufen? Wenn durchschnittlich in der Datenstruktur 14 Bytes pro Turm verbraten wären, macht das 1400 Bytes für 100 Türme. Das könnte bei einem UNO kritisch werden, der ja nur insgesamt 2kB RAM-Speicher hat. In dem Fall müßte man entweder doch wegen des RAM-Speicherbedarfs auf den MEGA gehen, oder sich eine Datenstruktur überlegen, die weniger RAM-Speicher pro Turm benötigt.

Überlegungen zu den beiden Punkten 1. und 2. würde ich lieber jetzt anstellen, bevor umfangreicher Bitshift-Code dazukommt. Denn wenn man erst ziemlich am Schluß feststellt, dass grundlegende Datenstrukturen noch geändert und angepaßt werden müssen, muß man sicher auch den Bitshift-Code wieder nochmal anfassen.

Hier ist jetzt die dokumentierte Version meines Sketches:

http://blog.blinkenlight.net/2013/03/01/lighthouses/ http://blog.blinkenlight.net/experiments/basic-effects/lighthouses/

Hallo,

hatte das Problem, dass ich Zeiten über 30 sek verwenden wollte. Daher die Anfrage an Hr. Klein bzgl. seines Sketches. Daher die Änderung von static uint16_t phase = setOutput(led); in

static uint32_t phase = setOutput(led);
uint8_t setOutput(uint8_t pin) {
  pinMode(pin, OUTPUT);
  return 0;
}

template <uint8_t rel, uint32_t d1, uint32_t d2, uint16_t d3, uint16_t d4,
          uint16_t d5, uint16_t d6, uint16_t d7, uint16_t d8>


void timer() {
  static uint32_t phase = setOutput(rel);

  phase = phase < d1 + d2 + d3 + d4 + d5 + d6 + d7 + d8 - 1 ? phase + 1 : 0;

  digitalWrite(rel, phase < d1                  ? LOW :
               phase < d1 + d2               ? HIGH :
               phase < d1 + d2 + d3            ? LOW :
               phase < d1 + d2 + d3 + d4         ? HIGH :
               phase < d1 + d2 + d3 + d4 + d5      ? LOW :
               phase < d1 + d2 + d3 + d4 + d5 + d6   ? HIGH :
               phase < d1 + d2 + d3 + d4 + d5 + d6 + d7 ? LOW :
               HIGH);
}

void blink() {
  timer<abl, 60000, 300000, 0, 0, 0, 0, 0, 0>(); }

Vielen Dank für die Hilfe!
mfg
Robert

Willkommen im Forum, das kann man so machen, siehe "Beispiele/Analog/Fading". Wenn Du dann delay() durch millis() ersetzt "Beispiele/Digital/BlinkWithoutDelay", kannst Du mehrere Kanäle getrennt steuern.

Wenn Du dann noch Dein eigenes Thema beginnst, ist auch Uwe zufrieden.

Keine Sorge, Uwe ist nett und ganz entspannt!

Mir geht es eher darum, daß Du mit einem passenden Themennamen auch die richtigen Leser und damit ggf. auch die richtigen Helfer findest.

Wenn Du einen Sketch zeigst, in dem außer cut&paste auch Deine Kreativität zu erkennen ist, brauchst Du nur zu beschreiben, wo es hakt, dann wird versucht, Dir zu helfen.