Array's

Hi everybody,
I am a newbie to the arduino/C/C++ world. I am trying to store points into an array, and it wont let me do this code:

void loop()
{
temp1 = digitalRead(2);
time = millis();
if(temp1 == 1)
{
for(int i=0;i<50000;i=i+1)
{
int buff = templ;

  • Serial.print(buff, DEC);*
  • }*
  • }*

}
I am trying to store 50000 points from pin2, but only if it read HIGH.
I would appreciate any help on this subject. Thank you.

First off, you don't have enough memory to create an array that large.

50000 elements would require a minimum of 50000 bytes for chars or bytes. Int is 2-bytes, so 100000 bytes. Even the Arduino Mega has only 8192 bytes, and keep in mind that is shared with all your other variables and other data.

I'm not sure why you are trying to store only the highs in an array. Since the digitalRead only returns 0 or 1, storing the 1's isn't very meaningful. You're just going to end up with an array of 1's.

Also you can't print your array like that.... well.... maybe you can, but it won't be what you expect.

I'll change it to store less data. I am only storing one's for now to test my code, I am going to need to take timing information from another source later and the I just want to make sure that I can use the arrays properly. Thanks

Something more that makes this not work:

for(int i=0;i<50000;i=i+1)
   {
     int buff[i] = templ;
     Serial.print(buff, DEC);
   }

You can’t declare an array like this. You must have a separate variable declaration statement that says how big the array will be. (With the exception of more advanced techniques of dynamic allocation.) The “int buff” inside the for loop will also cause the array to only exist within the for loop. Once the loop is done and the program moves outside of the “}” at the end of this block, the variable will cease to exist.

How would I create definition that states how long the array should be?

C/C++ allows you to declare variables before you use them, rather than just on first use. It’s good practice to do so because it makes the code much easier to modify later.

// This creates a global array of ints with 100 elements. 
// It will exist throughout the entire program.
int buff[100];  
                    

void loop()
{

// This creates an array of bytes with 5 elements.
// Because it is declared inside loop(), it will only exist within loop.
// It will be destroyed and a new one created each time the loop function gets run.
byte small_array[5];  // Just here for demonstration.


 temp1 = digitalRead(2);
 time = millis();
if(temp1 == 1)
 {
   for(int i=0;i<100;i=i+1)  // ok to have "int" here, but remember that the variable "i" will only exist inside the "for" loop.
   {
     [s]int [/s]buff[i] = temp1;  // get rid of the "int" here.
     Serial.print(buff, DEC);
   }
 }
 
}

UNTESTED CODE

// This creates a global array of ints with 100 elements.
// It will exist throughout the entire program.
byte buff[100]; //now uses 100 bytes of RAM, not 200. You could get off with just 13 bytes if you store bit values

int temp1; //store the state of pin 2
unsigned long time;

void setup() 
{
  pinMode(2,INPUT);
  Serial.begin(9600);
}

void loop()
{
  temp1 = digitalRead(2);
  time = millis();
  if (temp1==HIGH)
  {
      //sample the input
    for (int i=0;i<100;i=i+1)  // ok to have "int" here, but remember that the variable "i" will only exist inside the "for" loop.
    {
      buff[i] = digitalRead(2); //read 100 samples
    }
      //debug to console
      //print all samples
    for (int i=0;i<100;i=i+1)  // ok to have "int" here, but remember that the variable "i" will only exist inside the "for" loop.
    {
      Serial.print(buff[i]);
      Serial.print(" ");
      if (i%10==0) 
      {
        Serial.println();
      }
    }
  }
}

How would I create definition that states how long the array should be?

Either

const int ARRAY_LENGTH = 100;

or

#define ARRAY_LENGTH 100

Then:

byte myArray [ARRAY_LENGTH];
//
...
//
for (int i = 0; i < ARRAY_LENGTH; ++i)

Groove:

Wouldn't the "const int" declaration take up 2 bytes of RAM? Shouldn't it at least be "const byte" (for sizes of 255 elements or less)? Where are constants stored, anyhow (RAM, I would think)?

Also, using "#define" can be better than a constant (depending on the situation), since all the compiler does is substitute the value of the constant anywhere it appears in the code, so no extra RAM is used.

Just a few questions and points for those who may not know...

:)

cr0sh,

I'm not Groove, and I haven't verified this personally, but I think the compiler is smart enough to not use up RAM for a constant unless it needs to.

The only case I can think of where you would need to actually store an int constant in RAM is if you referenced a pointer to it, for example:

const int myconst = 42;
int *myptr = &myconst;

Regards,

-Mike

Wouldn’t the “const int” declaration take up 2 bytes of RAM?

Normally, no. (see Mike Murdock’s message for the exception)

Shouldn’t it at least be “const byte” (for sizes of 255 elements or less)?

It should be the appropriate datatype. In this case, because i is an int the const should be as well.

Where are constants stored, anyhow (RAM, I would think)?

Normally, nowhere. The compiler treats them as a proper constant (exchangable with “100” in this case).

Also, using “#define” can be better than a constant (depending on the situation), since all the compiler does is substitute the value of the constant anywhere it appears in the code, so no extra RAM is used.

Not a valid reason for using a #define. The significant difference is the preprocessor; const values are not available to the preprocessor; #define values are.

A small correction to Mike Murdock’s example…

const int myconst = 42;
const int *myptr = &myconst;

Hmm - looks like I need to go back and re-read my K&R! :D

Thanks for the explanations, Mike and CB.

/learn sumthin' new every day! :)

cr0sh:

I'm not so sure. The answer would seem to be yes, they do occupy space in RAM. I found some threads with posts about it: http://www.physicsforums.com/showthread.php?t=234518 http://www.geekpedia.com/KB114_What-is-the-difference-between-sharpdefine-and-const.html Also http://www.cplusplus.com/doc/tutorial/constants/ and lots more..

From a link in the physicsforum thread:http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.7

const identifiers are often better than #define because: - they obey the language's scoping rules - you can see them in the debugger - you can take their address if you need to - you can pass them by const-reference if you need to - they don't create new "keywords" in your program. In short, const identifiers act like they're part of the language because they are part of the language. The preprocessor can be thought of as a language layered on top of C++. You can imagine that the preprocessor runs as a separate pass through your code, which would mean your original source code would be seen only by the preprocessor, not by the C++ compiler itself. In other words, you can imagine the preprocessor sees your original source code and replaces all #define symbols with their values, then the C++ compiler proper sees the modified source code after the original symbols got replaced by the preprocessor.

There are cases where #define is needed, but you should generally avoid it when you have the choice. You should evaluate whether to use const vs. #define based on business value: time, money, risk. In other words, one size does not fit all. Most of the time you'll use const rather than #define for constants, but sometimes you'll use #define. But please remember to wash your hands afterwards.

Knowing this, or should I say assuming this, I would argue that when making a name for things like arduino I/O pins, it is better to use a #define after all, since RAM is pretty restricted. Unless the compiler really is smart enough like Murdock above suggests :-) (So after all this I still dont know for sure regarding the arduino)

I'm not so sure.

I am.

The answer would seem to be yes, they do occupy space in RAM.

For the most common use...

const byte LEDPIN = 13;

void setup( void ) 
{
  pinMode( LEDPIN, OUTPUT );
}

void loop( void ) 
{
  digitalWrite( LEDPIN, ! digitalRead( LEDPIN ) );
}

...typed-constants DO NOT consume SRAM. The generated code for the above Sketch is identical for this Sketch...

void setup( void ) 
{
  pinMode( 13, OUTPUT );
}

void loop( void ) 
{
  digitalWrite( 13, ! digitalRead( 13 ) );
}

Unless the compiler really is smart enough like Murdock above suggests

It is.

Coding Badly:

Okay. Thanks for clarifying! I'll continue using const for most things const then :)