Get more Flash-/RAMusage out of a ATMega32u4?

Go To Last Post
66 posts / 0 new

Pages

Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Freaks!

 

If the search would have been a useful tool, i would have used it. But its as bad as Google (gets me more than 12k of hits for "32u4 size").

 

My problem:

I wanted to switch from 328P to a 32u4 to get that more halve kilobyte of RAM. The sad thing is, that the same code uses much more RAM and Flash on the 3u4 than on the 328. So i already have the inromation that the USB functionality uses this space. Is there any way to get rid of the USB functionality? I do program with a ISP anyway.

 

 

Yes i use Google, but there is no search enginge within Google to search through those many useless results...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

To get more RAM without USB, use one of the new Mega1 devices.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If i could, i would ;-)

Yes i use Google, but there is no search enginge within Google to search through those many useless results...

Last Edited: Wed. Jan 16, 2019 - 09:45 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Try use less RAM would be my first thought. How have you tried minimizing RAM usage so far?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why the 32U4? Seems an odd choice when there are chips out there with much bigger memories.

 

[E2A]

For example, and sticking with the original AVR peripherals, the mega644, with 64k/4k, or mega1284 for a whopping 128k/16k.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

Last Edited: Sun. Jan 13, 2019 - 10:45 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you are not using USB you can throw all the USB code away.

 

Then you end up with all the SRAM and Flash for your project.

 

If SRAM was your main concern,  a mega644P or mega1284P is still only TQFP-44

But there are plenty of ARM chips with oodles of memory.    Most have USB too.

 

Obviously people choose 32U4 because they want to use USB.

An Arduino Leonardo has less "usable" Flash than a Uno because of the USB Bootloader and USB CDC comms.

 

If you throw the USB away for one project,   you can always restore it for the next project.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I thought the endpoint buffers in USB chips were only for use by the USB, did I just dream that?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The reasen i want this chip, is because im using a promicro. There is no better board with more SRAM with this size as far as i know.

 

I already developed a board with the same pinout as a ProMini and with the 1284 on it. But i dont want to spent any more time for this. My program might just fit if i can free some bytes.

(I sell the schematics and PCB-Layout for this. If anyone is interested...)

 

How can i free up this storage that is used from the USB???

 

 

 

Attachment(s): 

Yes i use Google, but there is no search enginge within Google to search through those many useless results...

Last Edited: Sun. Jan 13, 2019 - 03:09 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The ProMicro is just a junior Leonardo without proper header sockets.

 

You can trash the USB bootloader and CDC in exactly the same way.   And you can restore in exactly the same way.

 

Any Arduino "Leonardo" program will still expect USB.    But you can create your own custom board in boards.txt

Or ignore Arduino completely and write bare-metal programs in AS7.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Of course the bootloader was the first thing i trashed. But how do i get rid of the usb stuff?

 

Yes i use Google, but there is no search enginge within Google to search through those many useless results...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
I thought the endpoint buffers in USB chips were only for use by the USB, did I just dream that?
I've not used that device, but a casual reading of the datasheet shows no such restriction.  The header iom32u4.h shows:

#define RAMSTART     (0x100)
#define RAMSIZE      (0xA00)
#define RAMEND       (RAMSTART + RAMSIZE - 1)  /* Last On-Chip SRAM Location */

However it also shows:

#define XRAMSTART    (0x2200)
#define XRAMSIZE     (0x10000)
#define XRAMEND      (XRAMSIZE - 1)

Why would the header for a device which lacks an EBI include these?

 

Many have them but define them as 0 or (NA).  A search of other headers shows that the following devices have something else:

$ grep -r XRAMSIZE . | grep -v -e "(NA)" -e "(0)" -e " 0" | sort
./iom128rfa1.h:#define XRAMSIZE                        (0x0000)
./iom32u4.h:#define XRAMEND      (XRAMSIZE - 1)
./iom32u4.h:#define XRAMSIZE     (0x10000)
./iom32u6.h:#define XRAMEND      (XRAMSIZE - 1)
./iom32u6.h:#define XRAMSIZE     (65536)
./iox128a1.h:#define XRAMSIZE     EXTERNAL_SRAM_SIZE
./iox128a3.h:#define XRAMSIZE     EXTERNAL_SRAM_SIZE
./iox128d3.h:#define XRAMSIZE     EXTERNAL_SRAM_SIZE
./iox16a4.h:#define XRAMSIZE     EXTERNAL_SRAM_SIZE
./iox16d4.h:#define XRAMSIZE     EXTERNAL_SRAM_SIZE
./iox192a3.h:#define XRAMSIZE     EXTERNAL_SRAM_SIZE
./iox192d3.h:#define XRAMSIZE     EXTERNAL_SRAM_SIZE
./iox256a3.h:#define XRAMSIZE     EXTERNAL_SRAM_SIZE
./iox256a3b.h:#define XRAMSIZE     EXTERNAL_SRAM_SIZE
./iox256d3.h:#define XRAMSIZE     EXTERNAL_SRAM_SIZE
./iox32a4.h:#define XRAMSIZE     EXTERNAL_SRAM_SIZE
./iox32d4.h:#define XRAMSIZE     EXTERNAL_SRAM_SIZE
./iox64a1.h:#define XRAMSIZE     EXTERNAL_SRAM_SIZE
./iox64a3.h:#define XRAMSIZE     EXTERNAL_SRAM_SIZE
./iox64d3.h:#define XRAMSIZE     EXTERNAL_SRAM_SIZE

Ignoring the Xmega parts, and the non-existent m32u6, and the m128rfa1 which slipped through my grep, the m32u4 seems to be the only part with XRAM macros defined 'incorrectly'.

 

What am I missing?

 

The m32u4 datasheet also suggests that the m32u4 has the RAMPZ register.  I'm at a loss to understand why a device with 32KB of flash would need it.

 

I shudder to think what else has been overlooked in that datasheet.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What is the CDC? Does creating a custom board get rid of the USB stuff? Then how?

Yes i use Google, but there is no search enginge within Google to search through those many useless results...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

CDC only works if the USB code is loaded into the 32U4.

 

It is either put in the Bootloader area or in the Application area.

If you erase the whole chip,  you have an empty chip without any USB code.

 

Other makes have factory bootloaders in ROM e.g. ST, NXP.   Even some Atmel 8051.

AVRs have always had the Boot code in erasable Flash.    This is because punters have an overwhelming desire to shoot their own feet.

 

This is why you can't alter fuses from within a Bootloader.    USB chips come out of the factory with a DFU bootloader.    You do not need ab external programmer.

However you can destroy most things with ISP.   Or destroy everything with JTAG or HVPP.    i.e. you can do what you want with an empty AVR.

 

David.

Last Edited: Tue. Jan 15, 2019 - 08:42 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You have not answered a single question of mine...

Yes i use Google, but there is no search enginge within Google to search through those many useless results...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have told you how to use the 32U4 as a bare chip in AS7.

I have told you how to use the 32U4 as a crippled chip in Arduino with a "custom" board.txt.

 

I can understand the "convenience" of a cheap Ebay ProMicro as a prototype.

If you are creating your own pcbs it would seem wiser to choose 644P, 1284P with a similar footprint.

 

Note that you can use a BluePill in the Arduino IDE.   It gives you more SRAM, Flash,  USB, ...

and probably cheaper than a ProMicro.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Tobey wrote:
How can i free up this storage that is used from the USB???
As others have said it seems that until you actually start programming USB registers the entire SRAM from 0x100 to 0xAFF is available to your own code. You don't actually have to "do" anything to make this RAM available - it is by default. It is only if you set the ALLOC bit in the UECFG1X register that the USB might start to allocate 128/256/512 byte blocks of endpoint memory.

 

In the opening post you said:

The sad thing is, that the same code uses much more RAM and Flash on the 3u4 than on the 328. 

I simply don't believe that - what evidence do you have to support that assertion? 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Cliff,

 

The Leonardo / ProMicro will always link with the Arduino USB code in the Application section.

The Leonardo / ProMicro will always reserve 4kB of Boot area.

 

If you create a non-USB board in boards.txt that happens to use the 32U4 you will get regular non-USB memory usage.

 

Or you forget about Arduino completely.    Treat the 32U4 like any other bare AVR in an AS7 project.   e.g. no Boot section, no USB, ... unless you specifically program it.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That was kind of my point - as long as you don't enable USB you have all 2.5K to play with.

 

I'm still at a loss to understand why a 328 app ported to 32U4 should use very much more RAM or flash than the 328 version??

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've not used a 32U4 but the datasheet says this...

 

• Non-volatile Program and Data Memories
...
– 1.25/2.5KB Internal SRAM
...
• USB 2.0 Full-speed/Low Speed Device Module with Interrupt on Transfer Completion
...
– Fully independent 832 bytes USB DPRAM for endpoint memory allocation
...

 

which implies that the whole 2.5KB is independent of the USB.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The Leonardo design was a bit of a mess in several ways.    You have to rely on USB never being interrupted,   less Flash for your App,   inconvenient pin-mapping scheme, ...

 

Obviously a traditional Arduino App expects to have Serial comms and a bootloader.    This takes up quite a bit of space.

 

The beauty of the regular Uno, Mega, ... is that the Serial is provided by an external chip.    And is 100% reliable.    Even if you make a silly programming mistake.

 

32kB works pretty well in a Uno.   Especially since the bootloader is tiny.   You have 31.5kB for your App.

It is very difficult to fit graphics libraries and sketches in a Leonardo.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
I'm still at a loss to understand why a 328 app ported to 32U4 should use very much more RAM or flash than the 328 version??
He is using Arduino, and the Arduino framework does some things "on its own". In case of a board with USB support it apparently initializes USB to offer that as a serial connection to the application. 

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
If you are creating your own pcbs it would seem wiser to choose 644P, 1284P with a similar footprint.
or a mega32U4 with the HalfKay bootloader (USB HID)

PJRC Store - Pre-programmed ATMEGA32U4 Chip for DIY Teensy Projects

 

"Dare to be naïve." - Buckminster Fuller

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It is only if you set the ALLOC bit in the UECFG1X register that the USB might start to allocate 128/256/512 byte blocks of endpoint memory.

So the "too big" SRAM that it showed is only too big if the USB writes it? So i can just ignore this?

 

I simply don't believe that - what evidence do you have to support that assertion? 

 

My evidence is the output that showed me those values.

Yes i use Google, but there is no search enginge within Google to search through those many useless results...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am using Eclipse with with arduino librarys. I guess its the same as using Arduino IDE?

Of course the bootloader is already removed.

So the only way for me is then a custom boards.txt ? If anyone has some good links about it, i would much appreciate it.

Yes i use Google, but there is no search enginge within Google to search through those many useless results...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry but I missed the point that this was Arduino. I thought you were just switching from a plain 328 to a plain 32U4. If it's Arduino then the reason they made Arduinos with 32U4 was to reduce the part count and cost. With a 328 based Arduino there is the AVR (almost complete to use apart from a small UART bootloader at the top of the flash) and there is a separate UART to USB converter chip. For 32U4 based Arduino they used the USB function within the 32U4 itself to do the job of the previously external converter chip (that is to set up a USB-CDC serial link). This makes the 32U4 based Arudino cheaper to produce but it's at the cost that the USB is enabled and using some of the chip resources all the time.

 

If you really need more RAM you'd be better off looking at a 1284 based Arduino (which also happens to have an external USB chip too). In that you will get to play with almost the entire 16K of SRAM.

 

The 1284 is not a "standard" Arduino chip of course so you will need to add an additional "core" to your Arduino installation to support it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Tobey wrote:

I am using Eclipse with with arduino librarys. I guess its the same as using Arduino IDE?

 

When you say 'Arduino libraries' what do you mean? Do you simply mean pre-written Arduino .c and .h files?

 

If so, I don't see how any of the USB functionality is being carried into your code so the full 2.5k of RAM ought to be available.

What we haven't seen is any code. Can you post the .lss file?

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The regular Arduino main.cpp is:

#include <Arduino.h>

// Declared weak in Arduino.h to allow user redefinitions.
int atexit(void (* /*func*/ )()) { return 0; }

// Weak empty variant initialization function.
// May be redefined by variant files.
void initVariant() __attribute__((weak));
void initVariant() { }

void setupUSB() __attribute__((weak));
void setupUSB() { }

int main(void)
{
	init();

	initVariant();

#if defined(USBCON)
	USBDevice.attach();
#endif

	setup();

	for (;;) {
		loop();
		if (serialEventRun) serialEventRun();
	}

	return 0;
}

If your custom target does not define USBCON and does not ever serialEventRun it will not need to pull in the USB and Serial code.

 

God invented the Arduino.   It seems crazy to abandon the Arduino IDE.    Even more crazy to choose Eclipse.

 

Yes,  of course it can be done.  But you must be prepared to do a lot of stuff yourself.   There is lots of information and advice concerning custom boards and custom Cores.    You will still need to be wary of third party libraries.    They might assume "standard" Arduino boards.

If this is above your "pay grade",   you should be realistic.     Many people have experience of customising Arduino and the IDE.     Few people would complicate further with Eclipse.

 

There is a 1284P core from MightyCore.   As far as I know it is fairly robust.    Why not install MightyCore in the regular Arduino IDE and get on with your project?

 

David.

Last Edited: Wed. Jan 16, 2019 - 09:50 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I can not use a 1284 because it should have a ProMini pinout.

 

But i have considered to spend more time with implemnenting a 1284. What has to be added in the core? I wonder if i am able to achieve this! Im somewhere between a Arduino IDE and a AS7 user. The only things i use from Arduino is Serial and delay(); micros(); and librarys for Display/sdcard etc.

Yes i use Google, but there is no search enginge within Google to search through those many useless results...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I include "arduino.h".

 

I just remembered, that i edited the Mini file already, so dont get confused

 

See attached the lss files (as .log named)

 

 

Device: atmega32u4

Program:   35196 bytes (107.4% Full)
(.text + .data + .bootloader)

Data:       2049 bytes (80.0% Full)
(.data + .bss + .noinit)

 

 

 

Device: atmega328p

Program:   30998 bytes (94.6% Full)
(.text + .data + .bootloader)

Data:       1843 bytes (90.0% Full)
(.data + .bss + .noinit)

 

 

UPDATE:

MIC_tests was not up to date

Attachment(s): 

Yes i use Google, but there is no search enginge within Google to search through those many useless results...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Tobey wrote:

...The only things i use from Arduino is Serial...

 

Aha, because the 32U4 talks directly to the PC and not, in the case of a 328, via another chip which deals with the serial to USB conversion, when you use Serial then you call in a whole load of USB code. Hence your growth in size.

 

 

[E2A]

 

The code grows by 4k with a small increase in RAM usage.

 

So, ironically, by swapping chips to one with more RAM you have grown your code usage by over 12%. And your RAM usage by over 200 bytes which wipes out nearly half of the extra RAM you gained by swapping.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

Last Edited: Wed. Jan 16, 2019 - 11:10 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I also see that your code uses malloc() and friends, plus a lot of floating point.

 

 

Does the end application need Serial? If not then I'd use a normal serial port, with a USB-serial adaptor, for debugging and stick with the 32U4.

 

If you need Serial then go back to the 328 and look at reducing memory usage by optimising your code.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

Last Edited: Wed. Jan 16, 2019 - 11:12 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes i have a few floatys, but after i converted a lot of them to int. I' ll have a look at the serial.

Yes i use Google, but there is no search enginge within Google to search through those many useless results...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Tobey wrote:
Yes i have a few floatys, but after i converted a lot of them to int.
You only need one float operation (*/+-) to pull in the floating point library so it's all or nothing. Once you have "paid the price" once for one op the increment on subsequent float use is not that large in fact.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Tobey wrote:

Yes i have a few floatys, but after i converted a lot of them to int.

 

It looks like you have quite a few place where you are using 32-bit values. Do you need so much precision?

 

</p>
<p>    568c:    0e 94 8e 1a     call    0x351c    ; 0x351c <millis><br />
    5690:    c0 90 c9 06     lds    r12, 0x06C9    ; 0x8006c9 <lastButton2Pressed><br />
    5694:    d0 90 ca 06     lds    r13, 0x06CA    ; 0x8006ca <lastButton2Pressed+0x1><br />
    5698:    e0 90 cb 06     lds    r14, 0x06CB    ; 0x8006cb <lastButton2Pressed+0x2><br />
    569c:    f0 90 cc 06     lds    r15, 0x06CC    ; 0x8006cc <lastButton2Pressed+0x3></p>
<p>

 

If you could get away with 16-bit values you'd save around 240 bytes of code! (30 calls to millis x 2 'lds' instructions per return value @ 4 bytes)

 

It soon adds up.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

Last Edited: Wed. Jan 16, 2019 - 03:36 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When i use pow, does it use float (double) and then use the libraray anyway?

 

I am comparing timestamps for button actions (different functions of the same button). I cant imagine how i can use them with unsigned int because that overflow may bring problems with it.

Yes i use Google, but there is no search enginge within Google to search through those many useless results...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes,  pow() is a f-p function.   Why do you want to use pow()?

 

If you just want to address a bit in a variable,   it is much easier to do with bit-shifts.

You can reduce your memory usage by choosing the appropriate variable type.   e.g. uint8_t for expressions that are in the range of 0 - 255.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have to calculate a mathmatical equation that involves pow().

 

I have already changed a lot of variables.

 

I made a size test:

I had a function that was called 2 times, that took a float. I made a global variable and removed the parameter from the function. I thought if there was no parameter to copy, then it would be less code. Wrong: The code increased by 36 bytes...

Yes i use Google, but there is no search enginge within Google to search through those many useless results...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Tobey wrote:
I have to calculate a mathmatical equation that involves pow().

Show us.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

return (int) (100 / (S1_A_1 + S1_B_1*log(RntcDiv4/S1_R_REF_DIV4) + S1_C_1*pow(log(RntcDiv4/S1_R_REF_DIV4),2) + S1_D_1*pow(log(RntcDiv4/S1_R_REF_DIV4), 3) ));

Yes i use Google, but there is no search enginge within Google to search through those many useless results...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

By convention things like S1_A_1 would be constants: are they? If they are what are they defined as?

What size are your variables?

What range can they take? What precision do they need?

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That looks suspiciously like the canonical Steinhart-Hart thermistor equation below. If so, this is a candidate for simplification which can remove need for the pow() function.

 

Thermistor resistance is  related to temperature in degrees Kelvin by the following formula:

1/T= A + B*ln(R/Rt) + C*ln(R/Rt)2 + D*ln(R/Rt)3

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes.  you will have to use f-p in your project.    pow() seems unnecessary

float x = log(RntcDiv4/S1_R_REF_DIV4);
return (int) (100.0 / (S1_A_1 + S1_B_1*x + S1_C_1*x*x + S1_D_1*x*x*x));

I suspect that there might be some short cuts in precision that can be made.    After all you are only looking for an integer result.

 

I have not looked.    The Optimiser might improve the obvious simplification that I made.   i.e. it might have removed pow() anyway.

The most important lesson is that simpler expressions are easier to read.

 

I fully understand that Leonardo has a lot of "overhead" code.

Most apps can survive with 28k of application Flash.   It is things like Fonts and Images that eat up Flash memory.     Ok,  f-p maths might cost you 4kB but it is a one-off that makes your app easier to maintain.

 

David.

Last Edited: Fri. Jan 18, 2019 - 08:59 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So you're casting the result of your fancy F-P expression to int?  And the only variable is RntcDiv4?  Let me guess, it's a captured quantity from the ADC?  Surely a lookup table is a better choice.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Fri. Jan 18, 2019 - 12:49 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I thought that i would get answers here, but there are quite a lot of questions ;-).

 

Yes S1_A_1 is a constant. (#define S1_A_1 0.003354016)

 

This is the full function:

int getTempX100(int RntcDiv4){
    return (int) (100 / (S1_A_1 + S1_B_1*log(RntcDiv4/S1_R_REF_DIV4) + S1_C_1*pow(log(RntcDiv4/S1_R_REF_DIV4),2) + S1_D_1*pow(log(RntcDiv4/S1_R_REF_DIV4), 3) ));
}

 

It needs values from -20.0°C to 45.0°C or with int 2000 to 4500.

Yes i use Google, but there is no search enginge within Google to search through those many useless results...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:

Yes.  you will have to use f-p in your project.    pow() seems unnecessary

float x = log(RntcDiv4/S1_R_REF_DIV4);
return (int) (100.0 / (S1_A_1 + S1_B_1*x + S1_C_1*x*x + S1_D_1*x*x*x));

I suspect that there might be some short cuts in precision that can be made.    After all you are only looking for an integer result.

 

I have not looked.    The Optimiser might improve the obvious simplification that I made.   i.e. it might have removed pow() anyway.

The most important lesson is that simpler expressions are easier to read.

 

I fully understand that Leonardo has a lot of "overhead" code.

Most apps can survive with 28k of application Flash.   It is things like Fonts and Images that eat up Flash memory.     Ok,  f-p maths might cost you 4kB but it is a one-off that makes your app easier to maintain.

 

David.

I can not tolerate cuts in precision, because this is what i need. Its not just a weatherstation. Im measruing air masses temperature in flight.

 

Yes i have some fonts. Big numbers and small text and numbers.

 

Yes i use Google, but there is no search enginge within Google to search through those many useless results...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:

So you're casting the result of your fancy F-P expression to int?  And the only variable is RntcDiv4?  Let me guess, it's a captured quantity from the ADC?  Surely a lookup table is a better choice.

Yes, but i take 2 digits precision with it. Pow takes float and gives float.

 

Yes i use Google, but there is no search enginge within Google to search through those many useless results...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Tobey wrote:

Pow takes float and gives float.

 

Internally, the pow() function probably uses logarithms.

Since you are just squaring and cubing, a simple multiply

(or two) will be a lot faster and use less space.

 

--Mike

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Tobey wrote:

It needs values from -20.0°C to 45.0°C or with int 2000 to 4500.

 

So 250 different input values which return a 16-bit output value. That's a 500 byte lookup table which is a lot less flash than using the FP libraries.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I had another pow in my code:

float getHeight(float p){
    return (1 - pow(p/p0, 1/T_B))*T0x100/T_A_x100 + REFERENCE_ALTITUDE_H0;
}

T_B is 5.255

Yes i use Google, but there is no search enginge within Google to search through those many useless results...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Don't dismiss overlook a lookup table. {Sorry I couldn't help it}

 

Case in point: I use a precision 0.2°C accuracy 10K @ 25°C thermistor and a lookup table to convert resistance to temperature. Over your range -20 to +45°C   I need just 27 pairs of 16-bit integers to achieve within ±0.033°C conversion error.

 

{Edit: Your post #49 beat mine. Can you find what code sizes we are looking at for log() and pow() ? The MAP file should show this info.}

{Edit2: Doesn't your barometer chip have the capability to perform the height calculation ? }

 

Last Edited: Fri. Jan 18, 2019 - 09:05 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Now i want to come back to the topic. I appresciate the help you give me.

 

I now made a little modicication, so that USBCON does not get defined.

Now i took empty projects for ProMini and ProMicro ( with and without USBCON) to compare:

 

Device: atmega32u4
Program:    6638 bytes (20.3% Full)
Data:        552 bytes (21.6% Full)

Device: atmega32u4 (no USBCON defined)
Program:    3524 bytes (10.8% Full)
Data:        413 bytes (16.1% Full)

 

Device: atmega328p
Program:    2876 bytes (8.8% Full)
Data:        415 bytes (20.3% Full)

 

Now it looks very good for the SRAM. Better for the FLASH, but still much more than the ProMini needs.

Is there an easy way to tell what the difference in funtion use is?

 

Yes i use Google, but there is no search enginge within Google to search through those many useless results...

Pages