Currently working on a project but having some trouble with one section of it. What I need to happen is on power up the arduino checks to see if their is any force on a force sensor if their is not it turns the stepper motor until it detects force at which point it should turn the opposite way a set amount of steps
Heres my code currently
//Defines Control Pins:
const int Button = 5;// the pin our push button is on
const int Vibrator = 11; //pin 3 has PWM funtion
const int ForceSensor = A4; //pin A0 to read analog input
// defines Motor pins
#define stepPin 54
#define dirPin 55
const int dirPinX = 55; // this will pretty much be dictating rotation direction "clockwise/counterclockwise"
const int stepPinX = 54; // this pretty much dictates speed, reducing delays increases speed
const int enPinX = 38; // this enables or disables the motor
//Variables:
int value; //save analog value
int Position; // Creates Position Variable
void setup()
{
pinMode(Button,INPUT_PULLUP); // Set the Button as an input
pinMode(Vibrator, OUTPUT); //Set pin 3 as 'feedback output'
Serial.begin(9600); //Begin serial communication
// Declare All Stepper pins as Outputs
pinMode(stepPinX, OUTPUT);
pinMode(dirPinX, OUTPUT);
pinMode(enPinX, OUTPUT);
value = analogRead(ForceSensor); //Read and save analog value from potentiometer
if (value < 100){
homing();
}
}
void homing ()
{
value = analogRead(ForceSensor); //Read and save analog value from potentiometer
int digitalVal= digitalRead(ForceSensor);
digitalWrite(dirPinX,HIGH); // Enables the motor to move in a particular direction by switching between HIGH and Low
// Makes 200 pulses for making one full cycle rotation
while (value < 100)
{//This determines by how many degrees the stepper will move:3200steps is 360 degrees which means that 12.5 steps is 1.4 degrees, 1 degree = 8.929steps
digitalWrite(stepPinX,HIGH);
delayMicroseconds(500); // by changing this time delay between the steps we can change the rotation speed Higher Number= Lower Speed Lower Limit = 16 ms
digitalWrite(stepPinX,LOW);
Position++;//Updates Position Variable
delayMicroseconds(50);
}
}
void loop() {
// Get button event and act accordingly
int b = checkButton();
if (b == 2) doubleClickEvent();
if (b == 3) holdEvent();
value = analogRead(ForceSensor); //Read and save analog value from potentiometer
value = map(value, 0, 1023, 0, 255); //Map value 0-1023 to 0-255 (PWM)
analogWrite(Vibrator, value); //Send PWM value to vibrator
}
//=================================================
// Events to trigger
void doubleClickEvent() {
int digitalVal= digitalRead(ForceSensor);
digitalWrite(dirPinX,LOW); // Enables the motor to move in a particular direction by switching between HIGH and Low
// Makes 200 pulses for making one full cycle rotation
for(int x = 0; x < Position ; x++) {//Returns Motor To Position 0
digitalWrite(stepPinX,HIGH);
delayMicroseconds(500); // by changing this time delay between the steps we can change the rotation speed Higher Number= Lower Speed Lower Limit = 16 ms
digitalWrite(stepPinX,LOW);
delayMicroseconds(50);
}
Position = 0; //Resets Position Variable to 0
}
void holdEvent() {
int digitalVal= digitalRead(ForceSensor);
digitalWrite(dirPinX,HIGH); // Enables the motor to move in a particular direction by switching between HIGH and Low
// Makes 200 pulses for making one full cycle rotation
for(int x = 0; x < 1; x++) {//This determines by how many degrees the stepper will move:3200steps is 360 degrees which means that 12.5 steps is 1.4 degrees, 1 degree = 8.929steps
digitalWrite(stepPinX,HIGH);
delayMicroseconds(500); // by changing this time delay between the steps we can change the rotation speed Higher Number= Lower Speed Lower Limit = 16 ms
digitalWrite(stepPinX,LOW);
Position++;//Updates Position Variable
delayMicroseconds(50);
}
}
//=================================================
// MULTI-CLICK: One Button, Multiple Events
// Button timing variables
int debounce = 20; // ms debounce period to prevent flickering when pressing or releasing the button
int DCgap = 150; // max ms between clicks for a double click event
int holdTime = 151; // ms hold period: how long to wait for press+hold event
int longHoldTime = 3000; // ms long hold period: how long to wait for press+hold event
// Button variables
boolean buttonVal = HIGH; // value read from button
boolean buttonLast = HIGH; // buffered value of the button's previous state
boolean DCwaiting = false; // whether we're waiting for a double click (down)
boolean DConUp = false; // whether to register a double click on next release, or whether to wait and click
boolean singleOK = true; // whether it's OK to do a single click
long downTime = -1; // time the button was pressed down
long upTime = -1; // time the button was released
boolean ignoreUp = false; // whether to ignore the button release because the click+hold was triggered
boolean waitForUp = false; // when held, whether to wait for the up event
boolean holdEventPast = false; // whether or not the hold event happened already
boolean longHoldEventPast = false;// whether or not the long hold event happened already
int checkButton() {
int event = 0;
buttonVal = digitalRead(Button);
// Button pressed down
if (buttonVal == LOW && buttonLast == HIGH && (millis() - upTime) > debounce)
{
downTime = millis();
ignoreUp = false;
waitForUp = false;
singleOK = true;
holdEventPast = false;
if ((millis()-upTime) < DCgap && DConUp == false && DCwaiting == true) DConUp = true;
else DConUp = false;
DCwaiting = false;
}
// Button released
else if (buttonVal == HIGH && buttonLast == LOW && (millis() - downTime) > debounce)
{
if (not ignoreUp)
{
upTime = millis();
if (DConUp == false) DCwaiting = true;
else
{
event = 2;
DConUp = false;
DCwaiting = false;
singleOK = false;
}
}
}
// Test for hold
if (buttonVal == LOW && (millis() - downTime) >= holdTime) {
// Trigger "normal" hold
if (not holdEventPast)
{
event = 3;
waitForUp = false;
ignoreUp = true;
DConUp = false;
DCwaiting = false;
//downTime = millis();
holdEventPast = false;
}
}
buttonLast = buttonVal;
return event;
}
At the moment on power up if there is no force the motor does spin in the desired direction however once force is applied it does not stop
if their is force on the sensor on power up it functions correctly
Any ideas how to get this to work?
Thanks!
Does your force sensor have analog and digital output?
Are you aware you never use digitalVal?
Are you also aware the three local variables named digitalVal do not change each other?
From what I can tell the force sensor does have both digital and analog outputs
I didnt notice that I never actually used digitalVal its left over from when I was messing around getting the motor to change speed based on the force so ill be sure to remove that thanks
Not quite sure what you meant by the 3 local variables not changing each other sorry still kinda new to some of this and yeah I changed the pin for the vibration motor forgot to change the comment so ill be sure to fix that thanks!
@skylord711
Are you using arduino Mega? or.....
If you are using arduino mega the pin A0 and 54 is the same. and so.........
. Look image.
have defined this pins twice...
// defines Motor pins
#define stepPin 54
#define dirPin 55
const int dirPinX = 55; // this will pretty much be dictating rotation direction "clockwise/counterclockwise"
const int stepPinX = 54; // this pretty much dictates speed, reducing delays increases speed
I gave that a go and it didnt work not sure if I did it right
void homing ()
{
start:
int digitalVal= digitalRead(ForceSensor);
digitalWrite(dirPinX,HIGH); // Enables the motor to move in a particular direction by switching between HIGH and Low
// Makes 200 pulses for making one full cycle rotation
while (value < 100)
{//This determines by how many degrees the stepper will move:3200steps is 360 degrees which means that 12.5 steps is 1.4 degrees, 1 degree = 8.929steps
digitalWrite(stepPinX,HIGH);
delayMicroseconds(500); // by changing this time delay between the steps we can change the rotation speed Higher Number= Lower Speed Lower Limit = 16 ms
digitalWrite(stepPinX,LOW);
delayMicroseconds(50);
value = digitalRead(ForceSensor);
digitalWrite (value);
}
digitalWrite(dirPinX,HIGH); // Enables the motor to move in a particular direction by switching between HIGH and Low
// Makes 200 pulses for making one full cycle rotation
if (digitalVal < 100)
{goto start;}
}
Managed to work out a solution there's still some discrepancies in the code but all in all does what I need thanks to everyone for their advice!
Im attaching the code incase anyone needs it for anything similar its not perfect but it works
//Defines Control Pins:
const int Button = 5; //pin 5 is push button
const int Vibrator = 11; //pin 1 has PWM funtion
const int ForceSensor = A4; //pin A4 to read analog input
// defines Motor pins
#define stepPin 54
#define dirPin 55
const int dirPinX = 55; // this will pretty much be dictating rotation direction "clockwise/counterclockwise"
const int stepPinX = 54; // this pretty much dictates speed, reducing delays increases speed
const int enPinX = 38; // this enables or disables the motor
//Variables:
int value; //save analog value
int Position; // Creates Position Variable
void setup()
{
pinMode(Button,INPUT_PULLUP); // Set the Button as an input
pinMode(Vibrator, OUTPUT); //Set pin 3 as 'feedback output'
Serial.begin(9600); //Begin serial communication
// Declare All Stepper pins as Outputs
pinMode(stepPinX, OUTPUT);
pinMode(dirPinX, OUTPUT);
pinMode(enPinX, OUTPUT);
value = analogRead(ForceSensor); //Read and save analog value from potentiometer
if (value < 100){
homing();
value = digitalRead(ForceSensor);
}
}
void homing() {
int digitalVal = 0;
while (true) {
// Check if there is no input from ForceSensor
if (digitalRead(ForceSensor) == LOW) {
digitalWrite(dirPinX, HIGH); // Set direction to HIGH
digitalWrite(stepPinX, HIGH);
delayMicroseconds(500);
digitalWrite(stepPinX, LOW);
delayMicroseconds(50);
} else {
// If input detected, turn in LOW direction for 3200 steps
digitalWrite(dirPinX, LOW); // Set direction to LOW
for (int i = 0; i < 3200; i++) {
digitalWrite(stepPinX, HIGH);
delayMicroseconds(500);
digitalWrite(stepPinX, LOW);
delayMicroseconds(50);
}
// Exit the homing function
return;
}
}
}
void loop() {
// Get button event and act accordingly
int b = checkButton();
if (b == 2) doubleClickEvent();
if (b == 3) holdEvent();
value = analogRead(ForceSensor); //Read and save analog value from potentiometer
value = map(value, 0, 1023, 0, 255); //Map value 0-1023 to 0-255 (PWM)
analogWrite(Vibrator, value); //Send PWM value to vibrator
}
//=================================================
// Events to trigger
void doubleClickEvent() {
int digitalVal= digitalRead(ForceSensor);
digitalWrite(dirPinX,LOW); // Enables the motor to move in a particular direction by switching between HIGH and Low
// Makes 200 pulses for making one full cycle rotation
for(int x = 0; x < Position ; x++) {//Returns Motor To Position 0
digitalWrite(stepPinX,HIGH);
delayMicroseconds(500); // by changing this time delay between the steps we can change the rotation speed Higher Number= Lower Speed Lower Limit = 16 ms
digitalWrite(stepPinX,LOW);
delayMicroseconds(50);
}
Position = 0; //Resets Position Variable to 0
}
void holdEvent() {
int digitalVal= digitalRead(ForceSensor);
digitalWrite(dirPinX,HIGH); // Enables the motor to move in a particular direction by switching between HIGH and Low
// Makes 200 pulses for making one full cycle rotation
for(int x = 0; x < 1; x++) {//This determines by how many degrees the stepper will move:3200steps is 360 degrees which means that 12.5 steps is 1.4 degrees, 1 degree = 8.929steps
digitalWrite(stepPinX,HIGH);
delayMicroseconds(500); // by changing this time delay between the steps we can change the rotation speed Higher Number= Lower Speed Lower Limit = 16 ms
digitalWrite(stepPinX,LOW);
Position++;//Updates Position Variable
delayMicroseconds(50);
}
}
//=================================================
// MULTI-CLICK: One Button, Multiple Events
// Button timing variables
int debounce = 20; // ms debounce period to prevent flickering when pressing or releasing the button
int DCgap = 150; // max ms between clicks for a double click event
int holdTime = 151; // ms hold period: how long to wait for press+hold event
int longHoldTime = 3000; // ms long hold period: how long to wait for press+hold event
// Button variables
boolean buttonVal = HIGH; // value read from button
boolean buttonLast = HIGH; // buffered value of the button's previous state
boolean DCwaiting = false; // whether we're waiting for a double click (down)
boolean DConUp = false; // whether to register a double click on next release, or whether to wait and click
boolean singleOK = true; // whether it's OK to do a single click
long downTime = -1; // time the button was pressed down
long upTime = -1; // time the button was released
boolean ignoreUp = false; // whether to ignore the button release because the click+hold was triggered
boolean waitForUp = false; // when held, whether to wait for the up event
boolean holdEventPast = false; // whether or not the hold event happened already
boolean longHoldEventPast = false;// whether or not the long hold event happened already
int checkButton() {
int event = 0;
buttonVal = digitalRead(Button);
// Button pressed down
if (buttonVal == LOW && buttonLast == HIGH && (millis() - upTime) > debounce)
{
downTime = millis();
ignoreUp = false;
waitForUp = false;
singleOK = true;
holdEventPast = false;
if ((millis()-upTime) < DCgap && DConUp == false && DCwaiting == true) DConUp = true;
else DConUp = false;
DCwaiting = false;
}
// Button released
else if (buttonVal == HIGH && buttonLast == LOW && (millis() - downTime) > debounce)
{
if (not ignoreUp)
{
upTime = millis();
if (DConUp == false) DCwaiting = true;
else
{
event = 2;
DConUp = false;
DCwaiting = false;
singleOK = false;
}
}
}
// Test for hold
if (buttonVal == LOW && (millis() - downTime) >= holdTime) {
// Trigger "normal" hold
if (not holdEventPast)
{
event = 3;
waitForUp = false;
ignoreUp = true;
DConUp = false;
DCwaiting = false;
//downTime = millis();
holdEventPast = false;
}
}
buttonLast = buttonVal;
return event;
}