Arrayrange of 20'000 Possible? Or how to do?

Hi :slight_smile:

I wanna read the values of my accelerometer, connected on a ADC-Input for 2seconds.

int i;
for (i = 0; i < 20000; i = i ++) // 20'000 x 0.1ms --> 2000ms --> 2sec
{
sensorValue = analogRead(analogPin); // read accelerometer
array_acc = sensorValue ; // write accelerometer value to accelerater-array
}
I've tried it with the arduino uno, but there is a stack overflow.
Is this with the Arduino DUE possible, or do I need an other solution?
If yes: How can I solve this?
Thank you and have a nice day!

It's possible if you have enough RAM but most Arduinos do not. It will work on a Due.

Did you look at your post? Wonder why it went into itallics? Put code in code tags, the # button when editing.


Rob

you might add run length compression (and code tags ==> # button above the smileys :wink:

no guarantee you have 20000 samples, it depend heavily on the volatility of the signal.
// code is not tested

int array_acc[2000];
int size = 0;
while (size < 2000)                                             // 20'000 x 0.1ms --> 2000ms --> 2sec
{
   sensorValue = analogRead(analogPin);                       // read accelerometer
   size = RLE(analogRead(analogPin));                 // write accelerometer value to accelerater-array
 }

...
boolean RLE(int val)
{
  static int lastVal = -1;
  static int pos = 0;

  // setting the THRESHOLD higher compresses more
  // standard noise is 2 bits => THRESHOLD >=4
  if (abs(val - lastValue) > THRESHOLD)  // new run, 
  {
    pos += 2;
    array_acc[pos] = 1;  // runlength
    array_acc[pos+1] = lastVal = val;
  }
  else 
  {
    array_acc[pos]++;
  }
  return pos; 
}

update: code fix

in a more compact version of RLE you can do the following.
one analog read returns a 10 bits number.
That leaves 6 bits unused
this can be used to encode a run length of 1..64
drawback you must pack/unpack the bits, but this can be faster than the analogread itself.

another way to compress the samples is delta encoding.

byte ar[1000];

ar[0] = analogRead;

for (int i=1; i< 1000; i++)
{
  a = analogRead(A0);
  ar[n] = a - ar[n-1];
}

drawback is that you must sum from start to N to get value of ar[N]

What do you want to do with your 20000 samples? It's possible that we can suggest a way to achieve it without holding them all in memory.

Thank you for all this answers!

Punch-o-meter:
I wanna read my ADC(accelerometer) for about 2-3seconds, while I'm punching in my construction(sensor is on the construction)
Then in an other routine, I want to find the maximum and display it on my 2.8" TFT Shield also with the curve from the array.
I just wanna plot the range of about 10-20ms. so just that I can see the punch-curve.
But I wanna sample about 2-3seconds, that I've got enough time for punching.

I hope you can imagine a little bit what I wanna do (:

So you can sample and as long as no punch detected (under some treshold) no storage.

int idx = 0;
while ((x = analogRead(A0)) < 10);  // wait for punch
do 
{
  array[idx++] = x;
} while  ((x = analogRead(A0)) > 10);

Couldn't you just sample at 1ms? I imagine that the general speed of such a thing is not going to be that fast. This will reduce your array size by a factor of 10.

Thank you for your trigger soultion!
But the Problem is there, that the beginning is lost, so I would need a roundbuffer or something, which always overwrites the oldest one.
But I've found a Problem... the 2.8" TFT Touch Shield from adafruit does only work with the Arduino UNO and MEGA =S

Arduino UNO has not enough RAM and I don't think that the MEGA has enough to sample for about 2 seconds every 0.1ms.
What should I do now?

mirith:
Couldn't you just sample at 1ms? I imagine that the general speed of such a thing is not going to be that fast. This will reduce your array size by a factor of 10.

No every 1ms is too slow, maybe every 0.3ms would be enough.
But then there is still an array of 6666 needed.

But then there is still an array of 6666 needed.

The Mega has 8k so that would work as long as there isn't too much happening on the stack.

Or get one of the Mega1284 boards, they have 16k of RAM.

the 2.8" TFT Touch Shield from adafruit does only work with the Arduino UNO and MEGA

Why is that? Maybe it's something you can get around for the Due. Maybe you should use a different display. There is a Due GUI thread running here that is about using a GLCD on the Due.


Rob

Graynomad:

But then there is still an array of 6666 needed.

The Mega has 8k so that would work as long as there isn't too much happening on the stack.

Or get one of the Mega1284 boards, they have 16k of RAM.

the 2.8" TFT Touch Shield from adafruit does only work with the Arduino UNO and MEGA

Why is that? Maybe it's something you can get around for the Due. Maybe you should use a different display. There is a Due GUI thread running here that is about using a GLCD on the Due.


Rob

Thank you all for your fast answers!
So great this forum!
I've ordered now this 3.2" TFT LCD which is built for Arduino DUE :smiley:
http://www.elechouse.com/elechouse/index.php?main_page=product_info&products_id=2217

So I can sample now every 0.1ms and have still more than enough RAM free on the DUE (:

I just wanna plot the range of about 10-20ms. so just that I can see the punch-curve.
But I wanna sample about 2-3seconds, that I've got enough time for punching.

Before you try to estimate memory consumption , read a sensors data sheet. There is a sampling rate or max. freq. response.
I don't think your sensor needs to be sampled 10 000 sps, probably 50 - 1500. So you better to reduce a sampling rate.
Here is an project, board UNO can store in EEPROM accelerometer data for 5 sec, 3D.
http://coolarduino.wordpress.com/2013/12/24/gesture-recognition/