Pages: [1] 2   Go Down
Author Topic: sketch hangs, makes no sense to me, any help?  (Read 1646 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 40
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm getting extremely frustrated and annoyed at the Arduino, so much that I'm starting to look into alternatives.  This has happened to me before in other projects but this time I've decided to take a snippet and post a question.

Many times I've seen in a sketch after adding some code that the sketch hangs - sometimes it happens after outputting a couple of serial bytes (eg. a serial.print command) but the serial print command can not be the culprit.

I had a sketch that does some SPI communication etc, and I am writing a routine to allow me to send SPI responses in realtime back to the device.  This is a part o f the sketch:

----
 
Code:
     if ( recvcmd[bullshit] == ',' || recvcmd[bullshit] == cmdEndByte ) {
        int n;
        char carray[6];
        tempdigit.toCharArray(carray, sizeof(carray));
//        newData[digits] = atoi(carray);
        Serial.print ("digit ");
        Serial.print (digits);
        Serial.print (": ");
        Serial.println (atoi(carray));
        tempdigit = "";
        digits++;
      }

Moderator edit: CODE TAGS added
-----

Let me note that newData is defined earlier on globally as "int newData[250];" and likewise tempdigits is "String tempdigit;"

The // comment on the newData line is for testing.  The Serial.print's are just to show me that the pockets of the newData array were being populated correctly (for example no numbers larger than what has been defined are trying to be written).  It works as I expect, when I send a 1,2,3 I see 0 1 2 as the digits variables.  The sketch runs fine like this, just outputting what pockets would be written if I uncommented the newData line.  When I uncomment the newData line, the sketch hangs, it shows "ha" and then stops.  What actually happens is it performs a handshake when I turn the device on and says "handshake completed" but for some ridiculous reason, uncommenting this line affects it and doesn't even let the serial.print somewhere else in the code complete.

Does ANYONE have an answer for this, a reason or a way to work around it?  I'm getting so sick and tired of this I'm looking into alternatives.  C++ is annoying enough as it is to make it happy with coding and with unpredictable hangups like this just makes it that much more frustrating.

Any help would be much appreciated, even just to understand WHY it does this.
« Last Edit: June 29, 2012, 09:50:14 am by AWOL » Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 310
Posts: 26618
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Let me note that newData is defined earlier on globally as "int newData[250];"
That's 500 bytes of RAM.
Do you have 500 bytes of RAM spare?

Posting snippets is pointless.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Fort Lauderdale, FL
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6144
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

C++ is annoying enough as it is to make it happy with coding and with unpredictable hangups like this just makes it that much more frustrating.
Neither the ATmega328 or C++ are responsible for random hangups.  Unpredictable operation is the result of programming mistakes.  Sometimes these mistakes are not obvious (and very common), such as RAM usage.

Microcontrollers do not have memory managers, so the programmer is responsible for managing the memory.

As pointed out, you have a single array that is consuming 25% of the RAM in the ATmega.  You are using the String-class, which can wreak havoc on the heap.  The Serial.print()s shown in your snippet are also consuming RAM.  I assume you have other Serial.print() statements in your code as well as other variables as well.
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.c

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 639
Posts: 34724
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Many times I've seen in a sketch after adding some code that the sketch hangs
The processor never hangs. If it is not coming out of a piece of code it is because that is how the code is written. For example looking for a condition that can never possibly happen.

Quote
so much that I'm starting to look into alternatives
Any platform will do the same if you code it in the same way.

The great and humbling thing about computing so close to the processor is that when something goes wrong, it is almost always your fault. Take that thought and run with it, if you broke it, you can fix it.

The best, perhaps only way to post code is to post it all so others can have a go at seeing what is wrong. The very best way is to cut down the code so that it is very short and still shows the problem. Posting snippets is useless, almost all code snippets posted here are fine, with the error being elsewhere.
Logged

Finland
Offline Offline
Sr. Member
****
Karma: 1
Posts: 270
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The very best way is to cut down the code so that it is very short and still shows the problem.

And there is a good change that while trimming down the code you find the problem yourself.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 40
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

All points taken, thank you everyone who responded, I will have a look at some things again.  Grumpy Mike +1 on your recommendation, I have done that in the past, slimmed down code to represent a problem I am trying to solve to "filter" out all of the un-necessary and not applicable code to my problem.  You're dead on right it makes it easier to spot the problem.  I just have a hard time comprehending how running it with prints once shows 3 pocket arrays will be written and changing it to write those arrays and seeing a hangup as being in the code elsewhere, but it wouldn't be the first time or the last time that it was!  Perhaps the next run I will put the 3 commands in manually that would run in the loop, for example newData[0] = 1; newData[1] = 2; newData[2] = 3;   -  if that hangs it up then it must be a memory allocation issue or something similar.

Also thanks to the moderator for adding the code tags, I forgot to do that.
« Last Edit: June 30, 2012, 01:00:06 pm by catatung » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 40
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Also, as far as the memory allocation goes, I had that thought but I thought wouldn't the sketch crash immediately in all trials when the arrays were initialized?  Or does it only consume memory as the array is written to?  I was under the impression that when you declare an array with a type and size that the memory is reserved for that array and if you went too far, the hang would happen at the beginning of the sketch and could not be intermittent depending on the rest of the code accessing and attempting to use the variable.  Can someone confirm how the memory is allocated / used?
Logged

Fort Lauderdale, FL
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6144
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The issue is that "hang" is the wrong term.  The microprocessor doesn't "hang".  Instead it acts unpredictablely. This might appear to us as the processor "hanging", however, it's still jumping around doing stuff.

Until you start using instructions that need the stack, you probably won't see a problem.  So no, initializing may not be where the problems occur.
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.c

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 650
Posts: 50833
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I had that thought but I thought wouldn't the sketch crash immediately in all trials when the arrays were initialized?
When an array is allocated, it is given an initial set of values, if the array is global in scope. If not, no initialization is performed. Hence, no overwriting of values on the stack happens.

Quote
Or does it only consume memory as the array is written to?
No, the memory is consumed right away. It is only when that memory is accessed incorrectly that problems occur. Of course, it is a problem to consume more memory than you have, but the problem only manifests itself when two or more areas of the code (yours and the stack manager, for instance) are trying to access the same memory.

Quote
and could not be intermittent depending on the rest of the code accessing and attempting to use the variable.
Whether this is true, or not, depends on the type (global or local) of the variable, where it is allocated (heap or stack) and how it is used (read or read/write).
Logged

Offline Offline
Edison Member
*
Karma: 50
Posts: 1697
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
tempdigit.toCharArray(carray, sizeof(carray));
You appear to be using the String library. This is frequently the cause of the processor "hanging".

Pete
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 40
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the immense amount of information everybody.  El_Supremo I'm trying to get away from that.  Do you know how I can send an array to a routine without actually making one first if I only need it in the routine?  For example I have:

Code:
  char setLineOne[] = {'L','1',':','B','L','A','H',32,'B','L','A','H'};
  updateLine (101, setLineOne);
  char setLineTwo[] = {'L','2',':','B','L','A','H'};
  updateLine (102, setLineTwo);

I'm trying to be more efficient with memory usage but some things just baffle be so far in C++, such as this, from all my searching and reading I've found that you can't un-define an array or redefine it in a linear fashion (For example if I want to change the text of setLineOne after it exists I have to do it position by position eg. setLineOne[0] = 'N'; setLineOne[1] = 'e'; setLineOne[2] = 'w';    --  It seems ridiculous to me, I must be missing an easier way but the alternative of using multiple array names is wasteful too, was wondering if anyone here has a suggestion how to accomplish that?

Ideally I would like to just do something like "updateLine (102, (char){'L','2',':'}" or something to that effect.
Logged

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 99
Posts: 4835
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Also, as far as the memory allocation goes, I had that thought but I thought wouldn't the sketch crash immediately in all trials when the arrays were initialized?  Or does it only consume memory as the array is written to?  I was under the impression that when you declare an array with a type and size that the memory is reserved for that array and if you went too far, the hang would happen at the beginning of the sketch and could not be intermittent depending on the rest of the code accessing and attempting to use the variable.  Can someone confirm how the memory is allocated / used?

globals get allocated up front as do strings (C string arrays or C++ String objects) unless specially stored in flash program space. Nice long text messages can get you.

locals get allocated on the stack along with return addresses during run-time. That's why some problems don't show right away.

C++ String objects make copies of themselves when changing length then erase the original, shotgunning what heap you have while pushing the top higher. There is no O/S to check the holes for allocation space, no allocation table that I have ever seen.... anyone?

Code:
char setLineOne[] = {'L','1',':','B','L','A','H',32,'B','L','A','H'};

or you could
Code:
char setLineOne[] = "'L1:BLAH BLAH";

Quote
(For example if I want to change the text of setLineOne after it exists I have to do it position by position eg. setLineOne[0] = 'N'; setLineOne[1] = 'e'; setLineOne[2] = 'w';    --  It seems ridiculous to me, I must be missing an easier way

You could make the text array as long or longer than you need and then use string.h functions to manipulate the text.
strcpy() --- copies a string including the terminating zero
strncpy() --- copies as many chars as you specify and doesn't add the terminating zero
strstr()
strtok()
strchr()
strlen()
--and many, many more -- a full set in fact seemingly unknown to C++ only programmers.
http://www.nongnu.org/avr-libc/user-manual/group__avr__string.html


Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 310
Posts: 26618
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

GoForSmoke: subtle difference in the two examples of a char array you gave.
The first will almost certainly bite you on the derriere.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 99
Posts: 4835
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Not sure which you mean but I made a type with

Code:
char setLineOne[] = "'L1:BLAH BLAH";

as it should be

Code:
char setLineOne[] = "L1:BLAH BLAH";

My bad.  smiley-red

Sorry but even with view at 120%, "' (as opposed to ") isn't that clear to these old eyes.

Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 310
Posts: 26618
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

No, that wasn't what I meant.
The second is a C string, the first is not.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Pages: [1] 2   Go Up
Jump to: