Im new to Arduino so don't fully understand the language, but have written some code to allow me to change a motorcycle gears using a servo.
however I have some questions on how to approach some of the things I'm attempting. for example I assume the library for the servo is for those micro servos, I don't know if the same library will work with a 60kg servo?
my code I have written is fully functional and works great, but I will be adding many extra functions and will want to choose exactly when the relay turns off and on, so will need to get rid of the delay functions, however I still need the servo to do it movements as quick as possible. any help one this would be much appreciated. thanks.
#include <Servo.h>
Servo servo;
int pot = 90; // initial servo position (always return to 90 after servo has moved)
const int RELAY_PIN = 4; //switches off while moving the servo
const int buttonPin1 = 2; //go to 180 degrees
const int buttonPin2 = 3; //go to 0 degrees
const int buttonPin3 = 5; //go to 45 degrees
boolean currentState1 = LOW;//stroage for current button state
boolean lastState1 = LOW;//storage for last button state
boolean currentState2 = HIGH;//stroage for current button state
boolean lastState2 = HIGH;//storage for last button state
boolean currentState3 = HIGH;//stroage for current button state
boolean lastState3 = HIGH;//storage for last button state
boolean pos = true;
void setup(){
pinMode(buttonPin1, INPUT_PULLUP);
Serial.begin(9600); //initialize Serial connection
pinMode(buttonPin2, INPUT_PULLUP);
pinMode(buttonPin3, INPUT_PULLUP);
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, HIGH); // Set Relay to on state
}
void loop(){
//// down gear
currentState1 = digitalRead(buttonPin1);
if (currentState1 == HIGH && lastState1 == LOW){//if button has just been pressed
delay(10);
if (pos == true){
servo.attach(9); // attaches the servo on pin 9 to the servo object
servo.write(180); // tell servo to go to "180"
digitalWrite(RELAY_PIN, LOW); //relay off
delay(200);
servo.write(90); // tell servo to go to "90"
digitalWrite(RELAY_PIN, HIGH); //relay on
delay(150);
Serial.println("up");
pos = true;
servo.detach();
}
}
lastState1 = currentState1;
//// up gear
currentState2 = digitalRead(buttonPin2);
if (currentState2 == HIGH && lastState2 == LOW){//if button has just been pressed
delay(10);
if (pos == true){
servo.attach(9); // attaches the servo on pin 9 to the servo object
servo.write(0); // tell servo to go to "0"
digitalWrite(RELAY_PIN, LOW); //relay off
delay(200);
digitalWrite(RELAY_PIN, HIGH); //relay on
servo.write(90);
delay(150);
Serial.println("down");
pos = true;
servo.detach();
}
}
lastState2 = currentState2;
///// neutral
currentState3 = digitalRead(buttonPin3);
if (currentState3 == HIGH && lastState3 == LOW){//if button has just been pressed
delay(10);
if (pos == true){
servo.attach(9);
servo.write(45); // tell servo to go to "45"
delay(200);
servo.write(90);
delay(150);
Serial.println("neutral");
pos = true;
servo.detach();
}
}
lastState3 = currentState3;
}
P.S I have looked at using mills() to do the timing, but don't understand it to the extent where I feel I can implement it into my code. an edit to part of my code would help a lot!
thanks
The way that it works here is that you write the code to the best of your ability and if the code does not do what you want you post the code, a detailed description of what the code actually does and a description if what the code is supposed to do. Then we help.
Read the forum guidelines to see how to properly post code and some good information on making a good post.
Use the IDE autoformat tool (ctrl-t or Tools, Auto format) before posting code in code tags.
sure, so I've tried to include most of the detail next to the code, but the main function is for the servo to move to a set position when button 1 is pressed, then return to "90" position, and move to another set position when button 2 is pressed and then return to 90 again, and to have a relay turn off and on while the servo is moving (as this will turn the engine off to allow for a full throttle gear change).
I just need to modify the code to edit out the delays as these will create issues for any extra loops I might want to add.
I'm using an Arduino mega.
this is the info I have about the servo:
Note:
The best service voltage is 7.4V.It’s recommended to use 2s battery for power supply (6-8.4V)
2.The working angle of this servo is 180 degrees(PWM: 500us-2500us),
as the output of some remote controls can only be 1000-2000us,we recommend you to purchase 270 degrees model.(ASIN: B07KTSCN4J)
Feature:
High-precision metal gear.
Durable SS Metal Gear
Double Ball Bearing
Programmable Digital Amplifier with Mosft Drive
Bottom Side Axial Mount Hole
Orientation Angle: maximum 180deg
Mechanical Angle:360deg (Plug/Output wheel/Radio control system compatible with Futaba JR Hitec)
means the arduino stops creating a valid servo-signal. All and every RC-servo needs an infinite train of servo-signal-pulses to operate properly. If you stop feeding in a valid servo-signal the servo is in an undefined state and could start wiggle randomly.
I wasn't sure if I should detach the servo to prevent glitching or jittering while its waiting for a new command. is it even necessary?
I think I'm familiar with flags as I recon I've used one or two in my code?
I know what the mills() function does, but not quite sure how to replace the delays with it.
I have just been reading about State Machine programming, is this another potential way of doing it?
Posting a hand-drawn timing diagram that shows the timely relation between servo turned to a certain position and switching on/off the relais would clear things up a lot.
Adding to @groundFungus reply.... The level of the logic signals is missing but likely an "Arduino" will work. Note that some Arduino outputs 3.3 volt levels and the others output 5 volt logic levels.
all RC-servo work this way:
receive every 0,02 seconds a NEW short pulse where the short pulse defines the servohorn-position 0 to 180 degrees. Compare real position of servhorn with wanted position.
If there is a deviation between wanted and real position drive motor to minimise the deviation until (ideally) the deviation is down to zero.
servo.write(90) tells the servo-object create infinite pulsetrain with pulses 1500 microseconds long
servo.write(180) tells the servo-object create infinite pulsetrain with pulses 2000 microseconds long
servo.write(0) tells the servo-object create infinite pulsetrain with pulses 1000 microseconds long
you can imagine servo.write() similar to adjusting a volume-knob of an amplifier to a different position. The amplifier is amplifying all the time with the adjusted volume
until you change the knobs position.
similar thing with an rc-servo: create inifinite pulstrain with pulse-length X
best regards Stefan
I have-not yet tested at which point the relay should turn off as that will take some live tuning to get it right, so I'm trying to be able to choose when the relay turns off and on in relation to the servo, by changing a few numbers when it come to tuning.
the exact numbers don't matter. Your timing-diagram shall show the principles
turn servo to what position?
switch relay on or off ?
switching the relay prior or after turning the servo?
etc.