Low memory available, stability problems may occur.

algemene C code
Gebruikers-avatar
Berichten: 5043
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: Low memory available, stability problems may occur.

Berichtdoor nicoverduin » 02 Apr 2016, 08:57

Er zijn altijd weer betere oplossingen. En deze moet je zeker aanspreken :)

cpp code
#include "Arduino.h"

//
// feature from : http://arduino.stackexchange.com/questi ... of-structs
//
template<typename T> void PROGMEM_readAnything(const T * sce, T& dest) {
memcpy_P(&dest, sce, sizeof(T));
}

template<typename T> T PROGMEM_getAnything(const T * sce) {
static T temp;
memcpy_P(&temp, sce, sizeof(T));
return temp;
}

// number of items in an array
template< typename T, size_t N > size_t ArraySize (T (&) [N]){ return N; }


// Define a structure for our menu text output view
struct Str {
char textLineBold[25]; // De tekst die in het vet moet staan (Hoofdtitel of subtitel)
char textLineNormal[25]; // De tekst die normaal moet staan (Naast de subtitel)
boolean isMenuName; // Is het een hoofdtitel of een subtitel, true = hoofdtitel of menunaam
char nrMenu; // volgnummer, gelijke nummers horen bij elkaar
// boolean isChecked; // is deze titel ofgecheck, ja = true
};


// Define a structure for our menu list
const Str MenuList[] PROGMEM = {
{ "BEFORE FLIGHT CHECK" , "" , true , 0} ,
{ "AERODOME REGISTER" , "FILLED IN" , false , 0},
{ "MASTER SWITCH" , "ON" , false , 0},
{ "FUEL LEVEL" , "CHECK" , false , 0},
{ "MASTER SWITCH" , "OFF" , false , 0}
};

void setup()
{
Serial.begin(9600);
Serial.flush();
for (uint8_t i = 0; i < ArraySize(MenuList); i++) {
Str regelUitTabel;
PROGMEM_readAnything (&MenuList [i], regelUitTabel);
Serial.print(regelUitTabel.textLineBold);
Serial.print(",");
Serial.println(regelUitTabel.textLineNormal);
}
}

// The loop function is called in an endless loop
void loop()
{
//Add your repeated code here
}


De templates bovenin zijn zeer belangrijk die kun je of een een aparte .H bestand zetten of gewoon voor alle andere functies.
Wel moet je de struct aanpassen voor de maximale lengte. Masar dit werkt als een tierelier.

@edit: PROGMEM_getAnything() mag je weglaten. Wordt hier niet gebruikt.
Docent HBO Technische Informatica, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

Advertisement

Berichten: 49
Geregistreerd: 09 Mei 2015, 15:57

Re: Low memory available, stability problems may occur.

Berichtdoor doebi » 02 Apr 2016, 16:20

Hallo Nico,

voor je laatste voorbeeld leek me tof omdat alles netjes in de struct kon blijven, maar
ik krijg compiler errors

sketch_apr02atestprogmem:7: error: 'T' does not name a type
sketch_apr02atestprogmem:7: error: ISO C++ forbids declaration of 'sce' with no type [-fpermissive]
sketch_apr02atestprogmem:7: error: 'T' has not been declared
sketch_apr02atestprogmem:8: error: 'T' does not name a type
'T' does not name a type

Voor antwoord op je vorige vraag, "wat is er mis met 2 tabellen", op zich niets,
maar het is m.i. toch een stuk overzichtelijker om de relevante data samen te zetten, als
er bv in de ene tabel toevallig een lijn overgeslaan wordt door iets wat er bijkomt is meteen de hele boel verkeerd,
en je eigen fouten in code zoeken is nooit (voor mij dan toch) makkelijk.

Toch zeker bedankt voor je al tips, ik zal er trachten heb beste uit te halen.

Grt

Gebruikers-avatar
Berichten: 5043
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: Low memory available, stability problems may occur.

Berichtdoor nicoverduin » 02 Apr 2016, 17:37

Met welke versie van de Arduino werk je?

Om voor mij nog onduidelijke redenen zegt de IDE inderdaad dat het niet mag. Via EclipseArduino niets aan de hand.
Maar er zijn meerdere wegen naar Rome:
Nu zonder die template.
cpp code
#include "Arduino.h"

// number of items in an array
template< typename T, size_t N > size_t ArraySize (T (&) [N]){ return N; }


// Define a structure for our menu text output view
struc]t Str {
char textLineBold[25]; // De tekst die in het vet moet staan (Hoofdtitel of subtitel)
char textLineNormal[25]; // De tekst die normaal moet staan (Naast de subtitel)
boolean isMenuName; // Is het een hoofdtitel of een subtitel, true = hoofdtitel of menunaam
char nrMenu; // volgnummer, gelijke nummers horen bij elkaar
// boolean isChecked; // is deze titel ofgecheck, ja = true
};


// Define a structure for our menu list
const Str MenuList[] PROGMEM = {
{ "BEFORE FLIGHT CHECK" , "" , true , 0} ,
{ "AERODOME REGISTER" , "FILLED IN" , false , 0},
{ "MASTER SWITCH" , "ON" , false , 0},
{ "FUEL LEVEL" , "CHECK" , false , 0},
{ "MASTER SWITCH" , "OFF" , false , 0}
};

void setup()
{
Serial.begin(9600);
Serial.flush();
for (uint8_t i = 0; i < ArraySize(MenuList); i++) {
Str regelUitTabel;
//
// kopieer de juiste item regel uit de menu lijst naar een
// lokale buffer voor de lengte van die buffer
//
memcpy_P(&regelUitTabel, &MenuList[i], sizeof(regelUitTabel));
//
// toon test gegevens
//
Serial.print(regelUitTabel.textLineBold);
Serial.print(",");
Serial.println(regelUitTabel.textLineNormal);
}
}

// The loop function is called in an endless loop
void loop()
{
//Add your repeated code here
}
Docent HBO Technische Informatica, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

Berichten: 49
Geregistreerd: 09 Mei 2015, 15:57

Re: Low memory available, stability problems may occur.

Berichtdoor doebi » 03 Apr 2016, 11:24

Solved !


Nico, super bedankt, het werkt gewoon.

Resultaat geheugen :

De schets gebruikt 19.272 bytes (67%) programma-opslagruimte. Maximum is 28.672 bytes.
Globale variabelen gebruiken 829 bytes (32%) van het dynamisch geheugen. Resteren 1.731 bytes voor lokale variabelen. Maximum is 2.560 bytes.


Enigszins jammer dat er met vast lengte van de strings gewerkt wordt, maar ik begrijp dat dit is om per lijn te kunnen kopieren van programma naar ram geheugen.
Geweldig gewoon dat je me deze oplossing gaf.


<edit>
Eerst werkte ik met visual studio met visual micro, maar telkens ik mijn computer afsloot, had ik heel wat moeite om hetzelfde project opnieuw werkend te krijgen,
wilde dan weer niet compileren , echt raar, met visual basic heb ik dit nog nooit voorgehad.
Daarom werk ik met de simpelste compiler die er is,zonder toeters of bellen , namelijk de arduino compiler 1.6.5. Beetje spijtig , maar ik moet het ermee beredderen.
</edit>



Programma tot zover :

cpp code
/***************************************************
VL3
----> http://www.adafruit.com/products/1480
----> MAX7219ENG
----> CLICK TOUCH pannel

Color definitions for TFT SPI 2.2" Display
ILI9340_BLACK 0x0000
ILI9340_BLUE 0x001F
ILI9340_RED 0xF800
ILI9340_GREEN 0x07E0
ILI9340_CYAN 0x07FF
ILI9340_MAGENTA 0xF81F
ILI9340_YELLOW 0xFFE0
ILI9340_WHITE 0xFFFF
***************************************************/
#include <Keypad.h> // need the library for the keypad
#include <SPI.h> // need the library for ADA 1480 SPI controls
#include "Adafruit_GFX.h" // need the library for ADA 1480
#include "Adafruit_ILI9340.h" // need the library for ADA 1480
#include <Wire.h> // need the library for I2C
#include <LedControl.h> // need the library for max7219ENG works with common kathode
#include <EEPROM.h> // need the library for reading and writing minutes who are passed sinds startup
#include <avr/pgmspace.h>

// number of items in an array
template< typename T, size_t N > size_t ArraySize (T (&) [N]){ return N; }


// Leonardo
#define _dc 3
#define _rst 4
#define _cs 6
#define _miso 14
#define _sclk 15
#define _mosi 16


// Wiring sort leonardo vs adadfruit 1480
// NAME LEONARDO LCD ADAFRUIT 1480
// MISO ICP1 MISO 08 MISO
// +5V ICP2 VCC 02 VIN
// SCK ICP3 SCK 09 SCK
// MOSI ICP4 MOSI 07 MOSI
// GND ISP6 GND 01 GND
// D/C DIGI 3 03 D/C
// RESET DIGI 4 04 RESET
// LCD/CS DIGI 6 06 LCD/CS
// BACKLIGHT +5V 10 BACKLIGHT


// Wiring sort adafruit 1480 vs leonardo
// NAME LEONARDO LCD ADAFRUIT 1480
// GND ISP6 GND 01 GND
// +5V ICP2 VCC 02 VIN
// D/C DIGI 3 03 D/C
// RESET DIGI 4 04 RESET
// LCD/CS DIGI 6 06 LCD/CS
// MOSI ICP4 MOSI 07 MOSI
// MISO ICP1 MISO 08 MISO
// SCK ICP3 SCK 09 SCK
// BACKLIGHT +5V 10 BACKLIGHT


// Wiring sort leonardo vs MAX7219
// LEONARDO MAX7219ENG
// DIGI 10 12 LOAD
// DIGI 11 13 CLK
// DIGI 12 01 DIN
// +5V 19 V+
// GND 04 GND
// GND 09 GND

// Wiring sort leonardo vs clicktouchpannel
// LEONARDO CLICK TOUCH touch pannel
// A0 1 COL 1 (FROM BACKSIDE VIEW = MOST RIGHT)
// A1 2 COL 2
// A2 3 COL 3
// A3 4 COL 4
// A4 5 ROW 1
// A5 6 ROW 2
// DIGI 8 7 ROW 3
// DIGI 9 8 ROW 4 (FROM BACKSIDE VIEW = MOST LEFT)




// Using software SPI is really not suggested, its incredibly slow
// Adafruit_ILI9340 tft = Adafruit_ILI9340(_cs, _dc, _mosi, _sclk, _rst, _miso);
// Use hardware SPI
Adafruit_ILI9340 tft = Adafruit_ILI9340(_cs, _dc, _rst); // tft is our adadfruit ILI9340 control object

LedControl lc = LedControl(12, 11, 10, 1); // lc is our led control object
// arduino leonardo pin 12 is connected to the MAX7219 DIN pin 1
// arduino leonardo pin 11 is connected to the MAX7219 CLK pin 13
// arduino leonardo pin 10 is connected to the MAX7219 LOAD pin 12
// 1 as we are only using 1 MAX7219
// gnd on MAX7219 GND pin 4 and pin 9
// 5V on MAX7219 V+ pin 19
// resistor 10K betweenMAX7219 V+ pin 19 and ISET 18


// Define a structure for our menu text output view
struct Str {
char textLineBold[25] ; // De tekst die in het vet moet staan (Hoofdtitel of subtitel)
char textLineNormal[25] ; // De tekst die normaal moet staan (Naast de subtitel)

boolean isMenuName; // Is het een hoofdtitel of een subtitel, true = hoofdtitel of menunaam
char nrMenu; // volgnummer, gelijke nummers horen bij elkaar
};


// Define a structure for our menu list
const Str MenuList[] PROGMEM = {
{ "BEFORE FLIGHT CHECK" , "", true , 0 } ,
{ "AERODOME REGISTER", "FILLED IN", false , 0 },
{ "MASTER SWITCH" , "ON",false,0 },
{ "FUEL LEVEL" , "CHECK",false,0 },
{ "MASTER SWITCH","OFF",false,0 },
//0+5=5
{ "EXTERNAL","",true,1 },
{ "EXTERNAL","COMPLETED",false,1 },
//5+2=7
{ "BEFORE ENGINE START","",true,2 },
{ "SAFETY BELTS","FASTEN",false,2 },
{ "CANOPY","CLOSE LOCK",false,2 },
{ "SWITCHES","OFF",false,2 },
{ "CIRCUIT BRAKERS","ON",false,2 },
{ "BRAKES","HOLD(OR PARKING BRAKE)",false,2 },
//7+6=13
{ "ENGINE START","",true,3 },
{ "LANDING GEAR","SWITCHED DOWN",false,3 },
{ "MASTER SWITCH","ON",false,3 },
{ "FUELS VALVES","OPEN ON LOWEST",false,3 },
{ "FUEL POMP","CHECK",false,3 },
//13+5=18
{ "TAXI","",true,4 },
{ "BRAKES","CHECK",false,4 },
{ "SLIP INDICATOR","CHECK",false,4 },
{ "COMPASS","CHECK",false,4 },
//18+4=22
{ "RUN UP PART 1","",true,5 },
{ "FULL TANK","FULLEST(min 2min.)",false,5 },
{ "ENGINE INSTR.","Oil press.1,5-5,0bar",false,5 },
{ "ENGINE INSTR.","Oil temp. 50-110°C",false,5 },
{ "ENGINE INSTR.","CHT max 110°C",false,5 },
{ "ENGINE INSTR.","EGT max 900°C",false,5 },
{ "THROTTLE","3000 RPM",false,5 },
{ "MAGNETOS","CHECK-L,R,BOTH",false,5 },
{ "PROPELLER","MANUAL/CHECK",false,5 },
{ "THROTTLE","IDLE(+/-1400RPM)",false,5 },

{ "RUN UP PART 2","",true,6 },
{ "FLIGHT CONTROLS","FREE AND CORRECT",false,6 },
{ "TRIM","NEUTRAL+TRAVELLING",false,6 },
{ "FLAPS","POS.2+TRAVELLING",false,6 },
{ "FUEL TANK","FULLEST/BOTH",false,6 },
{ "MAGNETOS","BOTH",false,6 },
{ "ALTIMETER","SET(ALSO EFIS)",false,6 },
{ "SAFETY BELTS","FASTEN",false,6 },
{ "CANOPY","CLOSED,LOCKED",false,6 },
{ "PROPELLER","FULLY FINE(+/-5500RPM)",false,6 },
//22+20=42
{ "TAKE-OFF","",true,7 },
{ "FUEL PUMP","ON",false,7 },
{ "THROTTLE","FULL OPEN",false,7 },
//42+3=45
{ "AFTER TAKE-OFF","",true,8 },
{ "SPEED","100",false,8},
{ "BRAKES","APPLY (RG)",false,8},
{ "FLAPS","UP",false,8 },
{ "GEAR","UP AT 300FT",false,8 },
{ "MAP","REDUCE TO OPTIMAL",false,8 },
{ "THROTTLE","REDUCE TO OPTIMAL",false,8 },
{ "LANDING LIGHTS","OFF",false,8 },
{ "CLIMB SPEED","130KM/H",false,8 },
{ "FUEL PUMP","OFF",false,8 },
//45+10=55
{ "CRUISSE","",true,9 },
{ "THROTTLE","AS REQUIRED",false,9 },
{ "SPEED","AS REQUIRED",false,9 },
//55+3=58


};



// Hieronder globle variabelen of const ivm de menu afhandeling
const char PROGMEM MenuMin = 0; // Hierin staat het startadres van de menulines (het hoeft dus niet perse 0 te zijn in de declaratie)
const char PROGMEM MenuChapters = 9; // Hierin staat het aantal hoofdstukken van het menu
const char PROGMEM MenuMax = 57; // MenuList.size(); //57 = 58-1 (58 = total menulines, -1 cause of starting from 0);
char MenuNr = 0;
char MenuNrOld = 255;
char key;

// Hieronder globale variabelen of const ivm met de EEPROM en tijd-telling
unsigned long EEPROMDagTeller; // Hierin staat het aantal millis dat de vorige keer werd weggeschreven naar de EEPROM, veranderd gedurig
unsigned long EEPROMTotaalTeller ; // Hierin staat het aantal millis dat bij de opstart van het programma werd uitgelezen uit de EEPROM, eenmalig !
unsigned long EEPROMDagOldMillis = 0; // Hierin staat het aantal millis dat er voorbij zijn tijdens het opstart van deze sessie in de ARDUINO
const char PROGMEM EEPROMAdresDagTeller = 100 ; // op deze locatie in de EEPROM staat de dagteller in millis
const char PROGMEM EEPROMAdresTotaalTeller = 110 ; // op deze locatie in de EEPROM staat de totaalteller in millis

// Hieronder globale variabelen ivm de 4 aan te sturen relais
bool relayPump = false;
bool relayNaf = false;
bool relayST = false;
bool relayLL = false;

// Hieronder variablen, declaraties ivm het clicktouch keypad
#define KEYPADROWS 4
#define KEYPADCOLS 4
#define key0 0
#define keyEnd 1
#define keyHome 2
#define keyLL 3
#define keyRight 4
#define keyOk 5
#define keyCorrection 6
#define keyST 7
#define keyMin 8
#define keyPlus 9
#define keyPitot 10
#define keyPump 11
#define keyDown 12
#define keyLeft 13
#define keyUp 14
#define keyNaf 15

char keys[KEYPADROWS][KEYPADCOLS] = {
{ key0,keyEnd,keyHome,keyLL },
{ keyRight,keyOk,keyCorrection,keyST },
{ keyMin,keyPlus,keyPitot,keyPump },
{ keyDown,keyLeft,keyUp,keyNaf }
};

byte colPins[KEYPADCOLS] = { A0, A1, A2, A3 }; //connect to the column pinouts of the keypad
byte rowPins[KEYPADROWS] = { A4, A5, 8, 9 }; //connect to the row pinouts of the keypad
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, KEYPADROWS, KEYPADCOLS);


// hieronder variabelen om de dagteller te resetten
char keyCDagTeller = 0;

void setup() {
Serial.begin(9600);

tft.begin();

showInstructieDagTeller();

delay(5000); // 5 seconden tijd om de seriele monitor aan te zetten

//EEPROMTimeWrite(0UL,EEPROMAdresDagTeller); // DEZE LIJN IS SLECHTS 1 MALIG UIT TE VOEREN OM ZEKER TE ZIJN DAT DE DAGTELLER OP 0 STAAT
//EEPROMTimeWrite(0UL,EEPROMAdresTotaalTeller); // DEZE LIJN IS SLECHTS 1 MALIG UIT TE VOEREN OM ZEKER TE ZIJN DAT DE TOTAALTELLER OP 0 STAAT

EEPROMDagTeller = EEPROMTimeRead(EEPROMAdresDagTeller); // LEES BIJ OPSTART DE DAGTELLER
EEPROMTotaalTeller = EEPROMTimeRead(EEPROMAdresTotaalTeller); // LEES BIJ OPSTART DE TOTAALTELLER

lc.shutdown(0, false);// turn off power saving, enables display
lc.setIntensity(0, 8);// sets brightness (0~15 possible values)
lc.clearDisplay(0);// clear screen

}




void loop(void) {
handleEEPROMTime();
handleLC();
handleKey();
handleMenu();
}

void handleKey(){
key = keypad.getKey();

if (key != NO_KEY) { // als er een toest is ingedrukt
if (key == keyCorrection) { // en het is de "C" toets
keyCDagTeller++; // verhoog dan de teller
if (keyCDagTeller > 2) { // en is die teller 3 of meer
EEPROMDagTeller = 0; //
EEPROMTimeWrite(0UL,EEPROMAdresDagTeller); // wis de dagteller op de eeprom
keyCDagTeller = 0; // en wis die teller
}
} else { // het was niet de "C" toets
keyCDagTeller = 0; // dus wis die teller
}
// dus nog steeds ; er werd een toets ingedrukt
ShowKey(key); // toon ook de toets die werd ingedrukt

switch (key) { // Test welke toets werd ingedrukt
case keyPump : // De pump ?
relayPump = !relayPump;
break;
case keyNaf : // De Naf ?
relayNaf = !relayNaf;
break;
case keyST : // De ST ?
relayST = !relayST;
break;
case keyLL : // De LL ?
relayLL = !relayLL;
break;
case keyHome: // De Home ?
MenuNr = MenuMin;
break;
case keyEnd: // De End ?
MenuNr = MenuChapters;
break;
case keyUp: case keyPlus : // De Up of Plus ?
if (MenuNr > MenuMin) {
MenuNr--;
}
break;
case keyDown: case keyMin : // De Dn of Min ?
if (MenuNr < MenuChapters) {
MenuNr++;
}
break;
}
}
}



void handleLC() {
// de rechtse 3 7 segmenten zijn de dagteller en is uitgedrukt in minuten 999min = 15uur
// de linkse 4 7 segmenten zijn de totaalteller en is uitgedrukt in uren 9999uur

// unsigned long EEPROMDagTeller; // Hierin staat het aantal millis dat de vorige keer werd weggeschreven naar de EEPROM, veranderd gedurig
// unsigned long EEPROMTotaalTeller ; // Hierin staat het aantal millis dat bij de opstart van het programma werd uitgelezen uit de EEPROM, eenmalig !
// unsigned long EEPROMDagOldMillis=0;// Hierin staat het aantal millis dat er voorbij zijn tijdens het opstart van deze sessie in de ARDUINO
// #define EEPROMAdresDagTeller 32 // op deze locatie in de EEPROM staat de dagteller in millis
// #define EEPROMAdresTotaalTeller 48 // op deze locatie in de EEPROM staat de totaalteller in millis

unsigned long TimeToWrite;

if ( ( millis() % 4096) == 1 ) { // om de ongeveer 4 seconden (4096mili seconden) de 7 segment bijwerken
// soms zal er niet bijgewerkt worden omwille van de tijd en de MODULUS, maar dit is niet erg

TimeToWrite = (EEPROMDagTeller/60000UL); // DagTeller in millis dus delen door 1000 = seconden, delen door 60 = minuten

lc.setDigit(0,0, (byte) (TimeToWrite % 10) , false); // ones op de 1ste digit van rechts , we nemen via modulo 10 de eenheden
TimeToWrite /= 10UL;
lc.setDigit(0,1, (byte) (TimeToWrite % 10) , false); // tens op de 2de digit van rechts , we nemen via modulo 10 (en ervoor delen door 10) de tientallen
TimeToWrite /= 10UL;
lc.setDigit(0,2, (byte) (TimeToWrite % 10) , false); // hundreds op de 3de digit van rechts , we nemen via modulo 10 (en ervoor delen door 100) de honderdtallen


TimeToWrite = (EEPROMTotaalTeller/3600000UL); // TotaalTeller in millis dus delen door 1000 = seconden, delen door 60 = minuten, delen door 60 = uren;

lc.setDigit(0,3, (byte) (TimeToWrite % 10) , false); // ones op de 4ste digit van rechts , we nemen via modulo 10 de eenheden
TimeToWrite /= 10UL;
lc.setDigit(0,4, (byte) (TimeToWrite % 10) , false); // tens op de 5de digit van rechts , we nemen via modulo 10 (en ervoor delen door 10) de tientallen
TimeToWrite /= 10UL;
lc.setDigit(0,5, (byte) (TimeToWrite % 10) , false); // hundreds op de 6de digit van rechts , we nemen via modulo 10 (en ervoor delen door 100) de honderdtallen
TimeToWrite /= 10UL;
lc.setDigit(0,6, (byte) (TimeToWrite % 10) , false); // thousands op de 7de digit van rechts , we nemen via modulo 10 (en ervoor delen door 1000) de duizendtallen
}
}
void EEPROMTimeWrite(unsigned long TimeToWrite,char EEPROMOffset) {
unsigned long HulpLong = 0;
char HulpByte = 0;

HulpLong = TimeToWrite & 0x000000FF; // alle bits wissen behalve de 8 eerste
HulpByte = (char) HulpLong; // long -> byte = enkel de 8 rechtse bits onthouden
EEPROM.write(3 + (byte) EEPROMOffset, HulpByte); // de kleinste bitwaarden op eeprom adres 3 zetten
HulpLong = TimeToWrite & 0x0000FF00; // alle bits wissen behalve bit 8-15
HulpLong = HulpLong >> 8; // verschuif alle bits 8 posities naar rechts zodat bit 8-15 komt naar bit 0-7
HulpByte = (char) HulpLong; // long -> byte = enkel de 8 rechtse bits onthouden
EEPROM.write(2 + (byte) EEPROMOffset, HulpByte);
HulpLong = TimeToWrite & 0x00FF0000; // alle bits wissen behalve bit 16-23
HulpLong = HulpLong >> 16; // verschuif alle bits 16 posities naar rechts zodat bit 16-23 komt naar bit 0-7
HulpByte = (char) HulpLong; // long -> byte = enkel de 8 rechtse bits onthouden
EEPROM.write(1 + (byte) EEPROMOffset, HulpByte);
HulpLong = TimeToWrite & 0xFF000000; // alle bits wissen behalve de 8 laatste
HulpLong = HulpLong >> 24; // verschuif alle bits 24 posities naar rechts zodat bit 24-31 komt naar bit 0-7
HulpByte = (char) HulpLong; // long -> byte = enkel de 8 rechtse bits onthouden
EEPROM.write(0 + (byte) EEPROMOffset, HulpByte); // de grootste bitwaarden op eeprom adres 0 zetten




}

unsigned long EEPROMTimeRead(char EEPROMOffset) {
unsigned long HulpLong = 0UL;
char HulpByte = 0;
HulpByte = EEPROM.read(0 + (byte) EEPROMOffset); // lees de grootste bitwaarden van op eeprom adres 0
HulpLong += (unsigned long) HulpByte;
HulpLong = HulpLong << 8; // verschruif de bitwaarden naar links voor 8 bits
HulpByte = EEPROM.read(1 + (byte) EEPROMOffset);
HulpLong += (unsigned long) HulpByte;
HulpLong = HulpLong << 8; // verschruif de bitwaarden naar links voor 8 bits
HulpByte = EEPROM.read(2 + (byte) EEPROMOffset);
HulpLong += (unsigned long) HulpByte;
HulpLong = HulpLong << 8; // verschruif de bitwaarden naar links voor 8 bits
HulpByte = EEPROM.read(3 + (byte) EEPROMOffset); // lees de kleinste bitwaarden van op eeprom adres 3
HulpLong += (unsigned long) HulpByte;
return HulpLong;
}

void handleEEPROMTime() {
// 4294967295 milli seconds = 1193.046470833 hours = 71582.78825 minutes = 4294967.295 seconds (0-4294967295 = range unsigned long)
// eeprom may be used for 100.000 eeprom read / write cycles

// unsigned long EEPROMDagTeller; // Hierin staat het aantal millis dat de vorige keer werd weggeschreven naar de EEPROM, veranderd gedurig
// unsigned long EEPROMTotaalTeller ; // Hierin staat het aantal millis dat bij de opstart van het programma werd uitgelezen uit de EEPROM, eenmalig !
// unsigned long EEPROMDagOldMillis=0;// Hierin staat het aantal millis dat er voorbij zijn tijdens het opstart van deze sessie in de ARDUINO
// #define EEPROMAdresDagTeller 32 // op deze locatie in de EEPROM staat de dagteller in millis
// #define EEPROMAdresTotaalTeller 48 // op deze locatie in de EEPROM staat de totaalteller in millis

unsigned long HulpMillis = millis();

if ( HulpMillis > EEPROMDagOldMillis + 90000UL ) { // Slechts om de 90000milis = 1MIN 30 uitvoeren
EEPROMDagOldMillis = HulpMillis;
EEPROMDagTeller += 90000UL;
EEPROMTotaalTeller += 90000UL;
EEPROMTimeWrite(EEPROMDagTeller,EEPROMAdresDagTeller);
EEPROMTimeWrite(EEPROMTotaalTeller,EEPROMAdresTotaalTeller);
}


}

void ShowKey(char aKey) {

char *Message = (char*) "";
// if (key != NO_KEY) {

switch (key) {
case keyHome:
Message = (char*) "Home";
break;
case keyEnd:
Message = (char*) "End";
break;
case keyPlus:
Message = (char*)"+";
break;
case keyMin:
Message = (char*)"-";
break;
case keyLeft:
Message = (char*)"<";
break;
case keyRight:
Message = (char*)">";
break;
case keyUp:
Message = (char*)"Up";
break;
case keyDown:
Message = (char*)"Dn";
break;
case keyST:
Message = (char*)"ST";
break;
case keyPitot:
Message = (char*)"Pit";
break;
case keyOk:
Message = (char*)"Ok";
break;
case keyCorrection:
Message = (char*)"C";
break;
case keyPump:
Message = (char*)"pump";
break;
case keyNaf:
Message = (char*)"NAF";
break;
case keyLL:
Message = (char*)"LL";
break;

}
tft.setCursor(100, 100);
tft.setTextColor(ILI9340_BLUE);
tft.setTextSize(2);
tft.print(Message);
delay(100);
MenuNrOld = 255; // Als het oud menu nr <> menunr dan wordt het scherm straks hertekend, dus ...
// }

}


void handleMenu() {
char lus;
unsigned int ScreenX = 10; // op deze X coordinaat zal de volgende tekst op de tft komen (via tft.print)
unsigned int ScreenY = 10; // op deze Y coordinaat zal de volgende tekst op de tft komen (via tft.print)
Str regelUitTabel;
if (MenuNr != MenuNrOld) {
tft.fillScreen(ILI9340_BLACK);
tft.setTextSize(1);
tft.setTextWrap(false);
tft.setRotation(1);



for (lus = MenuMin; lus < ArraySize(MenuList); lus++) {

memcpy_P(&regelUitTabel, &MenuList[lus], sizeof(regelUitTabel));
// if (MenuList[lus].nrMenu == MenuNr) { //==ShowMenuNr
// if (MenuList[lus].isMenuName) { // deze lijn is een menu naam
if (regelUitTabel.nrMenu == MenuNr) {
if (regelUitTabel.isMenuName) {
ScreenX = 0;
tft.setCursor(ScreenX, ScreenY);
tft.setTextColor(ILI9340_BLUE); // menu namen zijn blauw
// tft.print(MenuList[lus].textLineBold);
tft.print(regelUitTabel.textLineBold);

// op deze lijn ook de relay status PUMP NAF ST LL plaatsen
tft.setTextColor(ILI9340_CYAN);
tft.setCursor(130,ScreenY);
if (relayPump==true) {
tft.print(F("PUMP ON"));
}
else {
tft.print(F("PUMP OFF"));
}
tft.setCursor(180,ScreenY);
if (relayNaf==true) {
tft.print(F("NAF ON"));
}
else {
tft.print(F("NAF OFF"));
}
tft.setCursor(225,ScreenY);
if (relayST==true) {
tft.print(F("ST ON"));
}
else {
tft.print(F("ST OFF"));
}
tft.setCursor(270,ScreenY);
if (relayLL==true) {
tft.print(F("LL=1"));
}
else {
tft.print(F("LL=0"));
}
}
else { // deze lijn is geen menu naam maar dus een menu item
ScreenX = 0;
tft.setCursor(ScreenX, ScreenY);
tft.setTextColor(ILI9340_WHITE); // menu items links zijn wit
// tft.print(MenuList[lus].textLineBold); //
tft.print(regelUitTabel.textLineBold);
ScreenX = 160;
tft.setCursor(ScreenX, ScreenY);
tft.setTextColor(ILI9340_YELLOW); // menu items rechts zijn geel
tft.print(regelUitTabel.textLineNormal);
// tft.print(MenuList[lus].textLineNormal); //
}
ScreenY += 15;
}
}
MenuNrOld = MenuNr;
}
}

void showInstructieDagTeller() {
tft.fillScreen(ILI9340_BLACK);
tft.setTextSize(5);
tft.setTextWrap(false);
tft.setRotation(1);
tft.setCursor(50,20);
tft.setTextColor(ILI9340_BLUE);
tft.print("WELCOME");
tft.setTextSize(2);
tft.setTextColor(ILI9340_RED);
tft.setCursor(10,150);
tft.print("TO RESET DAY CLOCK: ");
tft.setCursor(10,170);
tft.print("PUSH 3 x BUTTON C");
delay(1000);
}

Gebruikers-avatar
Berichten: 5043
Geregistreerd: 13 Mei 2013, 20:57
Woonplaats: Heemskerk

Re: Low memory available, stability problems may occur.

Berichtdoor nicoverduin » 03 Apr 2016, 11:32

Gebruik je toch eclipse: http://eclipse.baeyens.it/
Daar ontwikkel ik mee.

Er is nog wel een andere oplossing om het maximum uit het geheugen te persen, dat is door van de tabel een grote string te maken met de scheidingstekens en dan op het moment dat je een regel nodig hebt deze te gaan zoeken. Dus het kan wel maar als het niet nodig is.....

En als het echt niet meer gaat... Dan kun je overwegen een Nextion scherm te nemen. Kosten een paar euro meer dan de gewone TFT's maar daar wordt de hele user interface in het scherm ingebouwd. Dat doe je met een IDE onder Windows (tot op heden naar mijn weten nog geen Linux of Mac). Je bouwt daar je scherm op met menu's (Wyswyg), je kan het simuleren op een high level en zelfs een beetje programmeren. Je praat dan alleen nog met dat scherm via events of opdrachten naar het scherm. Gewoon via serial of SoftwareSerial. Ja maakt dus, net als in de industriële automatisering een HMI (Human-machine-interface).
Heb je er eenmaal mee gewerkt dan ga je waarschijnlijk nooit meer lopen k.tt.n met een gewone TFT scherm. En nee ik heb geen aandelen in Nextion maar ben er wel enthousiast over.
Voor de snelle-niet-nadenkende-kopers:
Er zijn 2 type in de handel. schermtype die beginnen met NX en goedkopere die beginnen met TJC. Die laatste moet je niet nemen want die krijg je niet geladen tenzij je in het bezit bent van de Chinese IDE. De internationale versie is het type NX. En als je niet thuis ben in low level interfacing en complexe trukendozen ga je de boot in.
Docent HBO Technische Informatica, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

Berichten: 49
Geregistreerd: 09 Mei 2015, 15:57

Re: Low memory available, stability problems may occur.

Berichtdoor doebi » 06 Apr 2016, 21:38

eclipse gedownload en geinstalleerd.

't Zal toch wat wennen worden, maar kdenk dat het de moeite zal lonen omwille van de meerwaarde
van een meer op "menselijker niveau" ide en compiler.
Voor mijn huidige projectje zal ik voorlopig nog bij de standaard compiler van arduino blijven omwille
van de dealine.

Zeker bedankt voor de tip.

Grt

Vorige

Terug naar C code

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 11 gasten