Sketchgröße verkleinern => NEUER SCHALTPLAN mit größerem Atmega1284

Hi,

leider musste ich jetzt doch feststellen, dass ein Atmega328 schnell an seine Speichergrenze kommt.
Vielleicht hat ja noch jemand einen Optimierungsansatz für mich....

Was ich aktuell ausschließen kann/möchte:

  • Wechsel von Atmega 328 auch auf zB Atmega2560 (bedeutet halt neue Platine)
  • Verzichten auf fertige Libraries indem man das selbst schreibt (zu sehr Laie, keine Chance)
  • Verzichten auf Funktionalitäten (ungern...)
  • Ich nutze bereits einen anderen Bootloader (Optiboot), der mir bereits minimal mehr Speicher als der Standard Nano Bootloader verschafft

Bei meinem Code sticht insbesondere eine Library hervor, die allein schon im Beispiel Sketch mit ca 18kb compiliert wird: GitHub - Zapalot/ArdOscForWiFlyHQ: A modified version of ArdOsc for working with the WiFlyHQ library on Arduino + GitHub - Zapalot/WiFlyHQ: WiFly RN-XV Arduino Library

Würde es etwas bringen, wenn man (sofern man programmiertechnisch in der Lage ist) alle Methoden, die man für sein Projekt nicht benötigt, aus der Library rauslöscht? Oder werden beim kompilieren sowieso nur die Methoden/Funktionen/etc. kompiliert, die auch im Sketch aufgerufen werden?

Hier mal mein aktueller Sketch, damit wir nicht nur über heiße Luft reden:

PART I:

//++++++++++++++++++++++++++++++++++++++++++++Libraries++++++++++++++++++++++++++++++++++++++++++++
#include <WiFlyHQ.h>
#include <ArdOSCForWiFlyHQ.h>
#include <DS3231.h>
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
#include <OneWire.h>
#include <DallasTemperature.h>
//++++++++++++++++++++++++++++++++++++++++++++++WIFLY++++++++++++++++++++++++++++++++++++++++++++++
char* ssid = "xxx";
char* pass = "xxx";
char* IPwifly = "x.x.x.x";       //IP Wifly Module
int Portwifly = 8000;                   //Touchosc: Outgoing
char* IPhost = "x.x.x.x";         //IP iPhone
int Porthost = 9000;                    //Touchosc: Incoming
WiFly WIFI;  
OSCServer server(&WIFI);                // receive
OSCClient client(&WIFI);                // send
//++++++++++++++++++++++++++++++++++++++++++++++DS3231+++++++++++++++++++++++++++++++++++++++++++++
DS3231  rtc(SDA, SCL); //Address==0x68!!!
byte day_,month_,year_,hour_,min_,sec_,control_temp;
byte prevMin=0;
//+++++++++++++++++++++++++++++++++++++++++++++DS18B20+++++++++++++++++++++++++++++++++++++++++++++
#define ONE_WIRE_BUS 14
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
//++++++++++++++++++++++++++++++++++++++++++++++PCA9685++++++++++++++++++++++++++++++++++++++++++++
Adafruit_PWMServoDriver board1 = Adafruit_PWMServoDriver(0x40);
Adafruit_PWMServoDriver board2 = Adafruit_PWMServoDriver(0x41);
const byte LED[] = {7,15,6,14,0,1,2,9,10,8,12,13,11,5};    //W1+2;B1+2;RB=7;UV=6;RED=15;RGB1;RGB2;Fans
const byte Fans = 1;//?????
//PCA 0= RoyalBlue
//1=Rot
//2=UV
//6=White1
//7=Blue1
//14=Blue2
//15=White2
//8+=Green
//9+ =Red
//10+ =Blue
unsigned int valueLight[14];
unsigned int prevValueLight[14];
byte LEDmode=0;
//++++++++++++++++++++++++++++++++++++++++++RGBWHEEL+++++++++++++++++++++++++++++++++++++++++++++++++
byte RGBmode=0;
float hue=0.0, saturation=1.0, value=1.0;
long rgb[3];
long rgbval;
byte bright[3] = {100, 100, 100}; 
byte FactorOfWheel = 25;
//++++++++++++++++++++++++++++++++++++++++++++Platinen++++++++++++++++++++++++++++++++++++++++++++
byte Platinen=2;
byte DS18Sensoren=Platinen*2;
//++++++++++++++++++++++++++++++++++++++++++++++LightArrays++++++++++++++++++++++++++++++++++++++++++
                            // 0  | 1  | 2  | 3  | 4  | 5  | 6  | 7  | 8  | 9  | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23  
byte lightArray[14] [24] = { {   0,   0,   0,   0,   0,   0,   0,  20,  40,  70, 100, 100, 100, 100, 100, 100, 100,  80,  50,  30,  20,  10,   0, 10 }, 
                             {   0,   0,   0,   0,   0,   0,   0,  20,  40,  70, 100, 100, 100, 100, 100, 100, 100,  80,  50,  30,  20,  10,   0,   0 },   
                             {   0,   0,   0,   0,   0,   0,   0,  20,  40,  70, 100, 100, 100, 100, 100, 100, 100,  80,  50,  30,  20,  10,   0,   0 },  
                             {   100,   0,   0,   0,   0,   0,   0,  20,  40,  70, 100, 100, 100, 100, 100, 100, 100,  80,  50,  30,  20,  10,   0,   0 },   
                             {   100,   0,   0,   0,   0,   0,   0,  20,  40,  70, 100, 100, 100, 100, 100, 100, 100,  80,  50,  30,  20,  10,   0,   0 }, 
                             {   0,   0,   0,   0,   0,   0,   0,  20,  40,  70, 100, 100, 100, 100, 100, 100, 100,  80,  50,  30,  20,  10,   0,   0 },  
                             {   0,   0,   0,   0,   0,   0,   0,  20,  40,  70, 100, 100, 100, 100, 100, 100, 100,  80,  50,  30,  20,  10,   0,   0 },   
                             {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0 },
                             {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0 },  
                             {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0 }, 
                             {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0 },  
                             {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0 },  
                             {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0 },
                             {   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0 } }; 


void setup() {
  //++++++++++++++++++++++++++++++++++++++++++++++WIFLY++++++++++++++++++++++++++++++++++++++++++++++
  Serial.begin(115200);
  WIFI.setupForUDP<HardwareSerial>(&Serial,115200,false,ssid,pass,"WiFly",IPwifly,Portwifly,IPhost,Porthost,false);
  server.addCallback("/auto",&autoLED);
  server.addCallback("/white",&autoWhite);
  server.addCallback("/blue",&autoBlue);
  server.addCallback("/royal",&autoRoyalBlue);
  server.addCallback("/red",&autoRed);
  server.addCallback("/purple",&autoPurple);
  server.addCallback("/rgbswitch",&rgbswitch);
  server.addCallback("/rgbmixer",&rgbmixer);
  server.addCallback("/factor",&wheelFactor); 
  server.addCallback("/rgb0",&rgbValue0);
  server.addCallback("/rgb1",&rgbValue1); 
  server.addCallback("/rgb2",&rgbValue2); 
  server.addCallback("/brightness0",&rgbBrightness0);
  server.addCallback("/brightness1",&rgbBrightness1);   
  server.addCallback("/brightness2",&rgbBrightness2);  

   
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH); 
  //++++++++++++++++++++++++++++++++++++++++++++++RTC+++++++++++++++++++++++++++++++++++++++++++++
  rtc.begin();  
  //setTime(21,22,20,29,10,14);
  //++++++++++++++++++++++++++++++++++++++++++++++PCA9685+++++++++++++++++++++++++++++++++++++++++++++
  board1.begin();
  board1.setPWMFreq(800); 
  //uint8_t twbrbackup = TWBR;
  //TWBR = 12;
  for (int i=0;i<13;i++) board1.setPWM(LED[i], 0, 0);
  //++++++++++++++++++++++++++++++++++++++++++RGBWHEEL+++++++++++++++++++++++++++++++++++++++++++++++++
  byte RGBmode=0;
  float hue=0.0, saturation=1.0, value=1.0;
  long rgb[3];
  long rgbval;
  long bright[3] = {100, 100, 100};  ///ansteuern????
  //++++++++++++++++++++++++++++++++++++++++++DS18B20+++++++++++++++++++++++++++++++++++++++++++++++++
  sensors.begin();
}

void loop() {
  getTimeAndTemp(rtc.getTime());  
  if (server.availableCheck(2)>0){}
//  if (LEDmode==0) getLight(); 
//  if (LEDmode==2) dimLED();
}

//++++++++++++++++++++++++++++++++++++++++++LIGHT++++++++++++++++++++++++++++++++++++++++++++++++

void getLight() {
  for (int i=0; i<14; i++) { 
    if (hour_<23) valueLight[i] = fadeLight(min_, sec_, map(lightArray[i][hour_+1],0,100,0,4095), map(lightArray[i][hour_],0,100,0,4095));
    else if (hour_==23) valueLight[i] = fadeLight(min_, sec_, map(lightArray[i][0],0,100,0,4095), map(lightArray[i][hour_],0,100,0,4095));
    if (prevValueLight[i] != valueLight[i]) {
      board1.setPWM(LED[i], 0, valueLight[i]);
      prevValueLight[i] = valueLight[i];
    }
  }
}
 
int fadeLight(byte mm, byte ss, const int PWMvalueSoon, const int PWMvalueNow) {
  float bruch = (float)3600 / (PWMvalueSoon - PWMvalueNow);
  int result;
  result = PWMvalueNow + ((3600 - (3600 - ((mm * 60) + (ss * 1)))) / bruch);
  return result;
} 

void dimLED() {
  for (int i=0; i<14; i++) board1.setPWM(LED[i], 0, 1000);
}

Part II:

//++++++++++++++++++++++++++++++++++++++++++CONTROL++++++++++++++++++++++++++++++++++++++++++++++
void getTimeAndTemp(Time t) {
  if (prevMin != t.min) {
    client.sendFloat(rtc.getTemp(),"/tempRTC");
    client.sendFloat(t.hour,"/hh");
    client.sendFloat(t.min,"/mm");
    prevMin = t.min;
    sensors.requestTemperatures();
    for (int i=0; i<DS18Sensoren; i++) {
      static char text[10] = "/tempLED#"; //wenn man Zahlen größer als 9 braucht >> atoi() verwenden und einfach text + 8 für das Ziel-Array übergeben
      text[8] = '0'+i; 
      client.sendFloat((float)(sensors.getTempCByIndex(i)),text);  
      if (LEDmode != 2 && sensors.getTempCByIndex(i)>=50) LEDmode=2;
      if (LEDmode == 2 && sensors.getTempCByIndex(i)<=35) LEDmode=0;
    }
  }
}
void setLEDfans() {
  if (hour_>=8 && hour_<21) board1.setPWM(Fans, 0, 4000);
  else board1.setPWM(Fans, 0, 0);
}
void setTime(byte hh, byte mm, byte ss, byte dd, byte mo, int yy) {
  rtc.setTime(hh,mm,ss);  
  rtc.setDate(dd,mo,yy);   
}
//+++++++++++++++++++++++++++++++++++++++++RGB+++++++++++++++++++++++++++++++++++++++++++++++
long HSV_to_RGB( float h, float s, float v ) {
  int i;
  float m, n, f;
  if ((s<0.0) || (s>1.0) || (v<0.0) || (v>1.0)) {
    return 0L;
  } 
  if ((h < 0.0) || (h > 6.0)) {
    return long( v * 255 ) + long( v * 255 ) * 256 + long( v * 255 ) * 65536;
  }
  i = floor(h);
  f = h - i;
  if ( !(i&1) ) {
    f = 1 - f; 
  }
  m = v * (1 - s);
  n = v * (1 - s * f);
  switch (i) {
  case 6:
  case 0:
    return long(v * 255 ) * 65536 + long( n * 255 ) * 256 + long( m * 255);
  case 1:
    return long(n * 255 ) * 65536 + long( v * 255 ) * 256 + long( m * 255);
  case 2:
    return long(m * 255 ) * 65536 + long( v * 255 ) * 256 + long( n * 255);
  case 3:
    return long(m * 255 ) * 65536 + long( n * 255 ) * 256 + long( v * 255);
  case 4:
    return long(n * 255 ) * 65536 + long( m * 255 ) * 256 + long( v * 255);
  case 5:
    return long(v * 255 ) * 65536 + long( m * 255 ) * 256 + long( n * 255);
  }
}

void RGBupdate(byte color, byte colorValue) {
  board1.setPWM(LED[(7+color)], 0, map((colorValue*bright[color]/100),0,255,0,4095));
  board1.setPWM(LED[(10+color)], 0, map((colorValue*bright[color]/100),0,255,0,4095));
  if (color==0) client.sendFloat(map((colorValue*bright[color]/100),0,255,0,4095),"/rgb0");
  else if (color==1) client.sendFloat(map((colorValue*bright[color]/100),0,255,0,4095),"/rgb1");
  else if (color==2) client.sendFloat(map((colorValue*bright[color]/100),0,255,0,4095),"/rgb2");
} 

//+++++++++++++++++++++++++++++++++++++++++OSC_VERARBEITUNG++++++++++++++++++++++++++++++++++++++++++++++++
void autoLED(OSCMessage *_mes) {
  if (_mes->getArgFloat(0)==0) LEDmode=0;
  else if (_mes->getArgFloat(0)==1) LEDmode=1;
}
void autoWhite(OSCMessage *_mes) {  
  if (LEDmode==1) {
    int value = (int)_mes->getArgFloat(0);
    if (value >= 4085) value = 4095;
    board1.setPWM(LED[0], 0, value);
    board1.setPWM(LED[1], 0, value);
  }
}
void autoBlue(OSCMessage *_mes) {
  if (LEDmode==1) {
    int value = (int)_mes->getArgFloat(0);
    if (value >= 4085) value = 4095;
    board1.setPWM(LED[2], 0, value);
    board1.setPWM(LED[3], 0, value);
  }
}
void autoRoyalBlue(OSCMessage *_mes) {
  if (LEDmode==1) board1.setPWM(LED[4], 0, (int)_mes->getArgFloat(0));

}
void autoRed(OSCMessage *_mes) {
  if (LEDmode==1) board1.setPWM(LED[5], 0, (int)_mes->getArgFloat(0));
}
void autoPurple(OSCMessage *_mes) {
  if (LEDmode==1) board1.setPWM(LED[6], 0, (int)_mes->getArgFloat(0));
}
void rgbswitch(OSCMessage *_mes) {
  if (LEDmode==1) {
    RGBmode=(int)_mes->getArgFloat(0);
    if (RGBmode==1) for (int i=0;i<7;i++) board1.setPWM(LED[i], 0, 0);
    else if (RGBmode==0) {  
      for (int i=0;i<7;i++) board1.setPWM(LED[i], 0, 100);
      for (int i=7;i<13;i++) board1.setPWM(LED[i], 0, 0);
    }
  }    
}
void rgbmixer(OSCMessage *_mes) {
  if (LEDmode==1 && RGBmode==1) {
    hue += (_mes->getArgFloat(0))/25; //0.00 - 6.00
    if (hue>6) hue=0;
    if (hue<0) hue=6;
    rgbval=HSV_to_RGB(hue, saturation, value);
    rgb[0] = (rgbval & 0x00FF0000) >> 16;
    rgb[1] = (rgbval & 0x0000FF00) >> 8;
    rgb[2] = rgbval & 0x000000FF;
    for (int i=0; i<3; i++) RGBupdate(i, rgb[i]);   
  }
}
void rgbValue0(OSCMessage *_mes) { 
  rgb[0]=_mes->getArgFloat(0);
  RGBupdate(0,rgb[0]);
}
void rgbValue1(OSCMessage *_mes) { 
  rgb[1]=_mes->getArgFloat(0);
  RGBupdate(1,rgb[1]);
}
void rgbValue2(OSCMessage *_mes) { 
  rgb[2]=_mes->getArgFloat(0);
  RGBupdate(2,rgb[2]);
}
void rgbBrightness0(OSCMessage *_mes) { 
  bright[0]=_mes->getArgFloat(0);  
  RGBupdate(0,rgb[0]);  
}  
void rgbBrightness1(OSCMessage *_mes) { 
  bright[1]=_mes->getArgFloat(0);  
  RGBupdate(1,rgb[1]);  
}    
void rgbBrightness2(OSCMessage *_mes) { 
  bright[2]=_mes->getArgFloat(0);  
  RGBupdate(2,rgb[2]);  
}  
void wheelFactor(OSCMessage *_mes) {
  FactorOfWheel=_mes->getArgFloat(0);
}

[/code]

currymuetze:
Bei meinem Code sticht insbesondere eine Library hervor, die allein schon im Beispiel Sketch mit ca 18kb compiliert wird: GitHub - Zapalot/ArdOscForWiFlyHQ: A modified version of ArdOsc for working with the WiFlyHQ library on Arduino + GitHub - Zapalot/WiFlyHQ: WiFly RN-XV Arduino Library

Würde es etwas bringen, wenn man (sofern man programmiertechnisch in der Lage ist) alle Methoden, die man für sein Projekt nicht benötigt, aus der Library rauslöscht? Oder werden beim kompilieren sowieso nur die Methoden/Funktionen/etc. kompiliert, die auch im Sketch aufgerufen werden?

Die Compilerparameter sollten eigentlich passend stehen, dass nicht benötigte/vorkommende Funktionen aus den Libs nicht compiliert werden.

Hab gerade nicht die Zeit, denn Sketch komplett durch zu arbeiten, aber ein Punkt fällt mir auf, denn du überdenken solltest!

float hue=0.0, saturation=1.0, value=1.0;
  long rgb[3];
  long rgbval;
  long bright[3] = {100, 100, 100};  ///ansteuern????

Warum werden dort float und long Werte genommen? Was haben diese Wert mit einem PWM Servo zu tun?

Für hue reicht ein int (0-359°), bzw. byte wenn man den ganzen Bereich auf 0 - 255 mapped.
saturation als Float anzulegen ist ebenfalls recht verschwenderisch, das gleiche mit value. Für beide Werte kann man besser ein byte nehmen und die Einstellungswerte *100 nehmen.

byte saturation = 100; byte value = 100;

Ansich sehe ich kein Problem, alles auf den Atmega unter zu bekommen.

Hi,
danke für den Hinweis. Das check ich noch mal.
Dass man long und floats vermeiden soll ist mir bewusst, leider weiß ich nicht wie ich diese ganzen floats vermeiden kann:

//+++++++++++++++++++++++++++++++++++++++++OSC_VERARBEITUNG++++++++++++++++++++++++++++++++++++++++++++++++
void autoLED(OSCMessage *_mes) {
  if (_mes->getArgFloat(0)==0) LEDmode=0;
  else if (_mes->getArgFloat(0)==1) LEDmode=1;
}
void autoWhite(OSCMessage *_mes) {  
  if (LEDmode==1) {
    int value = (int)_mes->getArgFloat(0);
    if (value >= 4085) value = 4095;
    board1.setPWM(LED[0], 0, value);
    board1.setPWM(LED[1], 0, value);
  }
}
void autoBlue(OSCMessage *_mes) {
  if (LEDmode==1) {
    int value = (int)_mes->getArgFloat(0);
    if (value >= 4085) value = 4095;
    board1.setPWM(LED[2], 0, value);
    board1.setPWM(LED[3], 0, value);
  }
}
void autoRoyalBlue(OSCMessage *_mes) {
  if (LEDmode==1) board1.setPWM(LED[4], 0, (int)_mes->getArgFloat(0));

}
void autoRed(OSCMessage *_mes) {
  if (LEDmode==1) board1.setPWM(LED[5], 0, (int)_mes->getArgFloat(0));
}
void autoPurple(OSCMessage *_mes) {
  if (LEDmode==1) board1.setPWM(LED[6], 0, (int)_mes->getArgFloat(0));
}
void rgbswitch(OSCMessage *_mes) {
  if (LEDmode==1) {
    RGBmode=(int)_mes->getArgFloat(0);
    if (RGBmode==1) for (int i=0;i<7;i++) board1.setPWM(LED[i], 0, 0);
    else if (RGBmode==0) {  
      for (int i=0;i<7;i++) board1.setPWM(LED[i], 0, 100);
      for (int i=7;i<13;i++) board1.setPWM(LED[i], 0, 0);
    }
  }    
}
void rgbmixer(OSCMessage *_mes) {
  if (LEDmode==1 && RGBmode==1) {
    hue += (_mes->getArgFloat(0))/25; //0.00 - 6.00
    if (hue>6) hue=0;
    if (hue<0) hue=6;
    rgbval=HSV_to_RGB(hue, saturation, value);
    rgb[0] = (rgbval & 0x00FF0000) >> 16;
    rgb[1] = (rgbval & 0x0000FF00) >> 8;
    rgb[2] = rgbval & 0x000000FF;
    for (int i=0; i<3; i++) RGBupdate(i, rgb[i]);   
  }
}
void rgbValue0(OSCMessage *_mes) { 
  rgb[0]=_mes->getArgFloat(0);
  RGBupdate(0,rgb[0]);
}
void rgbValue1(OSCMessage *_mes) { 
  rgb[1]=_mes->getArgFloat(0);
  RGBupdate(1,rgb[1]);
}
void rgbValue2(OSCMessage *_mes) { 
  rgb[2]=_mes->getArgFloat(0);
  RGBupdate(2,rgb[2]);
}
void rgbBrightness0(OSCMessage *_mes) { 
  bright[0]=_mes->getArgFloat(0);  
  RGBupdate(0,rgb[0]);  
}  
void rgbBrightness1(OSCMessage *_mes) { 
  bright[1]=_mes->getArgFloat(0);  
  RGBupdate(1,rgb[1]);  
}    
void rgbBrightness2(OSCMessage *_mes) { 
  bright[2]=_mes->getArgFloat(0);  
  RGBupdate(2,rgb[2]);  
}  
void wheelFactor(OSCMessage *_mes) {
  FactorOfWheel=_mes->getArgFloat(0);
}

Die Bibilothek bietet mir leider nur
_mes->getArgFloat(0);
_mes->addArgInt32(0);
_mes->getArgString(0);
siehe hier: ArdOscForWiFlyHQ/keywords.txt at master · Zapalot/ArdOscForWiFlyHQ · GitHub

HIer könnte ich hervorragend mit bytes arbeiten, aber keine Ahnung wie.
mit getArgInt32 habe ich leider nichts verbessert, daher wieder verworfen.

Temperaturen kannst du auch mit Integern als Hunderstel Grad abspeichern. z.B: 125 = 12,5°

Wenn du konsequent überall auf Float verzichten kannst, müssen die ganzen Funktionen zur Gleitkomma-Arithmetik nicht compiliert werden. Das bringt aber nur etwas wenn die WiFly Library nicht intern Float verwendet.

Deine Dallas Library wird allerdings auch Float verwenden, auch wenn man es nicht als Float abspeichert. Hier gibt es aber fertigen Code wie man die Sensoren ohne Library auslesen kann.

hi,

seid Ihr sicher, daß Ihr nicht aneinander vorbeiredet und einmal flash und einmal ram meint?
flash; ...mit ca 18kb compiliert wird...
ram: ...überall auf Float verzichten kannst...

gruß stefan

Sehe es so wie stefan.
float belegt mehr sram als int.
Am flashverbrauch (programmspeicher) ändert sich wenig.

Würde es etwas bringen, wenn man (sofern man programmiertechnisch in der Lage ist) alle Methoden, die man für sein Projekt nicht benötigt, aus der Library rauslöscht? Oder werden beim kompilieren sowieso nur die Methoden/Funktionen/etc. kompiliert, die auch im Sketch aufgerufen werden?

Genau das ist die Frage an die C++ Experten hier.
Wenn eine Klasseninstanz erzeugt wird und keine Methode benutzt wird habe ich festgestellt das nicht mehr flash verbraucht wird als vorher.

Das selbe habe ich bemerkt wenn ich Funktionen im Sketch habe aber diese nicht aufrufe.
Es kommt wohl drauf an was der Compiler (optimizer) daraus macht ?

Hallo,

richtig, currymütze redet vom Flash für sein Programmcode welches knapp wird.

Und seit Ihr Euch wirklich sicher das der Compiler nicht genutzte Funktionen einer Lib im Sketch außen vor läßt? Woher will der das wissen. Mein erster Gedanke war nämlich auch alle nicht benötigten Funktionen einer Lib zu entfernen. Ich würde sagen, originale Lib sichern und einfach mal testen.

Der AVR hat keine FPU! Jedesmal wenn du mit Gleitkommazahlen rechnest wird eine Funktion aufgerufen, die dass dann auf 8 Bit Integer-Arithmetik umsetzt. Diese Bibliothek belegt Speicher.

Das geschieht halt automatisch weit im Hintergrund. Und wenn irgendeine andere Bibliothek float verwendet hat man das drin.

Beispiel:
Ein fast leerer Sketch der nur Serial.begin() und einmal println() macht belegt ca. 2kB

Das braucht 2,5kB:

void loop() 
{
  int i = 50;
  i = i / 10;
  Serial.println(i);
}

Hier wird auch etwas mehr Code erzeugt, weil eine umfangreichere Version von println() aufgerufen wird

Das hier belegt 4kB

void loop() 
{
  float f = 123.45f;
  f = f / 10.0;
  Serial.println(f);
}

Deckt sich als mit dem was ich in Erinnerung hatte. Die Gleitkomma Lib belegt ca. 1,5-2kB

Doc_Arduino:
Hallo,

richtig, currymütze redet vom Flash für sein Programmcode welches knapp wird.

Und seit Ihr Euch wirklich sicher das der Compiler nicht genutzte Funktionen einer Lib im Sketch außen vor läßt? Woher will der das wissen. Mein erster Gedanke war nämlich auch alle nicht benötigten Funktionen einer Lib zu entfernen. Ich würde sagen, originale Lib sichern und einfach mal testen.

Wenn der Compiler es nicht weiß. :grin: Ob es in der IDE bereits so eingestellt ist, kann ich nicht sagen, ansonsten hier mal einlesen

http://www.mikrocontroller.net/articles/GCC:_unbenutzte_Funktionen_entfernen

Und wenn man sich dann mal die Compiler Einstellungen in der platform.txt ansieht:

compiler.c.flags=-c -g -Os -w -ffunction-sections -fdata-sections -MMD
compiler.cpp.flags=-c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD

Sollte also passen

Hallo,

sehr interessant mit dem Compiler Optionen. :slight_smile:

Der Compiler muss es wissen, logisch. :slight_smile:
Mein Beobachtungen würden bestätigt - Dies wird mit den Compiler Einstellungen optimiert.

Somit hätte currymütze nur die Möglichkeit alle Gleitkommavars aus seinem Sketch(incl in allen Lib's) zu eliminieren um 1.5..2kb flash zu sparen.

Oder einen Mega2560 zu nehmen.

oder direkt den Atmega1284P http://www.atmel.com/devices/ATMEGA1284P.aspx

Dürfte sogar einfach in die IDE einzubinden sein. Gibt es im Gegensatz zum 2560 auch als 40P-Dip

sschultewolter:
oder direkt den Atmega1284P http://www.atmel.com/devices/ATMEGA1284P.aspx
Gibt es im Gegensatz zum 2560 auch als 40P-Dip

Schaut gut aus.
Eine PCB mit Atmega40 pins im Dip Gehäuse ist leichter zu designen.

Das Ding hat sogar mehr RAM als der Mega. 16kB statt 8 :o

Serenifly:
Das Ding hat sogar mehr RAM als der Mega. 16kB statt 8 :o

Ja :smiling_imp:
4 8Bit Ports ...., eigentlich ein super Teil. Bin gerade dabei ein paar Testaufbauten durchzutesten. Sitzte an einer TQFN Version dran.

Designen?? Schau dir mal das Pinout an. Denn kannste fast 1:1 verbinden und hast alle Ports schön in einer Reihenfolge :slight_smile: Man muss nur dran denken, es sind nicht die schmalen PDIPs :wink:

Bild recht oben. Das andere sind MAX6592

hi,

ich hab' auch ein paar von den dingern hier, sind super. speicher satt, 2 serielle schnittstellen usw. kosten um die 5-7 euro das stück.
sind halt recht groß, aber das stört mich nicht.

gruß stefan

Hi,

vielen Dank für die rege Diskussion.
D.h. aber im Endeffekt, dass ich hier doch nur mit einer anderen CPU mit mehr Speicher weiterkomme, richtig?

4 8Bit Ports ...., eigentlich ein super Teil. Bin gerade dabei ein paar Testaufbauten durchzutesten. Sitzte an einer TQFN Version dran.

Welchen Bootloader kann ich den aufspielen?
Ich nutze ja beim Atmega328 den Optiboot da ich mit dem normalen Bootloader keinen Watchdog verwenden konnte.

VG
Thorsten

Ja, auf Dauer ist was anderes besser.

Generell wird der Atmega1284 + Arduino hier erklärt:

Die Seite ist aber veraltet. Aktuelle Core Files basierend darauf (für verschiedene IDE Versionen gibt es hier):
http://www.leonardomiliani.com/en/arduino/
nach unten scrollen