Wiring Diagram.pdf (579.2 KB)
Bowling Arcade Game Manual.pdf (3.5 MB)
I am building a half scale bowling game and in the process of automating the string pin setter. I am using a linear actuator (hereafter called actuator) for each pin (10 total) as well as 3 additional linear actuators (ball gate, sweep, and ball elevator).
I have elected to use a total of four 5V, 8 channel relay modules to isolate the Arduino Mega signals from the 12 volt (<5 amp) power requirements for each actuator. I have attached a wiring diagram of how I built the control panel. I have also attached the start of a manual that shows all the equipment specifications if needed.
When I first started, i wired all 13 actuators directly to the power supply and they worked great. However, when i built the control panel and hooked the actuators to the relays, I can only get two actuators to work at a time (and all 13 work but only 2 at a time) but no more than that. I’m lookng for a way to get as many as 13 actuators to work at the same time.
Note I have a 25 amp, 12 vdc power supply. Also note I use another power supply for all the lighter duty power requirements which provides 5, 12, and 24 vdc rated for 8 amps. I am using two relays to control the movement for each actuator (see page 12 of manual for that wiring schematic).
On the input side of each 8 channel relay, i am using 5 vdc from the power supply (not the Arduino). I am sharing the ground. On the output side of the relays i am powering from one of the power supplies to get the right voltage to each component. The Arduino Mega sends the input trigger as instructed per the Arduino code.
I have read the 3 to 4 forums on this topic as well as have done some online research. A single coil can draw 70-100mA; 8 relays activated simultaneously can exceed 600-800m; 32 relays activated simulataneously 2400 to 3200 mAmps which greatly exceeds the 500 mAmp capacity of the Mega. However, I understood that if the input side of the relays were powered directly from a power supply, this would address this problem. What am i doing wrong?
Several forums suggest adding a separate DC power supply to the GND/VCC/JD_VCC pins per the sketch below.
However, the relays i am using (shown below) do NOT have the GND/VCC/JD-VCC pins. The relays i am using look like this with the only pins being jumpers for high/low level trigger signals.
Should i change out my relays to this type of module with the GND/VCC/JD-VCC pins?
Arduino Sketch follows but let’s please focus on the potential wiring issues stated above and not on the sketch please. Let’s also not focus on the fact that transistors or solid state relays may have been a better choice please. Thanks in advance for your help.
// //////////////////////////////////////////////////////////// //
// //
// Arduino Sketch for Bowling Game //
// Rev 1.0 //
// January 19.2025 //
// Deron Butler //
// dbutler@josephdouglashomes.com //
// //
// /////////////////////////////////////////////////////////// ///
// *********************************************************************** //
// Libraries
// *********************************************************************** //
#include <FastLED.h> // Library for LED controls (future use)
#include <SerialMP3Player.h>
// *********************************************************************** //
// Definitions for LED Lighting
// *********************************************************************** //
#define NUM_STRIPS 2
#define NUM_LEDS_PER_STRIP 60
#define NUM_LEDS NUM_LEDS_PER_STRIP * NUM_STRIPS
CRGB leds[NUM_STRIPS * NUM_LEDS_PER_STRIP];
// *********************************************************************** //
// Definitions for MP3 Player
// *********************************************************************** //
#define TX 0
#define RX 1
SerialMP3Player mp3(RX, TX);
// NOTE: format micro SD cards as FAT16 or FAT32
// NOTE: label folders on micro SD "01", "02", etc
// NOTE: label files "001xxx.mp3" and "002xxx.mp3" where xxx can be anything
// NOTE: do not use files 008xxx.mp3 or 009xxx.mp3 as these result in errors
// Connect the Serial MP3 Player to the Arduino board
// YX5300 → Mega
// GND → GND
// VCC → 5V
// TX → RX (pin 2)
// RX → TX (pin 1)
// *********************************************************************** //
// Constants/Variables for Set Up
// *********************************************************************** //
int Mode = 1;
bool ball1 = HIGH;
bool ball2 = LOW;
int result =0;
bool split = LOW;
const int solenoidExtend[14] = {0, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47}; // Defines pinout for extending solenoid
const int solenoidRetract[14] = {0, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48}; // Defines pinout for retracting solenoid
const int pinDesignation[11] = {0, 8, 2, 3, 4, 5, 9, 10, 11, 12, 13}; // Defines pinout for bowling pin status
// NOTE: 1st position of an index is intentionally not used in this sketch
unsigned long laneResetTime = 0; // Assigns value of relative time in milliseconds
unsigned long currentTime = 0; // Assigns value of relative time in milliseconds
bool bowlPinState[] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW}; // LOW = pin standing; HIGH = pin has fallen
// NOTE: 1st position of an index is position 0 which is purposely chosen to be ignored in this sketch
bool data[10] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW}; // Variable to toggle (0 = OFF, 1 = ON)
unsigned long lastTime = 0;
// *********************************************************************** //
// Variables for Ball Return
// *********************************************************************** //
int ballReturnState = LOW; // Current reading from the button
int lastBallReturnState = LOW; // Previous reading from the button
bool ballReturn = LOW;
unsigned long ballReturnStartTime = 0; // Assigns value of relative time in milliseconds
unsigned long lastDebounceTime1 = 0; // Last time the button state changed
unsigned long debounceDelay1 = 500; // Debounce time in milliseconds
// *********************************************************************** //
// Variables for Service Button
// *********************************************************************** //
bool serviceButtonPressed = false;
int serviceButtonState = LOW; // Current reading from the button
unsigned long pressStartTime = 0;
// *********************************************************************** //
// Variables for Current Sensing
// *********************************************************************** //
float voltageOut[13] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
float current[13] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int currentMax = 2;
bool maxCurrentEvent[13] = {false,false,false,false,false,false,false,false,false,false,false,false,false};
unsigned long currentMaxTime[13] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // time when max current limit exceeded
unsigned long lastCurrentDebounceTime[13] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // Last time the current state changed
unsigned long currentDebounceDelay = 350; // Debounce time in milliseconds
// *********************************************************************** //
// Variables for Modes
// *********************************************************************** //
unsigned long ballRolledTime = 0;
int ballRolledState = HIGH;
int lastBallRolledState = HIGH;
// ________________________________________________________________________ //
// -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //
void setup() {
// -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //
// ________________________________________________________________________ //
Serial.begin(9600); // Opens the serial port at 9600 bps
// tell FastLED there's 60 NEOPIXEL leds on pin 51, starting at index 0 in the led array
FastLED.addLeds<NEOPIXEL, 51>(leds, 0, NUM_LEDS_PER_STRIP);
// tell FastLED there's 60 NEOPIXEL leds on pin 52, starting at index 15 in the led array
FastLED.addLeds<NEOPIXEL, 52>(leds, NUM_LEDS_PER_STRIP, NUM_LEDS_PER_STRIP);
mp3.begin(9600); // start mp3-communication
delay(500); // wait for init
mp3.sendCommand(CMD_SEL_DEV, 0, 2); //select sd-card
delay(500); // wait for init
// Mega Arduino Pin Assignments
// pin 0 is set up for TX above
// pin 1 is set up for RX above
pinMode(2, INPUT_PULLUP); // monitors **UNO** pin A0 for bowling pin 2 status
pinMode(3, INPUT_PULLUP); // monitors **UNO** pin D2 for bowling pin 3 status
pinMode(4, INPUT_PULLUP); // monitors **UNO** pin D3 for bowling pin 4 status
pinMode(5, INPUT_PULLUP); // monitors **UNO** pin D4 for bowling pin 5 status
pinMode(6, INPUT_PULLUP); // monitors **UNO** pin D7 for auto reset in 10th frame
pinMode(7, INPUT); // monitors **UNO** pin D8 (uses external pullup) for detecting ball roll
pinMode(8, INPUT_PULLUP); // monitors **UNO** pin D5 for bowling pin 1 status
pinMode(9, INPUT_PULLUP); // monitors **UNO** pin A1 for bowling pin 6 status
pinMode(10, INPUT_PULLUP); // monitors **UNO** pin A2 for bowling pin 7 status
pinMode(11, INPUT_PULLUP); // monitors **UNO** pin A3 for bowling pin 8 status
pinMode(12, INPUT_PULLUP); // monitors **UNO** pin A4 for bowling pin 9 status
pinMode(13, INPUT_PULLUP); // monitors **UNO** pin A5 for bowling pin 10 status
pinMode(14, INPUT_PULLUP); // monitors **UNO** pin D9 for spare
pinMode(15, INPUT_PULLUP); // monitors **UNO** pin D10 for strike
pinMode(16, INPUT_PULLUP); // monitors **UNO** pin D11 for ball 1
pinMode(17, INPUT_PULLUP); // monitors **UNO** pin D12 for ball 2
pinMode(18, INPUT_PULLUP); // monitors reset button NOTE: this may need an external pullup
pinMode(19, OUTPUT); // relay 1 (ball 1 light)
pinMode(20, OUTPUT); // relay 2 (ball 2 light)
pinMode(21, OUTPUT); // relay 3 (spare light)
pinMode(22, OUTPUT); // relay 4 (strike light)
pinMode(23, OUTPUT); // relay 5 (pin 1 raise)
pinMode(24, OUTPUT); // relay 6 (pin 1 lower)
pinMode(25, OUTPUT); // relay 7 (pin 2 raise)
pinMode(26, OUTPUT); // relay 8 (pin 2 lower)
pinMode(27, OUTPUT); // relay 9 (pin 3 raise)
pinMode(28, OUTPUT); // relay 10 (pin 3 lower)
pinMode(29, OUTPUT); // relay 11 (pin 4 raise)
pinMode(30, OUTPUT); // relay 12 (pin 4 lower)
pinMode(31, OUTPUT); // relay 13 (pin 5 raise)
pinMode(32, OUTPUT); // relay 14 (pin 5 lower)
pinMode(33, OUTPUT); // relay 15 (pin 6 raise)
pinMode(34, OUTPUT); // relay 16 (pin 6 lower)
pinMode(35, OUTPUT); // relay 17 (pin 7 raise)
pinMode(36, OUTPUT); // relay 18 (pin 7 lower)
pinMode(37, OUTPUT); // relay 19 (pin 8 raise)
pinMode(38, OUTPUT); // relay 20 (pin 8 lower)
pinMode(39, OUTPUT); // relay 21 (pin 9 raise)
pinMode(40, OUTPUT); // relay 22 (pin 9 lower)
pinMode(41, OUTPUT); // relay 23 (pin 10 raise)
pinMode(42, OUTPUT); // relay 24 (pin 10 lower)
pinMode(43, OUTPUT); // relay 25 (close ball gate)
pinMode(44, OUTPUT); // relay 26 (open ball gate)
pinMode(45, OUTPUT); // relay 27 (raise ball elevator)
pinMode(46, OUTPUT); // relay 28 (lower ball elevator)
pinMode(47, OUTPUT); // relay 29 (raise sweep)
pinMode(48, OUTPUT); // relay 30 (lower sweep)
pinMode(49, OUTPUT); // relay 31 (service light)
pinMode(50, OUTPUT); // relay 32 (spare)
pinMode(51, OUTPUT); // LED strip #1
pinMode(52, OUTPUT); // LED strip #2
// 53 not used
pinMode (A0, INPUT); // Analog signal for current sensor on linear actuator #1 (bowling pin 1)
pinMode (A1, INPUT); // Analog signal for current sensor on linear actuator #2 (bowling pin 2)
pinMode (A2, INPUT); // Analog signal for current sensor on linear actuator #3 (bowling pin 3)
pinMode (A3, INPUT); // Analog signal for current sensor on linear actuator #4 (bowling pin 4)
pinMode (A4, INPUT); // Analog signal for current sensor on linear actuator #5 (bowling pin 5)
pinMode (A5, INPUT); // Analog signal for current sensor on linear actuator #6 (bowling pin 6)
pinMode (A6, INPUT); // Analog signal for current sensor on linear actuator #7 (bowling pin 7)
pinMode (A7, INPUT); // Analog signal for current sensor on linear actuator #8 (bowling pin 8)
pinMode (A8, INPUT); // Analog signal for current sensor on linear actuator #9 (bowling pin 9)
pinMode (A9, INPUT); // Analog signal for current sensor on linear actuator #10 (bowling pin 10)
pinMode (A10, INPUT); // Analog signal for current sensor on linear actuator #11 (ball gate)
pinMode (A11, INPUT); // Analog signal for current sensor on linear actuator #12 (ball elevator)
pinMode (A12, INPUT); // monitors ball at elevator sensor NOTE: this may need an external pullup
// pins A13-A15 not used
}
// ________________________________________________________________________ //
// -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //
void loop() {
// -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //
// ________________________________________________________________________ //
// currentTime = millis(); // future use
// ________________________________________________________________________
// Mode 1: Lane Idle Until Next Ball is Rolled
// ________________________________________________________________________
if (Mode == 1) {
ballRolledState = digitalRead(7); // Monitors **UNO** ball lane sensor (trigger)
if (ballRolledState == !lastBallRolledState) { // if state changes to LOW, ball has been rolled
ballRolledTime = millis(); // sets time ball was rolled
Mode = 2;
}
lastBallRolledState = ballRolledState;
}
// ________________________________________________________________________
// Mode 2: Determine How Many Pins are Left
// ________________________________________________________________________
if (Mode == 2) {
unsigned long time = millis() - ballRolledTime; // Keeps track of how much time has passed since the ball was rolled
if (time > 3250 && data[2] == LOW) {
// NOTE: After ball sensor is triggered, computer has camera take photo of bowling pin deck. Computer determines what bowling
// pins have been knocked down and, in turn, sends data to UNO. Uno releases this data 3 seconds after ball sensor is triggered
// through the Uno pins defined as pinDesignation(ii)
for (int ii = 1; ii < 11; ii++) {
bowlPinState[ii] = digitalRead (pinDesignation[ii]); //Read **UNO** pins; High/LOW = Bowling pin has fallen/still standing
result = result + bowlPinState[ii];
}
if (result == 2) { // test for a split
if ((bowlPinState[7] + bowlPinState[10] == 2) || (bowlPinState[3] + bowlPinState[10] == 2) || (bowlPinState[4] + bowlPinState[5] == 2) || (bowlPinState[5] + bowlPinState[6] == 2)) {
split = HIGH;
}
}
if (result == 0) { // gutter ball
mp3.playF(01); // play from 01 file folder
mp3.play(01,15); // plays specifically mp3 001.xxx at volume 15
}
if (split == HIGH) { // split
mp3.playF(01); // play from 01 file folder
mp3.play(02,15); // plays specifically mp3 002.xxx at volume 15
}
bool spare = digitalRead(9);
if (spare == HIGH){
digitalWrite (20, HIGH); // turn on spare light
mp3.playF(01); // play from 01 file folder
mp3.play(03,15); // plays specifically mp3 003.xxx at volume 15
}
bool strike = digitalRead(10);
if (strike == HIGH){
digitalWrite (20, HIGH); // turn on spare light
digitalWrite (21, HIGH); // turn on strike light
mp3.playF(01); // play from 01 file folder
mp3.play(04,15); // plays specifically mp3 004.xxx at volume 15
}
ball1 = digitalRead(11);
if (ball1 == HIGH) {
digitalWrite (18, HIGH); // turn on ball 1 light
}
ball2 = digitalRead(12);
if (ball1 == HIGH) {
digitalWrite (19, HIGH); // turn on ball 2 light
}
data[2] = HIGH; // Insures this loop runs once
}
if (time > 4000) {
Mode = 3;
data[2] = LOW; // resets variable for Mode 2
result = 0;
split = LOW;
digitalWrite (20, LOW); // turn off spare light
digitalWrite (21, LOW); // turn off strike light
}
}
// ________________________________________________________________________
// Mode 3: Prepare Lane for Next Ball
// ________________________________________________________________________
if (Mode == 3) {
if(data[3] == LOW) {
laneResetTime = millis(); // Determines the start time of Mode 3
mp3.playF(01); // play from 01 file folder
mp3.play(05,15); // plays specifically mp3 005.xxx at volume 15
data[3] = HIGH; //Insures millis() read just one time for this mode
}
unsigned long time = millis() - laneResetTime;
if (time < 50) {
resetPinActuators(); // assures pin actuators not moving
resetSweepActuator(); // assures sweep actuator not moving
}
if (time >= 1500 && time < 8000) {
lowerBallSweep(); // 6 seconds required to lower sweep
}
if (time >= 4000 && time < 8000) {
raisePins(); //3 seconds required to raise pins which can overlap sweep operation
}
if (time >= 8000 && time < 8500) {
// pause for 1/2 second to allow pins to settle/untangle
resetPinActuators(); // Ensures actuators for bowling pins are off
resetSweepActuator(); // Ensures actuator or ball sweep is off
}
if (time >= 8500 && time < 15500) {
raiseBallSweep(); // allow 6 seconds to open
}
if (time >= 8500 && time < 12000) {
lowerPins(); // 3 seconds required to lower pins
}
if (time >= 15500) {
Mode = 1;
data[3] = LOW; //resets time variable for Mode 3
}
}
// ________________________________________________________________________
// Mode 4: Manual Service Required
// ________________________________________________________________________
if (Mode == 4) {
delay(50);
lowerBallSweep(); //
digitalWrite(49, LOW); // turns on service light as elevator or sweep needs attention from attendant
while (digitalRead(18) == LOW) {
// Do nothing, just wait for manual reset
}
}
// ________________________________________________________________________
// LED Lights
// ________________________________________________________________________
theaterChaseRainbow(50); //Subroutine for LED's with value of xx for SpeedDelay
// ________________________________________________________________________
// Ball Return Mode // Note: may run concurrently with any Mode
// ________________________________________________________________________
if (ballReturn == false) { //Ball return is not in use = false
int reading = digitalRead(A12); // read switch at ball return
if (reading != lastBallReturnState) { // Check to see if ball is at ball return sensor
lastDebounceTime1 = millis(); // Reset debounce timer
}
if ((millis() - lastDebounceTime1) > debounceDelay1) { // If enough time has passed, confirm the change
if (reading != ballReturnState) {
ballReturnState = reading;
if (ballReturnState == LOW) { // Only toggle when ball sensor actually detects the ball (LOW with INPUT_PULLUP)
ballReturn = true; // Ball return now active
ballReturnStartTime = millis();
// Serial.print("Status variable changed to: ");
// Serial.println(data[1]);
}
}
}
lastBallReturnState = reading;
}
if (ballReturn == true) { // Ball elevator = true when operating
unsigned long time = millis() - ballReturnStartTime; // keeps track of how long ball elevator has been running
if (time < 500) {
resetBallGateActuator(); // assures ball gate actuator not moving
resetBallElevatorActuator(); // assures ball elevator actuator not moving
}
if (time >= 500 && time < 3500) { // allows ball gate 3 seconds to close
closeBallGate();
}
if (time >= 3500 && time < 21000) {
raiseBallElevator(); //17 seconds required for full up stroke
resetBallGateActuator(); // stops ball gate actuator mid stroke
}
if (time >= 21000 && time < 22500) {
// pause for 1.5 seconds to allow ball to exit ball elevator
resetBallElevatorActuator(); // assures ball elevator actuator not moving
}
if (time >= 22500 && time < 38500) {
lowerBallElevator(); //15 seconds required for full down stroke
}
if (time >= 37500 && time < 40500) {
openBallGate(); // allow 3 seconds to open
}
if (time >= 40500) {
resetBallGateActuator(); // stops ball gate actuator mid stroke
resetBallElevatorActuator();
ballReturn = false; // changes ball return status to off after 40.5 seconds
}
}
// ________________________________________________________________________
// Service Mode // Note: Will Interrupt any Mode
// ________________________________________________________________________
int serviceButtonState = digitalRead(18); // Check if the service button has been pushed
if (serviceButtonState == LOW && serviceButtonPressed == false) { // conditions when button just pressed
pressStartTime = millis();
serviceButtonPressed = true;
Serial.println("button pressed");
}
if (serviceButtonState == HIGH && serviceButtonPressed == true) { // conditions when pressed button just released
if(millis() - pressStartTime > 500) {
if (millis() - pressStartTime >= 2500) { // request made to reset all pins if service button held for > 2.5 seconds
for (int ii = 1; ii < 11; ii++) {
bowlPinState[ii] = LOW; // resets all pins to standing if service button pushed longer than 2.5 seconds
}
}
}
Mode = 3; // re-rack bowling pins
data[3] = LOW;
serviceButtonPressed = false;
digitalWrite(49, HIGH); // turns off service light if on from Mode 4
}
// ________________________________________________________________________
// Detect High Current in Actuators // Note: may interrupt any Mode
// ________________________________________________________________________
for (int ii = 0; ii < 12; ii++) {
if(maxCurrentEvent[ii] == false) {
voltageOut[ii] = analogRead(ii); // read analog pins 0 to 11 to detect high current in linear actuators
int jj = ii + 1; // variable to match 0-12 with 1-13 instead
current[jj] = (voltageOut[ii] - 2.5) / 0.066; // formula to convert sensor reading to amps
if (current[jj] > currentMax) { // detects high current on linear actuator jj
lastCurrentDebounceTime[jj] = millis();
}
if (millis() - lastCurrentDebounceTime[jj] > currentDebounceDelay) { // overlooks actuator start up current
if (current[jj] > currentMax) {
maxCurrentEvent[jj] = true; // linear actuator #jj has exceeded max current
}
if (data[0] == LOW) {
currentMaxTime[jj] = millis(); // keeps track when this event starts
data[0] = HIGH; // runs this loop once
}
unsigned long time = millis() - currentMaxTime[jj];
if (jj < 11) {
if (time < 50) {
digitalWrite(49, HIGH); // turns on service light
digitalWrite(solenoidExtend[jj], LOW); // stop linear actuator with high current
digitalWrite(solenoidRetract[jj], LOW);
}
if (time >= 50 && time < 1500) {
digitalWrite(solenoidExtend[jj], LOW); // raise linear actuator with high current
digitalWrite(solenoidRetract[jj], HIGH);
}
if (time >= 1500 && time < 1550){
digitalWrite(solenoidExtend[jj], LOW); // stop linear actuator with high current
digitalWrite(solenoidRetract[jj], LOW);
}
if (time >= 1550 && time < 4500) {
digitalWrite(solenoidExtend[jj], HIGH); // lower linear actuator with high current
digitalWrite(solenoidRetract[jj], LOW);
}
if (time >=4500) {
maxCurrentEvent[ii] = false;
data[0] = LOW; // runs this loop once
}
}
else {
digitalWrite(solenoidExtend[jj], LOW); // stops movement of linear actuator for ball gate or elevator
digitalWrite(solenoidRetract[jj], LOW);
Mode = 4; // operator asistance is required for ball jam at ball gate or elevator
maxCurrentEvent[ii] = false;
data[0] = LOW; // resets loop variable
}
}
}
}
}
// ________________________________________________________________________ //
// -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //
// void subroutines
// -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //
// ________________________________________________________________________ //
void resetPinActuators() { // stops linear actuators for bowling pins 1-10
for (int ii = 1; ii < 11; ii++) {
digitalWrite(solenoidExtend[ii], LOW);
digitalWrite(solenoidRetract[ii], LOW);
}
Serial.println("Reset all bowling pin actuators"); // Prints text
}
void resetBallGateActuator() { // stops linear actuators for ball gate
digitalWrite(solenoidExtend[11], LOW); // pin 43
digitalWrite(solenoidRetract[11], LOW); // pin 44
Serial.println("Reset ball gate actuator"); // Prints text
}
void resetBallElevatorActuator() { // stops linear actuator for ball elevator
digitalWrite(solenoidExtend[12], LOW); //pin 45
digitalWrite(solenoidRetract[12], LOW); // pin 46
Serial.println("Reset ball elevator actuator"); // Prints text
}
void resetSweepActuator() { // stops linear actuator for sweep
digitalWrite(solenoidExtend[13], LOW); // pin 47
digitalWrite(solenoidRetract[13], LOW); // pin 48
Serial.println("Reset sweep actuator"); // Prints text
}
void raisePins() {
for (int ii = 1; ii < 11; ii++) {
digitalWrite(solenoidExtend[ii], LOW);
digitalWrite(solenoidRetract[ii], HIGH);
delay(50);
}
Serial.println("Raise Pins"); // Prints text
}
void lowerPins() {
for (int ii = 1; ii < 11; ii++) {
if (bowlPinState[ii] == LOW) {
digitalWrite(solenoidExtend[ii], HIGH);
digitalWrite(solenoidRetract[ii], LOW);
Serial.print("This pin still standing: ");
Serial.println(ii);
}
if (bowlPinState[ii] == HIGH) {
digitalWrite(solenoidExtend[ii], LOW);
digitalWrite(solenoidRetract[ii], HIGH);
Serial.print("This pin has fallen: ");
Serial.println(ii);
}
Serial.println("Lower Some Pins"); // Prints text
}
}
void openBallGate() {
digitalWrite(solenoidExtend[11], LOW);
digitalWrite(solenoidRetract[11], HIGH);
Serial.println("Open Ball Gate"); // Prints text
}
void closeBallGate() {
digitalWrite(solenoidExtend[11], HIGH);
digitalWrite(solenoidRetract[11], LOW);
Serial.println("Close ball gate"); // Prints text
}
void raiseBallElevator() {
digitalWrite(solenoidExtend[12], LOW);
digitalWrite(solenoidRetract[12], HIGH);
Serial.println("Raise Elevator"); // Prints text
}
void lowerBallElevator() {
digitalWrite(solenoidExtend[12], HIGH);
digitalWrite(solenoidRetract[12], LOW);
Serial.println("Lower Elevator"); // Prints text
}
void lowerBallSweep() {
digitalWrite(solenoidExtend[13], LOW);
digitalWrite(solenoidRetract[13], HIGH);
Serial.println("Lower Ball Sweep"); // Prints text
}
void raiseBallSweep() {
digitalWrite(solenoidExtend[13], HIGH);
digitalWrite(solenoidRetract[13], LOW);
delay(50);
Serial.println("Raise ball sweep"); // Prints text
}
void setPixel(int Pixel, byte red, byte green, byte blue) {
leds[Pixel].r = red;
leds[Pixel].g = green;
leds[Pixel].b = blue;
}
void setAll(byte red, byte green, byte blue) { // Future use if LED strips need to be shut off
for(int i = 0; i < NUM_LEDS; i++ ) {
setPixel(i, red, green, blue);
}
FastLED.show();
}
void theaterChaseRainbow(int SpeedDelay) {
byte *c;
unsigned long currentTime = millis();
if (currentTime - lastTime >= SpeedDelay) {
for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel
for (int q=0; q < 3; q++) {
for (int i=0; i < NUM_LEDS; i=i+3) {
c = Wheel( (i+j) % 255);
setPixel(i+q, *c, *(c+1), *(c+2)); //turn every third pixel on
}
FastLED.show();
for (int i=0; i < NUM_LEDS; i=i+3) {
setPixel(i+q, 0,0,0); //turn every third pixel off
}
}
}
lastTime = currentTime;
}
}
byte * Wheel(byte WheelPos) {
static byte c[3];
if(WheelPos < 85) {
c[0]=WheelPos * 3;
c[1]=255 - WheelPos * 3;
c[2]=0;
} else if(WheelPos < 170) {
WheelPos -= 85;
c[0]=255 - WheelPos * 3;
c[1]=0;
c[2]=WheelPos * 3;
} else {
WheelPos -= 170;
c[0]=0;
c[1]=WheelPos * 3;
c[2]=255 - WheelPos * 3;
}
return c;
}


