Just looking for suggestions - Lowest memory library options for the situation below.
Am a teacher out of industry (metallurgy/process control) making a high school project that needs multiple sensors to teach the basics of interfacing and autonomous control.
Basically, it's a souped up version of the obstacle avoiding robot. Laser cut layout below.
(light chasing, obstacle avoiding, temperature and pressure measuring robot.)
Running:
I2C BMP280
LCD SSD1306 (SPI)
TB6612 or L298 H Bridge (unsure)
Servo
PS2 controller
2 x LDR's
I have each bit working separately.
Looking to minimise library needs just to get this running at a basic level without running out of memory. No fancy library tweaks needed, just the basics.
Can anybody recommend the lightest library for
the BMP280 chip?
The LCD SSD1306 (128 x 64 pixel - monochrome)
and the servo.
that might get me out of trouble.
Haven't programmed it yet, but I can see the brick wall coming and am trying to avoid it.
plan B is multiple programs, but I'd rather have plan A with all on the chip at once.
Does anyone have experience with the lightest memory usage libraries for these sensors?
You don't say what you want to use the OLED for. If it is text, you can save a bit by using Adafruit's text libraries. Why a Nano anyway? A Pro Mega is much the same size, should kill any memory problem stone dead, and it seems that you have its power supply already.
Nick ->making 20 of them... Nanos are $3- each. Megas are about $18
OLED - going to display distance when close to an object for faultfinding and info, or temperature/pressure. Text, so I'll look into the Adafruit library.
Tom -> I can see I'll be very close to full memory, especially with the long divisions needed to make the distance calcs. Asking for input to find the library with the smallest footprint up-front to maximise the chance of success.
Will let you know how I go, but the libraries need a bit of memory. I don't need bells and whistles, just the basics. Any ideas on memories that are light on memory usage?
Read the information on the display libraries carefully, there is often a text-only mode that does not need a memory buffer.
If possible, avoid using floating point numbers in the calculations. If you handle decimal places yourself its often possible to use only integer math.
Andrew_F_In_Australia:
Tom -> I can see I'll be very close to full memory, especially with the long divisions needed to make the distance calcs. Asking for input to find the library with the smallest footprint up-front to maximise the chance of success.
What library are you using for the ultrasonic, look for NEWPING library, it does it all for you.
Tom...
Well my suggestion would be if at the beginning of the project you are already out of or very tight on memory, you really really ought to consider a board that has more memory.
For sure not long after you roll the boards out someone will say "can I add.................."
What I would probably do is lay the main board out so that say a UNO (or Nano) plugs in underneath and that you leave room to plug in a Mega, at least you then have the option.
And if you want to use all 3.3V with more speed etc, use a DUE.
I've found that we don't need newping, as I found an error in the basic ping sketch on the arduino IDE. Fixing this gives accurate and repeatable measurements without a library in my experience.
Will check it out anyway as it may reduce memory needs
The fix for the IDE default is:
The datasheet says to have a minimum 10 μs trigger time on the trigger pin to start measurement - the ping sketch on the IDE (for a 3 pin sensor) has 5.
Changing this to 12 μs gives repeatable measurements in my experience.
Reworked code below
const int trig = 3;
const int echo = 4;
void setup() {
// initialize serial communication:
Serial.begin(9600);
pinMode(echo,INPUT); //not really necessary, but... ...
pinMode(trig,OUTPUT);
}
void loop() {
// establish variables for duration of the ping, and the distance result
// in inches and centimeters:
long duration, inches, cm;
// The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
digitalWrite(trig, LOW);
delayMicroseconds(2);
digitalWrite(trig, HIGH);
// delayMicroseconds(5); //<---- THIS NEEDS TO BE MINIMUM 10 ACCORDING TO DATASHEET
delayMicroseconds(12);
digitalWrite(trig, LOW);
// The same pin is used to read the signal from the PING))): a HIGH pulse
// whose duration is the time (in microseconds) from the sending of the ping
// to the reception of its echo off of an object.
duration = pulseIn(echo, HIGH);
// convert the time into a distance
inches = microsecondsToInches(duration);
cm = microsecondsToCentimeters(duration);
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
delay(100);
}
long microsecondsToInches(long microseconds) {
// According to Parallax's datasheet for the PING))), there are 73.746
// microseconds per inch (i.e. sound travels at 1130 feet per second).
// This gives the distance travelled by the ping, outbound and return,
// so we divide by 2 to get the distance of the obstacle.
// See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
return microseconds / 74 / 2;
}
long microsecondsToCentimeters(long microseconds) {
// The speed of sound is 340 m/s or 29 microseconds per centimeter.
// The ping travels out and back, so to find the distance of the object we
// take half of the distance travelled.
return microseconds / 29 / 2;
}
bmp280_example: 8746 bytes (seeedstudio)
BMx280_I2C: 10828 bytes (2018 Gregor Christandl)
BMP280_DEV.h: 9540 bytes
Adafruit bmp280_sensortest:11930 bytes
I2C-Sensor_Lib iLib i2c_BMP280: 7374 bytes with pressure/height float calculations disabled.
I2C-Sensor_Lib iLib i2c_BMP280: 8606 bytes with pressure/height float calculations enabled.
(the I2C-Sensor library is in the IDE, I think. If not, it's here: GitHub - orgua/iLib: Library for various I2C-Sensors with examples for Arduino )
Are you concerned about program (flash) memory or dynamic (ram) memory? Most questions about memory on the Nano tend to be about lack of ram, but it looks like you are more concerned with program memory.
To do a fair comparison of libraries, you really need to run the same sketch on each library, adapting the sketch to the particular syntax of each library. Example codes are hard to compare because some are much more elaborate than others, have vastly varying amounts of text being displayed, etc. It is also problematic comparing libraries in isolation from the entire sketch, since that can give misleading results (as an example, you tested the I2C-Sensor_Lib library with and without float calculations, but that will make little difference if there is already a float calculation anywhere else in your code).
I have no actual experience with the BMP280 or SSD1306, but if you can run both devices on the SPI bus that would probably save a bit of program memory.
Thanks David - I ran out of pins and am using the MOSI and MISO on the ?memory flash(?) 3x2 pin header arrangement to get it to run.
The I2C as a backup is a plan if I can find a way to squeeze things in. I can see it as being on the limits. I'll make it work today and let you know later.
Concerned with both RAM and flash memories - am funding these myself so trying to avoid a couple of hundred dollars in extra cost in using a mega. Can see it's going to be a challenge but I'll solve it today.
AWOL -> That's the IDE example sketch as provided in the official build, not mine.
Difference is the IDE is the 3 pin sensor, I modified it to 4-pin with a separate trigger and echo. Had a look at the official sketch (examples|06. sensors|ping) and it should also be low. Suggest you let the IDE team know.
As a former senior engineer, I learnt quickly not to assume -> guessing that this pin was driven low to make sure it actually is low before it fires off the signal. I do know reliability increases greatly when you increase the trigger pulse to 12μs from the sketch's 5μs (datasheet said 10μs - I went 20% over to be sure - didn't appear to have any deliterious effects).