Min första kod fungerade inte,
då jag inte tänkt på vissa situationer
Här är en fungerande variant.
För att det skulle vara enkelt att duplicera koden och utan att det blir rörigt
har jag gjort servo "controllern" som en klass
den klassen hanterar ett servo, en "button" och två LED:s
vilka pinnar som används defineras i beginfunktionen.
om man vill kan man skapa en extra tab i Arduino IDE
(för att slippa ha ButtonControlledServo klassen i main filen)
denna döper man lämpligtvis till ButtonControlledServo.h
sedan flyttar man koden
fr.o.m. #include <Servo.h>
t.o.m. }; // end of ButtonControlledServo class
till denna nya tab.
avkommentera
//#include "ButtonControlledServo.h"
har provkört koden i UnoArduSim och det fungerar där,
har en Arduino Nano men orkar inte koppla upp det för att testa
vill inte programmera om den just nu heller.
Kod: Markera allt
/*
Program made by Emanuel Teljemo in 2020.
The purpose of the program is to control 2 servo motors that are installed in a ventilation system.
The servos turn airvalves on and off to focus the air flow from the chosen path.
TO DO LIST:
Shut down servos after 5 sec as a saftey measure against overheating
Add a function to control a relay based on both servos angle state
Add saftey control function to check servo position after movement
Shorten code (combine variables)
check, Remake button code so it only reads 1 signal and doesnt keeps running servos if button is hold
WARNING!
When this code was made I was experimenting so USE AT OWN RISK!
*/
#include <Servo.h>
//#define USE_SERVO_SPEED // uncomment this if you want your original behaivour i.e. move servo in small increments (experimental)
class ButtonControlledServo
{
public:
Servo servo;
char angle;
char minAngle;
char maxAngle;
byte servoSpeed;
byte buttonPin;
char countUpDown;
byte buttonPushedOld;
byte servoNr;
byte servoAtStartLedPin;
byte servoAtEndLedPin;
ButtonControlledServo() {
angle = 0;
minAngle = 0;
maxAngle = 0;
servoSpeed = 1;
buttonPin = 0;
countUpDown = 0;
buttonPushedOld = 0;
servoNr = 0;
servoAtStartLedPin = 0;
servoAtEndLedPin = 0;
}
void begin (byte _servoNr, int _buttonPin, int servoPin, int _servoAtStartLedPin, int _servoAtEndLedPin, char servoMinAngle, char servoMaxAngle, byte _servoSpeed) {
servoNr = _servoNr;
angle = servoMinAngle;
servoSpeed = _servoSpeed;
minAngle = servoMinAngle;
maxAngle = servoMaxAngle;
buttonPin = _buttonPin;
servoAtStartLedPin = _servoAtStartLedPin;
servoAtEndLedPin = _servoAtEndLedPin;
servo.attach(servoPin); // Attaches servo on pin
pinMode(servoAtStartLedPin, OUTPUT);
pinMode(servoAtEndLedPin, OUTPUT);
pinMode(buttonPin, INPUT); // not really necessary
servo.write(servoMinAngle); // Set the initial position for servo (homeing, when mounted it should be open)
}
void update() {
// the following makes sure that countUpDown is only activated once (it creates a button toggle functionality)
if (digitalRead(buttonPin) == LOW) { // Checks if button is pushed down
if (buttonPushedOld == LOW)
{
buttonPushedOld = HIGH;
if (angle == minAngle && countUpDown == 0) // countUpDown == 0 makes sure that the prev execution is completed
{
countUpDown = 1;
#ifndef USE_SERVO_SPEED
servo.write(maxAngle); // Moving the servo to the end
#endif
Serial.print("Movin servo "); Serial.print(servoNr); Serial.println(" to the end"); // Print text in serial monitor
delay(100); // button debounce
}
else if (angle == maxAngle && countUpDown == 0) // countUpDown == 0 makes sure that the prev execution is completed
{
countUpDown = -1;
#ifndef USE_SERVO_SPEED
servo.write(minAngle); // Moving the 1st servo to the beginning
#endif
Serial.print("Movin servo "); Serial.print(servoNr); Serial.println(" to the end"); // Print text in serial monitor
delay(100); // button debounce
}
}
}
else // if button 1 is not pressed
{
if (buttonPushedOld == HIGH)
{
buttonPushedOld = LOW; // only set if the button was pressed before
}
}
// the following is just a software timer (if not using USE_SERVO_SPEED)
// that give the servo enough time to move to the destination
if (countUpDown != 0) { // if servo is moving
angle = angle + servoSpeed * countUpDown ; // upcount or downcount the "timer" value
// fix overflow/underflow
if (angle < minAngle)
angle = minAngle;
else if (angle > maxAngle)
angle = maxAngle;
#ifdef USE_SERVO_SPEED
servo.write(angle); // Moving the servo to current angle
#endif
if (angle == minAngle) { // if at either end stop counter
digitalWrite(servoAtEndLedPin, LOW);
digitalWrite(servoAtStartLedPin, HIGH);
countUpDown = 0;
}
else if (angle == maxAngle) {
digitalWrite(servoAtEndLedPin, HIGH);
digitalWrite(servoAtStartLedPin, LOW);
countUpDown = 0;
}
// using s1speed as a factor to this delay
delay(servoSpeed); // Creates a delay to wait for servo to get in place before looping on
}
}
}; // end of ButtonControlledServo class
//#include "ButtonControlledServo.h"
// Defines pins on the arduino board
#define s1Pin 3 // Signal from servo 1
#define s2Pin 5 // Signal from servo 2
#define b1Pin 2 // Signal from pushbutton1
#define b2Pin 4 // Signal from pushbutton2
#define s1LedOpenPin 8
#define s1LedClosedPin 9
#define s2LedOpenPin 10
#define s2LedClosedPin 11
// Defines variables for servo 1
#define s1speed 10 // Speed for servo 1 movement
#define s1minAngle 7 // Angle of servo 1 arm when vent is closed
#define s1maxAngle 87 // Angle of servo 1 arm when vent is open
// Defines variables for servo 2
#define s2speed 10 // Speed for servo 2 movement
#define s2minAngle 7 // Angle of servo 2 arm when vent is closed
#define s2maxAngle 87 // Angle of servo 2 arm when vent is open
ButtonControlledServo bcs1;
ButtonControlledServo bcs2;
// Setup
void setup() {
// Connections
Serial.begin(9600); // Serial need to match buad rate. See buad rate in serial monitor
bcs1.begin(1, b1Pin, s1Pin, s1LedClosedPin, s1LedOpenPin, s1minAngle, s1maxAngle, s1speed);
bcs2.begin(2, b2Pin, s2Pin, s2LedClosedPin, s2LedOpenPin, s2minAngle, s2maxAngle, s2speed);
Serial.println("*Teljemo's servo controller initiated*"); // Print text in serial monitor
// Print for serial monitor
Serial.println("Starting angles are: "); // Print text in serial monitor
Serial.print(s1minAngle); // Prints angle of servo 1
Serial.println(" degrees for servo 1"); // Print text in serial monitor
Serial.print(s2minAngle); // Prints angle of servo 2
Serial.println(" degrees for servo 2"); // Print text in serial monitor
Serial.println("***********************************"); // Print text in serial monitor
}
// End of setup
//#define USE_SERVO_SPEED // uncomment this if you want your original behaivour i.e. move servo in small increments (without bugs)
// Loop
void loop() {
bcs1.update();
bcs2.update();
//End of loop
}
// End of program