Perhaps just a simple stack overflow issue. The amount of static allocation has reached the point where stack collides with it and things get trashed.
The datasheets aren't very clear about the voltage ratings, but from what I have heard, both variants are actually identical. They are only being tested under different conditions.
If all boards fail the same way it is clearly a software bug or a hardware issue (like supply voltage dropping when everything is active at the same time).
Still, my two test boards work perfectly, mega2561-16AU, with 14.7MHz crystals on 3.3V.
The datasheets aren't very clear about the voltage ratings, but from what I have heard, both variants are actually identical. They are only being tested under different conditions.Do you have more info on this?
On the other hand two test boards in the factory, failed in the weird way presented above: they do work, but not when I want to use BME680 code + SDCard code together. When this happens, the LCD will not even show anything, despite the bme/sdcard code being a few lines after, like the code wouldn't run in a linear way.
The same code runs on my two test boards perfectly. I'd say that yes, the hardware difference is a different mega2561-16AU used in the factory.
It almost looks like they designed the chip for 2.7-5.5V but experienced some problems and changed the specifications to 4.5-5.5V.
I would replace the AVR on a non working pcb but change nothing else (make sure to use the same hex file and the same fuse bits).
That is probably the only way to be sure it was a problem with the 2561 instead of 2561V version.
To check for stack overflows, do the following:
At the start of the code, fill the whole RAM after static allocations up to stack start with a known pattern. After a while, print out the ram and you'll see where the pattern is gone. If the pattern is gone, stack has reached that point. If the whole stack space is used up, you'll have a problem. This is easier to do with a debugger, but even with uart debug prints you can do it.
at24c eeprom;
ILI9341 lcd; // LCD
Inverter inverter; // regulated high voltage inverter for the Geiger tube
NMEA nmea;
DS1337 rtc;
SDClass sd; // the sdcard
TouchScreen touch; // touchscreen
ESP8266 wifi; // setup wifi on serial communication
Battery battery; // Battery manager
// define sensors
BME680 bme680; // Bosch BME680
GEIGER geiger; // Geiger LND712 tube
GP2Y1010AU0F pm25; // Sharp Optical PM sensor
void Devices::init() {
lcdReset.init(&PORTA, PA0);
lcdDC.init(&PORTA, PA1);
lcdCS.init(&PORTA, PA2);
lcdBacklight.init(&PORTA, PA3);
sdCS.init(&PORTE, PE3);
touchXP.init(&PORTA, PA4);
touchYN.init(&PORTA, PA5);
touchXN.init(&PORTF, PF6);
touchYP.init(&PORTF, PF7);
pwrUnit.init(&PORTA, PA6);
pwrWLAN.init(&PORTE, PE2);
pwrGPS.init(&PORTG, PG0);
pwrFAN.init(&PORTD, PD6);
pwrSPK.init(&PORTA, PA7);
pwrDustLED.init(&PORTD, PD7);
sdAvailable.init(&PORTE, PE5, DigitalPin::INPUT);
pwrBatteryADC.init(&PORTG, PG2);
pwrInverter5V.init(&PORTC, PC7);
eeprom.init(&i2c);
rtc.init(&i2c);
lcd.init(&lcdDC, &lcdReset, &lcdCS, &lcdBacklight, &spi);
touch.init(&adc, &touchXP, &touchYN, &touchXN, &touchYP);
}
// keep power pin High unless we want to shutdown
pwrUnit = ON;
_delay_ms(500);
pwrGPS = ON;
_delay_ms(500);
pwrWLAN = ON;
_delay_ms(200);
pwrSPK = 1; _delay_ms(1); pwrSPK = 0; // a short start beep
// system config
MCUCR |= (1 << JTD); MCUCR |= (1 << JTD); // disable JTAG so we can use PF4 (UNUSED),PF5 (BAT ADC),PF6 (TOUCH XN ADC),PF7(TOUCH YP ADC) for ADC and GPIO
adc.start(); // start ADC
uart0.start(0, 9600, 1); // connected to the GPS
uart1.start(1, 115200, 1); // used by esp8266 .
EICRB |= (1 << ISC00) | (1 << ISC01); // Configure INT4 to trigger on RISING EDGE
EIMSK |= (1 << INT4); // Configure INT4 to fire interrupts
i2c.init();
rtc.start();
time.init(callback_timeSecond, callback_timeMinute);
spi.startfast();
// start LCD
lcd.start(ILI9341::ROT0, BLACK, ON);
lcd.drawString(buffer, len, 0,0, 20, RED, BLACK, "1 ");
wifi.init(&uart1);
lcd.drawString(buffer, len, 0,0, 20, RED, BLACK, "2 ");
battery.init(&pwrBatteryADC, &adc, BATTERY_ADC); // init battery manager
lcd.drawString(buffer, len, 0,0, 20, RED, BLACK, "3 ");
inverter.start(&adc, INVERTER_ADC); // create Timer T1 PWM to drive inverter for regulated Geiger tube voltage
lcd.drawString(buffer, len, 0,0, 20, RED, BLACK, "4 ");
bme680.start(&i2c); // init Bosch BME680 sensor
lcd.drawString(buffer, len, 0,0, 20, RED, BLACK, "5 ");
pm25.init(&pwrDustLED, &adc, PMSENSOR_ADC); // init PM2.5 Sharp GP2Y1010AU0f sensor
lcd.drawString(buffer, len, 0,0, 20, RED, BLACK, "6 ");
int res1 = sd.begin(&sdCS, &sdAvailable, &spi);
cid_t cid;
int res2 = sd.mkdir("test-dir");
File f = sd.open("test-dir/test.txt", FILE_WRITE);
int res3 = f.write((uint8_t *)"Hello World!\r\n",14);
f.close();
sd.getCard().readCID(&cid);
1. If my code inits the BME680 (over I2c) and tries to write something to the SDCard, the device will NOT start, nothing, not even some innocent code just writing something on the screen.
The I2C lib is just a very basic read / write with no interrupts. When the problem happens, it doesn't even show "1,2,3..." even before getting to the BME680.start line. That's the weird part