Hallo,
für meine Haussteuerung habe ich einen Arduino Uno mit 32 Ein- und 32
Ausgängen (74HC165 & 74HC595), Ethernet für die Webseite und CAN-Bus mit
MCP2515 aufgebaut.
Manche haben den IO-Webserver schon aufgerufen,
http://mega-hz.dnshome.de:85
die IOs funktionieren ja schon, aber ich habe nicht mehr genug Speicher
frei um die Can-Bus routinen einzubauen.
Da ich eher der Hardworker bin, bitte ich Euch um Hilfe, den Code zu
optimieren!
hier das Listing:
IIRC braucht die mitgelieferte Standard-SD-Card Library
unverhältnismäßig viel Flash&Ram.
Da gibt es kleinere, ggfs. unter Verzicht auf exFAT und andere
Spielereien.
Ansonsten Strings wo möglich in F("...") klammern.
also
cl.print("checked"); --> cl.print(F("checked"));
Εrnst B. schrieb:> Da gibt es kleinere, ggfs. unter Verzicht auf exFAT und andere> Spielereien.
hast du nen link für eine sparsamere SD Library?
>> Ansonsten Strings wo möglich in F("...") klammern.
das geht doch aber nur für Strings mit sich nicht ändernden Daten, oder?
(z.B. die MAC-Adresse?)
Wolfram F. schrieb:> (z.B. die MAC-Adresse?)
geht für fast alle konstanten Strings, also alles was zwischen
Gänsefüßchen im Quelltext steht.
als Parameter zu s(n)printf gehts z.B. nicht, da könnte man auf
snprinf_P und PSTR ausweichen, wenn man auch noch die letzten Bytes
rausquetschen will.
Wolfram F. schrieb:> link für eine sparsamere SD Library
Leider nicht, bin länger nicht mehr mit Arduino unterwegs gewesen.
Sollte sich aber leicht was finden lassen, ggfs. kann man auch per
#define (-D Compileroption) die mitgeliferte SD-Lib verkleinern.
Ggf. noch auf digitalWrite und pinMode verzichten.
Hab jetzt nur mal kurz mit direktem Registerzugriff den Unterschied
angeguckt. Ein Pin als Output gesetzt und dann in der loop auf LOW.
digitalWrite/PinMode:
Der Sketch verwendet 1.268 Bytes (0%) des Programmspeicherplatzes. Das
Maximum sind 253.952 Bytes.
direkter Registerzugriff via Makro:
Der Sketch verwendet 660 Bytes (0%) des Programmspeicherplatzes. Das
Maximum sind 253.952 Bytes.
wow, das sind Unterschiede!
Aber mit direkter Register-Programmierung kenn ich mich leider nicht aus
:-(
Ich habe aber eben alle print ausgaben mit F() versehen, das brachte
schonmal 172 Bytes mehr!
Kannst Du mir den Code für die Makros mal schreiben?
@mega-hz
Schau dir das avr gcc tutorial hier auf der seite an! Dort findest du
alle infos und weißt danach auch selbst wie es geht.
Wenn du dir die arbeit nicht machen willst ist es sinnvoller sich einen
größeren arduino zu kaufen und den code dort laufen zu lassen..
alle pinMode, digitalWrite und digitalRead sind nun durch Fast ersetzt,
ergab 62 Bytes weniger Flashspeicher.
Byte für Byte.... :-)
Habe aber immernoch nur 825 Bytes SRAM frei,
mal sehen ob sich die Can-Routinen jetzt schon mit einbinden lassen...
Wolfram F. schrieb:> Da ich eher der Hardworker bin, bitte ich Euch um Hilfe, den Code zu> optimieren!
Wenn du unbedingt bei Arduino bleiben willst dann nimm einen
Mega2560 der "pinkompatibel" ist. Kost' ja nix ... und hat
viel mehr Flash und RAM.
> Speicheroptimierung
Vor Optimierung erfolgt erst mal Profiling um rauszufinden, wo wann
warum wieviel Speicher verbraucht wird. Darauf basierend kann dann u.U.
Optimierung erfolgen.
Als erstes findest du also heraus, selche Komponenten statisch /
dynamisch Speicher, Stack, Heap, Static Storage etc. benötigen und
wieviel.
Wolfram F. schrieb:> mal sehen ob sich die Can-Routinen jetzt schon mit einbinden lassen...
Und was soll ich sagen, die Can-Bus Routinen funktionieren nun!
Auch wenn nur noch 328Bytes frei sind (RAM) läuft der Webserver incl.CAN
nun!
Erstmal vielen Dank für Eure Tips!
Werde mich nun noch nach einer speichersparenden SD-Lib kümmern.
Da noch ne Frage an die Experten:
Wäre es nicht auch irgendwie möglich, die Webseite anstatt von einer
SD-Karte direkt von meinem Server zu laden und weiterzusenden?
Also anstatt SD.open / read usw. 192.168.2.223/web-io.htm ?
> Wenn du unbedingt bei Arduino bleiben willst dann nimm einen> Mega2560 der "pinkompatibel" ist. Kost' ja nix ... und hat> viel mehr Flash und RAM.
Das es größere Controller gibt, ist mir schon klar, wenn es nicht
geklappt hätte, wäre das ein Weg.
Arduino ist nur in der Test-/Aufbauphase, da praktisch.
Später kommt auf eine eigene Platine dann auch ein einzelner Controller.
Wolfram F. schrieb:> SD-Karte direkt von meinem Server zu laden und weiterzusenden?
Umständlich.
Wie groß ist die Webseite denn?
Wenn sie kleiner ist als der Flash-Bedarf der SD-Lib (und die SD nicht
für andere Sachen auch gebraucht wird) dann lad sie doch aus dem
AVR-Flash.
Und im HTML kannst du den Webbrowser ja direkt Bilder, JS, CSS usw. von
deinem Server laden lassen.
"Hilfe mir geht der Speicher aus" hört man auffällig oft von Arduino
Nutzern.
Ganz ehrlich: Wer so komplexe Programme hinbekommt, der kann das auch
ohne Arduino Software. Versuch es einfach mal, ist wirklich nicht
schwer.
Stefan U. schrieb:> "Hilfe mir geht der Speicher aus" hört man auffällig oft von Arduino> Nutzern.
Wer sich so gar nicht mit Mikrocontrollern befassen will und daher
copy&paste-Programmierung mit gewaltigem Overhead macht, der muß sich
eben einen fetteren Chip kaufen.
Was ja auch der Grund ist, wieso das Arduino-Ökosystem in der Industrie
jedenfalls dort keinen Fuß fassen konnte, wo es um Stückzahlen geht.
Nop schrieb:> Was ja auch der Grund ist, wieso das Arduino-Ökosystem in der Industrie> jedenfalls dort keinen Fuß fassen konnte, wo es um Stückzahlen geht.
Ich denke der Grund ist eher, dass das nie das Ziel war.
Naja, ich programmiere beruflich hauptsächlich in Java mit zahlreichen
Frameworks über Framworks. Das ist auch nicht gerade Platzsparend und
schon gar nicht effizient. Vor 20 Jahren war außerdem Java selbst noch
fast eine Scriptsprache.
Dennoch hat Java und seine Frameworks einen sicheren Platz im Enterprise
Umfeld. Da kommt es (wegen der geringen Stückzahl) eher auf niedrige
Entwicklungskosten an. In so einem Umfeld könnte Arduino durchaus
punkten. Also ich meine dort, wo man nicht in Massen für jedermann
produziert, sondern Spezialkonstruktionen für einzelne Anwendungsfälle.
c r schrieb:> Ich denke der Grund ist eher, dass das nie das Ziel war.
Und wieso kommen dann Leute auf die blödsinnige Idee, bei einem
Einzelprojekt wie einer DIY-Haussteuerung unbedingt am Controller sparen
zu wollen? Und bei Webserver, Ehternet, IO, CAN unbedingt 32k ROM und 2k
RAM verwenden zu wollen? Und das auch noch mit der Arduino-Bloatware?
Also entweder man hat Stückzahlen und will daher den Controller günstig
halten, dann macht man das nicht mit der Arduino-Software. Oder man hat
keine Stückzahlen, will die Entwicklung bequem halten und nimmt daher
die Arduino-Software, dann aber halt auch einen größeren Controller.
Ein Arduino Mega hat statt 2k/32k schonmal 8k/128k, und damit hätte der
TE seine Probleme nicht.
Die eierlegende Wollmilchsau, also bequeme Programmierung ohne
Einarbeitung, billigen Controller UND komplexe Anwendung, das geht nicht
gut. Von diesen drei Parametern sind nur jeweils zwei wählbar.
dieses Projekt ist ja erst so nach und nach entstanden und dafür ist der
Arduino doch prima! Da ich inzwischen aber noch ein paar Ideen habe,
plane ich einen Atmega128 zu verwenden, damit habe ich dann auch genug
Reserve.
Alles was das laufende Programm jetzt macht, ist nahe dem Ziel.
Was noch rein muss, sind diverse Auswertungen des CAN-BUSses und
Reaktionen auf bestimmte Daten. RTC, sonst ist nix mehr geplant.
Der 128er kommt dann mit allen anderen Teilen und OHNE Arduino
Bootloader auf eine Platine, die ich noch entwerfe.
Genauso habe ich meine UP-Platinen mit CAN-Bus entwickelt, erst auf dem
Arduino getestet dann PCB gemacht, ATMEGA8, MCP2515 und Relays drauf,
fertig!
Ich weiss garnicht, warum von einer bestimmten Personengruppe regelmäßig
auf die Arduinos geschimpft wird, ist doch ein prima "Baukasten"!
Ich kann mich noch gut an die Zeiten erinnern, wo Computer nur 8Bit
hatten und man sich qualvoll und unbequem mit LDA #$00 STA $400
Assembler rumquälen MUSSTE!
Dagegen ist so ein Arduino doch wirklich ein Leckerbissen!
Aber ich denke es sind die gleichen Leute, die auch PCBs, die mit EAGLE
gemacht wurden, nur belächeln...
Trotzdem bin ich heute einiges weiter gekommen und bedanke mich sehr
dafür!
Wolfram F. schrieb:> Ich kann mich noch gut an die Zeiten erinnern, wo Computer nur 8Bit> hatten und man sich qualvoll und unbequem mit LDA #$00 STA $400> Assembler rumquälen MUSSTE!> Dagegen ist so ein Arduino doch wirklich ein Leckerbissen!
obwohl er auch nur 8-Bit hat
@Stefan Us (stefanus)
>"Hilfe mir geht der Speicher aus" hört man auffällig oft von Arduino>Nutzern.
Dort gibt es halt einen hohen Anteil Anfänger und "mach mal schnell
Maker" ohne Hintergrundwissen.
>Ganz ehrlich: Wer so komplexe Programme hinbekommt, der kann das auch>ohne Arduino Software. Versuch es einfach mal, ist wirklich nicht>schwer.
Unfug! Man erfindet das Rad nicht neu! Die meisten Arduino-Libs sind
schon voll OK, das kann man mit vernünftigem Aufwand kaum besser machen.
Warst du nicht derjenige, der sich über die lernunwilligen Kinder
beschwert hat? Bei deiner Sichtweise kein Wunder . . .
Wolfram F. schrieb:> Ich weiss garnicht, warum von einer bestimmten Personengruppe regelmäßig> auf die Arduinos geschimpft wird, ist doch ein prima "Baukasten"!
Weil es nunmal kein Wunder ist, daß man dauernd Ressourcenprobleme hat,
wenn man seinen Controller unbedingt mit einen Lasagnedesaster aus
Bloatsoftware programmieren will.
Man kann dann einfach einen größeren Controller nehmen und muß halt
damit leben, daß die Leute, die das kritisieren, denselben Zweck mit
einem viel kleineren Controller erreichen können. Das ist der Lohn der
Einarbeitung nach Controller-Datenblatt.
Dies übrigens ohne flächendeckende Assemblerprogrammierung; das wird
heute nur noch in sehr wenigen Teilen gemacht. Für den Rest nimmt man
entweder C oder (im Wesentlichen) auf "C mit Klassen" begrenztes C++.
Dann braucht man ohne die Lasagne-Architektur auch nicht 100 Taktzyklen,
um einen Pin zu toggeln.
Andererseits gibt's ja sogar Leute, die für ein paar GPIOs unter einem
Raspi gar nicht erst anfangen. Hat den Vorteil, daß man dann weder
Assembler noch C noch C++ braucht, sondern das auch mehr oder weniger
mit Shellscripten hinbekommt. ;-)
Nop schrieb:> Weil es nunmal kein Wunder ist, daß man dauernd Ressourcenprobleme hat,> wenn man seinen Controller unbedingt mit einen Lasagnedesaster aus> Bloatsoftware programmieren will.>> Man kann dann einfach einen größeren Controller nehmen und muß halt> damit leben, daß die Leute, die das kritisieren, denselben Zweck mit> einem viel kleineren Controller erreichen können. Das ist der Lohn der> Einarbeitung nach Controller-Datenblatt.>> Dies übrigens ohne flächendeckende Assemblerprogrammierung; das wird> heute nur noch in sehr wenigen Teilen gemacht. Für den Rest nimmt man> entweder C oder (im Wesentlichen) auf "C mit Klassen" begrenztes C++.> Dann braucht man ohne die Lasagne-Architektur auch nicht 100 Taktzyklen,> um einen Pin zu toggeln.
Das geht auch alles mit der Arduino IDE...
c++ ist dort Standard
Die Arduino Komfort Funktionen muss man ja nicht verwenden, wenn sie
stören.
Nix "Bloat", wenn man nicht will.
Deine Argumente sind heiße Luft.
Im Codebeispiel übrigens noch:
- StrContains/StrClear: beide überflüssig.
- Verwendung von sprintf: Völlig unnötig für diesen Anwendungsfall, und
außerdem mit unnötigem Stackverbrauch. Wäre interessant zu sehen, ob
sich damit nennenswert Speicher sparen läßt - falls nicht anderswo im
Framework unter der Haube sowieso noch printfs herumspuken.
Alternative, zumal LED_num offensichtlich nicht größer als 8 werden kann
(weil j nur für 8 bits in der Schleife durchläuft):
Arduino F. schrieb:> Die Arduino Komfort Funktionen muss man ja nicht verwenden, wenn sie> stören.
Arduino ist aber gerade wegen des SW-Ökosystems so erfolgreich, also
wegen des Bloats. Und wie es der Zufall mit der ehißen Luft so will,
schau mal, was hier im konkreten Fall verwendet wird.
Nop schrieb:> was hier im konkreten Fall verwendet wird.
Wenn Hein Blöd seine Konservendose mit der Axt öffnet, dann kann
passieren, dass er ein paar Spritzer abbekommt.
Was ist in dem Fall scheiße/fehlerhaft?
(es sind auch Mehrfachnennungen erlaubt)
[ ] Die Axt ist kaputt, und muss durch eine modernere ersetzt werden
[ ] Die Dose entspricht nicht der Dosen Spezifikation
>> Später kommt auf eine eigene Platine dann auch ein einzelner Controller.>> Und dann hoffentlich auch ohne Arduino IDE ....
Hab noch keine A.IDE auf einer Platine gesehen!
Arduino F. schrieb:> Deine Argumente sind heiße Luft.
Haha DAS letzte Argumente der ArduinoZombies. Es ist nicht scheiße weil
man es ja nicht nutzen muss. Sehr gut! So wie der Zucker der den Kaffee
bitter macht, wenn man ihn nicht rein tut.
Müßig darauf hinzuweisen dass das Problem dann nicht mehr besteht, wenn
man die problematische Software nicht mehr einsetzt.
Aber "Arduino" ohne dieses ganze BLOAT, ist natürlich kein Arduino mehr,
sondern eine Platine mit Controller wie tausend andere auch. Darum nutzt
der TE auch das BLOAT weil er sich nicht damit beschäftigen will,
sondern er sich für den coolen Frood hält wenn er "server.begin()" in
die dunkle Nacht ruft, aber keine Taschenlampe hat um zu sehen was da
eigentlich hinter steckt. DAS wäre bei einer klassischen Lib anders, DIE
würde aber bisschen Skill erfordern. Will man also nicht.
Und da es natürlich keine guten oder schlechten Entscheidungen gibt,
sondern nur Konsequenzen, ist die Konsequenz aus deiner
Arduino-Entscheidung nun eben die dass es nicht funktioniert.
Glückwunsch. Danke. Weitergehen!
Cyblord -. schrieb:> ist die Konsequenz aus deiner> Arduino-Entscheidung nun eben die dass es nicht funktioniert.
Mit nem Arduino Mega würde es ja wieder funktionieren, was die
Speicherproblematik angeht. Nur hat der kein Ethernet; aber der
verwendete Uno hat das ja auch nicht, von daher bin ich auch ein wenig
verwundert, wie das überhaupt da reingeht. Es sei denn, es handelt sich
in Wahrheit um den Arduino Ethernet, der bis eben auf die
Ethernet-Schnittstelle mit dem Uno identisch ist.
Da es den Mega aber AFAIK nicht in der Ethernet-Ausfürhung gibt, wäre
das natürlich etwas tricky.
Wenn es eine ganze Haussteuerung ist, wäre es aber sowieso eine
Alternative, sich die lokalen Knoten aufzubauen ohne Ethernet, sondern
mit CAN.
Und dann als Zentralserver nen Raspi zu nehmen, der das Monitoring und
zentrale Koordination übernimmt. Etwa im Winter gucken, wie die
gemittelte Leistung der kleinen Dach-PV ist, daraus zu folgern, ob Sonne
scheint oder nicht, und dementsprechend tagsüber die Rolläden hochfahren
oder runter. Damit könnte man wohl Heizkosten sparen.
Außerdem wäre auch ewig viel Speicher da für Logfiles, was sicherlich
beim Debuggen und Optimieren hilft. Beispielsweise, wie lange die
sinnvolle Mittelungszeit der PV sein sollte, um bei "heiter bis wolkig"
vernünftig zu regeln.
Zudem hätte man dann eine Art von Schichten-Architektur im System, statt
alles in einem ball of mud zusammenzukleben, was zugegebenermaßen genau
das ist, wozu Arduino-Sketche ihrem Aufbau nach ohnehin sehr verführen.
Ist ja OK für schnell-mal-eben-was-prototypen, aber mehr auch nicht.
Nop schrieb:> Mit nem Arduino Mega würde es ja wieder funktionieren, was die> Speicherproblematik angeht. Nur hat der kein Ethernet; aber der> verwendete Uno hat das ja auch nicht, von daher bin ich auch ein wenig> verwundert, wie das überhaupt da reingeht. Es sei denn, es handelt sich> in Wahrheit um den Arduino Ethernet, der bis eben auf die> Ethernet-Schnittstelle mit dem Uno identisch ist.>> Da es den Mega aber AFAIK nicht in der Ethernet-Ausfürhung gibt, wäre> das natürlich etwas tricky.
Das Arduino Ethernet Shield passt auf UNO und Mega.
Arduino F. schrieb:> Das Arduino Ethernet Shield passt auf UNO und Mega
genau so ist es, Uno,Ethernet-Shield,Can-bus,shift-in,shift-out shield.
Nop schrieb:> Wenn es eine ganze Haussteuerung ist, wäre es aber sowieso eine> Alternative, sich die lokalen Knoten aufzubauen ohne Ethernet, sondern> mit CAN.
Und auch dies ist genau das, was der Haufen machen soll!
Die Ehternet Schnittstelle ist nur für die Webseite/Weboberfläche.
Die einzelnen Knoten haben je eine einstellbare CAN-ID und warten auf
Befehle (PWM oder Relays-Ausgang) und senden bei Bedarf 8 Analog-Werte,
wobei der erste Wert immer die Betriebsspannung (28V) in 8Bit und der
2.Wert immer den echten Zustand des Relays zurückliefert. Alle anderen
Eingänge können analog oder digital sein -> NTC oder auch Tür-Kontakt.
Nop schrieb:> #define STR_REQ_LED_LEN 7> #define STR_REQ_LED_NUM_POS 3> #define STR_REQ_LED_STATE_POS 5> void SetLEDs(void)> {> char str_req[STR_REQ_LED_LEN];> uint8_t i, j, LED_num = 0;>>> strcpy(str_req, "LEDx=y");>> for (i = 0; i < 4; i++)> {> for (j = 1; j > 0; j <<= 1)> {> str_req[STR_REQ_LED_NUM_POS] = ((char) (LED_num)) + '0';> str_req[STR_REQ_LED_STATE_POS] = '1';> if (strstr(HTTP_req, str_req))> {> LED_state[i] |= j; // save LED state> bitSet(Outputs,LED_num);> }> else> {> str_req[STR_REQ_LED_STATE_POS] = '0';>>>>> if (strstr(HTTP_req, str_off)) <<<soll str_req sein!?> {> LED_state[i] &= (~j); // save LED state> bitClear(Outputs,LED_num);> }> }> LED_num++;> }> }> shiftOut32(Outputs);> }
diese Routine bringt zwar 1482 Bytes mehr Flash und 2 Bytes mehr RAM
funktioniert (abgesehen von dem str_off Fehler) aber nur von Ausgang 0
bis 9 !
Wolfram F. schrieb:>> soll str_req sein!?
Jepp, vergessen.
Ich sehe gerade, daß LED_Num in jeder inneren Schleife hochgetickert
wird, so daß sie LED_Num mit 4mal von der äußeren Schleife und 8mal von
der inneren bis 31 gehen kann und nicht nur bis 7, wie ich annahm, daher
der Fehler.
Da in den Requests die LED-Nummer nicht mit führender 0 übergeben wird,
können die also lauten:
LED1=1 (bzw =0) bis LED31=1 (bzw. 0). Sinnvoll abgetestet mit meinem
Code werden aber nur die LEDS 0-9.
Mit AVR-GCC müßte auch die Funktion itoa() verfügbar sein und in
stdlib.h definiert sein. Ist allerdings kein ANSI-C, aber wenn's die
schon gibt, kann man die vorhandene auch nehmen.
1482 Bytes Flash für das bißchen Recoding ist definitiv ein Knaller,
damit kriegt man schonmal zumindest Codespace.
1
#define STR_REQ_LED_LEN 8
2
#define STR_REQ_LED_NUM_POS 3
3
4
void SetLEDs(void)
5
{
6
char str_req[STR_REQ_LED_LEN];
7
uint8_t i, j, LED_num = 0;
8
9
strcpy(str_req, "LED");
10
11
for (i = 0; i < 4; i++)
12
{
13
for (j = 1; j > 0; j <<= 1) /*after 0x80, uint8 wraps to 0*/
das funktioniert fast!
Output 31, also der letzte (0-31) lässt sich nicht schalten!
EDIT: lässt sich doch schalten!! Aber irgendwie ist alles etwas
langsamer jetzt!
und die Speicher Ersparnis ist runter auf +1288 Bytes im Flash.
Ich bräuchte mehr Ram-Speicher.
Anstatt die LED_State[] mit 4x 8Bit Belegung UND der long Variable
"Outputs" beide zu benutzen, könnte man das nicht auch nur mit der Long
Outputs machen?
Wolfram F. schrieb:> das funktioniert fast!> Output 31, also der letzte (0-31) lässt sich nicht schalten!> EDIT: lässt sich doch schalten!! Aber irgendwie ist alles etwas> langsamer jetzt!
Ich vermute, itoa() ist für Integer implementiert, also für
16bit-Variablen. Das ist auf einem 8-bitter umständlich, zumal hier ja
eigentlich nur 8bit-Ints gebraucht werden. Außerdem ist die Basis auch
noch variabel. Also wohl mit Modulo und Division und dann auch noch in
16bit.
Daher könnte man ein LEDtoa() selber implementieren, das sollte auch die
Flash-Ersparnis wieder raufschrauben.
also itoa(LED_num, str_req+STR_REQ_LED_NUM_POS, 10); ersetzen und den
Basisparameter (10 für dezimal) dabei rauswerfen. Das Eklige daran ist,
daß auf dem AVR zwar die nette Funktion div existiert, die einem
Quotient und Rest einer Division auf einen Schlag liefert, blöderweise
aber für 16bit-ints.
Also richtig zu Fuß und dann auch ohne Division und Modulo, das müßte
auch auf einem 8-bitter zügig gehen. 8-bit-Hacking, yeah. :-)
1
/*converts numbers 0-39 to 0 terminated ASCII, no leading zeros*/
2
void LEDtoa(uint8_t val, char *str)
3
{
4
if (val >= 30)
5
{
6
*str++ = '3';
7
val -= 30;
8
} else if (val >= 20)
9
{
10
*str++ = '2';
11
val -= 20;
12
} else /*between 10 and 19*/
13
{
14
*str++ = '1';
15
val -= 10;
16
}
17
*str++ = (char) val + '0';
18
*str = 0; /*string zero termination*/
19
}
> Anstatt die LED_State[] mit 4x 8Bit Belegung UND der long Variable> "Outputs" beide zu benutzen, könnte man das nicht auch nur mit der Long> Outputs machen?
Ja, das wäre auch eine Option; soviel Rewrite hatte ich jetzt spontan
nicht angedacht, um die Funktion "nach außen" hin konstant zu halten.
ok, DAS funktioniert! hat +58 Bytes Flash und 2 Bytes RAM gebracht.
Vielen Dank dafür!
Mit den Variablen Outputs und Inputs (je long) hätte man eigentlich ja
alles abgedeckt, eben 32Bits pro.
Dann bräuchte man die Input[8] nicht mehr, wären nochmal 9x8 Bytes...
Was zwar kein Speicherplatz jedoch weniger traffic bringt, wäre ne
Abfrage, ob sich was geändert hat, Out oder Inputs, wenn nicht, brauchen
die Ajax Daten auch nicht ständig hin und her geschickt werden.
Spätestens in 2 Monaten entstehen weitere Wünsche. Und da wird wieder
der Platz nicht reichen. Da kann man so lange rumoptimieren wie man
will, das führt aber nicht weiter.
Also sollte man jetzt schon schauen. ob es eine Architektur mit mehr
Platz gibt. z.B. Arduino Due mit 500 K Flash und 96 K Ram. Oder man
teilt das Programm auf mehrere Rechner auf: Arduino zum Steuern, Raspi
für den Web-Server.
wie ich schon weiter oben erwähnte, soll auf der Platine dann ein
Atmega128 Platz finden!
Nen PI für die Webseite?
Etwas overkill, oder?
Dann könnte man mit nem PI auch ALLES Steuern... aber wozu?
Ist preislich dann doch schon ein großer Unterschied.
Ziel ist es, daß die Webseite von meinem Server kommt,nicht mehr von der
SD-Karte.
bin gerade dabei, dies hinzubekommen.... und die Umleitung vom Arduino
zum Server klappt bereits,
client.println(F("HTTP/1.1 302 Found"));
client.println(F("Location:
http://192.168.2.222/Arduino/WEB-IO/web-io.htm"));
nur kommen die Ajax Daten nun nicht mehr an.
Wie ich die Verbindung wieder hinbekomme, weiss ich noch nicht.
Jemand ne Idee?
Wolfram F. schrieb:> nur kommen die Ajax Daten nun nicht mehr an.
Am einfachsten: Pack auf den AVR eine minimalst-Webseite, darin bindest
du Javascript+CSS von deinem Server ein. Im Javascript baust du die
Webseiten-Elemente/Layout zusammen, und sprichst deine AJAX-Endpoints
an.
So erfüllst du die "same domain policy" des Webbrowsers, hast aber
trotzdem 99% der Webseite von einem anderen Server geladen.
ja, aber dann hab ich ja quasi das, wie es jetzt mit sd-karte ist!
Das meiste der Webseite ist ja CSS und JS!
Müsste nicht in der Webseite wieder eine "Verbindung" zum Arduino
hergestellt werden?
Wolfram F. schrieb:> ja, aber dann hab ich ja quasi das, wie es jetzt mit sd-karte ist!> Das meiste der Webseite ist ja CSS und JS!> Müsste nicht in der Webseite wieder eine "Verbindung" zum Arduino> hergestellt werden?
Nein, ja.
Idee ist ein Minimal-HTML-File aus dem Arduino-flash(nicht SD!)
auszuliefern, und den Rest vom externen Server nachladen zu lassen.
Zusammenführen macht der Webbrowser.
Der AVR muss nicht Reverse-Proxy spielen.
AJAX dann natürlich direkt zwischen Webbrowser und AVR.
Εrnst B. schrieb:> Ansonsten Strings wo möglich in F("...") klammern.
hmmm wie macht man das bei sprintf?
sprintf(tmp_lcd_str, (F("faehrt %01d.%s")), (1+TRYS-f_cnt), dir_str);
error: cannot convert 'const __FlashStringHelper*' to 'const char*' for
argument '2' to 'int sprintf(char*, const char*, ...)'
ich erinnere mich auch an Problemchen mit strncmp_P strcpy_P obwohl
diese ja genau dafür da sind.
Joachim B. schrieb:> ich erinnere mich auch an Problemchen mit strncmp_P strcpy_P obwohl> diese ja genau dafür da sind.
AHA, jetzt habe ich erst kapiert, welche Sorgen dich da plagen, oder
geplagt haben...
Du mischt das Arduino Komfort F() Macro mit den Atmel Lib Funktionen....
Da klemmt es!
So geht das:
Wolfram F. schrieb:> client.println(F("<html><head><script> src='http://192.168.2.222/Arduino/WEB-IO/web-io.htm'>"));
Als Script natürlich ein Javascript-File, kein HTML-file angeben.
Im Javascript kannst du dann HTML-Fragmente zum Seitenaufbau und auch
Daten per AJAX von AVR & 192.168.2.222 nachladen.
Sorry, bin davon ausgegangen, dass du zumindest ein paar HTML-Grundlagen
beherrschst, nachdem oben die Anfrage nach AJAX kam...
Würde dir raten, das mit dem HTML erstmal ohne AVR, also "trocken", zu
üben.
Arduino F. schrieb:> AHA, jetzt habe ich erst kapiert, welche Sorgen dich da plagen, oder> geplagt haben...
hat eh nichts gebracht
das F() macro bringt ja viel, aber der Wechsel von sprintf zu sprintf_P
ist gelinde gesagt sinnlos
vorher sprintf
text data bss dec hex
28670 706 919 30295 7657
Binäre Sketchgröße: 29.376 Bytes
nachher sprintf_P
text data bss dec hex
28718 708 919 30345 7689
Binäre Sketchgröße: 29.376 Bytes
48 Byte im flash verloren und 2 Byte im data verloren, tolle
Optimierung.
Joachim B. schrieb:> tolle Optimierung.sprintf_P
Flash: 3.130 Bytes
Ram: 250 Bytes
sprintf
Flash: 3.128 Bytes
Ram: 266 Bytes
Getestet, mit meinem Programm, von eben....
Das Verlegen des Formatstrings ins Flash gewinnt die volle Stringlänge
im Ram, und kostet 1 Wort im Flash.
Arduino F. schrieb:> Das Verlegen des Formatstrings ins Flash gewinnt die volle Stringlänge> im Ram, und kostet 1 Wort im Flash.
hätte ich auch erwartet
aber der Optimierer -o3 überrascht mich immer wieder, wenn ich denke ich
schreibe besseren Code kommt hinterher optimiert was längeres raus.
vielleicht konnte er mit sprintf besser optimieren als mit sprintf_P
Joachim B. schrieb:> vielleicht konnte er mit sprintf besser optimieren als mit sprintf_P
Meine Kristallkugel sagt:
Wahrscheinlich pullern bei dem Experiment sowohl sprintf und sprintf_P
im Code rum. Damit wird wirksam verhindert, dass der Linker eine davon
rauswirft. Ganz im Gegenteil, er muss beide einbinden.
Arduino F. schrieb:> Meine Kristallkugel sagt:> Wahrscheinlich pullern bei dem Experiment sowohl sprintf und sprintf_P> im Code rum.
nur wenn
suche sprintf
ersetze sprintf_P
alle ersetzen
nicht funktioniert
allerdings weiss ich nicht wie die IDE mit dem tmp Speicher umgeht
Die Namen sehen ja gleich aus an den o-files ändert sich evtl. kaum was
ich kann das nur noch mal probieren in dem ich nach ersetzen von sprintf
jedes File noch mal absuche und dann das Projekt unter neuem Namen
abspeichere, nur müsste ich dann sicherheitshalbee alle Projektfiles
umbenennen und auch die #include umbenennen damit nix aus tmp rüber
streusselt, besser noch das neue auf einen anderen Compi spielen, der
den Cache tmp leeren.
Joachim B. schrieb:> allerdings weiss ich nicht wie die IDE mit dem tmp Speicher umgeht
Die macht das schon richtig.
Zumindest ist mir da noch nichts gegenteiliges aufgefallen.
Wolfram F. schrieb:> hast du Dir die Seite eigentlich mal angeschaut?
Scherzkeks -> 192.xxx ist eine aus dem internen Netz bei dir da kommt
keiner von aussen ran!
Nop schrieb:> Weil es nunmal kein Wunder ist, daß man dauernd Ressourcenprobleme hat,> wenn man seinen Controller unbedingt mit einen Lasagnedesaster aus> Bloatsoftware programmieren will.>> Man kann dann einfach einen größeren Controller nehmen
mache ich gerne statt nano328p 32k flash, 2k SRAM mighty mini mit 128k
flash und 16k SRAM und damit doppelt so viel RAM als der olle m2560 und
auch noch breadboard freundlicher.
Arduinoquäler schrieb:> Wenn du unbedingt bei Arduino bleiben willst dann nimm einen> Mega2560 der "pinkompatibel" ist. Kost' ja nix ... und hat> viel mehr Flash und RAM.
klar s.o. nur ist der mighty mini richtig teuer geworden, den m2560
bekommt man ja hinterher geworfen.
Stefan U. schrieb:> "Hilfe mir geht der Speicher aus" hört man auffällig oft von Arduino> Nutzern.> Ganz ehrlich: Wer so komplexe Programme hinbekommt, der kann das auch> ohne Arduino Software.
ist aber bequemer und das kostet halt, allerdings kann man sich auch mal
hinsetzen und überflüsiges rauswerfen, so habe ich bei meiner
Rolladensteuerung nach Sonnenstand auf dem Noka Display auch 1,5k flash
optimieren können, vorher auf dem nano328p 30700 nur noch 20 Byte frei,
nun nach Aufräumen 1,5k flash freigeschaufelt.
Arduino F. schrieb:> http://www.atmel.com/webdoc/AVRLibcReferenceManual...
danke hatte ich auch schon gefunden.