Help with project code. Thanks!

Hi All-

I am working on a design project for school and need some help with writing code for the Arduino. I am trying to use the Arduino to do the following:

  1. Record sound data.

  2. Threshold that sound data.

  3. Detect when sound breaks threshold, and output a signal to a speaker to signify threshold being broken.

  4. After the first time the signal breaks threshold, check every second and a half to see if a signal again broke threshold. If it did, just continue to check every second and a half. If it did not, then it should again output a signal to the speaker to signify threshold being broken.

I have written a working program in MATLAB, but am completely new to the Arduino board, and have never programmed in anything besides MATLAB, and need some help! This is the MATLAB code I wrote:


clear all
clc
daqreset

%%%%Phase 1

fs = 1000; %Sampling Rate
s = 3; %Time of data aquisition in seconds

TGOC1=analoginput(‘nidaq’,‘Dev2’);
addchannel(TGOC1,0);
set(TGOC1,‘SampleRate’,fs)
set(TGOC1,‘SamplesPerTrigger’,s*fs)
start(TGOC1)
SoundData=getdata(TGOC1);

NormalizedData=SoundData-(sum(SoundData)/length(SoundData));
Threshold=1.25*max(NormalizedData);

%%%%%Phase 2: Re-starting Acquisition. Waiting for first signal that breaks
%%%%%threshold.

RepControl=1;
s=30;
TGOC2=analoginput(‘nidaq’,‘Dev2’);
AO=analogoutput(‘nidaq’,‘Dev2’);
addchannel(TGOC2,0);
addchannel(AO,1);
set(TGOC2,‘SampleRate’,fs)
set(TGOC2,‘SamplesPerTrigger’,s*fs)

AO=analogoutput(‘nidaq’,‘Dev2’);
addchannel(AO,0);
% set(AO,‘SampleRate’,100)
OutputData=3;

start(TGOC2)
pause(1)
z=1
while RepControl==1
data=peekdata(TGOC2,100);
data=data-(sum(data)/length(data));
if max(data)>=Threshold
putsample(AO,OutputData)
pause(1)
putsample(AO,0)
RepControl=0
stop(TGOC2)
end
end
delete(TGOC2)
clear(‘TGOC2’)
delete(AO)
clear(‘AO’)

%%%%%Phase 3: predicting last beat

RepControl=1;
s=60;
TGOC3=analoginput(‘nidaq’,‘Dev2’);
A1=analogoutput(‘nidaq’,‘Dev2’);
addchannel(TGOC3,0);
addchannel(A1,1);
set(TGOC3,‘SampleRate’,fs)
set(TGOC3,‘SamplesPerTrigger’,s*fs)

A1=analogoutput(‘nidaq’,‘Dev2’);
addchannel(A1,0);
OutputData=3;

start(TGOC3)
while RepControl==1
pause(1.5)
data=peekdata(TGOC3,1400);
data=data-(sum(data)/length(data));
if max(data)<=Threshold
putsample(A1,OutputData)
pause(1)
putsample(A1,0)
RepControl=0
stop(TGOC3)
end
end
delete(TGOC3)
clear(‘TGOC3’)


The code and device works perfectly in MATLAB, and I think it should work using the Arduino as well. Here is my crude Arduino code for steps 1 -3 above, which is not working, but I’m not sure why. Help is greatly appreciated! Thanks all!


int analogPin = 3; // AI pin connected to analog pin 3
int outPin = 9; // outside leads to ground and +5V
int data[2999]; // variable to store the value read

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

void loop()
{
for (int i=1; i <= 3000; 1)
{
val = analogRead(analogPin); // read the input pin
data(i)=val;
delayMicroseconds(900);} // sample at about 1000 hz

threshold=1.25*max(data);

{ delay(2000)
val = analogRead(analogPin)
if (val>threshold)
analogWrite(outPin,255)
delay(1000)
analogWrite(outPin,0)
}
{ delay(2000)


In what way does your program not work? And something seems to have gone wrong with your cut/paste at the very bottom of the code. It would help if you could put this in code tags by using the button with the hash symbol when editing – that way, your indentation will be preserved.

Thanks for the feedback - I did not notice the hash symbol.

My Arduino code is as follows:

int analogPin = 3;     // AI pin connected to analog pin 3
int outPin = 9;        // outside leads to ground and +5V        
int data[2999];        // variable to store the value read

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

void loop()
{
  for (int i=1; i <= 3000; 1)
{
 val = analogRead(analogPin);    // read the input pin
 data(i)=val;      
 delayMicroseconds(900);}        // sample at about 1000 hz
             
 threshold=1.25*max(data);

{ delay(2000)
 val = analogRead(analogPin)
 if (val>threshold)
 analogWrite(outPin,255)
 delay(1000)
 analogWrite(outPin,0)
}

What I have written would be for the first two parts of the process: acquiring data, setting the threshold, and then turning on an output pin to indicate the first sound that breaks threshold.

The code did not compile onto the Arduino Nano board. Unfortunately, I have since burned out the board and am awaiting the arrival of a new one, so I don’t recall and can’t tell you the specific error I received.

coopergd, you can still compile, even when your Arduino is broken.

I see 4 problems with your code:

int data[2999];

This line consumes 5998 bytes of RAM in a controller that has only 1024.

  for (int i=1; i <= 3000; 1)

Assuming this is a conventional loop, this should probably be

  for (int i=1; i <= 3000; ++i)
data(i)=val;

In C/C++, arrays are indexed from 0 and use the syntax for access:

data[i-1] = val;
threshold=1.25*max(data)

The max macro doesn’t work this way in C/C++. It simply compares two values and returns the larger. If you want the max of the whole array, calculate it inside your for loop.

Mikal

Thanks, Mikal! I’ll implement ASAP.

Cool. One other thing:

When i is 3000, my proposed line

data[i-1] = val;

will cause an array overflow, because it writes to the 3000th element (#2999), in an array that has only 2999 elements. The largest index you can use is 2998 (because it starts from 0).

Clear? :slight_smile:

Mikal

I started off as a matlab programmer too. It’s easy to fall back and use that syntax hey!

Some of the matlab syntax I find more intuitive (loops, matricies/arrays)

Thanks, everyone, for the help! The code compiled and that aspect of the project is now functional. The working code…

int analogPin = 0;     // AI pin connected to analog pin 3
int outPin = 13;      // outside leads to ground and +5V
int val = 0;
int threshold = 0;
int threshold2 = 0;
int number = 3000;
int i;
int w = 0;

void setup()
{
 Serial.begin(9600);        //  setup serial
 pinMode(outPin, OUTPUT);
}

void loop()
{
   digitalWrite(outPin,HIGH);
   delay(100);
   digitalWrite(outPin,LOW);
      delay(100);
   digitalWrite(outPin,HIGH);
      delay(100);
   digitalWrite(outPin,LOW);
      delay(100);
   digitalWrite(outPin,HIGH);
      delay(100);
   digitalWrite(outPin,LOW);
      delay(100);
   digitalWrite(outPin,HIGH);
      delay(100);
   digitalWrite(outPin,LOW);
  for (i=1; i <= 3000; i++)
{
 val = analogRead(analogPin);    // read the input pin
 threshold=max(val,threshold);
 delayMicroseconds(900); //sample at 1K
 }     
threshold=1.25*threshold;
 digitalWrite(outPin,HIGH);
 delay(2000);
 digitalWrite(outPin,LOW);


while(w == 0)
{
 val = analogRead(analogPin);
 if (val>threshold)
 w = 1;
}

 digitalWrite(outPin,HIGH);
 delay(5000);
 digitalWrite(outPin,LOW);
 
 w = 0;
while( w == 0)
{
  threshold2 = 0;
  for (i=1; i <= 1333; i++)
{
 val = analogRead(analogPin);    // read the input pin
 threshold2=max(val,threshold2);
 delayMicroseconds(900); //sample at 1K
 }     
 if (threshold2 <= threshold)
 w = 1;
 
}
 digitalWrite(outPin,HIGH);
 delay(5000);
 digitalWrite(outPin,LOW);
 }