Hello everyone. Hope someone experienced could help me to resolve this.
I'm building a simple device using SIM800L (D2,D3) > Arduino Nano and and an OLED display 128x64 via IIC.
All works fine when I'm testing the SIM800> Arduino or Display> Arduino. But when I try using them all together then Arduino restarts itself constantly.
I'm using SoftwareSerial.h to interface with the SIM800L and it works fine.
For the OLED i'm using Adafruit_GFX.h and Adafruit_SSD1306.h libraries.
In Setup I do display.begin first and then SIM800.begin(9600)
If I try to use an AT command to SIM800 like SIM800.println("ATE0"); the display stop working. Actually the whole sketch stops working.
Banging my head in the wall for 2 days with no result.
Couldn't find any similar problem in google or here in the forum (maybe didn't search hard enough).
First off. Click the "build icon".
Then look at the build report. e.g. (this is just a random sketch for a Uno)
Sketch uses 28448 bytes (88%) of program storage space. Maximum is 32256 bytes.
Global variables use 1073 bytes (52%) of dynamic memory, leaving 975 bytes for local variables. Maximum is 2048 bytes.
Note that it says 975 bytes of SRAM are available. i.e. it looks good.
Adafruit_SSD1306 would attempt to allocate 1024 bytes at runtime. And it would FAIL.
If Global was 975 and local was 1073, the build still looks good.
Adafruit_SSD1306 would attempt to allocate 1024 bytes at runtime. And it would SUCCEED.
However you would only have 49 bytes left. Your program might run for a few seconds. But it will almost certainly crash.
If you want help with your sketch, paste or attach it to your message.
It is easier to show by example than to offer general advice.
Thanks. It makes more sense.
Here is the Build and the code (attached). Just wanted it to get SMS and print on the OLED. Didnt realise that it's such a hassle
Sketch uses 19276 bytes (62%) of program storage space. Maximum is 30720 bytes.
Global variables use 966 bytes (47%) of dynamic memory, leaving 1082 bytes for local variables. Maximum is 2048 bytes.
I just did ctrl-T to format the code.
Then search for print(" and change it to print(F("
Then search for println(" and change it to println(F(" Then search for ") and change it to "))
Then search for "); and change it to "));
Untested. Please just try it.
#include <SoftwareSerial.h>
#include <Adafruit_GFX.h> // OLED display
#include <Adafruit_SSD1306.h> // OLED display
#include <DS3231.h> // Clock
SoftwareSerial SIM800(2, 3); // 3 - RX Arduino (TX SIM800L), 2 - TX Arduino (RX SIM800L)
DS3231 clock;
RTCDateTime dt;
Adafruit_SSD1306 display(-1); //-1 if sharing Arduino reset pin with OLED reset
String intDateTime;
String Operator;
String GSMquality;
String IMEI;
boolean ATresult;
String PhoneNumber;
String CallerID;
String SMSbody;
String GSMeventDateTime;
//***************************************************************************
//***************************************************************************
void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
delay(100);
Serial.begin(9600);
Serial.println(F("Start Setup"));
clock.begin();
Serial.println(F("Modules Begin Complete"));
delay(1000);
// Set sketch compiling time taken from the Computer during compiling
//clock.setDateTime(__DATE__, __TIME__);
display.display(); // Display splash screen
delay(3000);
Serial.println(F("Display Splash"));
display.clearDisplay(); // Clear the display buffer.
Serial.println(F("Display splash screen done"));
// Display Device Info
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(12, 16);
display.println(F("GSM Controller"));
display.setCursor(22, 32);
display.println(F("Module"));
display.setCursor(29, 48);
display.println(F("V 1.0"));
display.display();
delay(3000);
display.clearDisplay();
display.display();
// SIM800L Initialise
SIM800.begin(9600);
delay(100);
SIM800.println(F("AT"));
delay(50);
SIM800.println(F("ATE0")); // Echo OFF
delay(50);
SIM800.println(F("AT+CMGF=1")); // Switch to SMS text format
delay(50);
Serial.println(F("End Setup"));
}// SETUP END
//***************************************************************************
//***************************************************************************
void loop() {
String SIMtext;
String prevSIMtext;
if (SIM800.available() > 0) {
SIMtext = SIM800.readString();
Serial.println(SIMtext);
}
if (Serial.available() > 0) {
SIM800.write(Serial.read());
}
if (SIMtext != prevSIMtext) {
ATmanager(SIMtext);
prevSIMtext = SIMtext;
}
} // LOOP END
//***************************************************************************
//***************************************************************************
// FUNCTIONS
void ATmanager(String incText) {
String ATmessage;
String ATcode;
int GSMq;
int x;
int y;
ATcode = incText.substring(2, 8);
ATcode.trim();
Serial.print(F("AT code is:")); Serial.println(ATcode);
if (ATcode == "+CSQ:") { // Signal Quality
x = incText.indexOf(":"); y = incText.indexOf(",");
GSMquality = incText.substring(x + 1, y);
GSMquality.trim();
GSMq = GSMquality.toInt();
//Serial.println(GSMq);
if (GSMq >= 0 && GSMq <= 9) {
GSMquality = "WEAK"; goto Z20;
}
if (GSMq >= 10 && GSMq <= 14 ) {
GSMquality = "FAIR"; goto Z20;
}
if (GSMq >= 15 && GSMq <= 19) {
GSMquality = "GOOD"; goto Z20;
}
if (GSMq >= 20 && GSMq <= 30) {
GSMquality = "BEST"; goto Z20;
}
if (GSMq = 99) {
GSMquality = "NONE";
}
Z20: Serial.print(F("GSM Quality: ")); Serial.println(GSMquality);
}// END OF CSQ
if (ATcode == "+COPS:") { // SIM Operator
x = incText.indexOf((char)34);
y = incText.indexOf((char)34, x + 1);
Operator = incText.substring(x + 1, y);
Serial.print(F("SIM Operator: ")); Serial.println(Operator);
}// END OF Operator
if (incText.substring(2, 3) != "+") { // IMEI
x = incText.indexOf("OK");
IMEI = incText.substring(2, x);
IMEI.trim();
Serial.print(F("IMEI: ")); Serial.println(IMEI);
}// END OF IMEI
if (ATcode == "+CMT:") { // SMS READING
x = incText.indexOf((char)34);
y = incText.indexOf((char)34, x + 1);
PhoneNumber = incText.substring(x + 1, y);
x = incText.indexOf((char)34, y + 1);
y = incText.indexOf((char)34, x + 1);
CallerID = incText.substring(x + 1, y);
x = incText.indexOf((char)34, y + 1);
y = incText.indexOf((char)34, x + 1);
GSMeventDateTime = incText.substring(x + 1, y);
SMSbody = incText.substring(y + 2, y + 128);
SMSbody.trim();
Serial.print(F("Number: ")); Serial.println(PhoneNumber);
Serial.print(F("CallerID: ")); Serial.println(CallerID);
Serial.print(F("DateTime: ")); Serial.println(GSMeventDateTime);
Serial.print(F("Message: ")); Serial.println(SMSbody);
// //OLED display
display.clearDisplay();
display.setTextSize(1);
display.print(F("Number: ")); display.println(PhoneNumber);
display.print(F("CallerID: ")); display.println(CallerID);
display.print(F("DateTime: ")); display.println(GSMeventDateTime);
display.print(F("Message: ")); display.println(SMSbody);
display.display();
} // END OF SMS READING
}// END OF ATmanager
//*********************************************************************
String getDateTimeValue() //getDateTimeValue();
{
dt = clock.getDateTime();
String YY, MO, DD, HH, MM, SS;
YY = String(dt.year);
MO = String(dt.month);
if (dt.month < 10) {
MO = "0" + MO;
}
DD = String(dt.day);
if (dt.day < 10) {
DD = "0" + DD;
}
HH = String(dt.hour);
if (dt.hour < 10) {
HH = "0" + HH;
}
MM = String(dt.minute);
if (dt.minute < 10) {
MM = "0" + MM;
}
SS = String(dt.second);
if (dt.second < 10) {
SS = "0" + SS;
}
String intDT = YY + "-" + MO + "-" + DD + " " + HH + ":" + MM + ":" + SS;
return intDT;
}
Please report back with your Memory Usage lines.
David.
Edit. Used a better search for the ") in a print statement. But I then had to manually search for ")); to check for any non-print changes. e.g. incText.indexOf(":");
Sketch uses 19412 bytes (63%) of program storage space. Maximum is 30720 bytes.
Global variables use 744 bytes (36%) of dynamic memory, leaving 1304 bytes for local variables. Maximum is 2048 bytes.
and goes through setup step ok. However in the main part it doesn't properly work. I have a same set of code but without anything related to the display and it works well and I can see it in the serial monitor.
Thinking of using a different OLED library than Adafruit where it doesn't use so much of SRAM. Maybe you have any idea which one would be the best in this case?
david_prentice:
1304 bytes is a lot healthier. 1304 - 1024 = 280 bytes. I would stick with Adafruit.
My "editing" was very cursory. As a general rule, print("message") can safely be put into Flash memory e.g. print(F("message"))
Only you know how your program should behave. So look at the problem area. e.g. what was the last good message. then trace execution from there.
David.
Yes I forgot to mention, I noticed you haven't changed all of the print( to print(F, When I changed all of the print( and println( to (F the code couldn't compile and returned:
exit status 1
Error compiling for board Arduino Nano.
...C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.29.0_x86__mdqgnx93n4wtt\hardware\arduino\avr\cores\arduino/WString.h:38:74: error: array must be initialized with a brace-enclosed initializer
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
C:\Users\asadi1\OneDrive - BP\Documents\Arduino\SIM800L_Beginning_4_Afrt_OLED_Updated_by_David\SIM800L_Beginning_4_Afrt_OLED_Updated_by_David.ino:101:52: note: in expansion of macro 'F'
Serial.print("SIM Operator: "); just sends a literal text string.
Serial.println(Operator); sends the value of the variable called Operator.
It is a feature of GCC that it puts "anonymous strings" into SRAM. And prints from SRAM.
Since the strings are anonymous, you can't access them from another part of the program. You certainly can't modify them.
It is sensible to store these "anonymous strings" in PROGMEM. Which is what the F() macro does.
Other compilers are wiser. They recognise that this data is anonymous. And store in Flash automatically.
It is a bit painful to wrap "messages" with F() but it does stop wasteful use of SRAM.
In your case, it should mean that everything works 100%.
I am impressed by your use of the String class methods. They make my head hurt. And you should be careful that you don't concatenate into monster strings.
Google for "anonymous string". I bet there is a good Wikipedia article.
David.
p.s. I would expect the new sketch pasted into #5 will build and run.
If you have errors or Warnings, paste offending lines. Or attach the whole build report.
Hi @david_prentice,
Sorry for not replying for so long. I was busy testing and trying all other OLED libraries available in the manager to find the one that is not as heavy as Adafruits. I found ssOLED library working great for me in this design. It is very simple and doesn't create any buffer (unless you need). It took some time to understand how it works, but it paid back.
Thank you very much for your time, I learned a lot.