Arduino Microcontroller Flash Memory

Hi,

I'm currently working on a project of mine. I don't have to get into details to make the things clear.

The projects consists in a external machine controlled by Arduino, which throughout it's servos it solves a certain task based on the input data.
The input data comes through an I2C protocol link directly to the Arduino.

The 1st step is to acquire the input data from the sensor.
The 2nd step is to calculate all the solutions depending on it's sensory data.
The 3rd step is to the move the servos as the solution says.

The Arduino that I have is a Leonardo.
The problem is that I barely have 28Kb for program storage with this bootloader. My code already has 27Kb, which includes 2 of the 3 steps. I predict it'll increase up to 40-45Kb. I don't have the money to buy a brand new Arduino, like the 2560, maybe a UNO, which is cheaper.
Is there any way of increasing the storage memory on the Arduino? Maybe ISP? EEPROM? SDCard? I tend to have a system which works independently, not collaborating with a PC.

Thank you,
RobertEagle

You can add more storage with external FRAM or EEPROM, but you can't execute code from there, unless you are running some kind of interpretive code like

Alternately, you can assemble a '1284P based board (I sell this bare board for $6 mailed in the US) with 128K Flash, 16K SRAM, 32 IO.
Use an offboard FTDI module to program it for independent operation.
Board and parts can be had for ~$25, less if you scrounge some and have an FTDI Basic equivalent and a wallwart for power already (or run from battery)
http://www.crossroadsfencing.com/BobuinoRev17/

Yes, it looks like a good choice, but I'm not from US.

Maybe linking another Arduino to the current Arduino and divide the problems?

Why complicate it? I send the boards internationally too. You can purchase from taydaelectronics.com, or Farnell.com?

So, you're saying this board is 100% compatible with the Arduino IDE?
Does it work if I apply the online tutorial for Xbee wireless programming for your board?

Yes it is.
Download the core files here and select Bobuino as board type.

Replace the /variants/bobuino/pins_arduino.h with this file, fixes an error in analog names and for SPI features.

Xbee should work just like on any other board, connects to the same serial port.
Is there a link for that tutorial?

pins_arduino.h (6.26 KB)

CrossRoads:
Yes it is.
Download the core files here and select Bobuino as board type.
GitHub - maniacbug/mighty-1284p: Mighty 1284P Platform for Arduino

Replace the /variants/bobuino/pins_arduino.h with this file, fixes an error in analog names and for SPI features.

Xbee should work just like on any other board, connects to the same serial port.
Is there a link for that tutorial?

Bob, do you recall the details of the SPI problem and why commenting out the line fixes it? I don't seem to have done that in my installation and I tried to follow most of the progress on
getting the bobuino working well.

Lefty

I think something was defined twice? Here and in the SPI library, commenting this out lets it compile.

#define NUM_DIGITAL_PINS            32
#define NUM_ANALOG_INPUTS           8
#define analogInputToDigitalPin(p)  ((p < NUM_ANALOG_INPUTS) ? 21 - (p) : -1)

extern const uint8_t digital_pin_to_pcint[NUM_DIGITAL_PINS];
extern const uint16_t __pcmsk[];
// comment next line to solve SPI problem?
//extern const uint8_t digital_pin_to_timer_PGM[NUM_DIGITAL_PINS];  

#define ifpin(p,what,ifnot)	    (((p) >= 0 && (p) < NUM_DIGITAL_PINS) ? (what) : (ifnot))
#define digitalPinHasPWM(p)         ifpin(p,pgm_read_byte(digital_pin_to_timer_PGM + (p)) != NOT_ON_TIMER,1==0)

#define digitalPinToAnalogPin(p)    ( (p) >= 14 && (p) <= 21 ? (p) - 14 : -1 )
// #define analogPinToChannel(p)	    ( (p) < NUM_ANALOG_INPUTS ? NUM_ANALOG_INPUTS - (p) : -1 )
#define analogPinToChannel(p)       ( (p) < NUM_ANALOG_INPUTS ? (NUM_ANALOG_INPUTS-1) - (p) : -1 ) // test to see if A0-A7 are off by 1

RobertEagle, What makes your code so long ?
You have the Wire library and the Servo library. The interface for the sensor, and making decisions.
That is not a lot to do.
Unless the sensor is a gyro/accel/compass/barometer I can't believe you need so much code.

Hi Erdin,

Well, there's only a sensor, as I said, on an I2C protocol. The Wire and Servo library doesn't take much memory. It's the algorithms in my program that it takes.
Till now, the code has 1300-1400 lines. It'll grow up to 2000, I suppose.

I'm making a Rubik cube solver having 4 ,,hands". Those 4 ,,hands" will be my way of solving the cube. I needed to develop the virtual movements, which took on average 500 lines, the data base of the algorithms, around 100 lines, and the pattern matching algorithms which took 800 lines and still takes. I'm not finished yet! I haven't designed yet the algorithms for the servos and for some filters.

I'm not using any library from the Internet, except those of the Arduino.

That needs a fair amount of coding. I understand it now.
It probably needs a Arduino Mega 2560 (or Bobuino). A Mega clone on Ebay is not expensive, but it has very cheap components.
You can use external I2C EEPROM, about 32kbyte for 3 dollars. But that can not be used for an algoritme, only to use it for example to log a temperature during a long time.

The Arduino compiler tends to produce oversized code by default.

It's particularly overzealous about inlineing functions: You can often save a lot of memory by telling it not to. You can add the attribute "attribute ((noinline))" to a function to tell it not to. I use a macro like this:

// Don't ever inline a function
#define NOINLINE __attribute__ ((noinline))

NOINLINE void function1()
{
  // Do something...
}

You can disassemble your program and see which functions are getting too big using "avr-objdump" and "avr-nm". I have a batch file:

rem Where you installed the Arduino IDE
set avr=c:\program files\arduino-0022\hardware\tools\avr\bin\avr-

rem The "build.path" from your preferences file
set build=c:\temp\arduino\build\

rem Name of your sketch goes here
set target=mysketch

rem program disassembly
%avr%objdump.exe -S -z %build%%target%.cpp.elf >disassembly_elf.txt

rem memory dump
%avr%nm.exe -S %build%%target%.cpp.elf >nm_out.txt

Yeah, why I didn't think about inlining..?
I'll try it, and I'll also try the idea of disassembling the program.

And Erdin,
I also thought that it would be a good idea if those 100 lines for the database shall be stored in the EEPROM, and then decoded with a simple solution of 20 lines, thus saving 80 lines, right? It would be a a slight improvement, but all summed up will reduce the size of the code (the inlining, and maybe the disassembling).

I'll come up with the new improvements.

Thank you,
RobertEagle

I still can't imagine how an EEPROM would help.
If you load data from EEPROM into RAM, you run out of RAM.

You can use the EEPROM as a database. For example a phone book, and only a single record is read from the EEPROM.

Let me explain.
You see, there are various methods of solving a Rubik cube. Every method has it's algorithms. Every algorithm has a certain amount of moves you have to execute.

Instead of having a function which defines an algorithm (like R2;L;F'..etc), you can store a key for each type of move (R2,F..etc) in every EEPROM location. Thus, you will have one single function for the all algorithms. The arguments of the function would be 2 variables which define a segment of the the EEPROM memory, which in terms of our understanding, it represents an algorithm.

Hope it'll save some space, and hope I've made the text crystal clear.

Okay, I understand. That will be possible.
So the 'algoritme' is data at a certain location.
It will be harder to handle, since you can not 'see' the source code of the data. But once the EEPROM is properly filled it should work.