Go Down

Topic: Arrays, Ping and MIDI (Read 81 times) previous topic - next topic

theotherjenkutler

Hi Everyone.
I've been working on a code to use 4 HC-SR04 Ultrasonic Distance Sensors to generate MIDI CC data. The compiler won't let me upload my code onto my Arduino and I can't figure out whats wrong with it. I suspect that it might have to do with the arrays. I know its a silly question but the "&&" can only be used to compare two values for a boolean value, correct? I was trying to use it in my arrays and I think I might have been using it wrong. Any example code of someone using pin arrays that don't begin at pin 0 would be really helpful. I'm confused on the syntax and I'm not quite sure what keywords to search for. Any help would be greatly appreciated!

the code is here:

Code: [Select]
int sr04TrigPins[4] = {0,1,2,3};
int sr04EchoPins[4] = {4,5,6,7};
unsigned char sr04Control[4] = {102,103,104,105};         // MIDI CC Control Values 102-105(undefined)
#define  midichannel 0;                                 
unsigned char status;


void setup()
{
  Serial.begin(115200); // connect to the serial port 115200
  pinMode(sr04TrigPins[], OUTPUT);
  digitalWrite(sr04TrigPins[], LOW);
  pinMode(sr04EchoPins[], INPUT);
}


void loop()
{
  for(int sr04TrigPins=0; sr04TrigPins < 4; sr04TrigPins++;)
  {
    digitalWrite(sr04TrigPins[], LOW);
    delayMicroseconds(2);
    digitalWrite(sr04TrigPins[],HIGH);
    delayMicroseconds(10);
    digitalWrite(sr04TrigPins[], LOW);
  }
  for(int sr04EchoPins=4; (sr04EchoPins >= 4) && (sr04EchoPins < 8); sr04EchoPins++;)
  {
    long duration = pulseIn(sr04EchoPins[], HIGH);
  }
    int distance = (duration/2) / 29.1;
    //Serial.println(distance);
    int ccVal = map(distance, 0, 110, 0, 127);
  for(int sr04Control=102; (sr04Control>=102) && (sr04Control<106); sr04Control++;)
  { 
    MIDI_TX(0xB0,sr04Control[],ccVal);
            }
  }


void MIDI_TX(unsigned char MESSAGE, unsigned char PITCH, unsigned char VELOCITY)
{
  status = MESSAGE + midichannel;
  Serial.print(status);
  Serial.print(PITCH);
  Serial.print(VELOCITY);
}



the error that I get from the compiler is "Arduino: 1.6.5 (Mac OS X), Board: "Arduino/Genuino Uno"

distancesensorsketch2.ino: In function 'void setup()':
distancesensorsketch2:11: error: expected primary-expression before ']' token
distancesensorsketch2:12: error: expected primary-expression before ']' token
distancesensorsketch2:13: error: expected primary-expression before ']' token
distancesensorsketch2.ino: In function 'void loop()':
distancesensorsketch2:19: error: expected ')' before ';' token
distancesensorsketch2:19: error: expected primary-expression before ')' token
distancesensorsketch2:19: error: expected ';' before ')' token
distancesensorsketch2:27: error: expected ')' before ';' token
distancesensorsketch2:27: error: expected primary-expression before ')' token
distancesensorsketch2:27: error: expected ';' before ')' token
distancesensorsketch2:31: error: 'duration' was not declared in this scope
distancesensorsketch2:34: error: expected ')' before ';' token
distancesensorsketch2:34: error: expected primary-expression before ')' token
distancesensorsketch2:34: error: expected ';' before ')' token
expected primary-expression before ']' token

  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences."

UKHeliBob

Code: [Select]
 pinMode(sr04TrigPins[], OUTPUT);
You can't refer to a whole array of pin numbers at once like that, you have to iterate through them with a for loop and deal with each of them individually.
Code: [Select]

for (int p = 0; p < 4; p++)
{
  pinMode(sr04TrigPins[p], OUTPUT);
  digitalWrite(sr04TrigPins[p], LOW);
  pinMode(sr04EchoPins[p], INPUT);
}
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

PaulS

Quote
I know its a silly question but the "&&" can only be used to compare two values for a boolean value, correct?
What is on either side needs to evaluate to true or false, but that doesn't mean that the term has to be a boolean. i > 40 is true for some values of i, but false for others.

Code: [Select]
 pinMode(sr04TrigPins[], OUTPUT);
  digitalWrite(sr04TrigPins[], LOW);
  pinMode(sr04EchoPins[], INPUT);

You can't use an array like that.

Code: [Select]
for(byte i=0; i<4; i++)
{
  pinMode(sr04TrigPins[i], OUTPUT);
  digitalWrite(sr04TrigPins[i], LOW);
  pinMode(sr04EchoPins[i], INPUT);
}

is the proper way.

Code: [Select]
 for(int sr04TrigPins=0; sr04TrigPins < 4; sr04TrigPins++;)

sr04TrigPins is the name of an array. Don't create a scalar variable with the same name.

See the above correction to fix the rest of the problems in your code.

theotherjenkutler

Thank you guys! This has been an incredible help. i feel like i finally am starting to get the hang of writing an array (after much confusion!) I really appreciate the feedback and the time you took to reply . What an incredible community!

Here is my revised code-

Code: [Select]
int sr04TrigPins[4] = {0,1,2,3};
int sr04EchoPins[4] = {4,5,6,7};
unsigned char sr04Control[4] = {102,103,104,105};         // MIDI CC Control Values 102-105(undefined)
#define  midichannel 0;                                 
unsigned char status;
long duration = 0;


void setup()
{
  Serial.begin(115200); // connect to the serial port 115200
  for (int p = 0; p<4; p++)
  {
    pinMode(sr04TrigPins[p], OUTPUT);
    digitalWrite(sr04TrigPins[p], LOW);
    pinMode(sr04EchoPins[p], INPUT);
  }
}


void loop()
{
  for(int q=0; q < 4; q++)
  {
    digitalWrite(sr04TrigPins[q], LOW);
    delayMicroseconds(2);
    digitalWrite(sr04TrigPins[q],HIGH);
    delayMicroseconds(10);
    digitalWrite(sr04TrigPins[q], LOW);
  }
  for(int r=4; (r >= 4) && (r < 8); r++)
  {
    long duration = pulseIn(sr04EchoPins[r], HIGH);
  }
    int distance = (duration/2) / 29.1;
    //Serial.println(distance);
    int ccVal = map(distance, 0, 110, 0, 127);
  for(int s=102; (s>=102) && (s<106); s++)
  { 
    MIDI_TX(0xB0,sr04Control[s],ccVal);
            }
  }


void MIDI_TX(unsigned char MESSAGE, unsigned char PITCH, unsigned char VELOCITY)
{
  status = MESSAGE + midichannel;
  Serial.print(status);
  Serial.print(PITCH);
  Serial.print(VELOCITY);
}



The compiler certainly seems less confused. Can't wait to get home and try it with the sensors. Thanks again, guys!

PaulS

Quote
The compiler certainly seems less confused.
It wasn't confused before. It knew exactly what was wrong.

PaulMurrayCbr

#5
Sep 01, 2015, 04:06 am Last Edit: Sep 01, 2015, 04:08 am by PaulMurrayCbr
Quote
I know its a silly question but the "&&" can only be used to compare two values for a boolean value, correct?
In C, a non-zero integer value is treated as true, and non-null pointers are also treated as true. This applies in &&, ||, and ?: expressions, as well as in conditional clauses in while(), if(), and for(;;).

I think the same applies to floating point values, but you would never use floating point values in that way.

On the arduino, LOW is zero and HIGH is non-zero (I think 1). This means that you can use LOW and HIGH as more-or-less synonyms of false and true in boolean expressions.

Code: [Select]

  while(!digitalRead(3)) {
    // button 3 is pressed. Do something.
  }


The main gotcha is that == HIGH and != HIGH won't match any old nonzero value in the way that && and || will: the values must be exactly 1 (I think).

UKHeliBob

Quote
i feel like i finally am starting to get the hang of writing an array
Good for you in getting it working.  Now let's improve it.

Firstly you have
Code: [Select]
int sr04TrigPins[4] = {0,1,2,3};
int sr04EchoPins[4] = {4,5,6,7};

None of the values held in the arrays are greater than 255 so would fit in a byte, and are not going to change while the program is running, so why not save some memory and make it impossible to change the values accidentally by using
Code: [Select]
const byte sr04TrigPins[] = {0,1,2,3};
const byte sr04EchoPins[] = {4,5,6,7};
Note that the compiler will work out the number of elements in the arrays if the initial values are given as above.

Secondly, if you decide to improve the program by changing the number of sensors you will need to go through the program and revise all of the instances of the 'magic' number 4 where it relates to the number of sensors.  In doing this it is easy to miss some.  You can prevent this happening and also make the program more readable by substituting a variable for the number, then you only need to change the value of the variable in one place and the whole program will be updated.  So, you could declare a global variable like this
Code: [Select]
const byte NUMBER_OF_SENSORS = 4;
then use it like this
Code: [Select]

  for(int q=0; q < NUMBER_OF_SENSORS; q++)
  {
    digitalWrite(sr04TrigPins[q], LOW);
    delayMicroseconds(2);
    digitalWrite(sr04TrigPins[q],HIGH);
    delayMicroseconds(10);
    digitalWrite(sr04TrigPins[q], LOW);
  }

Better still, get the program to work out how many sensors there are by looking at the array like this
Code: [Select]
const byte NUMBER_OF_SENSORS = sizeof(sr04TrigPins) / sizeof(sr04TrigPins[0]);
This works by taking the total number of bytes used by the array and dividing it by the number of bytes used by a singe element.  It will work whatever type of variable is used by the array so will continue to work if the array data type is changed if/when the program is updated.

This may seem like a lot of work for no gain when the original program already works but will pay dividends in the long term if you use such defensive programming techniques with more complicated programs.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

theotherjenkutler

Yes! Thanks!
I feel like the hardest thing in learning to write code is to learn how to think about it. This is extremely helpful! I will post a revised code.

Go Up