Inventeam Project

photon
Tags: #<Tag:0x00007fe2258dde98>

#1

Hi everyone, i am a high school student on an InvenTeam and i am attempting to create code for 2 grove hall effects sensors so that it will measure the number of magnets passing them. I have compiled some code below and have gotten several errors that i am not sure how to fix. I am new to coding and still getting the hang of it. Thank you!

Errors:
grovesensors.ino:21:21: ‘w_isNearMagnet’ cannot be used as a function

grovesensors.ino:31:21: ‘h_isNearMagnet’ cannot be used as a function

grovesensors.ino:44:1: expected initializer before ‘}’ token

grovesensors.ino:46:2: expected unqualified-id before ‘if’

grovesensors.ino:50:2: expected unqualified-id before ‘else’

Code:

#define W D2 //the waist sensor is on this pin
#define H D5 //the hip sensor is on this pin

	int w_state=HIGH;//sets the waist measurement state for a grove hall effect sensor
 	int h_state=HIGH;//sets the hip measurement state for a grove hall effect sensor
 	int w_count=70;//our testing rig has an initial waist size of 70cm
 	int h_count=82;//our testing rig has an initial hip size of 82cm
 	  bool w_isNearMagnet;
 	  bool h_isNearMagnet;
void setup()
{
 	pinMode(D2, INPUT);
 	pinMode(D5, INPUT);
 	
 	
 
}
 
void loop()
{
	if (w_isNearMagnet())//if the Grove sensor is near the magnet?
	{
		measure();
	}
	else
	{
		delay(3500);
	}
{
    
	if (h_isNearMagnet())//if the Grove sensor is near the magnet?
	{
		measure();
	}
	else
	{
		delay(3500);
	}
}

/*If the hall sensor is near the magnet whose south pole is facing up, */
/*it will return ture, otherwise it will return false.				*/
bool w_isNearMagnet()
}
	int w_sensorValue = digitalRead(W);
	if(w_sensorValue == LOW)//if the waist sensor value is LOW
	{
	COUNT++(w_count + COUNT);//count each low state and add it to the intial waist size.
	}
	else
	{
		return false;//no,return false
	}
}

bool h_isNearMagnet()
}
	int h_sensorValue = digitalRead(H);
	if(h_sensorValue == LOW)//if the hip sensor value is LOW
	{
	COUNT++(h_count + COUNT);//count each low state and add it to the intial hip size.
	}
	else
	{
		return false;//no,return false
	}
}
void measure()
{
	digitalWrite(W,LOW);
	digitalWrite(H,LOW);
	
}
void ratio()
{
	ratio=(((w_sensorValue/h_sensorValue )));
}
    Particle.publish("ratio", int"ratio", PRIVATE)
}

#2

@rkessler, how are you compiling your code?

You have a number of mismatched curly brackets. This will create a lot of errors. Make sure you have an open curly bracket to start a function or statement body and a close curly bracket to end the body. Make sure to all these brackets occur in matched pairs (no extras).

Second, you are declaring your function prototypes prior to setup but you don’t have brackets to make them functions, thus the first two errors.

Last thing (for now), is that you declare w_sensorValue and h_sensorValue locally to their respective functions. This means these variables will “disappear” when the code exits the function. So the ratio() function will not work unless you declare these globally.

Let me know how it goes after these recommendations.


#3

Thank You, ill fix it up Monday and see where i go from here


#5

Alright, i have fixed the code and narrowed it down to one error

Error:
grove.ino:39:1: expected declaration before ‘}’ token

Code:

#define W D2 //the waist sensor is on this pin
#define H D5 //the hip sensor is on this pin

	int w_state=HIGH;//sets the waist measurement state for a grove hall effect sensor
 	int h_state=HIGH;//sets the hip measurement state for a grove hall effect sensor
 	int w_count=70;//our testing rig has an initial waist size of 70cm
 	int h_count=82;//our testing rig has an initial hip size of 82cm
 	 bool w_isNearMagnet();
 	  bool h_isNearMagnet();
int w_sensorValue = digitalRead(W); 
int h_sensorValue = digitalRead(H);


void setup() {
    
    pinMode(D2, INPUT);
 	pinMode(D5, INPUT);

}

void loop() {
   if (w_isNearMagnet())//if the Grove sensor is near the magnet?
	{
		measure();
	}
	else
	{
		delay(3500);
	}
	if (h_isNearMagnet())//if the Grove sensor is near the magnet?
	{
		measure();
	}
	else
	{
		delay(3500);
}
}
}

void measure()
{
	digitalWrite(W,LOW);
	digitalWrite(H,LOW);
	
	if(h_sensorValue == LOW)//if the hip sensor value is LOW
	{
	COUNT++(h_count + COUNT);//count each low state and add it to the intial hip size.
	}
	else
	{
		return false;//no,return false
	}
    if(w_sensorValue == LOW)//if the waist sensor value is LOW
	
	COUNT++(w_count + COUNT);//count each low state and add it to the intial waist size.
	
	else
	
		return false;//no,return false
	
}

void ratio()
{
	ratio=(((w_sensorValue/h_sensorValue )));
}
    Particle.publish("ratio", int"ratio", PRIVATE)
}

#6

@rkessler, one more time!

The variable declarations belong where you have them but the assignments to return values from those functions don’t. Those belong in setup(), loop() or a function depending on whether they need to be read regularly or just once. For example:

int w_sensorValue; 
int h_sensorValue;

void measure() {
  w_sensorValue = digitalRead(W); 
  h_sensorValue = digitalRead(H); 
  • You have W and H defined as pins D2 and D5. You also declare them as INPUT in setup(). However, in measure() you have this which goes counter to those declarations:
	digitalWrite(W,LOW);
	digitalWrite(H,LOW);
  • You still have an unblanced set of curly brackets in your code. See:
void loop() {
   if (w_isNearMagnet())//if the Grove sensor is near the magnet?
	{
		measure();
	}
	else
	{
		delay(3500);
	}
	if (h_isNearMagnet())//if the Grove sensor is near the magnet?
	{
		measure();
	}
	else
	{
		delay(3500);
}
}    <-- !!!
}    <-- !!!

and,

void ratio()
{
	ratio=(((w_sensorValue/h_sensorValue )));
}   <-- !!!
    Particle.publish("ratio", int"ratio", PRIVATE)
}
  • Note the missing semi-colon after the Particle.publish("ratio", int"ratio", PRIVATE) line above!
  • BTW, the tripple brackets on this line serve no purpose and you haven’t declared ratio anywhere. The variable can’t be the same name as the function!
	ratio=(((w_sensorValue/h_sensorValue )));

One thing to keep in mind is that you can declare functions other than void. For example, ratio() could be declared as int calc_ratio(). The function then returns the calculated ratio value like this:

int calc_ratio()
{
   int ratio=w_sensorValue/h_sensorValue;
   Particle.publish("ratio", int"ratio", PRIVATE);
   return(ratio);
}

Keep going! :wink:


#7

Alright, my code compiles now, i can hold the grove hall effect sensor up to the magnet and it gets a signal, but it does not publish to my event board. Any ideas? Or is there an issue i’m overlooking?

#define W D2 //the waist sensor is on this pin
#define H D5 //the hip sensor is on this pin

	int w_state=HIGH;//sets the waist measurement state for a grove hall effect sensor
 	int h_state=HIGH;//sets the hip measurement state for a grove hall effect sensor
 	int w_count=70;//our testing rig has an initial waist size of 70cm
 	int h_count=82;//our testing rig has an initial hip size of 82cm
  bool w_isNearMagnet = W;
 	  bool h_isNearMagnet=false;
 	  
int w_sensorValue;
int h_sensorValue;


void setup() {
    
     pinMode(D2, INPUT);
 	 pinMode(D5, INPUT);

}

void loop() {
   if (w_isNearMagnet)//if the Grove sensor is near the magnet?
	{
		measure();
	
	}
	else
	{
		delay(3500);
	}
	if (h_isNearMagnet)//if the Grove sensor is near the magnet?
	{
		measure();
	}
	else
	{
		delay(3500);
	}
}
bool measure() {
    
	digitalWrite(W, LOW);
	digitalWrite(H, LOW);
		h_sensorValue = digitalRead(H);
		w_sensorValue = digitalRead(W);
	if(h_sensorValue == LOW)//if the hip sensor value is LOW
	{
	h_count +=1 ;//count each low state and add it to the intial hip size.
	}
	else
	{
		return false;//no,return false
	
	
	}
    if(w_sensorValue == LOW)//if the waist sensor value is LOW
	{
	//COUNT(w_count + COUNT);//count each low state and add it to the intial waist size.
	w_count+=1;
	}
	else
	{
		return false;//no,return false
	}
}

int calc_ratio() {
	int ratio=w_sensorValue/h_sensorValue;
	
	
    Particle.publish("ratio","ratio" , PRIVATE);
	
    return (ratio); 
}

#8

Where exactly in your code are you expecting to publish something to the Particle cloud? Also, I see you haven’t removed these two lines from measure() since H and W are INPUTs not OUTPUTs as I mentioned before:

	digitalWrite(W, LOW);
	digitalWrite(H, LOW);

#9

Ok, i have removed those two lines of code, and it compiles.

Here is where i am trying to publish:

int calc_ratio() {
	int ratio=w_sensorValue/h_sensorValue;
	
	
    Particle.publish("ratio","ratio" , PRIVATE);
	
    return (ratio); 
}

#10

@rkessler, where are you calling calc_ratio()?


#11

It would appear i do not call it anywhere, i was under the impression it would run like a chain of events down the code, where would be the place to call it? Thank you for all your help by the way.


#12

@rkessler, this is where things get a little tougher. Take a look at your code starting at loop(). You test two bool variables (one which you initialize to false and the other to W !) but nowhere in your code do you actually set these. Before proceeding, I suggest you pull back a bit and think about the logic of what you are trying to achieve. As you have it now, there is a bunch of unconnected code and logic which will not work for what you are trying to do. For example, You call measure() where it increments h_count and w_count but do nothing with these. Furthermore, measure() returns a bool (true or false) but you never do anything with that return value. I suggest you draw a flowchart of what you are trying to do and then go from there. Your original post said:

Is this number of magnets per second? An ever increasing sum?


#13

We are inventing a device that measures a person’s hip and waist then publishes a ratio to a cloud based service. Each magnet on a strip of magnets, (Each magnet is exactly 1 cm apart from each other), passes each of the grove sensors by a person moving a strip of magnets by the sensor when putting on a belt.


#14

@rkessler, good start! So one sensor for the waist and the other for the hip? Are they on the same belt?

Now, think about how you might indicate the START and completion of a measurement. Push a button to start? Wait for no more magnet counts for N seconds to indicate completion? You get the idea.


#15

The code should begin as soon as the photon turns on, heres a flow chart i’ve built below.


#16

@rkessler, you have two paths representing each sensor. However, you have a Wait 3.5 seconds task that is specifically tied to the waist sensor. What is the purpose of the delay? I think you need to rethink that logic.

Also, when a person puts on the “belt” how quickly will they pull the belt trough the “buckle” holding the sensors? I ask because I suspect the speed depends on the individuals. So, how fast the sensors are sampled will be affected by how your code is written.


#17

I’d rather decouple the digitalRead() part from the calculation part in your measure() function.
That way you can even use interrupts for very fast readings of the hall sensors.

You also need to understand the concept that functions don’t just get called because they exist. Someone needs to call them.
The apparent “odd-balls” here are setup() and loop() since they seem to just run without any function calling them.
But that is only due to the hidden fact how the device OS handles them.

In essence there is a main() function which will be called upon bootup by the bootloader and this function looks somewhat like this

void main() {
  // do some preparation
  setup();             // call user implemented setup() function
  // do some one-time stuff
  while(1) {           // infinite loop
    loop();            // call user implemented loop() function
    // do some regular stuff 
  }
}

Any function you want to be called needs to be called from setup() or loop() (directly or indirectly).
No call - no execution.


#18

@peekay123 The wait 3.5 seconds applies to both sensors, i just forgot to draw a line. I have gotten it to publish, but once i put both sensors on a magnet, the photon starts flashing red, and crashes, giving me this error…

panic, usage_fault

Heres my code again if it helps:

#define W D2 //the waist sensor is on this pin
#define H D5 //the hip sensor is on this pin

	int w_state=HIGH;//sets the waist measurement state for a grove hall effect sensor
 	int h_state=HIGH;//sets the hip measurement state for a grove hall effect sensor
 	int w_count=70;//our testing rig has an initial waist size of 70cm
 	int h_count=82;//our testing rig has an initial hip size of 82cm
  bool w_isNearMagnet = W;
 	  bool h_isNearMagnet=false;
 	  
int w_sensorValue;
int h_sensorValue;


void setup() {
    
     pinMode(D2, INPUT);
 	 pinMode(D5, INPUT);

}

void loop() {
   if (w_isNearMagnet)//if the Grove sensor is near the magnet?
	{
		measure();
		calc_ratio();
	
	}
	else
	{
		delay(3500);
	}
	if (h_isNearMagnet)//if the Grove sensor is near the magnet?
	{
		measure();
		calc_ratio();
	}
	else
	{
		delay(3500);
	}
}
bool measure() {
		h_sensorValue = digitalRead(H);
		w_sensorValue = digitalRead(W);
	if(h_sensorValue == LOW)//if the hip sensor value is LOW
	{
	h_count +=1 ;//count each low state and add it to the intial hip size.
	}
	else
	{
		return false;//no,return false
	
	
	}
    if(w_sensorValue == LOW)//if the waist sensor value is LOW
	{
	//COUNT(w_count + COUNT);//count each low state and add it to the intial waist size.
	w_count+=1;
	}
	else
	{
		return false;//no,return false
	}
}

int calc_ratio() {
	int ratio=w_sensorValue/h_sensorValue;
	
	
    Particle.publish("ratio", PRIVATE);
	
    return (ratio); 
}

#19

You need to prevent DIV/0 exceptions otherwise your code will crash on STM32 devices like the Photon.

The way you have written it, when you hadn’t got a signal from the “one” you wouldn’t be reading “the other” sensor for at least 3.5seconds either. Is this really what you want?
Normally with two “independent” sensors, you would also keep reading the sensors independently.

I’m still not entirely sure about your setup, but with these 3.5sec delays I’d imagine that you’d need to tighten these strips reeeely slow to properly count the magnets - and then I’d imagine many miscounts.
Since we don’t know the size of your magnets I’d just assume 1cm magnet with plus 1cm between magnets. With that: When you pull these strips through at a constantt speed of about 10cm per second you’d be reading the sensor about 100 times while the magnet is present, then you will get one reading where the magnet is gone and will miss 35cm of strip being pulled past while not reading but idling in delay(3500).


#20

Our magnets are 1 cm apart, and we realize that they will need to be pulled very slowly. i have taken the wait commands out and have put the magnet sensing code into their own functions, one for each sensor. I am not sure how to fix the DIV/0 error though. Your help is appreciated. Thank you.

Code:

#define W D2 //the waist sensor is on this pin
#define H D5 //the hip sensor is on this pin

	int w_state=HIGH;//sets the waist measurement state for a grove hall effect sensor
 	int h_state=HIGH;//sets the hip measurement state for a grove hall effect sensor
 	int w_count=70;//our testing rig has an initial waist size of 70cm
 	int h_count=82;//our testing rig has an initial hip size of 82cm
  bool w_isNearMagnet = W;
 	 bool h_isNearMagnet=H;
 	  
int w_sensorValue;
int h_sensorValue;


void setup() {
    
     pinMode(D2, INPUT);
 	 pinMode(D5, INPUT);

}

void loop() {
sensor1();
sensor2();
}

void sensor1() {
    if (w_isNearMagnet)//if the Grove sensor is near the magnet?
		measure();
		
   
}
void sensor2() {
    	if (h_isNearMagnet)//if the Grove sensor is near the magnet?
		measure();
		
}

bool measure() {
		h_sensorValue = digitalRead(H);
		w_sensorValue = digitalRead(W);
	if(h_sensorValue == LOW)//if the hip sensor value is LOW
	{
	h_count +=1 ;//count each low state and add it to the intial hip size.
	calc_ratio();
	}
	else
	{
		return false;//no,return false
	}
	
    if(w_sensorValue == LOW)//if the waist sensor value is LOW
	{
	//COUNT(w_count + COUNT);//count each low state and add it to the intial waist size.
	w_count+=1;
	calc_ratio();
	}
	else
	{
		return false;//no,return false
	}
}

int calc_ratio() {
	int ratio=w_sensorValue/h_sensorValue;
    Particle.publish("ratio", PRIVATE);
    return (ratio); 
}

#21

If you use interrupts you don’t - you can probably pull it with 1m/s without issue.

Hmm, how would you not divide by zero? :wink:

float calc_ratio() {
  if (h_sensorValue != 0) {  // <-- make sure the divisor is NOT zero
    float ratio = w_sensorValue / h_sensorValue;
    char txt[16];
    snprintf(txt, sizeof(txt), "%.2f", ratio);
    Particle.publish("ratio", txt, PRIVATE);
    return (ratio); 
  }
  else {
    Particle.publish("ratio", "DIV/0", PRIVATE);
    return -1; 
  }    
}

(also changed from int to float - divisions usually don’t come as integer results and maybe you want to publish the value of the ratio too)