Carbondale Illinois
Offline
Full Member
Karma: 1
Posts: 104
Making digital rivers.
|
 |
« on: November 13, 2011, 12:04:13 pm » |
First, I'm a geologist, not an EE guy; I can do simple sketches, but this stuff is way over my head. In short, I'm using the Arduino Pro in an electronic flow controller for educational river models we build (see www.emriver.com. A pro programmer wrote some nice code for me as a favor (in C++); it works, but we're bumping against memory limits; we have several large arrays, most of which are used to run "hydrographs" -- simulation of a flood; a curve that starts small, climbs to a max, and then tapers off. I am cleaning up and refining things because he's already done me WAY too many favors. Also we had to hard code a pwm v. flow rate curve because it could not be well described by a math function; so 255 numbers right there (we unit8_t 'd them, that helped). Also he as advised using "const" for variables, this put them in flash, correct? Many thanks for help :-) My friend isn't much versed on Arduino; he's asked me to ask you guys if there is a way to "load map" with the Arduino IDE, i.e. see how much SRAM is being used when the program runs.
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Tesla Member
Karma: 100
Posts: 6784
-
|
 |
« Reply #1 on: November 13, 2011, 12:18:21 pm » |
I assume you're using a 328 chip. I had a brief search for ATMega emulators but emulare was the only one I found that looks usable without a lot of work. Unfortunately it didn't seem very stable when I used it. Your mileage may vary. What use are you making of flash, EEPROM and RAM? There are techniques that you can use to trade off between them, but that's no good if they're all maxing out. Do you understand how your RAM is being used i.e. what is taking up the space? You can fiddle around with low level details of the storage mechanisms, for example you might be able to use less than 255 entries for your PWM calibration curve, but the biggest gains usually come from correcting architectural mistakes. For example, why are you using C++ rather than 'C'? Do you have much dynamic data? Are you using dynamic buffers anywhere? It's easy to grossly increase heap consumption just by misusing strings. I don't know what the memory layout is in the Arduino runtime, but usually the memory use will consist primarily of heap and stack. Do you know how much space each of these is using? Stack use you can determine from the address of an item on the top of the stack. heap use is harder to do and probably requires diving into the runtime library, but since it's open source that should be possible.
|
|
|
|
|
Logged
|
|
|
|
|
Carbondale Illinois
Offline
Full Member
Karma: 1
Posts: 104
Making digital rivers.
|
 |
« Reply #2 on: November 13, 2011, 12:27:47 pm » |
Thanks PeterH. Using the Pro 328. We have tons of flash left over, the code's only about 7K; it's the large arrays and lookup tables; my friend has used pointers for some as a help (as I understand it). Part of the problem is that I want the code to be hackable by students using our models (from grade 5 on up to PhD); and the code is now still barely accessible because it's pretty complex. And I think my friend did use C, I don't really know the difference, just that it compiles and runs fine, sorry, again, I'm a geoscientist trying to do the jobs of several people here :-) -- we are struggling in this economy. I did find info on PROGMEM: http://www.arduino.cc/playground/Learning/MemoryLooks like this would work, but with added complexity. Also this is a production item, we'll send dozens of these out to clients, and anything that risks flaky behavior is a real risk for us; most users will not want to reprogram themselves. Would really help if we could just calculate loading of sram, but I don't see a simple way to do that.
|
|
|
|
|
Logged
|
|
|
|
|
Carbondale Illinois
Offline
Full Member
Karma: 1
Posts: 104
Making digital rivers.
|
 |
« Reply #3 on: November 13, 2011, 12:31:31 pm » |
PeterH,
Sorry, should have mentioned I can email your replies to my friend and this may be a big help to him -- he'll know what all that means; he's a high level pro but not familiar with the specifics of Arduino.
He wanted to start from scratch but I wanted to use Arduino to make the project open source and easily modifiable by users. No good deed goes unpunished, right? :-)
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Tesla Member
Karma: 100
Posts: 6784
-
|
 |
« Reply #4 on: November 13, 2011, 12:38:09 pm » |
What does your Arduino actually do?
It sounds as if it is encompassing some pretty significant logic.
Have you considered changing the system architecture so that the Arduino acts as a remote sensor/actuator interface and the main logic happens on a PC? By providing a COM interface to the Arduino you can implement all the PC side stuff in Windows Script Host which people can code / hack in VB or javaScript. I'd consider that far more approachable for people who want to dive into the system. It also means the part they're hacking is just a file on the PC so easily fixable even by a non-techy. (And it means it is easy to produce log files, access databases and so on and enables all sorts of interesting possibilities. It does mean that you need a PC/laptop as well as the Arduino, and I don't know if that would be an issue, but it seems these days you can usually assume there is a computer wherever there is a person.
|
|
|
|
|
Logged
|
|
|
|
|
New Jersey
Offline
Edison Member
Karma: 26
Posts: 2450
|
 |
« Reply #5 on: November 13, 2011, 01:05:13 pm » |
There are a number of free memory functions that'll tell you how much SRAM you're consuming - search the forum for freemem.
An easy way out if you're short of space is to upgrade to a Mega - it's more expensive, but perhaps not so bad when that cost is wrapped up with the other components in your product.
I'd assumed as you're making a commercial product that your code is proprietary, but you mention that it's open source. In which case, post it here and there may be things the folks here can suggest to improve/clarify/reduce the memory footprint.
What part does the arduino play in the system? Flow control by PWMing the pump?
|
|
|
|
|
Logged
|
|
|
|
|
Netherlands
Offline
Tesla Member
Karma: 101
Posts: 9551
In theory there is no difference between theory and practice, however in practice there are many...
|
 |
« Reply #6 on: November 13, 2011, 01:40:44 pm » |
Can you post the code you have at the moment? A pro programmer wrote some nice code for me as a favor (in C++); it works, but we're bumping against memory limits; we have several large arrays, most of which are used to run "hydrographs" -- simulation of a flood; a curve that starts small, climbs to a max, and then tapers off. How large are these arrays? Can you post such a hydroGraph? For these kind of problems approximation by interpolation can be a real memory winner, I wrote the multimap() function for these kind of problems. see - http://arduino.cc/playground/Main/MultiMap - The idea of multimap() is to reduce all points of an array or a function (the wave in your case) to a substantial smaller subset of points, between which linear interpolation is an acceptable approximation of the original array/function. It is a speed - memory - precision tradeoff. Might help, Rob
|
|
|
|
|
Logged
|
|
|
|
|
Austin, TX
Offline
Faraday Member
Karma: 42
Posts: 5244
CMiYC
|
 |
« Reply #7 on: November 13, 2011, 01:53:36 pm » |
Also he as advised using "const" for variables, this put them in flash, correct? In this case, your pro-friend is wrong. const will not place constants/variables into FLASH. They will still consume RAM during the program's execution. Only variables which are explicitly placed into PROGMEM get put into FLASH. The only thing "const" really does is generate complier errors if your code attempts to modify a "constant."
|
|
|
|
|
Logged
|
|
|
|
|
Carbondale Illinois
Offline
Full Member
Karma: 1
Posts: 104
Making digital rivers.
|
 |
« Reply #8 on: November 13, 2011, 02:05:30 pm » |
OK everybody, here's the code. THANKS for your help! I've put description Exhibition / Gallery to make things neater: http://arduino.cc/forum/index.php/topic,78866Should mention programmer X (anonymous pal) wrote some very sweet encoder code; seems to not be enough of that around; it's in there. Steve PS. Yes, I know all the "30"'s in hydrographs can be replaced, we eventually want to have other numbers there :-)
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Tesla Member
Karma: 100
Posts: 6784
-
|
 |
« Reply #9 on: November 13, 2011, 02:30:11 pm » |
Only variables which are explicitly placed into PROGMEM get put into FLASH.
Isn't the Arduino compiler smart enough to do that with static consts? Many compilers are.
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
UK
Online
Brattain Member
Karma: 143
Posts: 19368
I don't think you connected the grounds, Dave.
|
 |
« Reply #10 on: November 13, 2011, 02:33:40 pm » |
Not a question of smart enough, think about how you might have a string constant that could be in flash memory, and then passed to Serial.print.
|
|
|
|
« Last Edit: November 13, 2011, 02:38:45 pm by AWOL »
|
Logged
|
Pete, it's a fool looks for logic in the chambers of the human heart.
|
|
|
|
UK
Offline
Tesla Member
Karma: 100
Posts: 6784
-
|
 |
« Reply #11 on: November 13, 2011, 03:11:40 pm » |
Not a question of smart enough, think about how you might have a string constant that could be in flash memory, and then passed to Serial.print.
Are you referring to the possibility of casting away const-ness?
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
UK
Online
Brattain Member
Karma: 143
Posts: 19368
I don't think you connected the grounds, Dave.
|
 |
« Reply #12 on: November 13, 2011, 03:13:21 pm » |
No, I'm referring to the difficulty of distinguishing entities in completely different memory spaces.
|
|
|
|
|
Logged
|
Pete, it's a fool looks for logic in the chambers of the human heart.
|
|
|
|
New Jersey
Offline
Edison Member
Karma: 26
Posts: 2450
|
 |
« Reply #13 on: November 13, 2011, 03:27:31 pm » |
We have tons of flash left over Progmem is an answer then. You don't really need anything more than one step of your hydro instructions in RAM proper. As I haven't used progmem before, I hacked this together as an experiment: #include <avr/pgmspace.h>
// One step within a hydrograph. struct hydrograph_step_t { // The duration of this step in seconds. prog_uint16_t seconds;
// The motor PWM value during this step (0-255). prog_uchar pwm; };
PROGMEM struct hydrograph_step_t Graph1[] = { {30,100},{30,110},{30,255},{0,0}}; PROGMEM struct hydrograph_step_t Graph2[] = { {30,1 },{40,90 },{50,128},{0,0}};
struct HydroGraph_t { char *Name; hydrograph_step_t *Steps; };
struct HydroGraph_t HydroGraphs[]= {{"Hydro1",Graph1},{"Hydro1",Graph2}};
struct hydrograph_step_t ThisStep;
void setup() { Serial.begin(9600); Serial.println("Progmem Test");
memcpy_P(&ThisStep,&(HydroGraphs[1].Steps[2]),sizeof(ThisStep)); Serial.print(ThisStep.seconds); Serial.print (" "); Serial.println(ThisStep.pwm,DEC); }
void loop() { } Seems to work 
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Tesla Member
Karma: 100
Posts: 6784
-
|
 |
« Reply #14 on: November 13, 2011, 04:06:25 pm » |
No, I'm referring to the difficulty of distinguishing entities in completely different memory spaces.
By 'eck, I had no idea all that was going on. I've been spoiled by systems with a unified address space.
|
|
|
|
|
Logged
|
|
|
|
|
|