I hope I'm posting this in the right place. I've already posted this to ladyadas forums but just in case I don't get a reply there... I'm hoping a cross-post here isn't too cheeky...
I've been trying for a while but I can't get to the bottom of this
I've got my Xport Direct connected normally (different pins from usual but correctly configured) to my Arduino Diecemilla and it works great with AF_Xport/NewSoftSerial, got plenty of sketches connecting to servers, pulling data etc...
I've also got a BlinkM connected to I2C (analog in 4/5) and it too works great, many sketches doing cool light things...
Problem is, I can't use both together. Whenever I call readline_timeout in AF_Xport my BlinkM stops working all together - xport keeps working fine... Took me long enough to narrow it down to being readline_timeout but I can't see what's causing the problems. It also seems to screw up a Serial.print I do for debugging as I send data over I2C... trims the line about half-way through.
Like I said, the whole thing works fine without readline_timeout... I can make the xport connect and send data out and I2C/BlinkM still works fine... it's just when I try to pull data back with readline_timeout
Any ideas why the conflict between the two? I've honestly run out of ideas...
Cheers in advance!
Solved: Turns out I had I had eaten all of the memory!
Whenever I see strange things like this (particularly with Serial.print and lost data), it begins to smell like like memory problems.
Hardware serial, NewSoftSerial and the Wire library all have pretty substantial buffers that use quite a bit of memory.
If you're not already using a 328 you might have to upgrade to get the extra memory.
Thanks etracer... that's a good place to start...
I'll try tweaking some more with memory in mind... (even though I might not be able to do anything)
I'm running a stock Diecimila with a 168 so I might try and find a 328 and do a quick swap rather than buying a whole new Duemilanove, it's been serving me well so far - just never really thought of RAM!
Thanks again etracer!
I went back and reworked the memory buffers in my code and everything started working in harmony
I must admit I never would've suspected memory even though it's a bit obvious in hindsight, it's easy to forget you've just got 1K to work with! This has taught me not to be a memory hog... and it also means I'll still be able to port my project to a pro mini once I'm done prototyping...
It's always great to fix weird little problems like this one that have been bugging you for ages...
The biggest consumer of memory that most people ignore are literal strings. So something as simple as:
Serial.println("Welcome to my wonderful sketch!");
Uses 31 bytes of memory - permanently! Add in a few more and it's easy to use up all your memory. That plus 128 bytes for hardware serial, 64 bytes for NewSoftSerial, and 32 bytes for the Wire library buffers, so you can see how it adds up fast.
Some techniques you can employ to reduce memory:
- Move your strings into PROGMEM. There are articles in the playground this and a library by mikalhart that help with this.
- Use appropriate data types. Don't use an int if you only need a byte (0-255). Avoid floats unless you absolutely need floating point results, etc.
- You can modify the libraries to reduce the allocated buffer sizes as a last resort if you don't need that much buffering.
Thanks yet again etracer... you're a fountain of knowledge!
I've been good with strict data types since I have quite a lot of intensive database background, and minimising the buffer sizes in libraries is what I did to get it working (it was way overkill by default for what I'm doing)
But the literal strings (particularly in Serial prints) is very interesting... I never even thought about that. All my string prints are wrapped in conditionals with a debug constant I set at the start, so it's easy for me to quickly remove them all at compile-time when I finish the project, but I leave them all on by default for debugging and didn't even think of the memory impact they'd have...
I think that'll definately have a big impact on my sketches too... I'll start by minimising the size of the debug strings and then maybe look into the PROGMEM stuff (that looks interesting too) if I find my sketches getting massive. Plenty of little memory savings to be had I'm sure!
Is there any simple way to figure out rough memory usage other than manual calculation? Obviously with flash size the compiler does a great job of telling you the size when compiled... but figuring out memory usage automatically is probably a lot more complicated I'm guessing...
Edit: Never mind - just noticed a nice little function in the example code for that great Flash (PROGMEM) library!
int size = 1024;
while ((buf = (byte *) malloc(--size)) == NULL);
Great! Thanks for the reference mem... more useful info.
It's probably a good thing I become educated better on memory usage on the ATMega since there's so little of it. It's easy to ignore it until it breaks - I was bound to run into this problem sooner or later!
On another note... is there any downsides to using the PROGMEM method of reading strings from ROM? Slower? I'm assuming the ROM module doesn't have a limited lifecycle of reads which the RAM wouldn't?
PROGMEM stores data in the PROGram MEMory area which is the flash memory - not EEPROM. Reads from the flash memory are very fast as that's where the program code lives. There is no limited read life-span. There is a limited write life-span (rated at 10,000 write cyles) - but it's only written when you program the chip by uploading a program. You can't dynamically write to flash memory when your program is running (you can only read).
Remember that there are 3 types of storage in the ATmega chips used in Arduino's.
- Flash memory - where the bootloader, program and optionally PROGMEM data are stored.
- SRAM - The memory used by your program at runtime. The SRAM is volatile and lost on power down.
- EEPROM - Available for you to store persistent data.
The different chips simply vary in the amount they have of each.
Sorry, of course! I'm just getting myself muddled up, Flash is indeed what I meant.
That makes sense that it's lifespan is only limited to the number of times the program is uploaded (which it is whether or not PROGMEM is used anyway of course) since it's writing out the various arrays at compile/upload... and I remember 10,000 writes being mentioned elsewhere for the flash lifespan, that's livable with!
PROGMEM (Flash library) is proving to be great though, after my buffer alterations I only had about 30 bytes of RAM free, now I'm around 260 bytes free and I'm sure there's plenty of other optimisations to be made... it's actually kinda fun and educational...
Thanks again for the help guys