Arraygröße verringern, ATTINY

Hallo, ich bin dabei mir eine IR Fernbedienung für meinen TV zu bauen.

hab mich für ein ATTiny 84 als Prozessor entschieden, wecher nach Kalibrierung des internen oszillators auch gut funktioniert.

Das einzige noch vorhandene Problem ist, das die Codes einfach zu groß sind…

Laut Arduino IDE ist RAM das Problem, nicht ROM:

Der Sketch verwendet 2554 Bytes (31%) des Programmspeicherplatzes. Das Maximum sind 8192 Bytes.
Globale Variablen verwenden 627 Bytes (122%) des dynamischen Speichers, -115 Bytes für lokale Variablen verbleiben. Das Maximum sind 512 Bytes.

Hat jemand eine Idee wie ich die Codes komprimieren kann?

Ein anderer Gedanke war, die Codes vielleicht im ROM zu speichern, ist dies möglich?

Schoneinmal danke für die Hilfe :grin:

#include <IRremote.h>

IRsend irsend;

short vorPin = 1;
int zurueckPin = 3;
int lauterPin = 7;
int leiserPin = 6;
int einPin = 0;
int einsPin = 9;
int sourcePin = 8;

int ledPin = 10;

int khz = 38;

static unsigned char vorCode[51] = { 1, 2, 3, 4, 5, 6, 5, 7, 5, 6, 8, 9, 5, 10, 5, 7, 5, 10, 5, 4, 5, 6, 5, 9, 5, 7, 3, 9, 5, 9, 5, 10, 5, 9, 5, 7, 5, 7, 5, 9, 5, 6, 5, 9, 5, 10, 5, 4, 3, 9, 5, };
static unsigned char zurueckCode[51] = { 2, 2, 5, 4, 5, 7, 3, 4, 5, 7, 5, 9, 5, 10, 3, 4, 5, 9, 3, 4, 5, 6, 5, 9, 5, 11, 3, 12, 5, 10, 5, 9, 5, 10, 5, 7, 5, 7, 5, 9, 3, 7, 3, 13, 5, 10, 5, 7, 5, 7, 5, };
static unsigned char lauterCode[51] = { 2, 1, 8, 6, 5, 7, 5, 7, 5, 7, 5, 10, 5, 9, 5, 6, 5, 9, 5, 7, 5, 7, 5, 6, 5, 7, 5, 9, 5, 9, 5, 10, 5, 9, 5, 7, 5, 7, 5, 10, 5, 7, 5, 9, 3, 13, 5, 10, 5, 9, 5, };
static unsigned char leiserCode[51] = { 2, 14, 5, 7, 5, 6, 5, 7, 3, 4, 5, 9, 5, 10, 5, 7, 5, 9, 3, 4, 5, 6, 5, 7, 8, 10, 5, 9, 5, 10, 5, 9, 5, 9, 5, 7, 5, 6, 5, 9, 5, 7, 5, 9, 5, 10, 5, 9, 5, 7, 5, };
static unsigned char einCode[51] = { 2, 1, 5, 7, 5, 7, 3, 7, 5, 7, 5, 10, 5, 10, 5, 7, 5, 10, 5, 7, 5, 10, 5, 4, 5, 10, 3, 9, 5, 9, 5, 10, 5, 9, 3, 4, 5, 6, 5, 9, 5, 7, 5, 9, 5, 6, 5, 9, 5, 7, 5, };
static unsigned char einsCode[51] = { 1, 14, 5, 6, 5, 7, 5, 7, 5, 6, 15, 10, 5, 9, 5, 6, 5, 6, 8, 10, 5, 9, 3, 9, 3, 4, 5, 10, 5, 9, 5, 10, 5, 9, 5, 7, 5, 7, 5, 10, 5, 9, 5, 7, 5, 7, 5, 6, 8, 9, 5, };
static unsigned char sourceCode[51] = { 2, 2, 5, 7, 3, 4, 5, 6, 5, 7, 5, 9, 3, 10, 8, 7, 5, 7, 3, 7, 5, 9, 5, 6, 5, 9, 5, 9, 5, 10, 5, 9, 5, 9, 5, 6, 5, 7, 5, 10, 5, 9, 5, 10, 5, 7, 5, 9, 5, 7, 5, };

static unsigned int globalCode[51];

static void loadIntoGlobalArray(unsigned char* array) {
    for (int i = 0; i < 51; ++i) {
        switch (array[i]) {
            case 1:
                globalCode[i] = 400;
                break;
            case 2:
                globalCode[i] = 395;
                break;
            case 3:
                globalCode[i] = 55;
                break;
            case 4:
                globalCode[i] = 190;
                break;
            case 5:
                globalCode[i] = 50;
                break;
            case 6:
                globalCode[i] = 200;
                break;
            case 7:
                globalCode[i] = 195;
                break;
            case 8:
                globalCode[i] = 45;
                break;
            case 9:
                globalCode[i] = 100;
                break;
            case 10:
                globalCode[i] = 105;
                break;
            case 11:
                globalCode[i] = 110;
                break;
            case 12:
                globalCode[i] = 90;
                break;
            case 13:
                globalCode[i] = 95;
                break;
            case 14:
                globalCode[i] = 390;
                break;
            case 15:
                globalCode[i] = 40;
                break;

        }
    }
}

void setup(){
    pinMode(vorPin, INPUT);
    pinMode(zurueckPin, INPUT);
    pinMode(lauterPin, INPUT);
    pinMode(leiserPin, INPUT);
    pinMode(einPin, INPUT);
    pinMode(einsPin, INPUT);
    pinMode(sourcePin, INPUT);
    pinMode(ledPin,OUTPUT);
    //Serial.begin(9600);
}

void loop(){
    if(digitalRead(vorPin) == 1){
        //Serial.println("vor schalten");
        loadIntoGlobalArray(vorCode);
        irsend.sendRaw(globalCode, 51, khz);
        delay(250);
    }
    if(digitalRead(zurueckPin) == 1){
        //Serial.println("zurueck schalten");
        loadIntoGlobalArray(zurueckCode);
        irsend.sendRaw(globalCode, 51, khz);
        delay(250);
    }
    if(digitalRead(lauterPin) == 1){
        //Serial.println("lauter schalten");
        loadIntoGlobalArray(lauterCode);
        irsend.sendRaw(globalCode, 51, khz);
        delay(250);
    }
    if(digitalRead(leiserPin) == 1){
        //Serial.println("leiser schalten");
        sendIR(leiserCode);
        delay(250);
    }
    if(digitalRead(einPin) == 1){
        //Serial.println("ein schalten");
        sendIR(einCode);
        delay(250);
    }
    if(digitalRead(einsPin) == 1){
        //Serial.println("eins schalten");
        sendIR(einsCode);
        delay(250);
    }
    if(digitalRead(sourcePin) == 1){
        //Serial.println("hdmi schalten");
        sendIR(sourceCode);
        delay(250);
    }
}


void sendIR(unsigned char* code) {
    loadIntoGlobalArray(lauterCode);
    irsend.sendRaw(globalCode, 51, khz);
    digitalWrite(ledPin,1);
    delay(100);
    digitalWrite(ledPin,0);
    //Serial.println(code[1]);
}

https://www.arduino.cc/en/Reference/Const Dadurch weiß der Compiler dass sich das nie verändert und kann die Variable wegoptimieren

Arrays die man nur liest lassen sich im Flash speichern https://www.arduino.cc/en/Reference/PROGMEM Dabei genau hinschauen wie das mit dem Auslesen geht

Danke für die schnelle Antwort, probiere ich gleich mal aus :)

Fünfzehn Möglichkeiten passen in ein Halbbyte, da könntest Du die Hälfte einsparen:

static unsigned char einsCode[26] = { 0x1E, 0x56, 0x57, 0x57 ...};

EDIT: [51] in [26] geändert, danke!

@agmue: Du meinst sicher:

Zahlen im Bereich 1 .. 15 passen in ein Halb-Byte

static unsigned char einsCode[[b]26[/b]] = { 0x1E, 0x56, 0x57, 0x57 ...}; // 1, 14, 5, 6, 5, 7, 5, 7

sonst sparst du nichts. ;)

Da konstante Daten im RAM sowieso eine Kopie im Flash haben, ist das Verwenden von PROGMEM der bessere Weg.

Die Vorschläge sollten es ja schon bequem retten. Ansonsten IRremote.h nicht benutzen und die Sendefunktion selbst schreiben. Du sendest ja eh RAW. Die Pins kannst Du auch noch const setzen, das müsste schon reichen, damit der Compiler sie in den Flash optimiert. Wenn ich mir das so ansehe, müsste Dein Sketch annähernd gar keinen SRAM brauchen, außer vielleicht ein paar byte von lokalen Variablen :)

Die Pins kannst Du auch noch const setzen

Dafür war der Hinweis auf const auch gedacht. Zwei Bytes für einen Pin zu verschwenden ist Unsinn

Er braucht einmal das Array globalCode im RAM. Aber die anderen können im Flash bleiben

globalCode bräuchte er nicht mehr, wenn er IRremote umgeht und direkt sendet.