Using Hall Effect Sensors

Our team is using hall effect sensor to detect the position of our elevator https://lh5.googleusercontent.com/Ngu0blYCnGO-NY7JoNbViHr-runBkHCfn4sBfsuqSBRbDyeHPAgp9TfR0pAQoJDnpVd6OCIU0zE=w1256-h803
This picture should give a good picture of what we are trying to do.
I want to be able to use hall effect sensors to set the height of the elevator fork contraption to the height of one tote or 2 or 3. Using one hall effect sensor mounted on that elevator and mounting the magnets in proper places could work I think.
What I need to know is how to program the team 971 WCP hall effect sensors in java. I currently have a program that uses setpoint PIDSubsystems, but my code crashes when i use the button to set the setpoint. How do you guys go about using hall effect as sensors?

Your photo didn’t display for me.

If you’re using something like the WCP hall effect sensor, most teams would treat that as a limit switch, observe its state via a DigitalInput, and count the number of times the switch tripped in code. The PID is a pretty long way to solving your problem.

I would recommend two limit switches on your elevator – one that trips when you are in the lowest position, and the one that rides on the elevator triggering at the various tote heights (note that I think of the hall effect sensor as a limit switch). This lets you know initially when the elevator is in the lowest position, so that you can correctly determine at what level you’re at.

Alternatively, you can always start the robot with the elevator at/below the first position, so that you know your starting position. I’m not a fan of this approach because it doesn’t work well if your robot crashes during a match.

I’m assuming you are trying to put the Hall Effect sensor on the actual elevator carriage with the magnets mounted on the sides of the rails the elevator rides in (or something similar). I would have a counter that increments or decrements every time you pass a magnet, depending on the current direction of the elevator. Our team is using a Hall Effect sensor with an encoder using the Hall Effect to zero the encoder value. Works like a charm so far.

A sensor with intermittent points of reference as you describe is not a good candidate for a PID sensor. To use PID, you really want a sensor that provides continuous feedback, like a potentiometer or a range finder. More details here.

So I have made a file to make the motor turn the elevator up and down based on the magnet, except that it doesn’t react based on the magnet.

package org.usfirst.frc.team2847.robot.commands;

import org.usfirst.frc.team2847.robot.Robot;

import edu.wpi.first.wpilibj.command.Command;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;

/**
 *
 */
public class MagicElevator extends Command {

	double dir;
	double go;
	double more;
	boolean done;

	public MagicElevator(double setpoint) {
		// Use requires() here to declare subsystem dependencies
		requires(Robot.elevator);
		this.dir = dir + setpoint;
	}

	// Called just before this Command runs the first time
	protected void initialize() {
		System.out.println(this);
		Robot.elevator.torro(go);
	}

	// Called repeatedly when this Command is scheduled to run
	protected void execute() {
		if (!Robot.elevator.isHallSet() && dir >= 1) {
			go = 1;
		} else if (!Robot.elevator.isHallSet() && dir <= -1) {
			go = -1;
		} else if (Robot.elevator.isHallSet() && dir >= 1) {
			dir = dir--;
		} else if (Robot.elevator.isHallSet() && dir <= -1) {
			dir = dir++;
		}

		if (dir != 0) {
			done = false;
		} else if (dir == 0) {
			done = true;
		}
		SmartDashboard.putNumber("whaeva", dir);
	}

	// Make this return true when this Command no longer needs to run execute()
	protected boolean isFinished() {
		return done;
	}

	// Called once after isFinished returns true
	protected void end() {
		Robot.elevator.nothing();
	}

	// Called when another command which requires one or more of the same
	// subsystems is scheduled to run
	protected void interrupted() {
		end();
	}
}

I set the setpoint double to -1 or one based on a button and elevator.nothing does what it says and torro spins the elevator motors based on the double inputted.
I also fear that if the elevator gets stopped on the point where the magnet is on it wont move. I want it to function in such a way that pressing my +1 button makes it add up so i can press it 3 times and it increment 3 heights of magnets. I can’t figure this out so help is appreciated.

Now i’m able to get the elevator to stop in response to the hall effect sensor, but once it use it to go up i cant press it to go up again, and if i go down i can only go down once. Pressing the button multiple times to add to count does nothing. What am i missing here?

package org.usfirst.frc.team2847.robot.commands;

import org.usfirst.frc.team2847.robot.Robot;

import edu.wpi.first.wpilibj.command.Command;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;

/**
 *
 */
public class MagicElevator extends Command {

	int count;
	int tcount;
	double go;
	boolean done;

	public MagicElevator(int setpoint) {
		// Use requires() here to declare subsystem dependencies
		requires(Robot.elevator);
		tcount = setpoint;
	}

	// Called just before this Command runs the first time
	protected void initialize() {
		System.out.println(this);
	}

	// Called repeatedly when this Command is scheduled to run
	protected void execute() {
		count = count + tcount;

		if (count > 0 && Robot.elevator.isHallSet()) {
			count = (count - 1);
		} else if (count < 0 && Robot.elevator.isHallSet()) {
			count = (count + 1);
		}

		if (count >= 1) {
			go = 1;
		} else if (count <= -1) {
			go = -1;
		}
		Robot.elevator.torro(go);

		if (count != 0) {
			done = false;
		} else if (count == 0) {
			done = true;
		}
		tcount = 0;
		SmartDashboard.putNumber("whaeva", count);
		SmartDashboard.putBoolean("hall", Robot.elevator.isHallSet());
	}

	// Make this return true when this Command no longer needs to run execute()
	protected boolean isFinished() {
		SmartDashboard.putNumber("finsishsjdfiaopsdfsa", count);
		return done;
	}

	// Called once after isFinished returns true
	protected void end() {
		Robot.elevator.nothing();
	}

	// Called when another command which requires one or more of the same
	// subsystems is scheduled to run
	protected void interrupted() {
		end();
	}
}

Since your command is ending when done==true, how are you getting another command to run? I think if you tie it to a button with whenPressed() or something like that, it reuses the same object each time. So you have to reinitialize everything in initialize.


	protected void initialize() {
                //reset fields to values defaulted to on construction
                go=0;
                done=false;
                count=0;
		System.out.println(this);
	}

I suspect you will also want to remember your setpoint and assign that to tcount in the initializer as well since it is being reassigned during execute()


public class MagicElevator extends Command {

        ...
        int mySetpoint;
        ...

	public MagicElevator(int setpoint) {
		// Use requires() here to declare subsystem dependencies
		requires(Robot.elevator);
		mySetpoint=setpoint;
	}

	// Called just before this Command runs the first time
	protected void initialize() {
                go=0;
                done=false;
                count=0;
		tcount=mySetpoint;
		System.out.println(this);
	}

Thanks cstelter, I did forget to reset the done variable didn’t I! I will test your suggestions when I get out of class. Also what would setting another mySetpoint variable do? Would this one carry over between reintialization? Wouldn’t it cause the tcount variable to keep adding without resetting on each press of the button that sets the setpoint to (1 -1 or 0)?