Go Down

Topic: Array's (Read 1 time) previous topic - next topic

SRaja001

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.

dilbert98122

#1
Feb 15, 2010, 04:37 am Last Edit: Feb 15, 2010, 04:41 am by spday Reason: 1
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.

SRaja001

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

dilbert98122

Something more that makes this not work:
Code: [Select]
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.

SRaja001

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

dilbert98122

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.

Code: [Select]

// 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);
  }
}

}


AlphaBeta

#6
Feb 15, 2010, 09:31 am Last Edit: Feb 15, 2010, 09:36 am by AlphaBeta Reason: 1
UNTESTED CODE
Code: [Select]
// 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();
     }
   }
 }
}

Groove

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


Either
Code: [Select]
const int ARRAY_LENGTH = 100;
or
Code: [Select]
#define ARRAY_LENGTH 100

Then:
Code: [Select]
byte myArray [ARRAY_LENGTH];
//
...
//
for (int i = 0; i < ARRAY_LENGTH; ++i)
Per Arduino ad Astra

cr0sh

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...

:)
I will not respond to Arduino help PM's from random forum users; if you have such a question, start a new topic thread.

Mike Murdock

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:
Code: [Select]
const int myconst = 42;
int *myptr = &myconst;

Regards,

-Mike

Coding Badly

Quote
Wouldn't the "const int" declaration take up 2 bytes of RAM?

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

Quote
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.

Quote
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).

Quote
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...
Code: [Select]
const int myconst = 42;
const int *myptr = &myconst;

cr0sh

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!  :)
I will not respond to Arduino help PM's from random forum users; if you have such a question, start a new topic thread.

raron

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
Quote
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)

Coding Badly

#13
Feb 16, 2010, 11:34 pm Last Edit: Feb 16, 2010, 11:36 pm by bcook Reason: 1
Quote
I'm not so sure.

I am.

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

For the most common use...

Code: [Select]
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...

Code: [Select]
void setup( void )
{
 pinMode( 13, OUTPUT );
}

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


Quote
Unless the compiler really is smart enough like Murdock above suggests

It is.

raron

Coding Badly:

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

Go Up