Go Down

Topic: arduino crash due to Serial and String... (Read 2343 times) previous topic - next topic

aq_mishu

Dec 16, 2017, 09:48 am Last Edit: Dec 16, 2017, 09:55 am by aq_mishu
Guys,

There is a post i made here: https://forum.arduino.cc/index.php?topic=517314.new#new which is like the same seeemed to me at here: http://forum.arduino.cc/index.php?topic=302843.0

Now, here is my entire code in attachment.


Now, I'm not that good in programming.. but as said symptoms are identical and thus I think it's either a SRAM issue  or something else. Coz  when I keep the serial reading by a terminal, it runs forever nearly... but if not, just powered up and running, then the game starts... hangs after few hours...

Yes!! RAM i haven't found changed but how?? coz i was taking the serial readings via terminal at all...

If it is due to SRAM and Strings... then I need your kind assistance to convert it to c_str()

I'm ore comfortable with String as you have seen in my codes... Thus how can we move forward??


aq_mishu

One note just incase I forgot... The hardware runs well... Ethernet shield and SPI driven and there is not issues  there... confirmed... the ONLY issue is it hangs after some time like the URL I gave, the same symptom. Also, earlier I used a blink LEd type thing for another disco light project (relay driven on/off) and there wa also serial output in code but it was running standalone... So Hope you now understands what I want to point...

Robin2

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. Just use cstrings - char arrays terminated with 0.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

aq_mishu

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. Just use cstrings - char arrays terminated with 0.

...R
Ya I know... that's what I came to know lately.. but as I'm more  of a String guy, I need kind assistance on how to convert them to what you said... I'm not saying rewriting the code for me... just one statement I need from experts as a sample...

In another of my project, I used String and then used
Code: [Select]
String datai2c = "MCS01";
  Wire.beginTransmission(displayI2CID); // transmit to device #8
  Wire.write(datai2c.c_str());    // sends five bytes
  Wire.endTransmission();
  datai2c = "";


for  a i2c transmission. That's where upto my level of skill... But also as I need many
Code: [Select]
str_rx = Serial.readStringUntil("\n"); for the purpose self explanatory, I need a solution alternative of such... Any help???

Robin2

It looks to me like you already have half of your answer in this code
Code: [Select]
String datai2c = "MCS01";
  Wire.beginTransmission(displayI2CID); // transmit to device #8
  Wire.write(datai2c.c_str());    // sends five bytes
  Wire.endTransmission();
  datai2c = "";

I think this will work
Code: [Select]
char datai2c[] = "MCS01";
  Wire.beginTransmission(displayI2CID); // transmit to device #8
  Wire.write(datai2c);
  Wire.endTransmission();
  datai2c[0] = 0;


However I would recommend defining all your cstrings as global (at the top of your program) so you know exactly how much memory they need - especially if you are using a lot of text.

You can also use the F macro to store fixed pieces of text in PROGMEM so that they don't use up SRAM memory.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

aq_mishu

Is it possible to write and make use of something like this?

Code: [Select]
void setup() {
  pinMode(hwSS, OUTPUT);
  pinMode(buzzer, OUTPUT);
  pinMode(readerLED, OUTPUT);
  pinMode(systemLED, OUTPUT);
  pinMode(logicSource, OUTPUT);
  pinMode(debugEnable, INPUT);
  digitalWrite(logicSource, HIGH);
  digitalWrite(buzzer, LOW);
  digitalWrite(readerLED, HIGH);
  digitalWrite(systemLED, HIGH);
  delay(100);
  digitalWrite(buzzer, HIGH);
  rebootTimer = EEPROM.read(REBOOT_OFFSET) * 3600000;
  keepAliveTimer = EEPROM.read(KEEPALIVE_OFFSET) * 60000;

  if(debugEnable == HIGH) {
    #define DEBUG
  }

  #ifdef DEBUG
   #define DEBUG_PRINT(x)     Serial.print (x)
   #define DEBUG_PRINTDEC(x)     Serial.print (x, DEC)
   #define DEBUG_PRINTHEX(x, HEX)  Serial.print (x, HEX)
   #define DEBUG_PRINTLN(x)  Serial.println (x)
  #else
   #define DEBUG_PRINT(x)
   #define DEBUG_PRINTDEC(x)
   #define DEBUG_PRINTHEX(x, HEX)
   #define DEBUG_PRINTLN(x)
  #endif
  
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  splashScreen();
  Serial.println();
  Serial.println(F("Type 'conf t' in 4 seconds to enter config mode\n"));
  smartDelayPrompt(4000);
  //Config the system
  if (str_rx == "conf t") {
    str_rx = "";
    configMode();
  }
  wdt_enable(WDTO_8S);
  wiegandInit();
  Serial.println();
  // start the Ethernet connection:
  if (inetInit()){
    Serial.println(F("Ethernet is up and ready with the config:"));
    showNetConfig ();
    keepAlive();
    digitalWrite(readerLED, LOW);
    digitalWrite(systemLED, LOW);
  } else {Serial.println(F("Ethernet failed to be ready."));soft_reset(3000);}
  
}


I have given the entire code here. The motivation is: I wish to keep an enable jumper, pin11 will be source and pin 12 will be a input_pullup. This way all I want to is manipulate the jumper use such a way, a if pin11 sends 0 then pin 12 will read LOW and thus will disable the debug. If we remove the jumper (as jumper removal will be ONLY for debug purpose), pin12 will see HI and will enable the debug process.

aq_mishu

You can also use the F macro to store fixed pieces of text in PROGMEM so that they don't use up SRAM memory.

...R
That part is now a standard practice for me...  :)

And how about reading?? As i do read a lot of String...

Robin2

I have given the entire code here.
Not as far as I can see.

Code: [Select]
And how about reading?? As i do read a lot of String...
Have a look at the examples in Serial Input Basics - simple reliable ways to receive data.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

aq_mishu

#8
Dec 16, 2017, 04:38 pm Last Edit: Dec 16, 2017, 04:48 pm by aq_mishu
Not as far as I can see.
Nope... the attachment has the entire code (yes, not the libraries... but do we need them??)

Plus what about the "#define issue base on if clause via debug enable port??

Robin2

Nope... the attachment has the entire code
Reply #5 (which I quoted from) has no attachment.

Please post the latest version of your complete program in your next Reply.

...R

Two or three hours spent thinking and reading documentation solves most programming problems.

aq_mishu

#10
Dec 16, 2017, 08:16 pm Last Edit: Dec 16, 2017, 08:22 pm by aq_mishu
The entire source code given... no hidings... :-p

Robin2

#11
Dec 16, 2017, 08:55 pm Last Edit: Dec 16, 2017, 09:00 pm by Robin2
I have lost track of your question now.

Is it this, from Reply #5
Quote
I have given the entire code here. The motivation is: I wish to keep an enable jumper, pin11 will be source and pin 12 will be a input_pullup. This way all I want to is manipulate the jumper use such a way, a if pin11 sends 0 then pin 12 will read LOW and thus will disable the debug. If we remove the jumper (as jumper removal will be ONLY for debug purpose), pin12 will see HI and will enable the debug process.
If so that seems a sensible thinng but I don't understand what problem you are having. I don't see any attempt to read the status of enablePin in setup(). For example
Code: [Select]
debugEnabled == digitalRead(enablePin);
(I think debugPin would be a more obvious name but YMMV).

And you can't use the state of a pin at runtime to set a #define at compile-time. You can use a variable, for example debugEnabled, to  determine whether things are printed - like this for example
Code: [Select]
if (debugEnabled == true) {
  Serial.println("my error message");
}



Separately, you still have String in lots of places and you also have lots of fixed text that is not using the F macro.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

aq_mishu

Separately, you still have String in lots of places and you also have lots of fixed text that is not using the F macro.

...R
first of all, sorry for causing the loose of track!!

OK now, I got it after a lot of reading and a hecktik day of loosing my 20 years of data through a HDD crash of my cloud drive. Blah!!

Anyway... So, yep, i understood...  though i tried to keep it a bit short, but discovered, i have to write  so many of the "IF"s  to achieve that. No sir, so far I can see in my codes, I have used a lot of F( as after learning that "F" thing it's now a defacto in my codes...

But still there are strings... (Strings). And I have tried to convert few, like:

Code: [Select]
//String str_rx = "";
char str_rx[30];

//String data = "";
int data;


Code: [Select]
if (str_rx == "conf t") {
    str_rx[0] = 0;
    configMode();
  }


Code: [Select]
static void smartDelayPrompt(unsigned long ms) {
  unsigned long start = millis();
  do {
    while (Serial.available() > 0){ 
      Serial.readBytesUntil(10, str_rx, 30);
    }
  }
  while (millis() - start < ms);
  //do something
}


etc, now the next error is at:

Code: [Select]
    if ((str_rx.startsWith("?"))||(str_rx.startsWith("help"))) { //show the help

and dont know how to solve it...  Plus,
Code: [Select]
void postData() {
  if (!inetOK) {
    inetInit();
  }
  wdt_reset();
  unsigned int strSize = EEPROM.read(SERVER_ADDR_SIZE);
  char server[strSize];
  eeprom_read_string(SERVER_ADDR_OFFSET, server, strSize);
  String myURL = "GET /attd_posting.php?tag=";
  myURL += data;
  myURL += " HTTP/1.1";
  digitalWrite(readerLED, HIGH);
  digitalWrite(systemLED, HIGH);
  client.stop();
  DEBUG_PRINTLN(F("Connecting to server..."));
  // if you get a connection, report back via serial:
 
.........
 
}
Here is also I think I need that String...

[God!!Why String is so giving pain... heap is why growing??]

Robin2

From Reply #12
Quote
etc, now the next error is at:

   
Code: [Select]
if ((str_rx.startsWith("?"))||(str_rx.startsWith("help"))) { //show the help
When you use cstrings you must use different functions to manipulate them. I gave you a link in Reply #2.

I agree that cstrings are not as easy to use as the String class - but that convenience is a luxury that comes with a much more powerful processor - such as PC or RaspberryPi.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

aq_mishu

#14
Dec 17, 2017, 12:09 am Last Edit: Dec 17, 2017, 12:56 am by aq_mishu
ummm... just it become hang again... RESET also  did not worked... I was wondering, why watchdog is not working...

looking into the link you gave...

One more thing... WDT Reset... can I use that?? Then I need a real describing of a practical step by step... like

if(condition matches) {
   WDT Reset;
}

Go Up