Go Down

Topic: possible compiler malfunction (Read 2153 times) previous topic - next topic

fizyplankton

first, what my project is supposed to do. it is supposed to do image tracking on a robot for a competition (the goals will have retro-reflective tape on them, and the camera on the robot has an LED ring around). it will recieve a 60x45 pixel image from the network, but since i dont have the ethernet shield yet, i am using a static test picture, the RGB values of which are stored in the flash space. it first checks if each pixel falls within the given RGB bounds, and stores the results in a 2d array called binaryImage (it used to store true/false values in it, but i later changed it to have numbers. the basic idea is unchanged tho). it then removes any isolated pixels, since those can't possibly be right, by calling removeSmallParticles(). it then calls blobifyBinaryImage2(), which assigns contiguous regions an ID, and stores the id in binaryImage (blobifyBinaryImage() was an earlier attempt, long since abandonned. note that blobifyBinaryImage() is different than blobifyBinaryImage2(). also, the IDs start at 2. an id of 0 means the pixel is off, aka not a viable target. 1 means that the pixel is viable, but is awaiting blobification. thus, blobs start at 2). then, small blobs are eliminated, then the blobs are re-ID'd by changing the pixels back to 1, then blobifyBinaryImage2() again. throught the process, statuses are printed to various leds, a 7 segment display, and even a portable DVD player (using the TVout library) which lets me see what the board sees live.

now, since it will operate VERY differently if i have a camera plugged in vs not, i have a couple of precompiler directives to modify its behavior by simply commenting out a #define line (i also included a few novelty precompiler directives, such as a dummy loading screen, and letting out team mascot, lyle, blink, at the risk of using pointless delay()s). one such constant is DISABLE_CAMERA. when the constant is present, i want it to read my test image from flash memory. if i comment out DISABLE_CAMERA, i want it to declare a 2d array called colorImage to prepare to recieve an RGB image over the network. whether the code looks at testimage or colorImage is also taken care of by these precompiler directives.

So whats the problem? a portion of my code looks like
Code: [Select]

#define DISABLE_CAMERA
#ifndef DISABLE_CAMERA
 byte colorImage[2700][3];
#endif
(i know that is a huge array, and that it only leaves my mega with 92 bytes of ram. thats fine). now as any C/C++ programmer knows, i could easily replace that with
Code: [Select]
#define DISABLE_CAMERA
#ifndef DISABLE_CAMERA
 gt4ghuitregbuitregbre
#endif
and still get a clean compile, since the compiler skips will skip that portion. now is where things start to get freaky. when i compile, i get errors about how i, in a nutshell, forgot my prototypes. including prototypes does indeed quiet the compiler. according to the troubleshooting guide, there are well known circumstances in which this can occur. none of those apply to me. BUT get this: if i change #ifndef to #ifdef or comment out #define DISABLE_CAMERA or move it to an #else clause under #ifndef, or otherwise use the precompiler directives to tell it to compile, it will compile. it doesnt matter what i declare in that line. int x; has the same effect. if the compiler is clearly instructed to ignore its declaration, it goes haywire and gives me irrelevent errors (colorImage is not used anywhere in the code yet). if i tell it to look at the line, then it will compile (or not, depending on what the line is. i.e. valid syntax, etc). while i know that the compiler has issues generating prototypes under certain circumstances, i believe the problem is in the precompiler, not the actual compiler itself.
NOTES: i have a mega 2560 by OSEPP. since i am very pressed for memory, i use bytes and chars for virtually everything. the image that im processing is 4 basketball goals with retro-reflective tape around them. finally, my code (sorry its so sloppy)

fizyplankton

sorry. i just realized. where it says
Code: [Select]
#ifdef UNDEFINED_CONSTANT
  int x;
#endif

it should read
Code: [Select]
#ifndef DISABLE_CAMERA
  byte colorImage[2700][3];
#endif

however, as i said, it shouldn't matter!

PaulS

Code: [Select]
 byte colorImage[2700][3];
Let me get my calculator out...

Yep, that's 8100 bytes. No Arduino has that much SRAM.

You don't have a compiler malfunction. You have a user error.

fizyplankton

#3
Jan 16, 2013, 01:23 pm Last Edit: Jan 16, 2013, 01:27 pm by fizyplankton Reason: 1
The mega 2560 has 8kb (*1024=8192 -2700*3=92). at any rate, ram isn't the issue. heck, i should be able to replace byte colorImage[99999][9999] because the compiler is clearly instructed to not look at that line
i quote http://arduino.cc/en/Main/ArduinoBoardMega2560
SRAM   8 KB

AWOL

Quote
No Arduino has that much SRAM.

Not strictly true

But I agree, unlikely to be a compiler issue.

Quote
The mega 2560 has 8kb (*1024=8192 -2700*3=92)

Also true, but then there's stack, serial buffers, strings, variables...
"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.

fizyplankton

what do you mean un likely to be a compiler issue? i very explicitly use the directives, and it downright ignores them . replace colorImane(2700)(3);(sorry for no square brackets  too dificult to type on my phone) with, i dont care, int x;. you will get the same result. the only way its not a compiler issue is if its a precompiler issue

AWOL

Quote
what do you mean un likely to be a compiler issue?

I mean, the compiler is robust.
The preprocessor is robust.
I think it unlikely that the problem lies there.

Unfortunately,  there is a problem with the forum at the moment, and I can't download your code.
"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.

billroy

If memory serves me right (no pun intended), the IDE does build step before the precompiler that rearranges your #defines and creates function prototypes.  I'm guessing you've run afoul of this step.

Perhaps someone who recalls what this build step does will join the thread and fill us in on whether it might be affecting your code in this instance.  I could be barking up the wrong tree.

-br

fizyplankton

#8
Jan 16, 2013, 01:46 pm Last Edit: Jan 16, 2013, 01:50 pm by fizyplankton Reason: 1
here is imagetracking.ino http://pastebin.com/7734cF7a
here is lyle.cpp http://pastebin.com/3pzgBvUU
here is lyle.h
Code: [Select]
#include <avr/pgmspace.h>

extern const unsigned char lyle[];
here is testimage.cpp http://pastebin.com/CnXTYxER
and here is testimage.h
Code: [Select]
#include <avr/pgmspace.h>

extern prog_uchar testimage[][3];
sorry if i violated any linking policies. also, you will need the TVout library

AWOL

Code: [Select]
void recursivelyFloodPixelIdToAdjacentPixels(byte row, byte col, byte blobId)
In the general computing world, the motto "To iterate is human, to recurse, divine" may hold true, but in the microcontroller world, I wouldn't recommend it.
"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.

pYro_65

This:
Code: [Select]
#define DISABLE_CAMERA
#ifndef DISABLE_CAMERA
 gt4ghuitregbuitregbre
#endif

void setup()  { return; }
void loop() {return;}  


produces this ( does not compile ):
Code: [Select]
#line 1 "_01_Initialisation.ino"

#define DISABLE_CAMERA
#ifndef DISABLE_CAMERA
 #include "Arduino.h"
gt4ghuitregbuitregbre


void setup();
void loop();
#line 4
gt4ghuitregbuitregbre
#endif

void setup()  { return; }
void loop() {return;}  


When I add an include on top, it compiled fine:

Code: [Select]

#include <SPI.h>

#define DISABLE_CAMERA
#ifndef DISABLE_CAMERA
 gt4ghuitregbuitregbre
#endif

void setup()  { return; }
void loop() {return;}


It is just a result of the IDE, add your defines to a header file instead, might fix things.

fizyplankton

it was the simplest algorithm that i could think of to flood fill a pixel/blob id to the contiguous blob. it runs quickly enough.

dhenry

Quote
i believe the problem is in the precompiler, not the actual compiler itself.


That's fairly easy to confirm: just declare the array and see if the issue persists.

But I have to say that leaving 92 bytes is tight - you better make sure that you do indeed need no more than that.

majenko


Quote
i believe the problem is in the precompiler, not the actual compiler itself.


That's fairly easy to confirm: just declare the array and see if the issue persists.

But I have to say that leaving 92 bytes is tight - you better make sure that you do indeed need no more than that.



I would seriously recommend replacing your Arduino with a ChipKit MEGA32 - it has a 32-bit CPU on it with 128KiB of RAM, and 512KiB of Flash.  It'd give you just a touch more breathing space...

fizyplankton

dhenry: im not at my computer right now (im at school) but i know that 92 bytes is very tight. i am not sure exactly how i will implememnt this until i do physical testing, but 92 bytes is a worst case scenario. even so, i can store multiple values in one byte by using bitshift operators if the values are small enough.
pYro: how would #Including <SPI.h> help? i am not using any SPI anything

Go Up