Memory for the Nano?

Hi,

I've got my project up and running. But I'm going to need more memory for sure, which is where I'm uncertain. There is so much choice on the market.

I2C would be nice, but happy if I need to wire the SPI.
Price, well most seem to be under £5 so not bothered, I'd rather get more than I need.
MUST BE easy to set up, plug n play as such on the Nano for a noob.

Very grateful for advice and pointers.

Many thanks,

Phil.

More memory for what purpose?

aarg:
More memory for what purpose?

Sorry aarg, I should have been more clear.

I've tested all my parts independently but not put them all together at the same time due to space.

at the mo I'm running a OLED I2c with 3 buttons, a BME280, and speaker. My program comes up to 65% of program space and 85% of the global space.With the IDE already warning me about loss of stability when I upload.

I've got a I2C RTC, and a SPI micro SD card to go on. So probably more program space and flash memory?

You can't add program space to a Nano

AWOL:
You can't add program space to a Nano

Oh !"$, I didn't know that, many thanks.

What about flash for global use? I'm up to 65% of program space so might be able to get away with a nano, if I can give it more thinking space?

Globals typically live in RAM.
You can't easily add RAM to a Nano either.
(You can add RAM, but accessing it means some kind of programmed transfer, so integration of the variables in it is your responsibility, not the compiler's)

AWOL:
Globals typically live in RAM.
You can't easily add RAM to a Nano either.
(You can add RAM, but accessing it means some kind of programmed transfer, so integration of the variables in it is your responsibility, not the compiler's)

Thanks AWOL, might not have been the news that I would have liked, but I'd rather have it sooner, than later.

Are you storing characters (strings) being written to OLED in flash or in ram?

You can save valuable ram by moving these things to flash.

https://forum.arduino.cc/index.php?topic=449857.0

darthclueless:
at the mo I'm running a OLED I2c with 3 buttons, a BME280, and speaker... I've got a I2C RTC, and a SPI micro SD card to go on.

Doesn't sound like it should be taking up all that space. Post your code please. Use code tags, but it sounds like it may be too long to paste into your post, so either add the .ino as an attachment (inconvenient for readers) or, if you have a GitHub account, upload it to Gist and post the link here using link tags.

How are you using the OLED? Graphics or text only? If only text, you may be able to make significant savings (flash and ram) using the u8x8 library.

avr_fred:
Are you storing characters (strings) being written to OLED in flash or in ram?

You can save valuable ram by moving these things to flash.

PROGMEM - Arduino Reference

Putting Constant Data Into FLASH - Arduino Due - Arduino Forum

Thanks avr fred, tbh I'm new to Arduino and am not so sure what I'm storing where and when lol a month in and my brain is beginning to FRY! I am sure that the code I'm running could be cut down in many ways, the pc that I use for the net is not linked to the laptop that I use for arduino, and not linked together. I'll get the program on a stick and post it up later so you can better understand the madness!!!

Many thanks again,

Phil.

There's a good chance you could PROGMEM some stuff and save on global RAM space. Without seeing your sketch we can only guess.

Thanks Paul n Jiggy,

I've got my code. The device is for measuring lung physio at home. My Son has Cystic Fybrosis, age 14 now. The physio he does at home using NHS devices is a bit hit and miss. There are two type of physio.

  1. PEP, (Positive Expiry Pressure) which is nothing more than a simple nylon pipe with restriction, linked to a mechanical pressure gauge (0~100Mb) The target being 20Mb for five seconds, counted in his head! it works by the back pressure expanding the lower lung, therefore clearing mucus.

  2. Acapella, This is a more complex mechanical device that opens and closes a restriction when you blow through it. the valve closing causes a 2Mb backwards pressure wave towards the lung. Vibrating the lung lining. Which in turn helps to clear mucus.

I'll say sorry upfront for having a few goto statements in the program. No torches and pitchfolks please :slight_smile: I'm an old school CNC programmer, so could not help myself!

The device cycle is...

  1. display "Kule Go" (an anagram of my Son Luke)
  2. Ask for physio type "PEP or Acapella"
  3. Load settings for physio type
  4. Physio cycle, Rest cycle until completed
  5. end cycle and go to head of void loop

In terms of the RTC and SD card, all I'd like to do is record, Date, Time, Physio type and Reps completed. Normally they do physio AM and PM. So it should not be a lot of data to write to the card.

Code on next post due to post size...(after 5min time out I think?)

Many thanks in advance,

Phil.

const int peprepeats = 2;   // pep repeats per session
const int peplength = 4000; // pep length in milliseconds
const int pepminpress = 18; // Mbar
const int pepmaxpress = 21; // Mbar
const int peprest = 30; //rest time between reps in seconds
const int acarepeats = 2;   // acapella repeats per session
const int acalength = 4000; // acapella length in milliseconds
const int acaminpress = 10; // Mbar
const int acamaxpress = 13; // Mbar
const int acarest = 30; //rest time between reps in seconds
const int pover = 0; //parental setting, 0=off / 1=on
const int cab = 85; // Calibration value
const int greenled = 3;
const int redled = 6;
const int blueled = 9;
const int button1 = 4;
const int button2 = 7;
const int button3 = 8;
int buttonstate1=0;
int buttonstate2=0;
int buttonstate3=0;
int phrepeats=0;
int phlength=0;
int phminpress=0;
int phmaxpress=0;
int phrest=0;
int pres3 = 0;
int pepcount = 0;
int Rep = 0;
int menu = 0;
#include <stdint.h>
#include "SparkFunBME280.h"
#include "Wire.h"
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
BME280 mySensor;

void setup() {
mySensor.settings.commInterface = I2C_MODE;
mySensor.settings.I2CAddress = 0x76;
mySensor.settings.runMode = 3; 
mySensor.settings.tStandby = 0;
mySensor.settings.filter = 0;
mySensor.settings.tempOverSample = 1;
mySensor.settings.pressOverSample = 1;
mySensor.settings.humidOverSample = 1;
Serial.begin(57600);
Serial.print("Program Started\n");
Serial.print("Starting BME280... result of .begin(): 0x");
Serial.println(mySensor.begin(), HEX);
delay(10);
Serial.print("Displaying ID, reset and ctrl regs\n");
Serial.print("ID(0xD0): 0x");
Serial.println(mySensor.readRegister(BME280_CHIP_ID_REG), HEX);
Serial.print("Reset register(0xE0): 0x");
Serial.println(mySensor.readRegister(BME280_RST_REG), HEX);
Serial.print("ctrl_meas(0xF4): 0x");
Serial.println(mySensor.readRegister(BME280_CTRL_MEAS_REG), HEX);
Serial.print("ctrl_hum(0xF2): 0x");
Serial.println(mySensor.readRegister(BME280_CTRL_HUMIDITY_REG), HEX);
Serial.print("\n\n");
Serial.print("Displaying all regs\n");
uint8_t memCounter = 0x80;
uint8_t tempReadData;
for(int rowi = 8; rowi < 16; rowi++ ){
Serial.print("0x");
Serial.print(rowi, HEX);
Serial.print("0:");
for(int coli = 0; coli < 16; coli++ ){
tempReadData = mySensor.readRegister(memCounter);
Serial.print((tempReadData >> 4) & 0x0F, HEX);
Serial.print(tempReadData & 0x0F, HEX);
Serial.print(" ");
memCounter++;}
Serial.print("\n");}
Serial.print("\n\n");  
Serial.print("Displaying concatenated calibration words\n");
Serial.print("dig_T1, uint16: ");
Serial.println(mySensor.calibration.dig_T1);
Serial.print("dig_T2, int16: ");
Serial.println(mySensor.calibration.dig_T2);
Serial.print("dig_T3, int16: ");
Serial.println(mySensor.calibration.dig_T3);
Serial.print("dig_P1, uint16: ");
Serial.println(mySensor.calibration.dig_P1);
Serial.print("dig_P2, int16: ");
Serial.println(mySensor.calibration.dig_P2);
Serial.print("dig_P3, int16: ");
Serial.println(mySensor.calibration.dig_P3);
Serial.print("dig_P4, int16: ");
Serial.println(mySensor.calibration.dig_P4);
Serial.print("dig_P5, int16: ");
Serial.println(mySensor.calibration.dig_P5);
Serial.print("dig_P6, int16: ");
Serial.println(mySensor.calibration.dig_P6);
Serial.print("dig_P7, int16: ");
Serial.println(mySensor.calibration.dig_P7);
Serial.print("dig_P8, int16: ");
Serial.println(mySensor.calibration.dig_P8);
Serial.print("dig_P9, int16: ");
Serial.println(mySensor.calibration.dig_P9);
Serial.print("dig_H1, uint8: ");
Serial.println(mySensor.calibration.dig_H1);
Serial.print("dig_H2, int16: ");
Serial.println(mySensor.calibration.dig_H2);
Serial.print("dig_H3, uint8: ");
Serial.println(mySensor.calibration.dig_H3);
Serial.print("dig_H4, int16: ");
Serial.println(mySensor.calibration.dig_H4);
Serial.print("dig_H5, int16: ");
Serial.println(mySensor.calibration.dig_H5);
Serial.print("dig_H6, uint8: ");
Serial.println(mySensor.calibration.dig_H6);
pinMode(greenled, OUTPUT);
pinMode(redled, OUTPUT);
pinMode(blueled, OUTPUT);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
}
void loop() {
start:
if (menu==0){
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(12,6);
display.println("Kule Go");
display.setTextSize(1);
display.setCursor(80,20);
display.println("Rv 2");
display.display();
delay(1000);
display.startscrolldiagright(0x00, 0x07);
delay(2000);
display.stopscroll();
display.clearDisplay();
display.setCursor(0,25);
display.println("  PEP   or    Acapella");
display.display();
menu = 1;}
digitalWrite(redled, LOW); 
digitalWrite(blueled,LOW);
digitalWrite(greenled,LOW);
digitalWrite(button1,LOW);
digitalWrite(button3,LOW);
delay(50);
buttonstate1=digitalRead(button1);
buttonstate3=digitalRead(button3);
if(buttonstate1==HIGH){
  //PEP select
  phrepeats=peprepeats;
  phlength=peplength;
  phminpress=pepminpress;
  phmaxpress=pepmaxpress;
  phrest=peprest;
goto physio;}

if(buttonstate3==HIGH){
  //Aca Select
  phrepeats=acarepeats;
  phlength=acalength;
  phminpress=acaminpress;
  phmaxpress=acamaxpress;
   phrest=acarest;
goto physio;}

goto start;
physio:
for (int Rep = 1; Rep < (phrepeats +1 ); Rep++){
int pres1 = ((uint32_t)mySensor.readFloatPressure()/cab); //Reference pressure
int phcount = 0;
while(phcount < phlength){
int pres2 = ((uint32_t)mySensor.readFloatPressure()/cab); //input pressure
int pres3 = (pres2 - pres1);
if (pres3<0){pres3=0;}
if (pres3>=phminpress && pres3 <= phmaxpress){
digitalWrite(redled, LOW);
digitalWrite(greenled, LOW);
analogWrite(blueled, 2+20); 
delay(50);
phcount = phcount +85;
}
if (pres3 > phmaxpress) {
analogWrite(redled, 5+pres3*2);
digitalWrite(greenled, LOW);
digitalWrite(blueled,LOW);
delay(50);
phcount = phcount +85;
}
if (pres3 < phminpress) {
analogWrite(greenled, 1+pres3/4);
digitalWrite(redled, LOW); 
digitalWrite(blueled,LOW);}
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0,0);
display.print("Rep = ");
display.print(Rep);
display.print(" of ");
display.print(phrepeats);
display.print(" READY");
display.setCursor(0,8);
display.print("Target = ");
display.print(phminpress);
display.print(" Mb = ");
display.print(pres3);
display.setCursor(0,16);
display.print("Pep Time = ");
display.print(phcount/10);
display.print(" of ");
display.print(phlength/10);
display.setCursor(0,24);
display.print("Pressure = ");
if (pres3<phminpress){display.print("Low");}
if (pres3>=phminpress && pres3 <= phmaxpress){display.print("Good");}
if (pres3>phmaxpress){display.print("HIGH");}
display.display();
}
digitalWrite(redled, LOW); 
digitalWrite(blueled,LOW);
digitalWrite(greenled,LOW);
tone(A0,1050,1000);

if  ((Rep)<(phrepeats)) {
for (int t = phrest; t > 0; t--){
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0,0);
display.print("Rep ");
display.print(Rep);
display.print(" of ");
display.print(phrepeats);
display.print(" Complete");
display.setTextSize(2);
display.setCursor(20,16);
display.print("Rest ");
display.print(t);
display.display();
   for (int g=4; g <= 35; g++){
      analogWrite(9, g);
      analogWrite(6, g);
      delay(20);}
   for (int g=35; g >= 4; g--){
      analogWrite(9, g);
      analogWrite(6, g);
      delay(20);}
}}}

display.clearDisplay();
display.setTextSize(2);
display.setCursor(15,0);
display.print("Physio");
display.setCursor(25,16);
display.print("Complete");
display.display();
delay(1000);
tone(A0,650,800);
delay(800);
tone(A0,850,800);
delay(800);
tone(A0,1050,800);
darthdad:
   for (int g=4; g <= 35; g++){
      analogWrite(9, g);
      analogWrite(6, g);
      delay(20);}
   for (int g=35; g >= 4; g--){
      analogWrite(9, g);
      analogWrite(6, g);
      delay(20);}

   for (int g=4; g <= 35; g++){
      analogWrite(3, g);
      analogWrite(6, g);
      delay(20);}
   for (int g=35; g >= 4; g--){
      analogWrite(3, g);
      analogWrite(6, g);
      delay(20);}
         for (int g=4; g <= 35; g++){
      analogWrite(3, g);
      analogWrite(9, g);
      delay(20);}
   for (int g=35; g >= 4; g--){
      analogWrite(3, g);
      analogWrite(9, g);
      delay(20);}
menu = 0;
if(pover == 1){goto darthdad;}}
Serial.print("Displaying ID, reset and ctrl regs\n");
Serial.print("ID(0xD0): 0x");

F() macro, and so on.

This is one of the reasons we ask you to post code

{goto darthdad;

Never ever use a "go to". You will get into a mess.

The whole code is just one long loop function. Break it up so it is easy to see what is happening. Functions should not go on at this length.

AWOL:

Serial.print("Displaying ID, reset and ctrl regs\n");

Serial.print("ID(0xD0): 0x");


F() macro, and so on.

This is one of the reasons we ask you to post code

Thanks AWOL, sadly I'm still none the wiser lol

The BME280 start up sketch does take a bunch of the memory, would be nice to cut out the bits I may not need.

I'm sorry, I don't understand your comment.

Grumpy_Mike:

{goto darthdad;

Never ever use a "go to". You will get into a mess.

The whole code is just one long loop function. Break it up so it is easy to see what is happening. Functions should not go on at this length.

Lol Grumpy Mike, I did say sorry before your read it! your were warned!

I'll change that one (Goto) into a 'while' statement :wink:

I hear what you say about goto's, but assure you they wont get me lost, I'm a cnc machinest/programmer by trade. Fanuc, Mazak's, Okuma GE n the like, and when you want a program to do what you say and not cut your hand off coz it got to the end of a loop, then a goto is what we would always use. I am avoiding using them though in Arduino :slight_smile:

What way do you mean "break it up", I'm used to one long program with no breaks, please post a simple bit of the code broken up in the way you want. then I'll follow and do the rest.

Many thanks, Phil.

AWOL:
I'm sorry, I don't understand your comment.

F() macro, and so on. <--I don't understand what you are saying here? what is F() macro?

This is one of the reasons we ask you to post code <--therefore I can't understand your reason

The F () macro

This is one of the reasons we ask you to post code <--therefore I can't understand your reason

You were complaining about shortage of memory, but had provided no evidence