/*
#define Chevron1 19
#define Chevron2 18
#define Chevron3 17
#define Chevron4 16
#define Chevron5 15
#define Chevron6 14
#define Chevron7 10
#define Chevron8 9
#define Chevron9 2
https://wokwi.com/projects/339041197472350802
*/
#include <Stepper.h>
#include <AFMotor.h>
#include "SoftwareSerial.h"
#include "Arduino.h"
#include "DFRobotDFPlayerMini.h"
DFRobotDFPlayerMini myDFPlayer;
SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
const int stepsPerRevolution = 200; // change this to fit the number of steps per revolution
// for your motor
// initialize the stepper library on pins 8 through 11:
Stepper SMGate(stepsPerRevolution, 7, 8, 11, 12);
Stepper SMChevron(stepsPerRevolution, 3, 4, 5, 6);
//AF_Stepper SMGate(stepsPerRevolution, 1);
//AF_Stepper SMChevron(stepsPerRevolution, 2);
//int Chevrons[] = {7,8,9,3,4,5,10,2,6};
//int Chevrons[] = {19,18,17,16,14,10,9,2,15};
int Chevrons[] = {14,10,9,18,17,16,2,19,15};
//Chevron_Locked should be set to the last chevron in the dialling sequence
int Chevron_Locked = Chevrons[8];
//How long should the locked chevron be lit before continuing dialling. Default is 1500 (1.5 seconds).
int ChevronLocked = 1500;
//How many steps the stepper motor must turn per symbol.
//This value is overritten by the calibrate function.
//If you bypass calibration this value must be set accordingly.
float Step_Per_Symbol = 30.77;
//How many steps to move the stepper motor for the chevron.
int Chevron_Step = 10;
//Sample Startgate addresses. un-comment the address you want.
//Abydos
int Address[] = {27,7,15,32,12,30,1};
//Othala (Asgard homeworld)
//int Address[] = {11,27,23,16,33,3,9,1};
//Destiny
//int Address[] = {6,17,21,31,35,24,5,11,1};
//Other variable definitions. No need to change these.
float LDR_avg = 0.0;
float LDR_cal = 0.0;
int Dialling = 0;
float Step_increment = 0;
int Address_Length = 9;
#define DATA_PIN 14 // Pin connected to DS of 74HC595
#define LATCH_PIN 15 // Pin connected to STCP of 74HC595
#define CLOCK_PIN 16 // Pin connected to SHCP of 74HC595
// How many of the shift registers
#define NUM_SHIFT_REGS 2
const uint8_t numOfRegisterPins = NUM_SHIFT_REGS * 8;
bool registers[numOfRegisterPins];
void setup() {
pinMode(DATA_PIN, OUTPUT);
pinMode(CLOCK_PIN, OUTPUT);
pinMode(LATCH_PIN, OUTPUT);
clearRegisters();
writeRegisters();
mySoftwareSerial.begin(9600);
Serial.begin(115200);
if (!myDFPlayer.begin(mySoftwareSerial)) { //Use softwareSerial to communicate with mp3.
while(true){
delay(0); // Code to compatible with ESP8266 watch dog.
}
}
myDFPlayer.volume(20); //Set volume value. From 0 to 30
myDFPlayer.play(10); //Play the first mp3
delay(10000);
SMGate.setSpeed(10);
SMChevron.setSpeed(10);
// initialize digital pin LED_BUILTIN as an output.
for (int tmp_chevron = 0; tmp_chevron < 9; tmp_chevron ++){
pinMode(Chevrons[tmp_chevron], OUTPUT);
}
Address_Length = sizeof (Address) / sizeof(int);
Dialling = 1;
}
// the loop function runs over and over again forever
void loop() {
setRegisterPin(i, !toggle);
writeRegisters();
delay(5000);
// digitalWrite(Chevron1, HIGH);
//SMGate.step(-1);
//SMChevron.step(1);
//delay(1000);
if (Dialling <= Address_Length){
dial(Dialling);
if (Dialling == Address_Length){
//SMChevron.step(Chevron_Step, FORWARD, SINGLE);
//SMChevron.release();
//Serial.println("Wormhole Established");
for (int tmp_chevron1 = 0; tmp_chevron1 < 9; tmp_chevron1 ++){
digitalWrite(Chevrons[tmp_chevron1], HIGH);
}
// digitalWrite(Ramp_Lights, HIGH);
myDFPlayer.play(6);// sound - Hier muss das GateWeiss+Blau aktiviert werden und aKtivierungs sound
delay(3000);
myDFPlayer.loop(11);
delay(10000);
myDFPlayer.play(2);// sound - Hier muss das GateWeiss+Blau deaktiviert werden und deaKtivierungs sound
for (int tmp_chevron = 0; tmp_chevron < 9; tmp_chevron ++){
digitalWrite(Chevrons[tmp_chevron], LOW);
}
//digitalWrite(Ramp_Lights, LOW);
// Serial.println("Wormhole Disengaged");
}
Dialling ++;
}
// digitalWrite(Chevron7, HIGH); // turn the LED on (HIGH is the voltage level)
// delay(1000); // wait for a second
//digitalWrite(Chevron7, LOW); // turn the LED off by making the voltage LOW
//delay(1000); // wait for a second
}
void clearRegisters() {
// Reset all register pins
for (int i = numOfRegisterPins - 1; i >= 0; i--) {
registers[i] = LOW;
}
}
void setRegisterPin(int index, int value) {
// Set an individual pin HIGH or LOW
registers[index] = value;
}
void writeRegisters() {
// Set and display registers
digitalWrite(LATCH_PIN, LOW);
for (int i = numOfRegisterPins - 1; i >= 0; i--) {
digitalWrite(CLOCK_PIN, LOW);
digitalWrite(DATA_PIN, registers[i]);
digitalWrite(CLOCK_PIN, HIGH);
}
digitalWrite(LATCH_PIN, HIGH);
}
void dial(int Chevron) {
//Serial.print("Chevron ");
//Serial.print(Chevron);
//Serial.println(" Encoded");
int Steps_Turn = 0;
if (Chevron == 1) {
Steps_Turn = round(Step_Per_Symbol * (Address[(Chevron - 1)] - 1));
myDFPlayer.play(8);//sound- long roll
SMGate.step(Steps_Turn, BACKWARD, SINGLE);
}else{
Steps_Turn = Address[(Chevron - 1)] - Address[(Chevron - 2)];
if ((Chevron % 2) == 0) {
if (Steps_Turn < 0) {
Steps_Turn = Steps_Turn * -1;
}else{
Steps_Turn = 39 - Steps_Turn;
}
Steps_Turn = round(Step_Per_Symbol * Steps_Turn);
myDFPlayer.play(8);//sound- long roll
SMGate.step(Steps_Turn, FORWARD, SINGLE);
}else{
if (Steps_Turn < 0) {
Steps_Turn = 39 + Steps_Turn;
}
Steps_Turn = round(Step_Per_Symbol * Steps_Turn);
myDFPlayer.play(8);//sound- long roll
SMGate.step(Steps_Turn, BACKWARD, SINGLE);
}
}
SMGate.release();
if ((Dialling == 9) && (Address[(Chevron - 1)] != 1)){
for (int tmp_fail_safe_gate = 0; tmp_fail_safe_gate <= 100; tmp_fail_safe_gate ++){
int tmp_fail_safe_chevron = random(7);
digitalWrite(Chevrons[tmp_fail_safe_chevron], LOW);
SMGate.step(5, BACKWARD, SINGLE);
SMGate.release();
digitalWrite(Chevrons[tmp_fail_safe_chevron], HIGH);
}
for (int tmp_chevron = 0; tmp_chevron < 9; tmp_chevron ++){
digitalWrite(Chevrons[tmp_chevron], LOW);
}
Dialling = 10;
}else{
Serial.print("Chevron ");
Serial.print(Chevron);
Serial.println(" Locked");
digitalWrite(Chevron_Locked, HIGH);
myDFPlayer.play(3);//sound- chevronlocked
SMChevron.step(Chevron_Step, BACKWARD, SINGLE);
SMChevron.release();
}
if (Dialling < Address_Length){
delay(ChevronLocked);
//sound- Chevron unLocked
SMChevron.step(Chevron_Step, FORWARD, SINGLE);
SMChevron.release();
digitalWrite(Chevron_Locked, LOW);
delay(20);
if ((Address_Length < 8) || (Dialling < 4)){
digitalWrite(Chevrons[(Chevron - 1)], HIGH);
}else if ((Address_Length == 8) && ((Dialling >= 4) && (Dialling <= Address_Length))){
if (Dialling == 4){
digitalWrite(Chevrons[(6)], HIGH);
}else if (Dialling == 5){
digitalWrite(Chevrons[(3)], HIGH);
}else if (Dialling == 6){
digitalWrite(Chevrons[(4)], HIGH);
}else if (Dialling == 7){
digitalWrite(Chevrons[(5)], HIGH);
}
}else if ((Address_Length == 9) && ((Dialling >= 4) && (Dialling <= Address_Length))){
if (Dialling == 4){
digitalWrite(Chevrons[(6)], HIGH);
}else if (Dialling == 5){
digitalWrite(Chevrons[(7)], HIGH);
}else if (Dialling == 6){
digitalWrite(Chevrons[(3)], HIGH);
}else if (Dialling == 7){
digitalWrite(Chevrons[(4)], HIGH);
}else if (Dialling == 8){
digitalWrite(Chevrons[(5)], HIGH);
}
}
}
}