Hot answers tagged

10

AVR is a modified Harvard architecture family, so code is stored in flash only, whereas data exists primarily in RAM when being manipulated. With that in mind, let's address your questions. Why on earth do I have to copy the damn content to RAM before accessing it? You don't need to per se, but by default code assumes that data is in RAM unless the code ...


9

The short answer is no: PROGMEM data is read-only. Flash memory limitations The first thing to understand is that Flash memory (where program space lives) is designed for long-term fixed storage. Reading from it is very fast and precise. However, generally speaking, you can't modify it on a byte-by-byte basis (e.g. changing a specific variable). You usually ...


8

This is how Print::print prints from program memory in the Arduino library: size_t Print::print(const __FlashStringHelper *ifsh) { const char PROGMEM *p = (const char PROGMEM *)ifsh; size_t n = 0; while (1) { unsigned char c = pgm_read_byte(p++); if (c == 0) break; n += write(c); } return n; } __FlashStringHelper* is an empty class ...


7

Well, this question has been wisely answered in an answer to Stack Overflow question C: differences between char pointer and array. Basically, what you're declaring as PROGMEM with, const prog_char testStringD[] PROGMEM = "JKL"; is both the array and the memory it points to, that is, the elements of the array, both in current's scope stack. Whereas ...


6

An easy way of accessing any type of data in PROGMEM is to use this small library: PROGMEM_readAnything.h #include <Arduino.h> // for type definitions 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) ...


6

I am afraid there is no good solution to this problem. One option I do like is to use the __flash qualifier instead of PROGMEM: const uint8_t ram_array[] = { 1, 2, 3, 4 }; __flash const uint8_t flash_array[] = { 5, 6, 7, 8 }; void function_reading_ram(const uint8_t *array) { uint8_t secondElement = array[1]; // ... } void function_reading_flash(...


5

You can try (explict unsigned long values): unsigned long fromValues = (0x00UL << 16) | (0x01 << 8) | 0xF3; Serial.println(fromValues); or: value = (((unsigned long) c1) << 16) | (c2 << 8) | c3; The issue is that the expression is implicit int and not long (as you are assuming). You need to tell the compiler about this. An ...


5

The way you've written in, the pointer is stored in flash, but the strings are stored in SRAM. Read the appropriate documentation (also found in the Arduino reference) more closely, and do as it says. char nmPokemon0[] PROGMEM = "MISSINGNO"; char nmPokemon1[] PROGMEM = "Bulbasaur"; ... PGM_P nameArray[] PROGMEM = { nmPokemon0, nmPokemon1, ... }; And ...


4

Your declaration of char buffers is done like so: char* move1 = "N/A"; This will only allocate 3 characters with an additional one for null termination i.e. not long enough to hold the name. You need to do: char buffer[16]; Where the length is long enough to hold your string.


4

Arduino Due (ARM Cortex-M3) doesn't need anything like PROGMEM as it has access into the flash memory in the same way as into the RAM. The const qualifier is enough to keep it in program memory only. The AVR based boards like UNO needs PROGMEM because there are different instructions for fetching data from program memory and g++ is not very advanced in this ...


4

all constant data are part of the sketch. where else should they be? in runtime they are loaded into RAM. PROGMEM directive prevents the loading into RAM.


4

The library, as it stands, doesn't support direct sending from PROGMEM. However it's not too hard to get around that - if your C++ is up to it. The IRsendRaw class is a child class that extends the IRsendBase with a single function. You just need to do the same thing to create a new class that implements the functions in a way that can read from PROGMEM. ...


4

There is also an OO solution possible, using the strategy design pattern, but this comes with some (slight) memory and performance penalties. You need to use C++ for this. Put each array you want to differ between flash/SRAM in a separate class (one per type). You get data hiding and possible separation of concerns for free. Instead of putting the array in ...


3

1) Why not just system("avrdude ..."); That's more or less what the Arduino IDE does. 2) If you really want to embed the data in the executable, see Embedding Blobs in Binaries. You would need to re-link and re-upload the program each time you change that data. You won't need the Arduino IDE, as it's only job is basically to call avr-g++ and avrdude. You ...


3

Including <avr/pgmspace.h> and using the PROGMEM qualifier macro are only two of the steps required in order to get this to work. Since the data will no longer be available via the data bus you will need to use the various pgm_read_*() macros or *_P*() functions defined in avr/pgmspace.h. These work by using the appropriate assembly code instructions ...


3

I can see no specific drawback in using static class members instead of global variables on Arduino. They will be managed the same in the end program. The only difference I can see may arise based on how you design your classes (if design is correct, then no special problem shall arise): Let's suppose you decale a class A: class A { public: void f(...


3

What this line: const prog_char *testStringC PROGMEM = "GHI"; does is to write prologue code to copy the characters in the string to SRAM, and then initializes the pointer stored in flash to this SRAM location. You must load the pointer via normal means, and then dereference the pointer as usual. const char *str = pgm_read_word(&testStringC); Serial....


3

I see one major flaw in your code, related to index usage on arrays. Arrays in C and C++ are using a 0-based index, meaning that, for an array containing N elements: the first element is accessible with index 0 the last element is accessible with index (N-1) However, your code uses TrueRandom.random(1,numPokemon+1); which means you'll get an index between ...


3

When I store it in the EEPROM, the extra time required to find it in EEPROM, pull it through the sketch, and then push it through to the db corrupts the data sourced from EEPROM and posts a jumbled mess of characters...if it even makes it to the db at all. Are you certain of that? It is incredibly unlikely that mere time will corrupt characters and data as ...


3

No. the code burned in an Arduino is compiled not interpreted like Basic. Basically your C language sketch is compiled into AVR assembly language. The resulting hexadecimal is what is burned to the Arduino. Yes you could disassemble the hex like we used to do in the good old days, but as before it is highly unpredictable and most of the time not very ...


3

The closest I could get to what you are trying to do is this: template <size_t table_size> struct Ex_class { int get_value(int index) const { return pgm_read_word(&_ex_table[index]); } int _ex_table[table_size]; }; void setup() { Serial.begin(9600); static PROGMEM const Ex_class<5> ex_object = {1, 2, 3, 4, 5}; for (int i = 0;...


3

You can not directly dereference something ("access an array") that is in flash memory. You have to use pgm_read_xxx functions from <avr/pgmspace.h> . In your case you should probably write something like this: tone(8, pgm_read_word(&melody[thisNote]), noteDuration); Pgm_read_word reads two bytes. You could also call that inside your tone() ...


3

The font definition table takes 960 bytes of RAM - nearly 1/2 of the the total usage. You can regain 480 bytes just by declaring that array as uint8_t; 1 byte each entry instead of 2 bytes each for ints. You can regain the remaining 480 if you still need to, by moving that table to program memory. The Arduino.cc site has a good discussion with examples. Just ...


3

const byte* const message[] PROGMEM = to use an item, load it in RAM strcpy_P(buffer, (byte*)pgm_read_word(&(message[i]))); source Arduino reference - PROGMEM


3

const char* text; is a pointer to constant not a constant pointer (char * const text is a constant pointer). So you can assign a pointer to a constant char array to const char* text; even a pointer to an array in PROGMEM. The compiler doesn't know the difference between a PROGMEM pointer and a pointer in SRAM. It is on you to work in code with a pointer to ...


3

It is a shame that gcc only supports the __flash qualifier in C mode, not in C++, so we have to use PROGMEM instead. Unlike __flash, which qualifies a variable just like const, the PROGMEM attribute only has effect when allocating room for a variable. Once the allocation is done, the compiler forgets about the attribute. In particular, a declaration such as ...


2

Probably because x is an array of integers (although in the code you posted you miss the '[]'), thus memcpy_p should run over rawlen integers, each integer occupies sizeof(uint16_t) bytes, hence rawlen * sizeof(uint16_t) bytes in program memory space.


2

Arduino documentation says, it is possible to keep constants like strings or whatever I don't want to change during runtime in program memory. All constants are initially in program memory. Where else would they be when the power is off? I think of it as embedded somewhere in the code segment, which must be fairly possible inside a von-Neumann-...


2

Using it with heterogeneous types is trickier, since it has to be copied by hand instead of using one of the pgm_read_*() macros. SimulatorRecord PendingRecord; memcpy_P(&PendingRecord, &SimulatorQueue[_iDataPos], sizeof(PendingRecord));


2

I have analysed your codes with a small Lua script: function pairsByKeys (t, f) local a = {} -- build temporary table of the keys for n in pairs (t) do table.insert (a, n) end table.sort (a, f) -- sort using supplied function, if any local i = 0 -- iterator variable return function () -- iterator function i = i + 1 return a[...


Only top voted, non community-wiki answers of a minimum length are eligible