I have PCA9685 Servo Button control aimed at Model railway point/turnout control wiring diagram and code.
But I would like to use the 3 pin toggle switch instead of the button as the diagram shows.
How can I wire one toggle switch each servo and do I need to edit the following code?
/* PCA9685ServoButtonsV3
31/12/23
Built on the foundations of PCA9685ServoButtonsV2
This time the relay code has been added.
This example uses 2 servos, one on Pin 0, the other on pin 12
Relays are on pins 12 and 13
adding more buttons/servos is just a matter of extending the code.
Code is written as a state machine without delay() so that other code (without delay()
can be added if needed.
PCA9685 board
2 servos
4 buttons
4 x 4.5k OHM resistors for Pull Down on buttons
2 relay modules
SDA/SCL connections for PCA9685
Arduino UNO: A4 (SDA), A5 (SCL)
Arduino Mega 2560: 20 (SDA), 21 (SCL)
ESP32: 21(SDA), 22 (SCL)
pins 8 - 11 for buttons with 4.7K pull down resistors
pins 12-13 relays
*/
#include "Wire.h"
#include "Adafruit_PWMServoDriver.h"
//PCA 9685 settings
// called this way, it uses the default address 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// you can also call it with a different address you want
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);
// you can also call it with a different address and I2C interface
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40, Wire);
#define USMIN 600 // This is the rounded 'minimum' microsecond length based on the minimum pulse of 150
#define USMAX 2400 // This is the rounded 'maximum' microsecond length based on the maximum pulse of 600
#define SERVO_FREQ 50 // Analog servos run at ~50 Hz updates
//end pca9685 settings
//position in the following array is the values you would get from the PCA9685 Servo setter project
//see https://www.digitaltown.co.uk/projectPCA9685ServoSetter.php
# define numButtons 4 //number of buttons controlling servos
int servoVariables[numButtons][5] = { //2 lines per servo (2 buttons)
{8,0,45,12,0}, //pin 8, servo 0, position,relay,off
{9,0,179,12,1}, //pin 9, servo 0, position,relay,on
{10,12,33,13,0}, //pin 10,servo 12, position,relay,off
{11,12,168,13,1} //pin 11, servo 12, position,relay,on
};
//System variables
unsigned long currentMillis; //will stire the current time in from millis()
unsigned long buttonTimer;//stores the next value in millis for debounce
int buttonDebounce = 200;//smaller vale makes buttons more sensitive, easier to get double press
//Servo movement function
void setServoPos(int servo, int pos) {
//This first bit of code makes sure we are not trying to set the servo outside of limits
int sendPos;
if (pos > 179) {
pos = 179;
}
if (pos < 0) {
pos = 0;
}
sendPos = USMIN + ((USMAX - USMIN) / 180 * pos);
if (servo > -1 && servo < 16) { //only try to move valid servo addresses
pwm.writeMicroseconds(servo, sendPos);
}
}
//deals with button presses
//This works but would become very complicated and hard to read with 16 servos
void buttonState() {
int q;
if (currentMillis - buttonTimer >= buttonDebounce) { //are buttons debounced
buttonTimer = currentMillis;//reset debounce timer
for(q=0;q < numButtons;q++){
if(digitalRead(servoVariables[q][0]) > 0){
setServoPos(servoVariables[q][1], servoVariables[q][2]);//move the servo
digitalWrite(servoVariables[q][3],servoVariables[q][4]);//set the relay to appropriate value
q=numButtons;//causes system to exit for loop and wait for debounce again
}
}
}
}
void setup() {
Serial.begin(9600);
Serial.println("PCA9685ServoSetterV3");
pwm.begin();
pwm.setOscillatorFrequency(27000000);
pwm.setPWMFreq(SERVO_FREQ); // Analog servos run at ~50 Hz updates
delay(10);//let the above values take effect
for(int q=0;q < numButtons;q++){
pinMode(servoVariables[q][0], INPUT);//set the pins used for buttons in the servoVariables array
pinMode(servoVariables[q][3], OUTPUT);//set the pins used for relays servoVariables array
}
}
void loop() {
currentMillis = millis();//get the current millis since board started for timing
buttonState();//deals with button presses
}