Building array to read data for a period of time

Hey! I want to sample two analog inputs voltage & current into an array. I will want to take maybe 0.5 seconds of data (35 periods) at 500-1000 Samp/sec (250-500 points per signal per second), then transfer the arrays to labview and do the phase calculation.

Here is my code:

const int analogIn0 = A0;
const int analogIn1 = A1;
int mVperAmp = 185; // use 100 for 20A Module and 66 for 30A Module
int RawCurrentValue= 0;
int RawVoltageValue= 0;
int ACSoffset = 2500;
int Denominator = 0;
float AcVoltage = 0;
float Voltage0 = 0;
float Voltage1 = 0;
float Amps = 0;

void setup(){
Serial.begin(9600);
}

void loop(){

RawCurrentValue = analogRead(analogIn0);
RawVoltageValue = analogRead(analogIn1);

Denominator = (10000)/(130000);

Voltage0 = (RawCurrentValue / 1023.0) * 5000;
Voltage1 = (RawVoltageValue / 1023.0) * 5000;
AcVoltage = (Voltage1 / Denominator ) ;
Amps = ((Voltage0 - ACSoffset) / mVperAmp);

Serial.print(Amps);
Serial.print(", ");
Serial.println(AcVoltage);

}

How do I do it?

Something like this:

. . .

int RawCurrentValue[250] ;  // Declare array for Current samples
int RawVoltageValue[250] ;  // Declare array for Voltage samples

. . .

void loop(){
  // Collect a burst of 250 Voltage and Current samples
  for (int k=0 ; k < 250 ; k += 1)
  {
    RawCurrentValue[k] = analogRead(analogIn0);
    RawVoltageValue[k] = analogRead(analogIn1);
    delay(2) ;    // Delay to get desired sample interval
  }
 
  Denominator = (10000)/(130000);

  // Calculate standard values of Voltage and Current and send to serial port
  for (int k=0 ; k < 250 ; k += 1)
  {
    Voltage0 = (RawCurrentValue[k] / 1023.0) * 5000;
    Voltage1 = (RawVoltageValue[k] / 1023.0) * 5000;
    AcVoltage = (Voltage1 / Denominator ) ;
    Amps = ((Voltage0 - ACSoffset) / mVperAmp);
      
    Serial.print(Amps);
    Serial.print(", ");
    Serial.println(AcVoltage);
  }
}]

Since Arduinos typically don't have much RAM, the array sizes are limited so you're probably going to have to settle for less than 500 samples. In the code above, I've saved the raw A/D reading because INT is a two byte value and the floating point representation computed later in the code is a REAL four byte value, that is the INT take up half as much RAM per sample.

If you need 500 data point, use a MEGA2560. It has 8KB memory for up to 4,000 analog readings, maybe 3,800 realistically since by default all 4 Serial ports are active and take memory as buffer space. This way you will have nearly 2000 samples.

How does labview read data from the serial port? Are you using something like VISA to open serial port and feeding the text string through some string operations?

liudr:
by default all 4 Serial ports are active and take memory as buffer space.

?

Denominator = (10000)/(130000);

Have you used a calculator? (The) (parentheses) (are) (useless). 10000 / 130000 is 0.

AcVoltage = (Voltage1 / Denominator ) ;

Dividing by 0 is stupid.

AWOL:
?

6442[Enter]

512
That plus pointers, regardless you use all 4 serial ports or not. I was trying to NOT involve any numbers. If you want some reading, you can find it here:

#if (RAMEND < 1000)
#define SERIAL_TX_BUFFER_SIZE 16
#else
#define SERIAL_TX_BUFFER_SIZE 64
#endif
#endif
#if !defined(SERIAL_RX_BUFFER_SIZE)
#if (RAMEND < 1000)
#define SERIAL_RX_BUFFER_SIZE 16
#else
#define SERIAL_RX_BUFFER_SIZE 64
#endif

Then some more

#if defined(UBRRH) || defined(UBRR0H)
  extern HardwareSerial Serial;
  #define HAVE_HWSERIAL0
#endif
#if defined(UBRR1H)
  extern HardwareSerial Serial1;
  #define HAVE_HWSERIAL1
#endif
#if defined(UBRR2H)
  extern HardwareSerial Serial2;
  #define HAVE_HWSERIAL2
#endif
#if defined(UBRR3H)
  extern HardwareSerial Serial3;
  #define HAVE_HWSERIAL3
#endif

liudr:
6442[Enter]

512
That plus pointers, regardless you use all 4 serial ports or not.

Are you sure about that?

AWOL:
Are you sure about that?

Are you not saying something?

liudr:
Are you not saying something?

No, I think you're saying too much.

I was just responding to your question mark.

The question mark was querying your assertion about unused Serial objects.

Then I provided you just enough information to see they are all using space. The buffers are static arrays and all 4 serial objects are created with the buffers.

Here's a simple experiment to try

void setup()
{
  Serial.begin (115200);
  //Serial1.begin (115200);
  //Serial2.begin (115200);
  //Serial3.begin (115200);
}

void loop (){}

while (exists "// comment")
{
Compile.
Note RAM usage.
Remove a // comment.
}

I see it now but I'm not telling why. You always have this "short" way of "telling" others your answers. I'll follow your lead. Don't want be banned.

I don't ban people for not knowing things - what a peculiar notion!

People get banned for wilfully ignoring simple guidelines designed to help people get help, or simply being wilfully stupid.
You're not in any danger of banning.

Am I short? (I'm 1.85 m tall, so no, I don't think so)

My best and favourite CS lecturer had a really great way of testing if you'd done your groundwork. Students would present their work and their conclusions, he'd take notes, ask a few questions, and then say something simple and innocuous like "Are you sure about that?" or "Are you happy with that?"
It usually meant he'd spotted something you hadn't, and you had to think fast.
Sometimes as he said it, there was the hint of a chuckle or there was a twinkle in his eye, and you knew you'd done OK.

But you never ignored even the simplest of his questions.
I think it's a valid technique, well over thirty years on.

MrMark:
Something like this:

. . .

int RawCurrentValue[250] ;  // Declare array for Current samples
int RawVoltageValue[250] ;  // Declare array for Voltage samples

. . .

void loop(){
  // Collect a burst of 250 Voltage and Current samples
  for (int k=0 ; k < 250 ; k += 1)
  {
    RawCurrentValue[k] = analogRead(analogIn0);
    RawVoltageValue[k] = analogRead(analogIn1);
    delay(2) ;    // Delay to get desired sample interval
  }

Denominator = (10000)/(130000);

// Calculate standard values of Voltage and Current and send to serial port
  for (int k=0 ; k < 250 ; k += 1)
  {
    Voltage0 = (RawCurrentValue[k] / 1023.0) * 5000;
    Voltage1 = (RawVoltageValue[k] / 1023.0) * 5000;
    AcVoltage = (Voltage1 / Denominator ) ;
    Amps = ((Voltage0 - ACSoffset) / mVperAmp);
     
    Serial.print(Amps);
    Serial.print(", ");
    Serial.println(AcVoltage);
  }
}]



Since Arduinos typically don't have much RAM, the array sizes are limited so you're probably going to have to settle for less than 500 samples. In the code above, I've saved the raw A/D reading because INT is a two byte value and the floating point representation computed later in the code is a REAL four byte value, that is the INT take up half as much RAM per sample.

Thanks for the replies!
But I do not understand the "delay(2) ; // Delay to get desired sample interval" What do you mean and what happens if I increase or decrease the delay?

lamela:
Thanks for the replies!
But I do not understand the "delay(2) ; // Delay to get desired sample interval" What do you mean and what happens if I increase or decrease the delay?

In your original post you said

I will want to take maybe 0.5 seconds of data (35 periods) at 500-1000 Samp/sec

that is, 1 sample every 1 to 2 milliseconds. Ignoring the overhead of the sampling loop and the digital data reads, "delay(2)" gives you a sample every 2 milliseconds. In reality it's going to be about 2.2 milliseconds because the AnalogReads are on the order of 100 microseconds each plus a handful of microseconds for the loop overhead. "delay(1)" would put the sample rate in your specified range, but higher sampling rate means a shorter data collection given the limited RAM available.