Hi there,
I need help with coding.
I am trying to control the DC motor with a push of a button to spin once and then stop at a specific position. I have an Arduino board (Wemos D1 Pro is one that I have at the moment), three magnetic hall sensors, and MOSFET to drive the motor.
H1 acts like a trigger.
H2 acts like MODE SELECTOR, On state (D3 HIGH) is SPIN ONCE mode, and
the OFF state (D3 LOW) is SPIN INFINITE mode, keep the motor running as long as the trigger is pressed.
Here is what I want:
CASE 1: SPIN ONCE MODE
In a stationary position, the gear which has a small neodymium magnet on it always rests at the position like in my image, and Hall Sensor H3 on the D2 pin is at a LOW state when the magnet is close to it. ( I am using Pulldown resistors 10K)
MODE SWITCH is at an ON state, and the D3 input is at a HIGH state, which means it is in SPIN ONCE MODE, if the H1 button is pressed either once or held pressed and D5 is at LOW, the motor will start spinning, and as it starts spinning it will change the state of a H3 to HIGH as the magnet goes far from the sensor, and keep running until the magnet on the gear reaches HALL SENSOR again, and when it does, HALL Sensor will go to LOW again and stop the motor. I repeat, no matter if the H1 is pressed once or held pressed, the motor has to stop after one rotation.
CASE 2 - SPIN INFINITE MODE
H2 is at an OFF state, and the D3 input is at a LOW state. When I press and hold the H1, the motor starts spinning and it spins as long as the button is pressed, ignoring the H3. When I release button H1, the motor should stop.
H1, H2, and H3 are the same hall sensors marked as 49E. I changed the design from switches and push buttons to hall sensors to prevent "wear off" the micro contacts.
What I have now is the code that works fine but with only 2 hall sensors, H1 for TRIGGER and H2 as MODE SELECTOR, and that runs for 700ms to spin once, but it is hard to get the motor in the exact position every time. Now I added one more sensor H3 to detect the exact position of the gear to turn off the motor, but I am stuck on the code.
I would appreciate it if someone could help with the code.
Here is my code for time-based design, but I would like to change it to work with 3 sensors and turn off the motor at the H3 position instead of time-based rotation:
//////// WIRE PIN AN COMPONENT LAYOUT /////////
#define LED_BUILTINN D4
#define MOSFET_PIN D7 // The Digital pin that attaches to the MOSFET gate, to turn it on and off.
#define TRIGGER_PIN D5 // The digital pin that attaches to the trigger pin
#define MODE_PIN D3 // The Digital pin that attaches to the SWITCH, to switch between Full auto and burst mode.
//////// CONFIG VALUES /////////
int Max_ON_Time = 700; // The time in MS for one rotation...
//////// INTERNAL VALUES /////////
int TriggerStatus = LOW; // The state of the trigger LOW => pressed, HIGH => Not Pressed
int TriggerReadValue = LOW; // The value read from the digital trigger pin.
int CurrentSleepTime = 0; // The ammount of time the mosfet has been on.
// The setup routine runs once when you press reset.
void setup() {
// Initialize the digital pin as an output.
pinMode(LED_BUILTIN, OUTPUT); // LED pin
pinMode(MOSFET_PIN, OUTPUT); // Set the MOSFET pin as an output so that we can send power to the MOSFET.
pinMode(MODE_PIN, INPUT); // The MODE SELECTOR pin
digitalWrite(MOSFET_PIN, LOW); // Make sure we start with power OFF!
digitalWrite(LED_BUILTIN, LOW); // Make sure we start with power OFF!
}
// The loop routine runs over and over again forever.
void loop() {
ReadTrigger(); // Update the trigger state
if(TriggerStatus == LOW) // If the trigger is pushed.
{
SetMosfet(HIGH); // First turn the Mosfet On
while (TriggerStatus == LOW)
{
int spinOnceMode = digitalRead(MODE_PIN);
if(spinOnceMode == HIGH) // If the H2 has power on it it's in Spin Once mode.
{
if(CurrentSleepTime < Max_ON_Time){ // If we have not completed a cycle
CurrentSleepTime = CurrentSleepTime + 1; // Leave the mosfet on, and increase time counter.
} else {
SetMosfet(LOW); // If a full cycle has gone, turn the Monfet Off.
}
delay(1); // Sleep for one milisecond
}
ReadTrigger(); // Update the trigger status (We stay in the loop untill the trigger is released)
}
SetMosfet(LOW); // Make sure the Mosfet is off when the trigger is released
CurrentSleepTime = 0; // Reset time counter when the trigger is released.
}
}
// This function updates the trigger status when it's called.
void ReadTrigger()
{
int TriggerReadValue = digitalRead(TRIGGER_PIN);
TriggerStatus = LOW;
if(TriggerReadValue == HIGH) {
TriggerStatus = HIGH;
}
}
// This function set the Mosfet state
void SetMosfet(int val)
{
digitalWrite(LED_BUILTIN, val); // turn the LED on / off to indicate what the mosfet should be dooing
digitalWrite(MOSFET_PIN, val); // turn the Mosfet on / off
}