Hi I need a servo to be activated by a hall effect sensor. I need the servo to start at 0 degrees then once the hall effect sensor is triggered I need the servo to move to 170 degrees and stay there. Once the hall effect sensor is triggered again I need it to move back to 0 degrees. So far I have come up with the following but need help.
#include <Servo.h> //include the servo library
Servo servo; // create servo object to control a servo
int pos = 0; // variable to store the servo position
int inPin = 0; // select the input pin for the Hall Effect Sensor
int servoPin = 9; // select the pin for the servo
int val = 0; // variable to store the value coming from the sensor
int mean = 508;
int sensitivity = 20;
void setup()
{
servo.attach(9); // attaches the servo on pin 9 to the servo object
{
pinMode(servoPin, OUTPUT); // declare the servo as an OUTPUT
}
}
void loop()
{
for(int servoPin; pos = 0;)
val = analogRead(inPin); // read the Hall Effect Sensor
if (val > (mean + sensitivity) || val < (mean - sensitivity))
{
digitalWrite(servoPin, pos += 170); // goes from 0 degrees to 170 degrees
servo.write(pos); // tell servo to go to position in variable ‘pos’
}
for(int servoPin; pos = 170;)
val = analogRead(inPin); // read the Hall Effect Sensor
if (val > (mean + sensitivity) || val < (mean - sensitivity))
{
digitalWrite(servoPin, pos -= 170); // goes from 170 degrees to 0 degrees
servo.write(pos); // tell servo to go to position in variable ‘pos’
}
}
Thanks in advance.
Have a look on the main site at the reference page to see how to construct a ''for' loop
I've already looked at that and that really doesn't answer my question.
Well, you haven't actually asked a question, you said you needed help. And Groove certainly offered help, because your for loops are missing an element. If you looked at the page mentioned, and haven't changed the code, then you clearly haven't understood it completely and might want to look at it again. You need three expressions in your for (): initialization, termination condition, and loop increment.
Don't be so quick to dismiss help...
You said that you needed help, but you didn't say what sort of help you needed, so I looked at your code and saw that it couldn't possibly work, because of the way your for loops were constructed.
I thought it better that you took a look at how to do it properly, and rather than reiterate a perfectly good explanation, I'd link to it, so you could go off and see where you had gone wrong.
Then you could correct it, and come back with further questions, which I would have been happy to answer.
I certainly wasn't going to write your assignment for you.
You should also look at the rules for variable scope.
Sorry I didn't mean to sound dismissive to your help Groove. This is the first and only time I will need to program an Arduino as I need to create this program for a project for work. If you can see what I am missing in my original code and help me out in order to achieve what I stated I needed this code to do I would be grateful.
You've said a couple of times that you need help. Can you be more specific with what the current issue you're working on is?
I just need to make the code that I have listed above work. It needs to be triggered by the hall effect sensor to go from 0 to 170 then sit at 170. Then the next time the hall effect sensor is activated it needs to go from 170 to 0 and sit at zero. Then it needs to repeat the process until I turn off the power.
And how precisely is it failing right now?
According to what Groove said my "for" argument is set up incorrectly. Would this be correct to do what I need to do?
#include <Servo.h> //include the servo libary
Servo servo; // create servo object to control a servo
// a maximum of eight servo objects can be created
int pos = 0; // variable to store the servo position
int inPin = 8; // select the input pin for the Hall Effect Sensor
int servoPin = 9; // select the pin for the servo
int val = 0; // variable to store the value coming from the sensor
int mean = 508;
int sensitivity = 20;
void setup()
{
servo.attach(9); // attaches the servo on pin 9 to the servo object
{
pinMode(servoPin, OUTPUT); // declare the servo as an OUTPUT
}
}
void loop()
{
for(int pos = 0; pos < 170; pos += 170)
val = analogRead(inPin); // read the Hall Effect Sensor
if (val > (mean + sensitivity) || val < (mean - sensitivity))
{
digitalWrite(servoPin, pos += 170); // goes from 0 degrees to 170 degrees
servo.write(pos); // tell servo to go to position in variable ‘pos’
}
for(int pos = 170; pos>=1; pos-=170)
val = analogRead(inPin); // read the Hall Effect Sensor
if (val > (mean + sensitivity) || val < (mean - sensitivity))
{
digitalWrite(servoPin, pos -= 170); // goes from 170 degrees to 0 degrees
servo.write(pos); // tell servo to go to position in variable ‘pos’
}
}
Why are you reading the value of the hall-effect sensor inside the for loops? Shouldn't you do that before the for loops?
Your increment for the for loop means that the loop body will execute once and only once. Given that, what possible benefit does the for loop provide?
The Servo library owns the pin once you invoke the Servo::attach() function. Setting the mode of the pin afterwords is wrong.
Are you trying to set the servo position using Servo::write() (the correct way to do it) or using digitalWrite() (the wrong way to do it)? You can't do both. The digitalWrite() function's second argument is either HIGH or LOW, not some arbitrary value.
It doesn't look like it would work. You really don't need those for loops, loop will take care of that. All you need there, is to detect the hall effect sensor. When you see it when you weren't seeing it before, check where the servo is with Servo.read. If it's at 0, send it to 170 and vice versa.
This hall effect sensor detection seems odd
if (val > (mean + sensitivity) || val < (mean - sensitivity))
When you see the hall effect sensor, what value does analog read provide? If it's ~508, that if won't work. This is better in that case:
if ((val < (mean + sensitivity)) && (val > (mean - sensitivity)))
edit: added brackets
So let me go into a little more detail on how I came to the program in my original post. I combine this program for running a servo:
#include <Servo.h> //include the servo libary
Servo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created
int pos = 0; // variable to store the servo position
void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
}
void loop()
{
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(15); // waits 15ms for the servo to reach the position
}
for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(15); // waits 15ms for the servo to reach the position
}
}
which turns a servo on a delay. With this program which used a hall effect sensor to turn on a LED:
int inPin = 0; // select the input pin for the Hall Effect Sensor
int ledPin = 13; // select the pin for the LED
int val = 0; // variable to store the value coming from the sensor
int mean = 508;
int sensitivity = 20;
void setup() {
pinMode(ledPin, OUTPUT); // declare the ledPin as an OUTPUT
}
void loop() {
val = analogRead(inPin); // read the Hall Effect Sensor
if (val > (mean + sensitivity) || val < (mean - sensitivity)) {
digitalWrite(ledPin, HIGH); // turn the ledPin on
}
else {
digitalWrite(ledPin, LOW); // turn the ledPin off
}
}
I used both programs separately with no problems but I can't seem to find the right way to combine the two to make the hall effect sensor be the trigger for the servo to move.
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(15); // waits 15ms for the servo to reach the position
}
You only need to loop like this is when you need to slow the sweep down.
(and being pedantic, as I am, it goes from 0 to 179 "degrees", not as the comment says.)
much simpler is a myservo.write (0); or a myservo.write (180);
In the first sketch, the servo is moved in 1 degree increments, in the for loop, with a 15 millisecond pause between steps.
In the second sketch, you turn on a LED when the sensor reading exceeds some value, and turn it off when the reading falls below that threshold.
Combining the two sketches is easy:
#include <Servo.h> //include the servo libary
Servo myservo; // create servo object to control a servo
int pos = 0; // variable to store the servo position
int inPin = 0; // select the input pin for the Hall Effect Sensor
void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
}
void loop()
{
val = analogRead(inPin); // read the Hall Effect Sensor
if (val > (mean + sensitivity) || val < (mean - sensitivity))
{
// Move the servo one way
for(pos = 0; pos <= 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(15); // waits 15ms for the servo to reach the position
}
}
else
{
// Move the servo the other way
for(pos = 180; pos>=0; pos-=1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(15); // waits 15ms for the servo to reach the position
}
}
}
I fixed "my" comments...
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
{ taps fingers impatiently }
Try this:
int inPin = 0; // select the input pin for the Hall Effect Sensor
int ledPin = 13; // select the pin for the LED
int val = 0; // variable to store the value coming from the sensor
int mean = 508;
int sensitivity = 20;
void setup()
{
pinMode(ledPin, OUTPUT); // declare the ledPin as an OUTPUT
}
void loop()
{
static bool DetectingHallEffect=false; // We will likely detect the hall effect sensor several times, make sure we only react when we first detect it.
val = analogRead(inPin); // Read the Hall Effect Sensor
if((val < (mean + sensitivity)) && (val > (mean - sensitivity))) // Do we see the sensor?
{
if(!DetectingHallEffect) // Make sure we only do this once for each detection of the hall effect sensor
{
DetectingHallEffect=true; // This will be true until we don't see the sensor any more
if(servo.read()==0) // Check where the servo is and move it to the other position
servo.write(170);
else
servo.write(0);
}
}
else
DetectingHallEffect=false; // Don't see the sensor any more, permit action the next time we see it
}
Note that I've assumed that the analogread is close to the mean value when the sensor is detected, rather than the way you have it in your led example. Note also that I don't have a compiler on this machine to syntax check it. Might get you a bit closer though.
AWOL:
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
{ taps fingers impatiently }
This was the original program. I changed mine to move at 170 degree increments.
Both of the examples above look good but again since my knowledge of programming is VERY limited I don't know which one would be better to use. Maybe a third party can help?
wildbill:
Try this:
int inPin = 0; // select the input pin for the Hall Effect Sensor
int ledPin = 13; // select the pin for the LED
int val = 0; // variable to store the value coming from the sensor
int mean = 508;
int sensitivity = 20;
void setup()
{
pinMode(ledPin, OUTPUT); // declare the ledPin as an OUTPUT
}
void loop()
{
static bool DetectingHallEffect=false; // We will likely detect the hall effect sensor several times, make sure we only react when we first detect it.
val = analogRead(inPin); // Read the Hall Effect Sensor
if((val < (mean + sensitivity)) && (val > (mean - sensitivity))) // Do we see the sensor?
{
if(!DetectingHallEffect) // Make sure we only do this once for each detection of the hall effect sensor
{
DetectingHallEffect=true; // This will be true until we don't see the sensor any more
if(servo.read()==0) // Check where the servo is and move it to the other position
servo.write(170);
else
servo.write(0);
}
}
else
DetectingHallEffect=false; // Don't see the sensor any more, permit action the next time we see it
}
Note that I've assumed that the analogread is close to the mean value when the sensor is detected, rather than the way you have it in your led example. Note also that I don't have a compiler on this machine to syntax check it. Might get you a bit closer though.
Wild Bill this looks really good my only question is will the servo stay at that position? I need it to start at zero then when hall effect is true go to 170 and stay there and then hall effect is true again go to 0 and stay there.