Sketch working on a Micro doesn't work on an Uno?

Hi guys!
I have a school gardening project where I make an indoor grow box which can switch between growing mushrooms to growing greens.
It uses an DS3231 RTC to keep time, and a SSD1306 OLED display to show information on a screen. It uses a DHT11 sensor to read humidity and temperature. It uses a humidifier for relative air humidity for mushrooms and to fog nutrients on the roots of growing greens, and a fan for ventilating out too hot or too humid air.
This works great on my Micro but takes up all of the available program storage, and I want to add more code so I'd like to switch to an Arduino Uno instead.
But, strangely, the code that works so well on my Micro doesn't work at all on my Uno (I have tried several Uno's to be sure it wasn't broken). It complains about not being able to find the display, and if I remove most of the program then usually it complains about not being able to find the RTC. If most of the code is gone then it finds the RTC and OLED and print out some information about time on the screen.
I can't really find a reason for the problems in the code and the hardware setup works well on the Micro. I have double and triple checked all pins to make sure I still use the correnct pins on the Uno.
I could really use some ideas on what could cause this cause I've tried all I can think of..
I'm using these libraries:

#include <DHT.h>
#include <TimeLib.h>
#include <RTClib.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeMono9pt7b.h>

Question: How much more program space does the Uno have compared to the Micro?

The Arduino Micro uses the atmega32u4, which has 32K program memory and 2.5K ram. The UNO has the same 32K program memory but less ram at 2K.

The Adafruit_SSD1306 library will need 1K of ram for a display buffer, which is not shown in the dynamic memory usage reported by the compiler. You can save a bit of program memory by disabling the Adafruit splash image in the Adafruit_SSD1306.h file:

 34 
 35 // Uncomment to disable Adafruit splash logo
 36 //#define SSD1306_NO_SPLASH
 37 

This neat little hack freed up 5% of program space :slight_smile: Thanks!

You can save a bit of program memory by disabling the Adafruit splash image in the Adafruit_SSD1306.h file

The UNO has the same 32K program memory but less ram at 2K

How can I see how much RAM the program uses when running?

If you will post your code, there may be other optimizations to be done.

3584 bytes after the bootloaders have taken their shares.

1 Like

If you will post your code, there may be other optimizations to be done.

It's over 600 lines. Not sure everyone would appreciate such a long post :slight_smile: Or is it possible to post and see it truncated?

I had neglected the difference in the size of the bootloader, so the UNO does have more available program memory.

From your first post, it appears you know how to post code, so just post the entire code the same way. The forum will display the code in a box that is much smaller than the full 600 line length.

Brace yourselves, here comes the full program :face_with_peeking_eye:

#include <DHT.h>
#include <TimeLib.h>
#include <RTClib.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeMono9pt7b.h>
#define pump_pin 4 // Output pin for water pump
#define oxygen_pin 5 // Output pin for oxygenating water/nutrient solution
#define fan_pin 13 // Output pin for the fan when not using PWM and using relay instead
#define DHT11Pin 9
#define mode1_pin 7 // Input pin for selecting mushroom growing
#define mode2_pin 8 // Input pin for selecting vegetable growing 
#define mushlight_pin 10 // Output pin for the ambient mushroom lighting
#define growlight_pin 11 // Output pin for supplemental vegetable grow lighting
#define moist_pin 12 // Output pin for the humidifieri
#define DHTType DHT11
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

#define pwm_pin 6 // PWM output pin for fan speed control

Looks like there's scope for more F() macro use

1 Like

You really need to read the forum guidelines. It's all explained somewhere there.

Won't help much, he made it clear from post #1 that he's short on code space AND ram. Though sure, keeping it out of RAM will help. I've never looked at whether there's a code penalty for F, or just a speed penalty. Do you know?

Why use a float values to store a bool? Save some space.

Also one might consider using all ints for the humi and temp reading. When display them convert them to a decimal value just for display purposes, when trying to free up some ram.

Usually, I find that if I'm trawling through code, some factoring comes automagically.
Also, in setup, zeroing globals that are already zero is a waste of time and space.

1 Like

Not a lot that can be done to reduce the size.

Since you are only using one font, and always the same color and size, you can set the font, text size, and text color in setup and not repeat it multiple times in the code.

You have identical code to print the current humidity in several places, moving that to a function will slightly reduce the code size, and make it easier to use the F() macro for the text. The same applies for printing the temperature.

The F() macro works when printing to the display, you might be able to save enough ram to get the code to fit on an UNO/Nano.

Be careful with the F() macro, the compiler normally recognizes identical text literals and consolidates them into a single copy in memory, unfortunately it does not do that when using the F() macro, so you can end up using additional program memory with redundant copies of identical text.

There are other display libraries that can reduce or eliminate the display buffer, which saves considerable ram. It does not appear you are doing any graphics on the display, other than some circles for the % and degree symbol, so a text-only display library may help considerably.

Yep, reducing your variable sizes will help a bit.
For another thing, I'd look at parallellisms between the two modes, seeking out duplication of code and data that could be removed. But that requires in-depth knowledge of your process. It might be that pulling your config from EEPROM would help, because you'd only have half as much 'stuff' to manage; that works better when there are three or more similar requirements. I had hoped to see, in your code, larger data structures that could be slimmed.

Other than that, though, your probably faced with conversion to a State Machine implementation to reduce the if-then-else hierarchy. That will entail a rethink along some pretty fundamental lines, though, so it's not an overnighter for someone not versed in that. Poorly done, though, it'll likely consume more space, so there's that.
The OLED library I'm using had several embedded fonts. I started out using three, but switching to one saved me a lot of memory.

Good suggestions, thank you!
This is my first Arduino sketch and I'm new to the coding language so it's a learning process :slight_smile:
Do you guys think the problem it won't run on the Uno is because of RAM?