Low memory available, stability problems may occur.

algemene C code
Berichten: 49
Geregistreerd: 09 Mei 2015, 15:57

Low memory available, stability problems may occur.

Berichtdoor doebi » 31 Mrt 2016, 18:42

Code: Alles selecteren

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

// Define a structure for our menu list
struct Str MenuList[] = {
  { "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

  // er zijn veel meer menuregels, maar dit is niet relevant voor dit forum
  // het gaat erom te kunnen tonen hoe het opgebouwd is

}



Bovenstaande code gebruik ik om een menustructuur te kunnen weergeven. Er zijn
veel meer regels in de menustructuur dan hierboven in de code wordt getoond,
het gaat er om dat ik de manier waarop het is opgebouwd kan tonen aan dit forum.

Werken met deze manier lukt prima voor mijn doel.
Echter, deze manier van opslaan vreet RAM geheugen. Is er een manier om deze struct
mee in het programmageheugen op te slaan. De waardes in de structure veranderen niet,
deze bevatten enkel de data nodig om het menu te kunnen opbouwen.

Ik krijg nu de meldingen :

"De schets gebruikt 18.180 bytes (63%) programma-opslagruimte. Maximum is 28.672 bytes.
Globale variabelen gebruiken 2.180 bytes (85%) van het dynamisch geheugen. Resteren 380 bytes voor lokale variabelen. Maximum is 2.560 bytes.
Low memory available, stability problems may occur."

Wat me zorgen baart.

Advertisement

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

Re: Low memory available, stability problems may occur.

Berichtdoor nicoverduin » 31 Mrt 2016, 19:11

Tja ik ben bank dat je van mij en Shooter dezelfde antwoorden ga krijgen. Zet die hele sketch eens hier neer en geef eens aan welke library je gebruikt.
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 » 31 Mrt 2016, 19:15

Ok, hier de code (staat nog veel debug tekst en code tussen) :

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



// 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

//const byte KEYPADROWS = 4; //four rows
//const byte KEYPADCOLS = 4; //three columns

#define KEYPADROWS 4
#define KEYPADCOLS 4
/*
#define key0 0
#define keyEnd 1 //1
#define keyHome 2 //2
#define keyLL 3 //3
#define keyRight 4 //4
#define keyOk 5 //5
#define keyCorrection 6 //6
#define keyST 7 //7
#define keyDown 8 //12
#define keyLeft 9 //13
#define keyUp 10 //14
#define keyNaf 11 //15
#define keyMin 12 //8
#define keyPlus 13 //9
#define keyPilot 14 //10
#define keyPump 15 //11
*/

#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 keyDown 12
#define keyLeft 13
#define keyUp 14
#define keyNaf 15
#define keyMin 8
#define keyPlus 9
#define keyPitot 10
#define keyPump 11



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

*/

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


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

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, KEYPADROWS, KEYPADCOLS);

bool relayPump = false;
bool relayNaf = false;
bool relayST = false;
bool relayLL = false;






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

// Define a structure for our menu list
struct Str MenuList[] = {
{ "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


};
const char MenuMin = 0;
const char MenuChapters = 9;
const char MenuMax = 57; // MenuList.size(); //57 = 58-1 (58 = total menulines, -1 cause of starting from 0);

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


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

tft.begin();

delay(500);

delay(10000); // 10 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

/*
Serial.print("Read Day :");
Serial.println(EEPROMDagTeller);
Serial.print("Read Total :");
Serial.println(EEPROMTotaalTeller);
*/

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



}


byte MenuNr = 0;
byte MenuNrOld = 255;
char key;

void loop(void) {

EEPROMTimeHandle();
lcHandle();

if (MenuNr != MenuNrOld) {
ShowMenu(MenuNr);
MenuNrOld = MenuNr;
}

key = keypad.getKey();
ShowKey(key);

switch (key) {
case keyPump :
relayPump = !relayPump;
break;
case keyNaf :
relayNaf = !relayNaf;
break;
case keyST :
relayST = !relayST;
break;
case keyLL :
relayLL = !relayLL;
break;
case keyHome:
MenuNr = MenuMin;
break;
case keyEnd:
MenuNr = MenuChapters;
break;
case keyPlus:
MenuNr++;
break;
case keyMin:
MenuNr--;
break;

case keyUp:
MenuNr--;
break;
case keyDown:
MenuNr++;
break;
}
if (MenuNr > 200) {
MenuNr = MenuMin;
}
if (MenuNr > MenuChapters) {
MenuNr = MenuChapters;
}
}
/*
void printNumber(int v) {
int ones;
int tens;
int hundreds;

ones = v % 10;
v = v / 10;
tens = v % 10;
v = v / 10;
hundreds = v;

//Now print the number digit by digit
lc.setDigit(0, 2, (byte)hundreds, false);
lc.setDigit(0, 1, (byte)tens, false);
lc.setDigit(0, 0, (byte)ones, false);
}
*/
void lcHandle() { //(unsigned long TimeToWrite)
// 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/1000UL); // DagTeller in millis dus delen door 1000 = seconden, delen door 60 = minuten
TimeToWrite /= 60UL;
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/1000UL); // TotaalTeller in millis dus delen door 1000 = seconden, delen door 60 = minuten, delen door 60 = uren;
TimeToWrite /= 60UL;
TimeToWrite /= 60UL;
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;
Serial.print("Time : ");
Serial.print( millis() );
Serial.print(" Ik moest op eeprom adres ");
Serial.print( (byte) EEPROMOffset);
Serial.print(" deze waarde plaatsen : ");
Serial.println(TimeToWrite);
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 EEPROMTimeHandle() {
// 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 += HulpMillis;
EEPROMTotaalTeller += HulpMillis;
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(125);
MenuNrOld = 255; // Als het oud menu nr <> menunr dan wordt het scherm straks hertekend, dus ...
}

}

void ShowMenu(long ShowMenuNr) {
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)
tft.fillScreen(ILI9340_BLACK);
tft.setTextSize(1);
tft.setTextWrap(false);
tft.setRotation(1);
for (lus = MenuMin; lus < MenuMax + 1; lus++) {
if (MenuList[lus].nrMenu == ShowMenuNr) {
if (MenuList[lus].isMenuName) { // deze lijn is een menu naam
ScreenX = 0;
tft.setCursor(ScreenX, ScreenY);
tft.setTextColor(ILI9340_BLUE); // menu namen zijn blauw
tft.print(MenuList[lus].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("PUMP=1");
}
else {
tft.print("PUMP=0");
}
tft.setCursor(180,ScreenY);
if (relayNaf==true) {
tft.print("NAF=1");
}
else {
tft.print("NAF=0");
}
tft.setCursor(225,ScreenY);
if (relayST==true) {
tft.print("ST=1");
}
else {
tft.print("ST=0");
}
tft.setCursor(270,ScreenY);
if (relayLL==true) {
tft.print("LL=1");
}
else {
tft.print("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); //
ScreenX = 160;
tft.setCursor(ScreenX, ScreenY);
tft.setTextColor(ILI9340_YELLOW); // menu items rechts zijn geel
tft.print(MenuList[lus].textLineNormal); //
}
ScreenY += 15;
}
}
//return (ScreenY > 10); // Als er een text op het scherm werd gezet is screen Y > 10 , dan functie terugmelding true

}

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

Re: Low memory available, stability problems may occur.

Berichtdoor doebi » 31 Mrt 2016, 19:17

Het uiteindelijke menu moet eigenlijk nog eens zo lang zijn als wat er nu staat ...

Alle andere suggesties op de code zijn ook welkom hoor, ik ben meer gewend vb te programmeren :-)

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

Re: Low memory available, stability problems may occur.

Berichtdoor nicoverduin » 31 Mrt 2016, 20:22

De code op zich is niets mis mee. Je hebt gewoon teveel RAM onnodig nodig. Ik denk dat het splitsen wordt van je struct in losse arrays. Maar ik moet ff kijken in wat oude software waar ik iets vergelijkbaars heb gedaan.
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 » 31 Mrt 2016, 21:58

Ik heb de code wat opgeschoond en wat minor bugs opgelost,
en belangrijk voor dit topic, enkele variabelen kon ik via PROGMEM declareren en maakte ik gebruik van de macro F()
Dit resulteerde in ongeveer 180 bytes ram die vrij kwamen, helaas nog lang niet genoeg.
Ik zou de strings in de struct MenuList ook via PROGMEM moeten kunnen declareren, maar ik vind niet hoe.

De opgeschoonde code :
Code: Alles selecteren

/***************************************************
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>


//      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

                           





const char menu_01[] PROGMEM = "BEFORE FLIGHT CHECK";

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

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


// Define a structure for our menu list
const struct Str MenuList[] = {
  { "BEFORE FLIGHT CHECK" , "", true , 0 } ,
 // { menu_01 , "", 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);


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


 
  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();
  ShowKey(key);

  switch (key) {
  case keyPump :
    relayPump = !relayPump;
    break;
  case keyNaf :
    relayNaf = !relayNaf;
    break;
  case keyST :
    relayST = !relayST;
    break;
  case keyLL :
    relayLL = !relayLL;
    break; 
  case keyHome:
    MenuNr = MenuMin;
    break;
  case keyEnd:
    MenuNr = MenuChapters;
    break;
  case keyUp: case keyPlus :
    if (MenuNr > MenuMin) {
      MenuNr--; 
    }
    break;
  case keyDown: case keyMin :
    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)
 
  if (MenuNr != MenuNrOld) {

    tft.fillScreen(ILI9340_BLACK);
    tft.setTextSize(1);
    tft.setTextWrap(false);
    tft.setRotation(1);
    for (lus = MenuMin; lus < MenuMax + 1; lus++) {
      if (MenuList[lus].nrMenu == MenuNr) {      //==ShowMenuNr
        if (MenuList[lus].isMenuName) {               // deze lijn is een menu naam
          ScreenX = 0;
          tft.setCursor(ScreenX, ScreenY);
          tft.setTextColor(ILI9340_BLUE);           // menu namen zijn blauw
 
          // strcpy_P(buffer1,(char*)pgm_read_word(&MenuList[lus].textLineBold));
         
          tft.print(MenuList[lus].textLineBold);
 
          // tft.print(buffer1);
         
         
         
          // 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);    //
          ScreenX = 160;
          tft.setCursor(ScreenX, ScreenY);
          tft.setTextColor(ILI9340_YELLOW);         // menu items rechts zijn geel
          tft.print(MenuList[lus].textLineNormal);  //
        }
        ScreenY += 15;
      }
    }
    MenuNrOld = MenuNr;
  }
}












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

Re: Low memory available, stability problems may occur.

Berichtdoor nicoverduin » 01 Apr 2016, 08:20

Ik denk dat de meest handige oplossing is om de strings uit jouw tabel in een aparte tabel te zetten.
Bijgaand een voorbeeldje wat ik bedoel
cpp code
// Define a structure for our menu text output view
struct Str {
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 MAX_MENU_TEXT_LENGTH 25 // maximale string lengte + 1

// Define a structure for our menu list
const PROGMEM char MenuTextNormal[][MAX_MENU_TEXT_LENGTH] = {
"BEFORE FLI" ,
"AERODOME REGISTER" ,
"MASTER SWITCH" ,
"FUEL LEVEL" ,
"MASTER SWITCH"
};

void setup()
{
Serial.begin(9600);
//
// printen teksten
//
for (uint8_t i = 0; i < 5; i++){
char printText[MAX_MENU_TEXT_LENGTH];
strcpy_P(printText, MenuTextNormal[i]);
Serial.println(printText);
}

}

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


In dit voorbeeld worden dus de string in Flash gezet.
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 » 02 Apr 2016, 07:35

Hallo, kzal dat eens proberen, alvast dank Grt

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

Re: Low memory available, stability problems may occur.

Berichtdoor doebi » 02 Apr 2016, 07:44

Kan ik een het array zo maken dat er 2 strings op 1 index staan

const PROGMEM char Menu[][1][MAX_MENU_TEXT_LENGTH] =

?

Maar hoe doe vul ik die dan op ?

C++ toch nog wat vreemd voor me.


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, 08:30

Het heeft niets met C++ te maken. Ik heb ooit zelf ook zitten kl..ien met dit probleem in deze library : https://github.com/nicoverduin/AutoTest
Toen wilde ik ook een struct in Flash gooien. Allemaal constanten en toch niet door gaan. Uiteindelijk heb ik van de hele struct een string gemaakt die ik dan in het geheugen uit elkaar trek. Dit om zo weinig mogelijk geheugen te gebruiken. De strings waren ook niet allemaal even lang. Maar dat vereist nog wel wat diepte kennis omdat je dan met tokens (separators) gaat werkern. Omdat ik de hele zaak sequentieel doorloop was het te doen. Jij maakt gebruik van een tabel en dan wordt het lastiger omdat je van hot naar her kan springen. Dan is een vaste lengte van de tekst essentieel omdat je dan direct kunt berekenen waar je moet zijn via de index.
Maar wat is er mis et 2 tabellen? een voor de normale en een voor de bold tekst?
Docent HBO Technische Informatica, Embedded ontwikkelaar & elektronicus
http://www.verelec.nl

Volgende

Terug naar C code

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 5 gasten