Atmega328P-PU alternatives if more memory is needed

Hello,

my CarDuino project is going great, I've been making huge progress over the last few days, but there's one growing problem -- I am fast running out of memory space on the "head unit" Atmega328P-PU, whose job it is supposed to be to collect sensor data from other Atmegas and Attinies around the car via I2C, and then display that data on an Adafruit 1.4'' TFT screen.

I have barely implemented a third of the features that I would like my finished CarDuino to be able to do, but already I am at 85% of the head unit Atmega's memory space, and I am already using 75% of dynamic memory with global variables. I've thrown out a few superfluous variables and slimmed down a few calculation routines, but it hasn't changed this problem fundamentally.

So now I have been looking at other options, and the Atmega1284P-PU right now looks like the best alternative. I'd like to have it as a PDIP package, so my CarDuino can be a standalone circuit on a perfboard.

Now, can the Atmega1284P-PU be programmed via ArduinoISP with an Arduino Uno board? And how does that work with all the libraries? Could I just use the ones that work with the Atmega328P-PU?

I don't really need more input pins, the number of pins that the Atmega328P-PU provides would be just about enough for this project. It's really just that my vision for my CarDuino is turning out to simply be unfeasible with 32KB memory.

It's really just that my vision for my CarDuino is turning out to simply be unfeasible with 32KB memory.

So, I am hearing both SRAM and flash issues.

The 1284 is a great chip, with 16K of SRAM (twice the Arduino Mega.) I would personally recommend buying a board like what Crossroads builds for your programming and development and a couple of naked chips to build out your prototype unit. Having a known, good working board is great way to avoid frustration and keep the project moving forward.

Almost all libraries and code samples run on the 1284. There is a very active 1284 group here so I would expect great support if any issues arise.

Ray

You can use a bigger controller, or distribute your project onto multiple controllers. The TFT looks like a promising task for a dedicated controller.

Maybe one of my small footprint boards:
http://www.crossroadsfencing.com/BobuinoRev17/

My way of thinking is just, it'd be easier to have it all done by one IC, both the I2C data collecting and the displaying of that data on the TFT screen. Updated data is collected from most sensors via I2C in three second intervals, so there'd be no problem running even very long loop routines with one head unit IC.

And it'd just be more convenient to not have to think about wiring two parallel running Atmega328s on the same perfboard.

Are there any other important differences between the two chips to consider, before I make a decision?

So the Atmega1284 can not be programmed with an Arduino Uno as ArduinoISP via serial, is that right?

DrDiettrich:
You can use a bigger controller, or distribute your project onto multiple controllers. The TFT looks like a promising task for a dedicated controller.

In my experience, the ILI9341 SPI has a relatively low impact on uC performance so the 2nd uC is more appropriate in my opinion if the primary uC is pinout challenged. If so, the second uC with the LCD can simply be programmed as a terminal display and only the necessary control characters implemented.
Basic Arduino serial monitor.

So the Atmega1284 can not be programmed with an Arduino Uno as ArduinoISP via serial, is that right?

No, you can program it via ISP.

Ray

"So the Atmega1284 can not be programmed with an Arduino Uno as ArduinoISP via serial, is that right?"

Make you life easy and get a USB/Serial adapter, $7 here
http://www.tinyosshop.com/index.php?route=product/search&filter_description=true&filter_sub_category=true&filter_name=ftdi%20basic
Mini-B and Micro-B connectors available, I use both regularly, here to power a '1284P board during bootloading, and then for serial downloading:

Well I guess I will "make my life easier" then by buying a dedicated programmer for the 1284 :wink:

Given that at current count, my CarDuino will consist of at least two Atmegas (or one Atmega and one 1284) and about four Attinies, it's already a pain to keep switching my two Uno boards that act as ISPs back and forth depending on which IC I want to work on on any given evening...

Although Nick Gammon appears to have succeeded at programming an Atmega1284P with an Uno board: Gammon Forum : Electronics : Microprocessors : How to make an Arduino-compatible minimal board

Anyway, I know this is a huge project, but I've set myself no time constraints and I don't mind if it takes until next spring to fully complete (that is actually my projected time line right now). And being that my "tech" background is in web and database programming and graphics design, I've got certain ideas about how I want the user interface to look... I'm a very "visual" kind of guy, who just won't be happy with simply dumping out a few fuel consumption statistics on a screen in a pixelated basic system font. And I guess that's why 32 KB won't be enough for my head unit microcontroller... :wink:

For example, dissastisfied with the free fonts that came with the Adafruit display, or the way any other fonts look on the display, I am currently working on a function as part of the head unit sketch that will parse any integer or float that you feed into it, and then display that number on the screen as a sequence of bitmaps from 0 to 9 that I've created with a graphics program. There will be subfolders on the TFT's microSD card for different font types and font sizes, all of them filled with little bitmaps of the numbers from 0 to 9, which that function will be given as parameters to construct a directory path for access. I mean, if you've got several gigs of memory on your microSD card, you might as well use a little bit of it... :slight_smile:

But again, shenanigans like that take up memory space, and that's why I need something bigger than the Atmega328 :wink:

My experience shows that with a bit of magic, you can SIGNIFICANTLY reduce the code size.

Now the real question is: how many of these will you be making? Is it a commercial product?

If you'll be making just one, sure, just get a bigger chip... If you'll be making hundreds, try following:

  1. writing your own routines for the "simple stuff" - digitalRead and digitalWrite functions, as well as pinMode, analogRead and such are written to be foolproof and they take a huge amount of space. This holds true for the Arduino bootloader as well as the Arduino core.

  2. follow this:
    how to make it smaller

  3. if everything else fails, use assembly...

I have managed to change my code size of a simple clock project, using these tricks (not even the assembly tho) and some more magic from 3700 bytes flash, about 50? bytes ram to 1000 bytes flash, 0 bytes ram...

thegoodhen:
If you'll be making just one, sure, just get a bigger chip... If you'll be making hundreds, try following:

At the moment, this is a pure hobby project for my own enjoyment. I've had people who drive the same car as me tell me that they'd be interested in "buying" my CarDuino once it's completed, but I am not really developing it with that in mind as my main focus. In fact, I've been thinking about putting it online as "open-source" once it's all completed.

But even if I do decide to reap the benefits of my development work and put the project on a more commercial foundation, in the end, an Atmega1284 is $10, and an Atmega328 is $4. The $6 that you save by using the cheaper Atmega328 will be spent again on man-hours slimming down your code to fit within the 32KB of the 328.

On the other hand, look at all the libraries that my head unit will have to include... the two Adafruit libraries, and then Wire.h, SPI.h, SD.h ... that alone takes up a lot of space, and will be difficult to downsize.

But again, at this point, it's purely a hobby. I enjoy computer programming and building gadgets (although I'm still learning with respect to the Arduino microcosm), and that's as far as it goes. :wink:

EDIT:

Before I spend more time developing my "numbers to bitmaps" function as described above... do you guys know if maybe there's already such a function out there that somebody has written? In most web oriented programming languages, this can be done with about ten lines of code, but it seems that it's a little trickier with the Arduino... I don't mind going through the trouble, but if somebody has already done the work, that would of course be pretty neat.

My 0.02€ on program size:

When a program reaches memory limits, expect that it will grow further. Then it's a waste of time to tweak specific parts of the code, because much more time will be required to maintain such code later.

Don't worry about many libraries, if these are for different purposes. The linker is quite clever, and doesn't include unused library code and variables.
In rare cases a redesign of a library can save 80% space, as I found out with the IRremote library. There the default decode() method tries to invoke all protocol decoders, in order to find out which of these protocol applies. If you know that e.g. your controller uses only the NEC protocol, calling that decoder immediately will remove all other decoders from flash. Try alternative libraries, to find the best (smallest) for your project.

What you can and should do, is avoiding bad coding practices.

  1. Stay away from String objects, they are time and memory hogs. Use char arrays instead. This applies to C++ in general, and even to C#.
    Avoid dynamic objects at all, i.e. those created using "new". Static objects are okay.

  2. Avoid complicated if-statements, if the same can be done immediately.
    Bad:

bool some_condition = digitalRead(somePin); //or some similar boolean computation
if (some_condition == true) {
 digitalWrite(ledPin, HIGH);
}
else
if (some_condition == false)
{
 digitalWrite(ledPin, LOW);
}

Good:

bool some_condition = digitalRead(somePin);
digitalWrite(ledPin, some_condition); //or !some_condition, as required

That's not only less text, it also uses less memory.

  1. Stay away from direct port access, or similar low-level coding. It will bite you when you have to debug or modify your code later.

  2. Be careful with C++ templates. Some look very nice and short, but expand into much code.

DrDiettrich:
When a program reaches memory limits, expect that it will grow further. Then it's a waste of time to tweak specific parts of the code, because much more time will be required to maintain such code later.

Like I said, I've only implemented one third, if that, of the functions that I want my CarDuino to have, and already that sketch claims three quarters of the 328's resources. So far, it does little more than poll two other ICs in regular time intervals via I2C and display a few numbers on the screen with a few icons (which are stored as BMPs on the microSD card).

I have yet to implement things such as a light bulb checking device (which will mean two more Attinies to poll via I2C), as well as a "convenience module" which will monitor outside temperature, windshield wash level, and if I can get myself to really go crazy, it will also monitor if the soft top is properly shut or thrown all the way back (this is a convertible). So that means probably another Atmega328 to poll, and puts my total number of I2C devices within my CarDuino network at a whopping six.

All this means additional variables that will have to be handled. Moreover, I still haven't really designed a user interface that lets you navigate back and forth between different pages of the TFT screen, as well as a "preferences" page, where I want to be able to adjust user settings that will then be stored in the EEPROM.

Again, I know that this is a huge project, it's probably going to be one of the bigger programming jobs I have ever done, including much of the work I have done with databases and web pages. And although progress has been really quite considerable in a short amount of time, which also gives me confidence that this kind of project can be done in the end, I don't expect this "mother of all CarDuinos" to be ready to install before next spring.

DrDiettrich:
3) Stay away from direct port access, or similar low-level coding. It will bite you when you have to debug or modify your code later.

So far, I'm only doing direct port access with an Attiny that interprets the car's crankshaft sensor signal and generates an RPM reading from that. The sensor produces a very fast moving square wave, with cycle lengths of about 200 us when the car is revved up to high RPMs, and because digitalRead takes up precious microseconds, I am directly accessing the port with my pin change ISR to check if a pin is high or low. But because that's almost literally the only thing that this Attiny does, besides calculate the true RPM from the signal and report it as a 16-bit integer to the head unit Atmega via I2C, I don't expect difficulties. The code on that Attiny is about 96% finished and so far there haven't been any problems.

Here's the key part of that code:

void setup(){

 GIMSK = 0b00100000;    // pin change interrupt 
 PCMSK = 0b00000010;    // interrupt on pin PB1
 sei();                 // enable interrupts
}

void loop(){}

ISR(PCINT0_vect) {

  if ((PINB & 1 << crankshaft) != 0) crankRisingTimestamp = micros();
  }

I am currently working on a function as part of the head unit sketch that will parse any integer or float that you feed into it, and then display that number on the screen as a sequence of bitmaps from 0 to 9 that I've created with a graphics program. There will be subfolders on the TFT's microSD card for different font types and font sizes, all of them filled with little bitmaps of the numbers from 0 to 9, which that function will be given as parameters to construct a directory path for access. I mean, if you've got several gigs of memory on your microSD card, you might as well use a little bit of it...

IMO, not a good idea. Fonts (bitmaps) need to be in PROGMEM or in SRAM, depending on just how the display system is designed for performance.

And being that my "tech" background is in web and database programming and graphics design, I've got certain ideas about how I want the user interface to look... I'm a very "visual" kind of guy, who just won't be happy with simply dumping out a few fuel consumption statistics on a screen in a pixelated basic system font.

I can be 'graphic anal' at times, but generally my EE-self will take control and be satisfied with just data.
The above being said, you are IMO never going to be happy with the current graphic libraries; you are working with a uC and trying to do the business designed to be done on a microprocessor, say maybe the Beagle or the Raspberry Pi. I suspect you can go ahead and build-out your system with multiple Attinies and a fat 8-bit uC but my gut tells me you are going to be redesigning in less than 6 months. You are going to need far more SRAM if you get into serious graphic displays. Why not just use an inexpensive Tablet to begin with for the display? Use a R-Pi as the collective brains for all the data feeds - even post them to a real database and HTML5 the stuff over to the display tablet. There are a number of Android easy-development systems out in the free market, the most common is likely MIT's APP Inventor.

So, my recommendations is to move to 32-bit with 500MB - 1GB or RAM and write this stuff in a high level language. You may find a 1284 to be a nice hub uC to just aggregate the Attinies and then pass the data over to the r-Pi for some real grunt-work and publishing the HTML to the tablet's browser with some back-end Android code to glue stuff.

Here is what a $3 processor can do with HTML5.
YouTube: Here

I do not expect the above to impress you as you are a professional web developer; but it should give you a sense of what you could do using websockets and html5 and javascript.

Ray

I'll admit that web development, and the way of doing things that it entails, is an approach that appears to be quite different from that of programming a microcontroller, or even an entire network of microcontrollers.

I'm still fairly new to the Arduino world, or even microcontroller programming itself. That said, my experience in web development stretches back a good 17 years.

Anyway, it's a totally different approach when you have to consider that in microcontroller programming, memory is a very precious resource, one that you can run out of very quickly. You're just not used to memory being that scarce, and it takes a bit to realize that you have to scale down your visual ideas so they will fit within 32, or even 128kb of memory.

Maybe I will scale down my ideas a bit so they will fit onto the Atmega1284.

I'm personally not a big fan of Raspberries. Haven't done a lot of work with them, but they're just not my kind of thing.

I have actually considered this here:

http://www.4dsystems.com.au/product/uLCD_24PTU/

In this setup, a "head unit" Atmega would simply be sending variables to the screen, which has its own on-board CPU, and that CPU would then do all the graphics processing.

I haven't quite decided yet if that's what I want to do, but it's probably worth thinking about.

$8 vs $4, but yes, the 1284 with 4x flash, 8x SRAM, 2x EEPPROM, 2x hardware serial, and 4x 8-bit ports are more than 328.
http://www.mouser.com/Semiconductors/Integrated-Circuits-ICs/Embedded-Processors-Controllers/_/N-a86bc?Keyword=atmega1284&FS=True
http://www.mouser.com/Search/Refine.aspx?Keyword=atmega328
Be sure to compare 1284 vs 1284P, and 328 vs 328P. I think Hansibull's core lets you select P (picopower) vs non P.
[ur[]http://www.mouser.com/Search/Refine.aspx?Keyword=atmega328[/url]

carguy:
At the moment, this is a pure hobby project for my own enjoyment. I've had people who drive the same car as me tell me that they'd be interested in "buying" my CarDuino once it's completed, but I am not really developing it with that in mind as my main focus. In fact, I've been thinking about putting it online as "open-source" once it's all completed.

But even if I do decide to reap the benefits of my development work and put the project on a more commercial foundation, in the end, an Atmega1284 is $10, and an Atmega328 is $4. The $6 that you save by using the cheaper Atmega328 will be spent again on man-hours slimming down your code to fit within the 32KB of the 328.

On the other hand, look at all the libraries that my head unit will have to include... the two Adafruit libraries, and then Wire.h, SPI.h, SD.h ... that alone takes up a lot of space, and will be difficult to downsize.

But again, at this point, it's purely a hobby. I enjoy computer programming and building gadgets (although I'm still learning with respect to the Arduino microcosm), and that's as far as it goes. :wink:

EDIT:

Before I spend more time developing my "numbers to bitmaps" function as described above... do you guys know if maybe there's already such a function out there that somebody has written? In most web oriented programming languages, this can be done with about ten lines of code, but it seems that it's a little trickier with the Arduino... I don't mind going through the trouble, but if somebody has already done the work, that would of course be pretty neat.

I see... Well... I have done micro-optimizations to cut down the cost by tens of cents before... $6 is a HUGE amount of money... But it depends on your target market, should you decide to sell it. In my case, I was competing against chinese guys that sell clock soldering kits for the price I can't even get the components. :smiley:

thegoodhen:
I see... Well... I have done micro-optimizations to cut down the cost by tens of cents before... $6 is a HUGE amount of money... But it depends on your target market, should you decide to sell it. In my case, I was competing against chinese guys that sell clock soldering kits for the price I can't even get the components. :smiley:

Well, that's because they use cheap mass produced parts, and they themselves, in turn, mass produce the end consumer product on industrial scales. That way, they can cut their cost per unit in a way that your business can probably only ever dream about. And that's why you can order breakout modules for the Arduino at $3 a piece from Hong Kong with free shipping.

I have to say I am feeling tempted, once my own car computer is complete, to go on and give the project a few more tweaks to actually make it marketable. For example, I'd have to switch from perfboards to SMD, and a few other things would also have to be a bit more "polished" than the DIY job I am doing for my own car.

I am going to have to see what kind of potential demand there actually will be. And as anybody in marketing will tell you, sleek visuals go a long way in selling a product (well, if the product itself is crap and poorly engineered, then sleek looks won't save the day for you after all... but that's a different story). I will install this car computer in my own car first, and then we'll see what happens when I show pictures of it to other people.

carguy:
Well, that's because they use cheap mass produced parts, and they themselves, in turn, mass produce the end consumer product on industrial scales. That way, they can cut their cost per unit in a way that your business can probably only ever dream about. And that's why you can order breakout modules for the Arduino at $3 a piece from Hong Kong with free shipping.

I have to say I am feeling tempted, once my own car computer is complete, to go on and give the project a few more tweaks to actually make it marketable. For example, I'd have to switch from perfboards to SMD, and a few other things would also have to be a bit more "polished" than the DIY job I am doing for my own car.

I am going to have to see what kind of potential demand there actually will be. And as anybody in marketing will tell you, sleek visuals go a long way in selling a product (well, if the product itself is crap and poorly engineered, then sleek looks won't save the day for you after all... but that's a different story). I will install this car computer in my own car first, and then we'll see what happens when I show pictures of it to other people.

The way I see it, you have two options: target at a low amount of rich people or high number of poor people. :smiley:
If your product is innovative in a way, you can setup a nice kickstarter campaign and charge $30 bucks for something that I would be forced to sell for $1, because my target market is different...
If you get an opportunity to sell in large volumes to "general public" you gotta keep the price low, but price is not really an issue with kickstarter campaigns/"hipster" market places.

These "gadget boxes" , as I like to call them, which add modern functionality to older cars, tend to be quite pricey. Because they are limited-run products, for a handful of customers. And because somebody who goes through the trouble of developing and engineering those gadget boxes very probably won't enjoy working without adequate pay in the long run.

My estimate is that everything included, I'm looking at around $120 to $150 for parts. And then I'd have to think about how much I could charge people per unit for all the effort I will have had to put into developing this car computer. Considering that I'd probably sell no more than ten of these things per year, and at some point run out of new customers because this is an old car that no longer gets made and there are only so many people who will want to go through the trouble of installing something like it, I would probably have to set the retail price at around $300. Yes, that's a lot of money, but if you look at companies offering similar more or less bespoke gadgets, it would still be within reason.

Another idea would be to look at this car computer as having created a product core, which can be adapted to cars of other makes and models. In the end, what do I do with my system... I count injection intervals, I count speed signal square waves, I count crankshaft intervals. Nearly every older car will produce those signals in some way, shape, or form. And I keep track of fuel tank levels (your fuel level sensor in your tank is just a simple slide pot), and of oil and coolant temperatures (both simply thermistors which are gauged against an analog reference voltage). So with a handful of changes to my code(s), I could have a system for a '92 VW Jetta instead of the 1998 MG F for which I am building my system at the moment.

But that's all in the future. Right now, I'll just build this car computer for my own fun and enjoyment... and then, perhaps, I'll take it from there someday :wink:

carguy:
These "gadget boxes" , as I like to call them, which add modern functionality to older cars, tend to be quite pricey. Because they are limited-run products, for a handful of customers. And because somebody who goes through the trouble of developing and engineering those gadget boxes very probably won't enjoy working without adequate pay in the long run.

My estimate is that everything included, I'm looking at around $120 to $150 for parts. And then I'd have to think about how much I could charge people per unit for all the effort I will have had to put into developing this car computer. Considering that I'd probably sell no more than ten of these things per year, and at some point run out of new customers because this is an old car that no longer gets made and there are only so many people who will want to go through the trouble of installing something like it, I would probably have to set the retail price at around $300. Yes, that's a lot of money, but if you look at companies offering similar more or less bespoke gadgets, it would still be within reason.

Another idea would be to look at this car computer as having created a product core, which can be adapted to cars of other makes and models. In the end, what do I do with my system... I count injection intervals, I count speed signal square waves, I count crankshaft intervals. Nearly every older car will produce those signals in some way, shape, or form. And I keep track of fuel tank levels (your fuel level sensor in your tank is just a simple slide pot), and of oil and coolant temperatures (both simply thermistors which are gauged against an analog reference voltage). So with a handful of changes to my code(s), I could have a system for a '92 VW Jetta instead of the 1998 MG F for which I am building my system at the moment.

But that's all in the future. Right now, I'll just build this car computer for my own fun and enjoyment... and then, perhaps, I'll take it from there someday :wink:

Hmmm... I am not sure what it will consist of, but $150 for parts seems like a humongous amount of money. If you want, send me a partlist once you're done and I can try and take a look into how it could be made cheaper...

(And no, I don't want to steal the idea from you and sell it at a profit, I just naturally jump from one thing to another and this is something different from what I've been doing, so it sparked my interest. :D)