Hilfe beim Sketch verkleinern

Hallo liebe Gemeinde,
mein sketch scheint zu groß, wo kann ich noch was umändern um auf 2048 byte zukommen?
Die Fehlermeldung :
Der Sketch verwendet 2738 Bytes (133%) des Programmspeicherplatzes. Das Maximum sind 2048 Bytes.
Globale Variablen verwenden 262 Bytes (204%) des dynamischen Speichers, -134 Bytes für lokale Variablen verbleiben. Das Maximum sind 128 Bytes.

Der/ das Sketch:

/*






*/

//******************************
// LEDs deklarieren (einige doppel als Dummy)
byte leds[]   = {16,2,13,7,6,5,10,4,12,8,3,11,9,13,2,14,15};

//LEDs Blinkzeiten deklarieren(einige doppel als Dummy)
long ledtakt[] = {6000,2500,4000,7500,3300,9000,5700,2400,10000,6800,7300,8000,3690,7500,55000,9690,10500,2540,3000};

// Variablen für  millis()-Zeiten beim Schalten
long ledtime[sizeof(leds)];

void setup() {
 Serial.begin(9600);
  // Pins mittels Schleife auf OUTPUT setzen
 for (int i=0;i<sizeof(leds);i++)
    pinMode(leds[i], OUTPUT);
    // Serielle Ausgabe auf Monitor zur Kontrolle, kann später entfernt werden
    Serial.begin  (9600); 
}

boolean milliSekundenTakt(int dauer, long &alterWert) {
// Parameter "dauer": Dauer einer Schaltzeit (ein/ 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 blinkenImTakt() {
  
// Alle  LEDs ein/aus 
  for (int i=0;i<sizeof(leds);i++) // alle LEDs in einer Schleife durchgehen
  {
    if (milliSekundenTakt(ledtakt[i],ledtime[i])) // Takt für diese LED abgelaufen?
    {
      digitalWrite(leds[i],!digitalRead(leds[i]));  // wenn ja ==> Umschalten
      
      {
     
      }  
    Serial.print("Pin");Serial.print(leds[i]);Serial.print(" = ");Serial.println(digitalRead(leds[i]));
    }
  }
}
void loop() {
  blinkenImTakt();


}

Welche Möglichkeiten seht ihr? was kann besser gemacht werden?

Nachtrag:
SerialPrint auskommentiert, Fehlermeldung:

Der Sketch verwendet 1144 Bytes (55%) des Programmspeicherplatzes. Das Maximum sind 2048 Bytes.
Globale Variablen verwenden 171 Bytes (133%) des dynamischen Speichers, -43 Bytes für lokale Variablen verbleiben. Das Maximum sind 128 Bytes.
Nicht genug Arbeitsspeicher; unter http://www.arduino.cc/en/Guide/Troubleshooting#size finden sich Hinweise, um die Größe zu verringern.
Fehler beim Kompilieren für das Board ATtiny2313/4313.
Jetzt neu: zu wenig Arbeitsspeicher? Damit ist doch nicht der Progrsmmspeicher, sondern der Arbeitsspeicher des Rechners gemeint? Oder irre ich hier?

Naja...
Knapp ist knapp...
Und Tiny bleibt knapp...

Du könntest versuchen die konstanten Arrays ins Flash zu verlagern.

Glaube aber nicht, dass das reicht.
Denn ein Bisschen Ram muss ja noch für den Stack bleiben.

Ja, ja ...
Da wird noch ein tieferer Griff in die Trickkiste erfolgen müssen.

unsigned int ledakt[];

und die doppelten (9, 13, 2) rausnehmen.

Serial raus.

Welcher Arduino hat so viele Pins und so wenig Flash/RAM ?

Hallo,

du hast 17 LEDs
damit verballerst du 17x 2 Byte für ledtakt[], habe das auf unsigned int geändert, macht trotzdem 34 Byte
und dann verballerst du nochmal 17x 4 Byte für ledtime, macht 68 Byte
und 17 Byte für die LED Pinummern, macht in Summe 119 Bytes nur für deine Initialisierungen. Du hast aber nur 128 Byte RAM. Das Programm selbst bentöigt auch noch etwas Luft, das weiß der Compiler und meckert.

Übrigens werden deine Funktionen nicht so funktionieren wie gewünscht. signed ist auch mit unsigned vermischt.
Datei > Voreinstellungen > Compiler Warnungen > "ALLE".

Für dein Vorhaben haste jedoch einfach den falschen µC.
ATtiny841 oder 1634 wäre besser.

Danke.
Also aufem UNO läuft es.
Soll wie schon bemerkt, auf einen 2313, der liegt hier noch rum. Daher die 2048 Grenze.

die Vermischung Unsigned/ signed korrigiere ich.
Die überzähligen "PINS" in der Aufzählung sind eingeschleust, weil mitunter einfach mal kein Pin angesteuert wurde.
Schau ich mal, wie es nach allen Korrekturen läuft.
Die vorgeschlagenen µC? Ob die zwei Händlerapotheken die vorrätig haben, eher nicht...( Fragen morgen, kostet ja nix).

Die Aufrechnung ist ja klasse, muss icxh nur noch die Litaratur dazu finden. Macht dann ja die Auswahl des µC leichter, wenn man aufem Papier vorrausrechnen kann. Danke.

Fazit: Umstricken, anderen µC beschaffen, und gut...

Hallo,

wobei die vorgeschlagenen ATtinys auch keine 17 freien Pins haben. Viele Pins und viel RAM/Flash hat ein ATmega 1284P. Gibts im lötfreundlichen DIP Gehäuse.

char ... 1 Byte (8 Bit), signed
Byte ... 1 Byte (8 Bit), unsigned
(un)signed int ... 2 Byte (16Bit)
(un)signed long ... 4 Byte (32Bit)
float ... 4 Byte (32Bit)

zu finden > diese Seite > Learning > Referenz

Auch ein ATmega328 reicht für das Programm.
Der ist Arduino IDE freundlicher da nichts geupdatet werden muß.

Grüße Uwe

@ Doc_Arduino: Danke.
Benötigt 15, evtl. wäre Port PA2 /Reset) noch nutzbar. Das Datenblatt jetzt nochmal genauer studiert, würde der 4313 für meine Fälle reichen.

Alle Ausweichmodlle sind nicht bei den örtlichen Apothekern zu bekommen.
Werde einen größeren Postenversch. Modelle beim Versander des geringsten Misstrauens bestellen.
Nochmals ein großes Danke an alle Beteiligten.
Vielleicht kan ich irgendwann auch mal helfen...

Danke Uwefed, kommt mit auf die Bestelliste, die Versandkosten müssen sich ja lohnen.

Hallo,

vom Resetpin würde ich erstmal die Finger lassen. Da muss man genau wissen was man macht. Dafür müssen die Fuses geändert werden und dann ist die Frage ob man danach je wieder flashen kann. Über ISP jedenfalls nicht mehr. Ohne vorher angepassten Bootloader ist das der sichere Weg einen µC vor Neuprogrammierung zu schützen - für alle Zeiten. Ohne externen Quarz, nimmste den internen RC, haste noch 2 Pins mehr.

ups, das wäre ja beinahe ins Auge gegangen. Danke für die Warnung.

Ich mag den ATtiny4313, leider ist der Preis gestiegen, weshalb ich auf arduino pro mini 5v oder alternativ aus D umgestiegen bin. Mit dem CP2102 Konverter leicht über USB zu programmieren. Alternativ verwende ich den Nano oder aus D. Nur mal so als Beispiel, natürlich gibt es auch andere Anbieter.

Doc_Arduino:
... für alle Zeiten.

Der Vollständigkeit halber: Mit einer höheren Spannung läßt sich da wohl noch was machen, probiert habe ich es aber bislang nicht: Arduino rettet verfuste ATtinys.

Wenn du als Ziel 17 unabhängige Blinkfrequenzen an einem attiny2313 hast, sind die 128 Byte RAM die größte Herausforderung.

Am meisten zu holen wäre, wenn du kein unsigned long je Pin brauchst und dir zum Blinken Zähler mit geringerer Auflösung reichen. Da wären dann einige "Optimierungen" möglich.

Fragt sich aber, ob das überhaupt das Ziel deines sportlichen Ehrgeiz ist (nur weil ein 2313 da rumfliegt).

... alle Welt sagt: Geht nicht, mach was anderes, nimm 'nen größeren Controller ... und einer der keine Ahnung von all den Unkenrufen hat setzt sich einfach hin und macht es ... :smiley:

AT Tiny 2313 mit 17 unterschiedlich blinkenden LEDs (jeweils via 1 kOhm) und ein "leicht" modifizierter Sketch:

byte          ledtakt[17] = {60,25,40,75,33,90,57,24,100,68,73,80,37,75,254,97,105};
unsigned long ledtime[17] = {0};

void setup()
{
  DDRD = 0b01111111;
  DDRA = 0b00000011;
  DDRB = 0b11111111;
}

void loop() 
{
  for( byte LED = 0; LED < 17; LED++ ) 
     {
       if( millis() - ledtime[LED] < (ledtakt[LED]*100) ) continue;
       while( millis() - ledtime[LED] >= (ledtakt[LED]*100) ) ledtime[LED] += (ledtakt[LED]*100);        
       digitalWrite( LED, !digitalRead(LED) );       
     }
}

Zusammengestöpselt, getestet ... und läuft!
Ist übrigens ein netter Sternenhimmel für Weihnachten oder so...

Ok, ok, Asche auf mein Haupt, der eine extreme Wert 55000 ist maximal auf 25400 gesetzt. Sieht aber dennoch gut aus.

Der Sketch verwendet 912 Bytes (44%) des Programmspeicherplatzes. Das Maximum sind 2048 Bytes.
Globale Variablen verwenden 95 Bytes (74%) des dynamischen Speichers, 33 Bytes für lokale Variablen verbleiben. Das Maximum sind 128 Bytes.

Bis nächste Tage, ich ziehe in Kürze um und habe keine Ahnung, wann ich wieder online sein kann
LG, Rudi
:wink:

warum nutzt du für leds[] und ledtakt[] eine long Variable, da müßte uint16_t doch reichen? Dann bist du bei 1280Byte und bei 99 Byte.

Einige der Arrays scheinen mir konstante Werte zu beinhalten. Dann sollte man die auch als solche deklarieren. Dann könnten die ins Flash, wo wohl noch Platz ist.

Gruß Tommy

Tommy56:
Einige der Arrays scheinen mir konstante Werte zu beinhalten. Dann sollte man die auch als solche deklarieren. Dann könnten die ins Flash, wo wohl noch Platz ist.

const "Variablen" (z.B. const int var = 5) landen i.d.R. automatisch im Flash. Bei Arrays ist das allerdings nicht der Fall. Da muss man etwas weiter ausholen

Über PROGMEM. Es wäre aber evtl. ein Weg, um RAM zu sparen.

Gruß Tommy

Rudi:
Globale Variablen verwenden 95 Bytes (74%) des dynamischen Speichers.
Ok, ok, Asche auf mein Haupt, der eine extreme Wert 55000 ist maximal auf 25400 gesetzt. Sieht aber dennoch gut aus.

Glückwunsch. Wenns passt, erübrigt sich weiteres Feilen. Blinkdauern im 100 ms Raster und bis max 25,5 sec. sind vermutlich eine problemlose Vereinfachung.

Der nächste Wunsch ist wohl eher: unterschiedliche ein- und aus-Dauern :wink:

unterschiedliche ein- und aus-Dauern

Interessanter Gedanke :wink: Aber dann macht der 2313 wirklich schlapp. Ich dachte eher an ein einfaches "verschieben / rotieren" der Zeitwerte, das geht aber nur bis 15 LEDs. Ab 16 fangen Instabilitäten an. Aber auch ohne "Extras" ist das schon ein netter Weihnachts-Blinker, der kaum "langweilig" aussieht. :smiley: