#include "ESP32Servo.h" //servo library
#include "IRremote.h" //ir sensor library
//#include "StepperAK.h" //stepper library
#include "Stepper.h" //stepper library
//#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <WebSerial.h>
#define LED_BUILTIN 2 //ESP Pin 2
#define A1 34 //ESP Pin 34
#define motorpin1 13 //13 //digotal pins used for the stepper motor
#define motorpin2 14 //14
#define motorpin3 32 //32
#define motorpin4 33 //33
#define delaytime 90
//18,19,21,22,23,25,26,27 - Servos 0-7
//0,2,4,5.12,15
AsyncWebServer server(80);
//HalfStepper _Motor (200, 13, 14, 32, 33); //(200, 7, 6, 5, 4);
Stepper stepper(4,motorpin1,motorpin2,motorpin3,motorpin4); //instantiate stepper motor object
IRrecv irrecv(A1); //instantiate a IR receiver object
//decode_results results; //instantiate a decode_results object.
int btn_value = 0;
Servo myservo[8] = {Servo(), Servo(), Servo(), Servo(), Servo(), Servo(), Servo(), Servo()}; //array of servo objects
//row 1 is servo 1, row 2 servo 2, etc...
//1=1/8,2=1/4,3=3/8(dotted 1/4),4=1/2
byte song1[9][104] = {{1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, //song1 = Jingle Bells, right hand melody.
{0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, //finger 1 starts on g below middle c.
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, //http://www.pianolessons4children.com/sheetmusic/Jingle_Bells_C_Major.pdf
{0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
{0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,1,0,0,0,0,0,0,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,0,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0},
{2,2,2,2,6,1,1,2,2,2,2,6,6,2,2,2,2,6,6,2,2,2,2,6,2,2,2,2,2,6,2,2,2,2,2,6,2,2,2,2,2,2,2,2,2,2,2,2,2,4,4,2,2,4,2,2,4,2,2,3,1,6,2,2,2,3,1,2,2,2,1,1,2,2,2,2,4,4,2,2,4,2,2,1,2,0,3,1,6,2,2,2,3,1,2,0,0,1,1,2,2,2,2,8}};
byte song2[9][12] = {{1,0,0,0,1,0,0,0,0,0,0,0}, //song2 = test sequence
{0,1,0,0,0,1,0,0,0,0,0,0}, //
{1,0,1,0,0,0,1,0,0,0,0,0},
{0,1,0,1,0,0,0,1,0,0,0,0},
{1,0,1,0,0,0,0,0,1,0,0,0},
{0,1,0,1,0,0,0,0,0,1,0,0},
{0,0,1,0,0,0,0,0,0,0,1,0},
{0,0,0,1,0,0,0,0,0,0,0,1},
{9,9,9,9,1,1,1,1,1,1,1,1}};
byte song3[9][36] = {{0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, //song3 = Lucky by Jason Mraz, right hand melody.
{1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, //finger 1 starts on middle c.
{0,0,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,1,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0},
{0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0},
{1,1,1,3,1,1,1,1,4,1,1,1,1,1,4,1,1,1,2,1,2,1,2,0,3,1,1,1,1,2,3,1,3,1,1,1}};
int song1steps[4] = {220, 250, 300 ,300}; //amount of steps to move stepper motor.
int song2steps[4] = {150, 250, 425 ,60};
int song3steps[4] = {100, 350, 300 ,300};
byte flag =1; //intialize flag variable used for delay timing later
byte m = 0; //intialize counter variable m for later use
const char* ssid = "Alliswell"; // Your WiFi SSID
const char* password = "lordis111"; // Your WiFi Password
void recvMsg(uint8_t *data, size_t len){
WebSerial.println("Received Data...");
String d = "";
for(int i=0; i < len; i++){
d += char(data[i]);
}
WebSerial.println(d);
if (d == "ON"){
digitalWrite(LED_BUILTIN, HIGH);
}
if (d=="OFF"){
digitalWrite(LED_BUILTIN, LOW);
}
}
///////////////////////////////////////////////////////////////////
void setup() {
// Serial.begin(9600); //begin serial communication
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.printf("WiFi Failed!\n");
return;
}
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
// WebSerial is accessible at "<IP Address>/webserial" in browser
WebSerial.begin(&server);
WebSerial.msgCallback(recvMsg);
server.begin();
// for (int ii=0; ii < 8; ii++) { //attach all the servos. uses digital pins 2-9
// myservo[ii].attach(2+ii); }
myservo[0].attach(18); //for ESP pin 18
myservo[1].attach(19); //for ESP pin 19
myservo[2].attach(21); //for ESP pin 21
myservo[3].attach(22); //for ESP pin 22
myservo[4].attach(23); //for ESP pin 23
myservo[5].attach(25); //for ESP pin 25
myservo[6].attach(26); //for ESP pin 26
myservo[7].attach(27); //for ESP pin 27
for (int k = 0; k < 8; k++) { //reset all servos
myservo[k].write(107);
delay(15);
}
irrecv.enableIRIn(); //start the ir receiver
pinMode(motorpin1, OUTPUT); //pins used for the stpper motor
pinMode(motorpin2, OUTPUT);
pinMode(motorpin3, OUTPUT);
pinMode(motorpin4, OUTPUT);
stepper.setSpeed(4000); //sets stpper speed. found experimentally to work
}
void loop() {
WebSerial.println("Hello!");
// delay(2000);
//if (irrecv.decode(&results))
if (irrecv.decode())
{
// Serial.println(results.value);
btn_value = irrecv.decodedIRData.command;
Serial.println(btn_value);
//*****************************************************
//if (results.value == 16724175) { //#1 on remote
if (btn_value == 48) { //#1 on remote
for (int i = 0; i < 105; i++) { //for loops cycle through the song array to find the values of the notes
for (int j=0; j < 9; j++) {
//code to play the notes. different angles because of the different finger heights.
if (song1[j][i] == 1) {
if (j == 0 || j == 2 || j == 4 || j == 6) {
myservo[j].write(55);
}
if (j == 1 || j == 3 || j == 5 || j == 7) {
myservo[j].write(35);
}
}
//code to delay to get proper note timing. adjust according to the tempo of the song.
if (j == 8) {
delay(song1[j][i]*150);
}
//a zero in the last row indicates that the stepper has to move
// if (song1[j][i] == 0 || j == 8) {
//move stepper
// }
}
for (int k = 0; k < 8; k++) { //reset all servos. 107 value found experimentally
myservo[k].write(107);
}
delay(90);
}
}
//*****************************************************
//if (results.value == 16718055) { //#2 on remote
if (btn_value == 24) { //#2 on remote
for (int i = 0; i < 12; i++) { //for loops cycle through the song array to find the values of the notes
for (int j=0; j < 9; j++) {
//code to play the notes
if (song2[j][i] == 1) {
if (j == 0 || j == 2 || j == 4 || j == 6) {
myservo[j].write(55);
}
if (j == 1 || j == 3 || j == 5 || j == 7) {
myservo[j].write(35);
}
}
//code to delay to get proper note timing and move stepper
if (j == 8) {
delay(song2[j][i]*100);
}
//a zero in the last row indicates that the stepper has to move
// if (song2[j][i] == 0 || j == 8) {
//move stepper
// }
}
for (int k = 0; k < 8; k++) { //reset all servos
myservo[k].write(107);
}
delay(90);
}
}
//*****************************************************************
//if (results.value == 16743045) { //#3 on remote
if (btn_value == 122) { //#3 on remote
for (int i = 0; i < 37; i++) { //for loops cycle through the song array to find the values of the notes
for (int j = 0; j < 9; j++) {
//code to play the notes
if (song3[j][i] == 1) { //changed back to 3 -that was removed tempororily
if (j == 0 || j == 2 || j == 4 || j == 6) {
myservo[j].write(55);
}
if (j == 1 || j == 3 || j == 5 || j == 7) {
myservo[j].write(35);
}
}
//code to delay to get proper note timing
if (j == 8) {
delay(song3[j][i]*350); //changed back to 3 -that was removed tempororily
flag = song3[j][i]; //changed back to 3 -that was removed tempororily
}
//a zero in the last row indicates that the stepper has to move
// if (song1[j][i] == 0 || j == 8) {
//move stepper
// }
}
for (int k = 0; k < 8; k++) { //reset all servos
myservo[k].write(107);
}
delay(90);
}
}
//*****************************************************************
irrecv.resume();
}
}