B4R Tutorial Using PROGMEM to save memory

Erel

Administrator
Staff member
Licensed User
The smaller Arduinos like the Arduino Uno have 2k of RAM. The subs stack and the global variables use this memory.

If your program includes constant data then you can use PROGMEM to store the data in the program code and access it without loading the whole data into the the limited RAM.

Complete example:
B4X:
Sub Process_Globals
   Public Serial1 As Serial
End Sub

Private Sub AppStart
   Serial1.Initialize(115200)
   Log("AppStart")
   Log("RAM: ", AvailableRAM)
   For i = 0 To 20
     Log(GetByte(i))
   Next
End Sub

Private Sub GetByte(Index As UInt) As Byte
   Return RunNative("getdata", Index)
End Sub

#if C
#include <avr/pgmspace.h>
const PROGMEM byte data[] = { //change the data here
1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 0xFF, 0xFE,
8, 9, 10, 11, 0xFF, 0xFE,
8, 9, 10, 11, 0xFF, 0xFE,
8, 9, 10, 11, 0xFF, 0xFE,
8, 9, 10, 11, 0xFF, 0xFE,
8, 9, 10, 11, 0xFF, 0xFE,
8, 9, 10, 11, 0xFF, 0xFE,
8, 9, 10, 11, 0xFF, 0xFE
};

B4R::Object beo1;
B4R::Object* getdata(B4R::Object* o) {
   return beo1.wrapNumber(pgm_read_byte_near(data + o->toLong()));
}
#end if
1. Update the data array with your own data.
2. Use GetByte to read from the stored data.
 

derez

Expert
Licensed User
The attached program is at the max memory usage.
Can you show me how to use PROGMEM to store the notes frequencies ?
I guess I'll have to put them in an array but then I need to keep a map that holds the array index per frequency - will that not use additional memory ? (possible solution - to use the index instead of the name, in the subs).
Does it have a delay in comparison to the global definition ?

Note: to hear the music in a speaker (0.5W, 8ohm) use a npn transistor, emitter to ground, speaker between collector and Vcc (5V), pin 8 to the base through a resistor (~5k - 10K)
 

Attachments

Last edited:

Erel

Administrator
Staff member
Licensed User
Your program is near the program size limit for Arduino Uno (32kb). PROGMEM will not help in this case. PROGMEM is useful when you want to reduce the RAM usage.

For your program there are two possible solutions:
1. Switch to a board with larger flash memory such as Arduino Mega or ESP8266.
2. Improve the program flow. Your program mixes data with code. It should be quite simple to create an array with the relevant commands and a small sub that processes the array data and calls onenote with the correct parameters.

For further discussion please start a new thread.
 
Top