Germany
Offline
Newbie
Karma: 0
Posts: 16
|
 |
« on: December 02, 2011, 04:58:21 am » |
I upgraded to 1.0 yesterday. It took me a while to adapt the libraries (e.g. ds1307 clock), but I managed to get it compiled. The sketch used about 25k of flash before, now I can't upload it anymore to the Arduino Uno, because it's blown up to 31,5k.
I make use of Ethernet, SD, Wire, OneWire, DallasTemperature, DS1307 and DHT11 (humidity sensor) libraries. If helpfull, I can post the sketch.
Any help greatly appreciated!
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Sr. Member
Karma: 19
Posts: 420
Always making something...
|
 |
« Reply #1 on: December 02, 2011, 07:51:38 am » |
OneWire 2.1 has an option, if you edit OneWire.h, to use a small but slower CRC algorithm. For OneWire 2.0, the slow code was the default. 2.1 defaults to the fast code. The size change should be about 250 bytes.
Unfortunately, some of 1.0's new features, like xyz.print() returning byte counts, simply consume more code space.
If you had posted code, I might have investigated if any one thing was a huge contributor to the size change. But instead, I'm writing this message.. (hint: your chances of more useful help are always better if you post code that demonstrates your problem).
|
|
|
|
|
Logged
|
|
|
|
|
Germany
Offline
Newbie
Karma: 0
Posts: 16
|
 |
« Reply #2 on: December 02, 2011, 08:05:28 am » |
Thanks for your reply! I'd love some expert have a look at the code in any case!  Some of the variable and function names are german, I am afraid. Here it is: #include <MemoryFree.h> #include <EEPROM.h> #include <SD.h> //SD-Karte #include <SPI.h> //Kommunikation mit Ethernet-Shield #include <Ethernet.h> //#include <dht11.h> //Feuchte-Sensor #include <OneWire.h> //Kommunikation mit Temperatur-Sensoren #include <DallasTemperature.h> //Temperatur-Sensoren #include <Wire.h> //I2C für Uhr #include <DS1307.h> //Uhr-Chip //#include <Arduino.h>
#define DHT11PIN 2 //Digitaler Pin, an dem DHT11 angeschlossen ist #define ONE_WIRE_BUS 3 //Digitaler Pin für 1-Wire
// Enter a MAC address and IP address for your controller below. // The IP address will be dependent on your local network: byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; byte ip[] = { 192,168,1, 177 };
// Initialize the Ethernet server library (port 80 is default for HTTP) EthernetServer server(80); //dht11 feuchtesensor; OneWire oneWire(ONE_WIRE_BUS); //Instanz für 1-Wire-Device DallasTemperature tempSensors(&oneWire); //Temperatursensor int uhrzeit[7]; const int relais1 = 5, relais2 = 6; //Relais für Pumpe auf Pins 5, 6 const char eingabeTaste = 13; const char tabTaste = 9; //const char refreshString[] = "<meta http-equiv=\"refresh\" content=\"1; URL=/\">"; boolean nichtGespeichert = true; //fuer minuetliches Speichern
void setup() { Serial.begin(9600); //serielle Verbindung über USB starten
Ethernet.begin(mac, ip); // start the Ethernet connection server.begin(); // Ethernet Server starten tempSensors.begin(); // 1-Wire-Temperatursensoren starten pinMode(10, OUTPUT); //fuer SD-Karte: Chip select pin als OUTPUT setzen while (!SD.begin(4)) { //nur mit SD-Karte geht's weiter! Serial.println("SD-Karte?!"); delay(200); }; DDRC|=_BV(2) |_BV(3); // POWER:Vcc Gnd muss was für I2C sein, für die Uhr PORTC |=_BV(3); // VCC PINC3 //stelleUhr(); //Uhr nur einmal stellen!!
pinMode(relais1, OUTPUT); //Pin für relais1 pinMode(relais2, OUTPUT); //Pin für relais2 }
void loop() { RTC.get(uhrzeit,true); //Uhrzeit einlesen if (uhrzeit[0]<30 && nichtGespeichert) { //einmal in der Minute //readDHT11(); //DHT11-Feuchtesenser lesen und schreiben tempSensors.requestTemperatures(); // 1-Wire lesen werteSpeichern(); //Daten mit Zeitstempel speichern nichtGespeichert = false; } else if (uhrzeit[0]>=30) nichtGespeichert = true; webServer(); controlHeater(); }
void controlHeater() { float tempSollTag = changeTemp("h/tetag.htm",'='); float tempSollNacht = changeTemp("h/tenac.htm",'='); float tempSollWasser = changeTemp("h/tewas.htm",'='); DeviceAddress tempHV={ 0x28, 0x99, 0x88, 0x4A, 0x03, 0x00, 0x00, 0xD3 }; DeviceAddress tempHR={ 0x28, 0x99, 0x87, 0xAD, 0x02, 0x00, 0x00, 0xD8 }; DeviceAddress tempSpeicherOben ={ 0x28, 0x86, 0x5A, 0x08, 0x03, 0x00, 0x00, 0x96 }; DeviceAddress tempSpeicherMitte={ 0x28, 0x71, 0x4C, 0x08, 0x03, 0x00, 0x00, 0x81 }; DeviceAddress tempSpeicherUnten={ 0x28, 0xCA, 0x75, 0x08, 0x03, 0x00, 0x00, 0x09 }; DeviceAddress tempAussen={ 0x28, 0xD8, 0xC1, 0xAD, 0x02, 0x00, 0x00, 0xEF };
}
void webServer() { EthernetClient client = server.available(); // listen for incoming clients if (client) { // an http request ends with a blank line char* anfrage="h/12345.678"; int zeichenzaehler=0; while (client.available()) { char charVomClient = client.read(); if ((zeichenzaehler++ >= 5) &&(zeichenzaehler <=14)) anfrage[zeichenzaehler-4] = charVomClient; //Zeichen 12345.678 nach anfrage Serial.print(charVomClient); } Serial.println(); Serial.print("Anfrage: "); Serial.println(anfrage); if (anfrage[2]=='_') //"te*"=temperatur or "ta*"=tag { if (anfrage[3]=='t') //Temperatur { char upDown=anfrage[6]; //'+' or '-' switch (anfrage[4]) { case 't': //Tag anfrage="h/tetag.htm"; break; case 'n': //Nacht anfrage="h/tenac.htm"; break; case 'w': //Wasser anfrage="h/tewas.htm"; } changeTemp(anfrage, upDown); sendFile(client, anfrage); }//if else //Zeiten { boolean hour = (anfrage[6]=='h' || anfrage[6]=='i'); // !hour == minute boolean up = (anfrage[6]=='m' || anfrage[6]=='h'); // !up == down boolean startTime = (anfrage[5]=='s'); char heizzeit = anfrage[4]; boolean deleteTime = (anfrage[5]=='x'); switch (anfrage[3]) { case '1': anfrage="h/tamoX.htm"; break; case '2': anfrage="h/tadiX.htm"; break; case '3': anfrage="h/tamiX.htm"; break; case '4': anfrage="h/tadoX.htm"; break; case '5': anfrage="h/tafrX.htm"; break; case '6': anfrage="h/tasaX.htm"; break; case '7': anfrage="h/tasoX.htm"; } anfrage[6]=heizzeit; if (deleteTime) setTimeToND(anfrage); else changeTime(anfrage, startTime, hour, up); sendFile(client, anfrage); } } else { if (anfrage[2]==' ') anfrage="h/index.htm"; if (anfrage[8]=='t') anfrage="log.txt"; sendFile(client, anfrage); //alle sonstigen Anfragen }; delay(1); //Zeit für die TCP-Übermittlung client.stop(); // close the connection } }
/*void readDHT11(void) { int chk = feuchtesensor.read(DHT11PIN); //liest DHT11 switch (chk) //Fehlerbehandlung für DHT11 { case 0: break; case -1: Serial.println("DHT11: C err"); //checksum break; case -2: Serial.println("DHT11: T err"); //timeout break; default: Serial.println("DHT11: err"); break; } }*/
|
|
|
|
|
Logged
|
|
|
|
|
Germany
Offline
Newbie
Karma: 0
Posts: 16
|
 |
« Reply #3 on: December 02, 2011, 08:06:18 am » |
Second half of the code (didn't fit in one message): void werteSpeichern(void) //sichert alle Sensordaten in "log.txt" { Serial.print("werteS RAM: "); Serial.println(freeMemory()); File logFile = SD.open("LOG.TXT", FILE_WRITE); if (logFile) { logFile.print(uhrzeit[4]); //Datum und Uhrzeit logFile.print( "."); logFile.print( uhrzeit[5]); logFile.print( "."); logFile.print( uhrzeit[6]); logFile.print( " "); logFile.print( uhrzeit[2]); logFile.print( ":"); logFile.print( uhrzeit[1]); logFile.print( ":"); logFile.print( uhrzeit[0]); logFile.print( tabTaste);
/* logFile.print( feuchtesensor.humidity); logFile.print( tabTaste); logFile.print( feuchtesensor.temperature); logFile.print( tabTaste); */
logFile.print( (int)(tempSensors.getTempCByIndex(0)*100)); logFile.print( tabTaste); logFile.println( (int)(tempSensors.getTempCByIndex(1)*100));
delay(10); logFile.close(); } else Serial.println("Op file err"); }
boolean sendFile(Client& client, char* filename) { File file = SD.open(filename); if (file) { char c=file.read(); while (c != -1) { client.write(c); c = file.read(); } file.close(); return true; } else return false; }
float changeTemp(char* filename, const char upDown) { float temperature=0.0; File file = SD.open(filename, FILE_WRITE); if (file) { int positionInFile=0; char* last=" "; //length 5 file.seek(0); last[4]=file.read(); while (last[4] != -1) { if (last[4]=='>' && last[2]=='v' && last[3]=='"') positionInFile=file.position();//Start der Var // Serial.print("last: "); Serial.println(last); if (positionInFile!=0 && last[4]=='<') //weiterlesen, bis '<' erreicht { last[4]=0; temperature= (last[0]-48)*10 + (last[1]-48) + (last[3]-48)/10.0; // Serial.print("Temperatur: "); Serial.println(temperature); if (upDown=='+') temperature += 0.5; else if (upDown=='-') temperature -= 0.5; last[0]=temperature/10+48; last[1]=(int)(temperature-(int)(temperature/10)*10)+48; last[2]='.'; if ((int)(temperature*10) % 10 != 0) last[3]='5'; else last[3]='0'; // Serial.print("last: "); Serial.println(last); file.seek(positionInFile); for (int i=0;i<=3;i++) file.write(last[i]); last[4]=-1; } else { for (int i=0;i<4;i++) last[i]=last[i+1]; last[4] = file.read(); }; } file.close(); return temperature; } else return -1.0; }
int getTime(File& file, int& hour, int& minute) { char* last=" "; //length 3 last[2]=file.read(); while (last[2] != -1) { if (last[2]=='>' && last[0]=='v' && last[1]=='"') last[2]=-1; else { for (int i=0;i<2;i++) last[i]=last[i+1]; last[2] = file.read(); } } for (int i=1;i<=2;i++) last[i] = file.read(); if (last[1]=='N' && last[2]=='D') { hour=-1; minute=-1; } else { hour= (last[1]-48)*10 + (last[2]-48); for (int i=0;i<=2;i++) last[i] = file.read(); minute= (last[1]-48)*10 + (last[2]-48); }; return file.position(); }
boolean setTimeToND(char* filename) { File file = SD.open(filename, FILE_WRITE); if (file) { file.seek(0); for(int i=0; i <= 2; i++) { int hour, minute; int positionInFile=getTime(file, hour, minute); if (hour >= 0) { file.seek(positionInFile-5); file.print("ND "); Serial.println("ND geschrieben."); } else i=3; }; file.close(); return true; } else return false; }
boolean changeTime(char* filename, boolean startTime, boolean isHour, boolean up) { File file = SD.open(filename, FILE_WRITE); if (file) { int hour, minute; file.seek(0); int positionInFile=getTime(file, hour, minute); if (hour < 0) { file.seek(file.position()-2); file.print('00:00'); while(file.read()!='N'); file.seek(file.position()-1); file.print('00:00'); } else { if (!startTime) positionInFile=getTime(file,hour,minute); char* timeString="00:00"; if (isHour) { if (up) hour += 1; else hour -=1; if (hour==-1) hour=23; if (hour==24) hour=0; } else { if (up) minute += 10; else minute -= 10; if (minute < 0) minute=50; if (minute >50) minute=0; }; timeString[0]=hour/10+48; timeString[1]=(int)(hour-(int)(hour/10)*10)+48; timeString[3]=minute/10+48; timeString[4]=(int)(minute-(int)(minute/10)*10)+48; file.seek(positionInFile-5); for (int i=0;i<=4;i++) file.write(timeString[i]); }; file.close(); return true; } else return false; }
|
|
|
|
|
Logged
|
|
|
|
|
Dallas, TX USA
Offline
Edison Member
Karma: 25
Posts: 1617
|
 |
« Reply #4 on: December 02, 2011, 01:17:25 pm » |
So why upgrade? Unless you need the new features of 1.0, it really isn't worth the work to use it and as you have seen, it breaks literally 100% of the existing libraries and can cause your code to no longer fit. Since 1.0 was not well published during the beta/RC period prior to its release, I predict that many issues will crop up and you will see a flury of updates. So I'd hold off on using it for a while. If you still want to use 1.0 there are few easy things that might work in your specific case. If you are using a pre "uno" board, - upgrade your bootloader to use the smaller optiboot bootloader top make your board an "uno" board. Either use optiloader and another Arduino board or use the IDE using the optiboot image. https://github.com/WestfW/OptiLoaderhttps://github.com/WestfW/Arduino/tree/master/hardware/arduino/bootloaders/optibootYou can also save several hundred bytes of code by changing the head and tail pointers in HardwareSerial to use unsigned chars instead of ints. This is an easy change and should have been done in the official code. (but we all know how hard it is to get any patches into Arduino) Simple go edit hardware/cores/arduino/HardwareSerial.cpp and change: struct ring_buffer { unsigned char buffer[RX_BUFFER_SIZE]; int head; int tail; }; to struct ring_buffer { unsigned char buffer[RX_BUFFER_SIZE]; unsigned char head; unsigned char tail; };
|
|
|
|
|
Logged
|
|
|
|
|
"The old Europe"
Offline
Edison Member
Karma: 0
Posts: 2003
Bootloaders suck!
|
 |
« Reply #5 on: December 02, 2011, 01:47:28 pm » |
You can also shave off a few bytes (50-100), if you use your own main() function. Instead of: void setup(void) { // setup-code }
void loop(void) { // loop-code }
you'd just use: int main(void) {
init(); // this initializes all the timers and so forth
// your setup() code goes here
while(1) { // your loop() code goes inside the while loop }
} This also disables the 'serial event' code btw.
|
|
|
|
|
Logged
|
• Upload doesn't work? Do a loop-back test. • There's absolutely NO excuse for not having an ISP! • Your AVR needs a brain surgery? Use the online FUSE calculator. • My projects: RGB LED matrix, RGB LED ring, various ATtiny gadgets... • Microsoft is not the answer. It is the question, and the answer is NO!
|
|
|
|
Germany
Offline
Newbie
Karma: 0
Posts: 16
|
 |
« Reply #6 on: December 02, 2011, 02:10:51 pm » |
Unless you need the new features of 1.0, it really isn't worth the work to use it and as you have seen, it breaks literally 100% of the existing libraries and can cause your code to no longer fit.
I come to believe that that's the way to go... Why invest lots of work without the need for new features? Thanks also for the helpful hints! Same to you, madworm! I guess I will need these hints later anyhow, when I'll get to the limits. There's still a lot to do for my little Arduino! ;-)
|
|
|
|
|
Logged
|
|
|
|
|
SF Bay Area (USA)
Offline
Faraday Member
Karma: 78
Posts: 5453
Strongly opinionated, but not official!
|
 |
« Reply #7 on: December 02, 2011, 10:42:52 pm » |
I can do some analysis, but... nearly every library you're using is giving me compile errors. Do you happen to have pointers to the 1-compatible versions of onewire, ds1370, dallastemperature, and etc? (Yeah, I can probably fix them, but then I wouldn't know for sure whether I'm using the same code that you're using. PM me a zip file if you want.)
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Sr. Member
Karma: 19
Posts: 420
Always making something...
|
 |
« Reply #8 on: December 03, 2011, 11:34:20 am » |
I also might investigate, but at the risk of repeating myself, it's pointless without having the code to reproduce the problem.
@barish - you posted your sketch, but that is not enough. Imagine, if you will, that you some random person who might help, but has nothing other that a clean copy of the Arduino IDE. Try downloading a fresh copies of Arduino, both 1.0 and 0023. Can you reproduce the exact result in both using only fresh downloads of both Arduino IDEs, and the files you've provided? If not, you haven't posted enough to reproduce the problem!
|
|
|
|
« Last Edit: December 03, 2011, 11:48:48 am by Paul Stoffregen »
|
Logged
|
|
|
|
|
Germany
Offline
Newbie
Karma: 0
Posts: 16
|
 |
« Reply #9 on: December 03, 2011, 01:02:20 pm » |
Paul, I wasn't aware that you'd like to compile the code and reproduce the problem. Instead I thought you would look over my sketch to see if there was obvious memory waste. I will see if I can upload the modified libraries I use to make them available to you guys. Thanks for your effort so far! Edit: Here's the zip-file of my "libraries" folder: http://goo.gl/BMGYs
|
|
|
|
« Last Edit: December 03, 2011, 01:10:15 pm by barish »
|
Logged
|
|
|
|
|
0
Offline
Edison Member
Karma: 28
Posts: 1077
Arduino rocks
|
 |
« Reply #10 on: December 03, 2011, 06:41:59 pm » |
SD.h has grown by almost 2KB for a simple example. The SD/examples/ReadWrite sketch is 13580 bytes on 1.0 and it is 11686 bytes on 0022.
Most of this is due to new features added to the SD.h wrapper in 1.0. The base code for SdFat has not been changed much from 0022.
Part is due to something else in 1.0. For my new version of SdFat a similar example, SdFatReadWrite, is 12098 bytes on 1.0 and 11682 on 0022. So there is a 416 byte increase in this example with the same code on both systems.
|
|
|
|
|
Logged
|
|
|
|
|
SF Bay Area (USA)
Offline
Faraday Member
Karma: 78
Posts: 5453
Strongly opinionated, but not official!
|
 |
« Reply #11 on: December 03, 2011, 07:06:02 pm » |
look over my sketch to see if there was obvious memory waste. I'm afraid the "interesting question" is not "how can we fix your sketch?", but rather "why did the sketch get 25% bigger?", so we don't particularly want to look at the source for your sketch, but the size of the binaries of everything involved...
|
|
|
|
|
Logged
|
|
|
|
|
Germany
Offline
Newbie
Karma: 0
Posts: 16
|
 |
« Reply #12 on: December 04, 2011, 02:51:18 am » |
Part is due to something else in 1.0. For my new version of SdFat a similar example, SdFatReadWrite, is 12098 bytes on 1.0 and 11682 on 0022. So there is a 416 byte increase in this example with the same code on both systems.
If I understand there's something about 1.0 you don't know yet the cause. Well I hope someone will find out. @westfw: nothing to be afraid for, I hope you can compile and fix something now. All I want is a smaller binary after all, no matter where the problem lies.
|
|
|
|
« Last Edit: December 04, 2011, 02:54:09 am by barish »
|
Logged
|
|
|
|
|
0
Offline
Edison Member
Karma: 28
Posts: 1077
Arduino rocks
|
 |
« Reply #13 on: December 04, 2011, 07:44:27 am » |
Looks like most of the increase is in Ethernet. The Ethernet WebServer example is 10146 bytes on 1.0 but only 5446 bytes on 0022. That's 4,700 bytes more. I didn't look at the library code for Ethernet but the example was not changed much. Here is the diff for the example in 1.0 and 0022: 24c24 < IPAddress ip(192,168,1, 177); --- > byte ip[] = { 192,168,1, 177 }; 29c29 < EthernetServer server(80); --- > Server server(80); 41c41 < EthernetClient client = server.available(); --- > Client client = server.available(); The SD library is about 1,500 bytes larger due to new features. These two libraries add about 6,200 bytes.
|
|
|
|
|
Logged
|
|
|
|
|
Germany
Offline
Newbie
Karma: 0
Posts: 16
|
 |
« Reply #14 on: December 04, 2011, 02:03:25 pm » |
Thanks, fat16lib, so that must be the biggest chunk of my memory increase. But shouldn't there be some options for the lib to use less space? E.g. I don't need to open multiple files. I mean, 5k more or less, that must be important to many users (I imagine).
|
|
|
|
|
Logged
|
|
|
|
|
|