[SOLVED] Odd failure in initialising SSD1306 display when code present in loop()

Background: I have a pretty basic project that is a fork of another project based on the LeonardoCAN board from Hobbytronics. That project uses the MCP2515 chip onboard to the LeonardoCAN, and an SSD1306 OLED display driven over SW or HW SPI (D10-13).

Im converting this to use the same MCP2515 CAN chip but offboard via SPI (D10-13), and an SSD1306 OLED display driven by I2C (A4&5)

Hardware: Arduino Uno, MCP2515 CAN chip w TJA1050 interface (D10-13), SSD1306 128x64 OLED display (A4&5)

Problem: This is where it gets strange, i can initialise everything just fine except when it comes to filtering the CAN input using init_Filt from mcp_can.h (Seeduino shield library). However, the means of failure is super odd. If it was an issue with the filtering function I would expect it to fail in the loop() section of code. But whenever the init_Filt function is present within the codebase it fails in setup() with the display.begin() function [line 82], and never gets to executing the offending init_Filt() [line 184]. This is super odd, because logically the call to init_Filt() should only occur after the display has been initialised on line 82 with display.begin().

I have already tried trimming down the code base to just the SSD1306 and MCP2515 relevant sections in case it was a memory error, but to no avail. Both the MCP2515 and SSD1306 example code run flawlessly.

Im a bit stumped (could be because im groggy with cold and flu tabs), but I cant think of why adding a function into another portion of the codebase causes a failure in setup(). Unless the micro is simply running out of SRAM when it is allocating the memory for display.begin()

Code is available here: EliteGaugeDiscrete/Elite_Gauge_Pro.ino at master · porterble/EliteGaugeDiscrete · GitHub

Help?

SOLVED: Malloc issue, see post #4

How about posting the trimmed down code and the actual error message?

A couple of things

  1. An Uno does NOT have pin23 (line #8) so maybe make it pin 13
  2. The CAN board defaults to C/S on pin #9 but you have it set to pin #10. Did you change the jumpers on the back of the board as described here
  3. That function you are having trouble with returns a value to indicate success/failure. You might want to capture it and display it?

evanmars:
How about posting the trimmed down code and the actual error message?

That is the trimmed down code, any further trimming allows the code to work. Hence why im thinking its a memory allocation issue.

There is also no error message, display.begin() only returns T/F, which is captured at line 82.

blh64:
A couple of things

  1. An Uno does NOT have pin23 (line #8) so maybe make it pin 13
  2. The CAN board defaults to C/S on pin #9 but you have it set to pin #10. Did you change the jumpers on the back of the board as described here
  3. That function you are having trouble with returns a value to indicate success/failure. You might want to capture it and display it?
  1. Yep, im not referencing the LED currently, that was just a leftover from trying to get it to work on a Leonardo which was having USB reset issues.
  2. Its not a CAN shield, its a secondary CAN module. However it doesnt change whether its on pin 9 or 10.
  3. Which function? Im already capturing the failure at line 82 for display.begin(), which means it never gets to init_Filt(). Capturing init_Filt() it will do nothing, it never gets executed.

To wrap this up, it was a memory allocation issue.

I ran the code through the gcc memory analyser, and a few placed freeMemory() routines and found that display.begin() was trying to allocate 1.1kb of SRAM for the display buffer. On the Atmega 328P this wasnt possible with only 2kb of SRAM, but on the 32U4 that the Leonardo uses the 2.5kb of SRAM is sufficient to find enough contiguous memory to allocate.

In the end it came back to my most hated of issues with microcontrollers... malloc()