//____________________/COMUNICANÇÂO/______________________//
// 12345//00:00:00/
// 180A 180B 180C 180D

int TextXy[] = {0,0}; //coordenadas para imprimir caracteres recebidos do Esp8266

String Recebido; // Recebe mensagens do Esp8266
String Mensagem; // Recebe mensagens e comandos do Hc-06

unsigned long int valorData = 27555; //Guarda o valor das horas em segundos recebido pelo Esp8266;

int msg_Esp = 0; //faz a contagem de quantas barras aparecem em 12345//00:00:00/
int ok_Esp = 0; // Valida a inicialização do programa e indica se há ou não internet no esp8266 e bloqueia no inicio de um evento
int Reset = 1; // inicia/reinicia um evento ao iniciar o sistema ou em um horário específico

int Chances = 0; //permite a kin virar-se para uma direção aleatória se tiver o valor 4

byte Necessidades[] = {0,0,0,0,0,0,0}; //alterna seu valor ao receber um comando como: 6N

int valorAnteriorY[] = {0,0};  //Obtem o ultimo valor em ValorX / ValorY / ValorZ para 
int valorAnteriorX[] = {0,0};  //colocar-la na posição em que estava antes da função
int valorAnteriorZ[] = {0,0};  //"Observation()".

unsigned long Valor1; //valores utilizados para verificação dos horários
unsigned long Valor2; //
unsigned long Valor3; // 
unsigned long Valor4; //

char comando;

char Ctrl[] = {'.','W','S','D','A'}; //caracteres de comando
// outros: 
//velocidade dos motores 0-255ve 0-255vd 
//posição X do pescoço 40-160X 
//posição Y da cabeça 20-180Y 
//posição Y do pescoço 65-180H 
//olhos abertos 00O 
//olhos fechados 00o 
//posições limitadas/ilimitadas: T/t 
char resposta[] = {'F','Y','N'}; //Possiveis respostas para uma solicitação

//____________________/EVENTOS/______________________//

unsigned long Hora[17][2] = { //valor em segundos
  {0, 27000},    // 0 1   00:00 a 07:30 dormir
  {27000, 30000},// 1 2   07:30 a 08:20 Acordar
  {30000, 34200},// 2 3   08:20 a 09:30 Café da manhã
  {34200, 40200},// 3 4   09:30 a 11:10 Aleatório
  {40200, 45000},// 4 5   11:10 a 12:30 Aleatório
  {45000, 48600},// 5 6   12:30 a 13:30 Aleatório
  {48600, 51000},// 6 7   13:30 a 14:10 Almoço
  {51000, 56400},// 7 8   14:10 a 15:40 Aleatório
  {56400, 58200},// 8 9   15:40 a 16:10 Aleatório
  {58200, 61200},// 9 10  16:10 a 17:00 Lanche
  {61200, 65400},// 10 11 17:00 a 18:10 Aleatório
  {65400, 67200},// 11 12 18:10 a 18:40 Aleatório
  {67200, 69000},// 12 13 18:40 a 19:10 Janta
  {69000, 72660},// 13 14 19:10 a 20:11 Aleatório
  {72660, 77400},// 14 15 20:11 a 21:30 Aleatório
  {77400, 81300},// 15 16 21:30 a 22:35 Lanche
  {81300, 86399} // 16 17 22:35 a 23:59 Dormir

};
unsigned long D_Hora[17][2] = { //guarda valores em segundos para resetar tarefas
//
  {1, 2},        // 1
  {27001, 27002},// 2
  {30001, 30002},// 3
  {34201, 34202},// 4
  {40201, 40202},// 5
  {45001, 45002},// 6
  {48601, 48602},// 7
  {51001, 51002},// 8
  {56401, 56402},// 9
  {58201, 58202},// 10
  {61201, 61202},// 11
  {65401, 65402},// 12
  {67201, 67202},// 13
  {69001, 69002},// 14
  {72661, 72662},// 15
  {77401, 77402},// 16
  {81301, 81302} // 17
}; 



int Num_Event = 99; //Obtem um numero expecífico para iniciar um evento

int Confirmar = 3; //Recebe um valor caso um pedido seja confirmado, recusado ou pendente
int Solicitado = 0; //inicia uma solicitação em alguns eventos

//Rseume todos os numeros que executam uma mesma ação no robô
int Comer[5] = {2,6,9,12,15};
int aleatorio[8] = {3,4,7,8,10,11,13,14};
int dormir[2] = {0, 17};

boolean Task_0; //ativa comandos
boolean Task_1; //ativa a função piscar
boolean Task_2; //ativa a função Observar
boolean Task_3; //ativa a função Emotes pela função "VideoAnimation"; pode ser ativado com "At_Frame = 1"
boolean Task_4; //ativa a função VideoAnimation pela função "Emotes"; pode ser ativada com "At_Gif = 1"
boolean Task_5; //ativa o Cooler
boolean Task_6; //ativa os leds frontal aleatório
boolean Task_7; //ativa os leds frontal arco_iris
boolean Task_8; //ativa o Delay_A
boolean Task_9; //ativa o Delay_B
boolean Task_10;//ativa o Delay_C

//____________________/EMOTES/______________________//

int At_Frame = 0; //Utilizado para Iniciar uma animação de Emotes após a animação de vídeo


//                               10 20  30  40  50  60  70  80  90  100
// 180 = Esquerda e 90 = Direita 90 100 110 120 130 140 150 160 170 180
// Servo motor com adaptação extrutural X

//                          10  20  30  40  50  60  70  80  90 100 110 
// 180 = Baixo e 80 = cima  80  90 100 110 120 130 140 150 160 170 180
// Servo motor com adaptação extrutural Y

// 180 = baixo; 105 = cima;
//Codenadas do servo/pescoço de 180 a 105

int limite = HIGH; //permnite ou não com que o robo se movimente para posições exessivas (desativar essa opção pode resultar em danos nos mecanismos)

// define o valor minimo, caso o motor chegue nesse valor, será desligado imediatamente
int vxmin = 40;  // Controle X do pescoço
int vxmax = 160; // -
int vymin = 20; // Controle Y da cabeça
int vymax = 180; // - 
int vzmin = 65;  // Controle Z do pescoço
int vzmax = 180; // - 

int ValorX = 90;  // valores que Guardam a memória de posicionamento dos servos
int ValorY = 150; //
int ValorZ = 65; // 

int VXA = 0;  //guarda o estado anterior do Servo X
int VYA = 0;  //guarda o estado anterior do servo Y
int VZA = 0;  //guarda o estado anterior da estrutura do pescoço: servo Z

int Velocidades[] = {20,20,20}; // guarda as velocidades escolhidas pelo usiário e pelo sistema
int ComandVel = 255; //obtem um valor numerico em Serial_2 e guarda em Velocidades[]

// 0 finaliza emotes
// 1 comando de tempo
// 2 comando de expressão do olho aberto
// 3 comando de servos-motores
// 4 controle de motores
// 5 comando de expressão dos olhos fechados

//              1           1              1                 1                  1
//                     0,1 2 3 4 5 6 7 8 9  10,11,12,13,14,15,16,17,18,19, 20,21,22,23,24,25,26,27,28,29
int linhas[10][23] = {{3,3,3,2,1,3,3,2,0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0}, // dormir (solicitado); linhas que guardarão os comandos  0
               {2,1,2,3,3,3,1,3,1,3, 3, 1, 2, 0,0,0,0,0,0,0,0,0,0}, // dormir (confirmação)
               {3,3,3,2,1,3,3,2,1,3, 3, 2, 0, 0,0,0,0,0,0,0,0,0,0}, // acordar
               {3,3,3,2,5,1,2,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // mal-estar
               {3,3,3,2,1,3,3,1,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Fome / sede (solicitado)
               {3,3,3,1,2,1,3,3,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Fome / sede (Confirmação)
               {3,3,3,2,1,3,3,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // calor (Alternativa A)
               {3,3,3,1,3,3,2,1,3,3,2,1,3,3,2,1,3,3,2,1,2,3,0}, // calor (Alternativab B)
               {3,3,3,2,1,3,1,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // frio
               {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} // Entediada
 };
int  Eyes[9][23] = {{0,0,0,15,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // dormir (solicitado); guardam os tipos de olhares        2
               {17,0,3,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0}, // dormir (confirmação)
               {0,0,0,15,0,0,0,11,0,0,0, 0, 0,0,0,0,0,0,0,0,0,0,0}, // acordar
               {0,0,0,16,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // mal-estar
               {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Fome / sede (Olhos definidos pelo sistema) (solicitado)
               {0,0,0,0,14,0,0,0,0, 0, 0,0,0,0,0,0,0,0,0,0,0,0,0}, // Fome / sede (Confirmação)
               {0,0,0,14,0,0,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // calor
               {0,0,0,0,0,0,7,0,0,0,15,0,0,0,8,0,0,0,15,0,12,0,0}, // calor (Alternativab B)
               {0,0,0,6,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0} // frio
};
int  EyesClose[9][23] = {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // dormir (solicitado); guardam os tipos de olhares        5
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // dormir (confirmação)
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // acordar
                    {0,0,0,0,29,0,0,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // mal-estar
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Fome / sede (Olhos definidos pelo sistema) (solicitado)
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Fome / sede (Confirmação)
                    {0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // calor
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // calor (Alternativab B)
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} // frio
};
int  Tempo[9][23] = {{0,0,0,0,5000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // dormir (solicitado); tempo em milis                    1
               {0,1000,0,0,0,0,10000,0,5000,0,0,30000,2,0,0,0,0,0,0,0,0,0,0}, // dormir (confirmação)
               {0,0,0,0,10000,0,0,0,10000,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // acordar
               {0,0,0,0,0,5000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // mal-estar
               {0,0,0,0,5000,0,0,1500,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Fome / sede (solicitado)
               {0,0,0,6000,0,20000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Fome / sede (Confirmação)
               {0,0,0,0,10000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}, // calor
               {0,0,0,3000,0,0,0,5000,0,0,0,1500,0,0,0,5000,0,0,0,2000,0,0,0}, // calor (Alternativab B)
               {0,0,0,0,3000,0,500,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} // frio
};
int  velocidade[9][23] = {{2,5,5,0,0,20,25,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0}, // dormir (solicitado); velocidade dos servos        3
                    {0,0,0,30,50,5,0,100,0,30,5,0,0,0,0,0,0,0,0,0,0,0,0}, // dormir (confirmação)
                    {10,2,5,0,0,50,5,0,0,10,10,0,0,0,0,0,0,0,0,0,0,0,0}, // acordar
                    {20,10,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // mal-estar
                    {30,5,255,0,0,30,5,0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Fome / sede (solicitado)
                    {5,5,5,0,0,0,10,10,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Fome / sede (Confirmação)
                    {5,10,2,0,0,15,10,5,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // calor
                    {255,255,255,0,10,20,0,0,10,20,0,0,10,20,0,0,10,20,0,0,0,30,0}, // calor (Alternativab B)
                    {255,255,255,0,0,20,0,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} // frio
};                    
int  srv[9][23] = {{1,2,3,0,0,3,1,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0}, // dormir (solicitado); servo escolhido                     3
             {0,0,0,1,2,3,0,3,0,1,3,0,0,0,0,0,0,0,0,0,0,0,0},  // dormir (confirmação)
             {1,2,3,0,0,1,3,0,0,1,3,0,0,0,0,0,0,0,0,0,0,0,0}, // acordar
             {1,2,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // mal-estar
             {1,2,3,0,0,1,2,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Fome / sede (solicitado)
             {1,2,3,0,0,0,1,2,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Fome / sede (Confirmação)
             {1,2,3,0,0,1,2,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // calor
             {1,2,3,0,1,2,0,0,1,2,0,0,1,2,0,0,1,2,0,0,0,1,0}, // calor (Alternativab B)
             {1,2,3,0,0,2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} // frio
};
// servos: 
// 1 eixo Ycabeça
// 2 eixo X pescoço
// 3 eixo Y pescoço

int  angulo[9][23] = {{180,130,65,0,0,90,160,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0}, // dormir (solicitado); angulo de giro do servo           3
                {0,0,0,140,160,180,0,150,0,180,180,0,0,0,0,0,0,0,0,0,0,0,0}, // dormir (confirmação)
                {150,90,130,0,0,180,65,0,0,140,90,0,0,0,0,0,0,0,0,0,0,0,0}, // acordar OK
                {170,160,65,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // mal-estar
                {180,160,130,0,0,140,130,0,65,0,0,0,0,0,0,0,0,0,0,0,0,0,0},// Fome / sede (solicitado)
                {110,130,165,0,0,0,180,130,90,2,0,0,0,0,0,0,0,0,0,0,0,0,0}, // Fome / sede (Confirmação)
                {10,130,130,0,0,150,130,65,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, // calor
                {150,130,95,0,120,90,0,0,150,130,0,0,120,180,0,0,150,130,0,0,0,180,0}, // calor (Alternativab B)
                {140,130,80,0,0,180,0,180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} // frio

};


int Pcomand[] = {2, 0}; //controla o cursor de comandos {tipo de animação , etapas da animação}
int Rcomand = 1; //usado no comando de delay
int MotorC = 0;

  int Motor[5][4] = { //controla os sentidos dos motores
//Motor
// E   D
 {0,0,0,0}, //Nada     0
 {1,0,1,0}, //Frente   1
 {0,1,0,1}, //Ré       2
 {1,0,0,1}, //Direita  3
 {0,1,1,0}  //Esquerda 4
 //            X X  
};
//____________________/ANIMAÇÃO DE VÍDEO/______________________//
/*
int At_Gif = 0; //Utilizado para Iniciar uma animação de vídeo após a animação de gestos 
int I_Gif = 0; //Indica o inicio de uma animação de gif 
int N_Gif = 0; //Indica o ponto frame atual do gif
int F_Gif = 0; //Indica o Final de uma animação de gif

//Variável para controle de gifs
int INF[3][9] = { // Inicio / Numero atual / Fim
//F  F  T   B   C   L   S   L   F  
 {0, 8, 25, 32, 38, 47, 52, 58, 62}, // Inicio
 {0, 8, 25, 32, 38, 47, 52, 58, 62}, // Numero atual
 {7,24, 31, 37, 46, 52, 57, 61, 84}, // FInal
};
*/
//____________________/OLHOS/______________________//

int olhos[30][14] = {
// Direito        Esquerdo
// a b c d e f g  A B C D E F G 
  {1,1,0,0,1,1,1, 0,0,1,1,1,1,1}, //pacifica -------0 X P O
  {1,1,0,0,1,1,1, 1,1,0,0,1,1,1}, //pacifica_D -----1 X
  {0,0,1,1,1,1,1, 0,0,1,1,1,1,1}, //pacifica_E -----2 X
  {1,1,0,1,1,1,1, 1,0,1,1,1,1,1}, //cansada --------3 X P O
  {1,0,1,1,1,1,1, 1,0,1,1,1,1,1}, //cansada_D ------4 X
  {1,1,0,1,1,1,1, 1,1,0,1,1,1,1}, //cansada_E ------5 X
  {1,1,0,0,0,1,1, 1,0,1,1,1,0,1}, //sede -----------6 X P O
  {0,0,1,1,1,0,1, 1,0,1,1,1,0,1}, //sede_D ---------7 X
  {1,1,0,1,0,1,1, 1,1,0,0,0,1,1}, //sede_E ---------8 X
  {0,1,1,0,1,1,0, 0,1,1,0,1,1,0}, //fome -----------9 X
  {0,0,0,0,1,1,0, 0,0,0,0,1,1,0}, //brincar --------10 X
  {1,1,0,0,0,0,0, 0,0,1,1,0,0,0}, //frio -----------11 X
  {0,1,0,0,0,1,0, 1,0,1,0,1,0,0}, //calor ----------12 X
  {0,0,0,0,0,0,1, 0,0,0,0,0,0,1}, //estatico ---------13 P
  {0,1,1,0,0,0,0, 0,1,1,0,0,0,0}, //olho_fechado-1 -14 X comum
  {1,1,1,0,0,0,0, 0,1,1,1,0,0,0}, //olho_fechado-2 -15 X cansado
  {0,1,0,0,0,0,0, 0,0,1,0,0,0,0}, //triste ---------16
  {1,0,0,0,1,1,1, 0,0,0,1,1,1,1}, //feliz ----------17 P O
  {1,0,0,0,1,1,1, 1,0,0,0,1,1,1}, //feliz_D --------18
  {0,0,0,1,1,1,1, 0,0,0,1,1,1,1}, //feliz_E --------19
  {1,0,1,0,0,1,1, 0,1,0,1,1,0,1}, //gentil ---------20 P O
  {0,1,0,1,1,0,1, 0,1,0,1,1,0,1}, //gentil_D -------21
  {1,0,1,0,0,1,1, 1,0,1,0,0,1,1}, //gentil_E -------22
  {0,0,0,0,1,1,1, 0,0,0,0,1,1,1}, //brava ----------23 P O
  {0,0,0,1,1,1,0, 0,0,0,1,1,1,0}, //brava_D --------24
  {1,0,0,0,1,1,0, 1,0,0,0,1,1,0}, //brava_E --------25
  {1,1,1,0,0,1,1, 0,1,1,1,1,0,1}, //corada ---------26 P o
  {0,1,1,1,1,0,1, 0,1,1,1,1,0,1}, //corada_D -------27
  {1,1,1,0,0,1,1, 1,1,1,0,0,1,1}, //corada_E -------28
  {0,0,0,0,0,0,0, 0,0,0,0,0,0,0}  //Desligado ------29
  
   
  // X = Olhos usados em eventos
  // P = funcionam na função piscar
};
int olhosP[] = {0,3,6,17,13,20,23,26};
int olhosO[] = {0,3,6,17,20,23,26}; //olhos que tem animação de observação,
//e ativam a função "Observar" caso Eye_Memory seja igual a um deles

int Number = 0; //usado atualmente na função "Piscar"
int Number1 = 0; //usado atualmente na função "Observar" para mudar a posição dos olhos

int Number_Eye[] = {1, 0}; //Guarda a posição atual para uma expressão dos olhos {A , B}
//A = um valor que dará prioridade a um olhar diferente: piscar / Observar / estático
//B = guarda o valor do olhar que ficou em segundo plano
int Eye_Memory = 0; //Guarda a posição padrão escolhida no evento atual (Utilizado também na função "Observar").
int Eyes_Closed = 14; //Guarda a posição na qual o olho se fechará com um formato diferente, por exemplo: 14, 15, 16
/*INFORMAÇÕES DE SERVIÇO:
 * Nome: Kin_Kitsune
 * senha: 2570
 * velocidade: 115200
 * versão: linvorV1.8
 * enviar a palavra reset/Reset/RESET/ok/Ok/OK para resetar listas de rede wifi
 */
 
/* ESQUEMA DE CONEXÕES DA CABEÇA
   

   [A.B.C.D.E.F.G.s.s.D1.D2.SC.SE.SB.SD.SN.S] Novo
   [x.x.+.+.+.+.+.+.+. -. -. -. -. -. -. -.-] 

//     olhos     A  B  C  D  E  F  G    D1.D2.CL.SE.SC.SD.SB.SN
//int Portas[] = {33,34,35,36,37,38,39, 26,27,11,29,28,31,30,32};

   
   [B.C.D.E.F.G.s.s.a.b.c.d.e.f.g.S.o] antigo
   [A.x.+.+.+.+.+.+.+.+.+.+.+.+.+.+.+] 

  Letras de A - G: Olho Esquerdo
  Letras de a - g: Olho Direito
  S: Servo_motor
  s: Speaker, + e - 
  o: GND/desligado
  x: N/D (Sem pinos)

  ESQUEMA DE PINOS NO PESCOÇO (Visão de frente a kin)
  Potenciometros
  [-.S.P2.P1.+]  [m.m] - motor do pescoço 
  [SN.SB.SD.SE.SC.D2.D1.G.F.E.D.C.B.A] - leds dos olhos

   -: negativo
   +: positivo
   S; Servo da cabeça
   m: motor do pescoço L.R
   A - G: olhos Esquerdos
   a - g; olhos direitos
   P1: potenciometro de controle X (esquerda e direita)
   P2: potenciometro de controle Y (Cima e baixo)
  
 ESQUEMA DE PINOS NA PLACA REGULADORA DE TENSÃO
 
 08 Pino emissor de tensão (Energia que alimenta os motores)
 09 Pino 12V+
 10 pino emissor de tensão (Energia que alimenta a placa de relés)
 11 pino emissor de tensão (Energia que alimenta a placa de relés)
 12 Gnd
 13 Gnd
 14 Gnd 
 15 Gnd
 16 Gnd
 17 Gnd 
 
*/
//#include "Fr-Var.h"
//#include <VarSpeedServo.h>
#include <Servo.h>
#include "neotimer.h"

Servo ServoS;
Servo ServoC;
Servo ServoP;
//VarSpeedServo ServoS;
//VarSpeedServo ServoC;
//VarSpeedServo ServoP;


Neotimer Delay_comand = Neotimer(0); //comando de tempo para emotes


Neotimer Delay_0A = Neotimer(500); //tempo de retardo da desativação dos motores de locomoção
Neotimer Delay_0B = Neotimer(10000); //Tempo para desligar ventiladores em caso de ausencia
Neotimer Delay_1 = Neotimer(3000);//Inicia a função "Piscar"
Neotimer Delay_2 = Neotimer(1000);//Inicia a função "Observation"
Neotimer Delay_A = Neotimer(60000); //Tempo para escolha do anfitrião 
Neotimer Delay_B = Neotimer(60000); //Tempo de reação durante o Evento
Neotimer Delay_C = Neotimer(60000); //Tempo de reação após a conclusão do evento

//     olhos     A  B  C  D  E  F  G    D1.D2.   SE.SC.SD.SB.SN
//int Portas[] = {33,34,35,36,37,38,39, 26,27,11,29,28,31,30,32};
int Portas[] = {28,29,30,31,32,33,34, 26,27,11,35,36,37,38,39};
//                 motores      ND           Velocidade
//int PortasM[] = {42,43,41,40, 22,23,24,25, 8,9}; //Portas que controlam motores
int PortasM[] = {22,23,24,25, 42,43,41,40, 8,9}; //Portas que controlam motores mod


#define servo  A0 //controle Y da cabeça
#define servoC A1 //controle X do pescoço
#define servoP A2 //controle Y do pescoço
#define botton A3 //botão generico



void setup(){ 
randomSeed(analogRead(A7));
Serial.begin(115200); //Serial USB
Serial2.begin(115200); //Serial Bluetooth
Serial3.begin(115200); //Serial Esp8266

ServoS.attach(servo);
ServoC.attach(servoC);
ServoP.attach(servoP);

//ServoS.slowmove(120, 10);
//ServoC.slowmove(130, 10);
//ServoP.slowmove(80, 10);

ServoS.write(120);
ServoC.write(130);
ServoP.write(80);

for ( int Np = 0; Np <= 14; Np++) { //cria um loop que se repete 9 vezes
  if (Np <= 9){
  pinMode(Portas[Np], OUTPUT); //define todas as portas de leds como saida
  digitalWrite(Portas[Np], LOW); //deixa todas as portas de leds desligadas
  } else {
  pinMode(Portas[Np], INPUT); //define as portas restantes como entradas
  }
  if (Np <= 9){ //verifica se o NP é menor ou equivalente a 7
  pinMode(PortasM[Np], OUTPUT); //define todas as portas de 0 a 7 como saída 
  digitalWrite(PortasM[Np], LOW); // define todas as portas de 0 a 7 como desligadas
} 
 }
 pinMode(botton, INPUT);

Conect(); //verifica se há conexão com a internet
}

void loop(){
 Bloqueio(); //bloqueia algumas funções de acordo com eventos 
 Serial_2(); //verifica se recebeu algum comando via Bluetooth
 Olhos(); //faz impressões continuas nos olhos 
}

//____________________/Olhos/____________________//
void Olhos(){
int set;

if(Number_Eye[0] == 1){
  
digitalWrite(Portas[7], HIGH); //ativa o olho Direito
for (int i = 0; i <= 6; i++){ //laço que se repete 7 vezes
int set = i; //guarda em set o valor de " i "
 digitalWrite(Portas[i], olhos[Eyes_Closed][set]);////imprime um olho feliz no olho direito
 digitalWrite(Portas[i], olhos[29][set]);//desliga o olho atual para imprimir o desenho do olho direito
}
digitalWrite(Portas[7], LOW); //desliga o olho dirteito

digitalWrite(Portas[8], HIGH); //ativa o olho esquerdo
for (int i = 0; i <= 6; i++){ //laço que se repete 7 vezes
int set = i + 7; //guarda em set o valor de " i " somado com 7
 digitalWrite(Portas[i], olhos[Eyes_Closed][set]);//imprime um olho feliz no olho esquerdo
 digitalWrite(Portas[i], olhos[29][set]);//desliga o olho atual para imprimir o desenho do olho esquerdo
}
digitalWrite(Portas[8], LOW); //desliga o olho esquerdo
  
} else if (digitalRead(Portas[11]) == HIGH){ //verifica se os sensores na cabeça foram acionados
digitalWrite(Portas[7], HIGH); //ativa o olho Direito
for (int i = 0; i <= 6; i++){ //laço que se repete 7 vezes
int set = i; //guarda em set o valor de " i "
 digitalWrite(Portas[i], olhos[17][set]);////imprime um olho feliz no olho direito
 digitalWrite(Portas[i], olhos[29][set]);//desliga o olho atual para imprimir o desenho do olho direito
}
digitalWrite(Portas[7], LOW); //desliga o olho dirteito

digitalWrite(Portas[8], HIGH); //ativa o olho esquerdo
for (int i = 0; i <= 6; i++){ //laço que se repete 7 vezes
int set = i + 7; //guarda em set o valor de " i " somado com 7
 digitalWrite(Portas[i], olhos[17][set]);//imprime um olho feliz no olho esquerdo
 digitalWrite(Portas[i], olhos[29][set]);//desliga o olho atual para imprimir o desenho do olho esquerdo
}
digitalWrite(Portas[8], LOW); //desliga o olho esquerdo


}else if(digitalRead(Portas[13]) == HIGH) { //verifica se os sensores abaixo da cabeça estão ativos
digitalWrite(Portas[7], HIGH); //ativa o olho Direito
for (int i = 0; i <= 6; i++){ //laço que se repete 7 vezes
int set = i; //guarda em set o valor de " i "
 digitalWrite(Portas[i], olhos[20][set]);////imprime um olho feliz no olho direito
 digitalWrite(Portas[i], olhos[29][set]);//desliga o olho atual para imprimir o desenho do olho direito
}
digitalWrite(Portas[7], LOW); //desliga o olho dirteito

digitalWrite(Portas[8], HIGH); //ativa o olho esquerdo
for (int i = 0; i <= 6; i++){ //laço que se repete 7 vezes
int set = i + 7; //guarda em set o valor de " i " somado com 7
 digitalWrite(Portas[i], olhos[20][set]);//imprime um olho feliz no olho esquerdo
 digitalWrite(Portas[i], olhos[29][set]);//desliga o olho atual para imprimir o desenho do olho esquerdo
}
digitalWrite(Portas[8], LOW); //desliga o olho esquerdo

} else {

if (digitalRead(Portas[10]) == HIGH){ //verifica se o sensor do olho direito, está ativado para fechar o olho direito
digitalWrite(Portas[7], HIGH); //ativa o olho Direito
for (int i = 0; i <= 6; i++){ //laço que se repete 7 vezes
set = i; //guarda em set o valor de " i "
 digitalWrite(Portas[i], olhos[14][set]);////imprime um olho fechado no olho direito
 digitalWrite(Portas[i], olhos[29][set]);//desliga o olho atual para imprimir o desenho do olho esquerdo
}
digitalWrite(Portas[7], LOW); //desliga o olho dirteito

} else { //mantém o olho aberto na configuração desejada caso o sensor não esteja ativo

digitalWrite(Portas[7], HIGH); //ativa o olho Direito
for (int i = 0; i <= 6; i++){ //laço que se repete 7 vezes
set = i; //guarda em set o valor de " i "
 digitalWrite(Portas[i], olhos[Number_Eye[1]][set]);//imnprime um desenho de Number_eye no olho direito
 digitalWrite(Portas[i], olhos[29][set]);//desliga o olho atual para imprimir o desenho do outro olho
}
digitalWrite(Portas[7], LOW); //desliga o olho direito
}


if (digitalRead(Portas[12]) == HIGH){ //verifica se o sensor esquerdo está ativo para fechar o olho esquerdo
digitalWrite(Portas[8], HIGH); //ativa o olho esquerdo
for (int i = 0; i <= 6; i++){ //laço que se repete 7 vezes
set = i + 7; //guarda em set o valor de " i " somando com 7
 digitalWrite(Portas[i], olhos[14][set]);//imprime um olho fechado no olho esquerdo
 digitalWrite(Portas[i], olhos[29][set]);//desliga o olho atual para imprimir o desenho do outro olho
}
digitalWrite(Portas[8], LOW); //desliga o olho esquerdo

} else {

digitalWrite(Portas[8], HIGH); //desliga o olho direito
for (int i = 0; i <= 6; i++){ //laço que se repete 7 vezes
set = i + 7; //guarda em set o valor de " i " somando com 7
 digitalWrite(Portas[i], olhos[Number_Eye[1]][set]);//imnprime um desenho de Number_eye no olho esquerdo
 digitalWrite(Portas[i], olhos[29][set]);//desliga o olho atual para imprimir o desenho do outro olho
}
digitalWrite(Portas[8], LOW); //desliga o olho esquerdo
}

}


}

//-------------------------------------------------------//
//____________________/EVENTOS/____________________//???

void Brevia(){

// o leitor passará uma unica vez em Brévia, 
//aqui será definido toda a programação de uma 
//brévia antes do mesmo iniciar.


}

void Cancelado(){

}

void Eventos(){
// o leitor passará uma unica vez em eventos, 
//aqui será definido toda a programação de um novo 
//evento quando o mesmo for confirmado pelo anfitrião

 
}
void Concluir(){

}
//-------------------------------------------------//


//____________________/FUNÇÃO PISCAR/____________________// 
void Piscar(){ 
 if (Delay_1.repeat()){
  Delay_1 = 500; //deine um curto tempo para piscar
  Number++;
 if (Number == 1){
  Number_Eye[0] = 1;
  Number++;
 }
 if (Number == 3){
  Number_Eye[0] = 0;
  Number = 0;
  int set1 = random(5, 13);
  Delay_1 = set1 * 1000; 
  //Serial.println("Piscar: ok");
  }
 }
}
//-------------------------------------------------------//

//____________________/OPÇÕES DE BLOQUEIO/____________________// 
void Bloqueio(){
if (ok_Esp != 3){ //Impede que eventos diários iniciem em ordem de horários(PADRÃO)
 Serial_3();
}
if (Task_0 == HIGH){
 comandos(); 
}
if (Task_1 == HIGH){
  for (int i = 0; i <= 7; i++){ //laço que se repete 9 vezes
 if(Eye_Memory == olhosP[i]){ //verifica se Eye_Memory é igual a um dos valores de olhosP[]
  Piscar(); //executa o programa da animação dos olhos
 }
 }
}
if (Task_2 == HIGH){
 for (int i = 0; i <= 6; i++){ //laço que se repete 9 vezes
 if(Eye_Memory == olhosO[i]){ //verifica se Eye_Memory é igual a um dos valores de olhosO[]
  Observar(); //executa o programa da animação dos olhos
 }
 }
}
if (At_Frame == 1){
  Emotes();
}

if (Task_5 == HIGH){ // ativa o ventilador 
 digitalWrite(Portas[9], HIGH);
}else{
 digitalWrite(Portas[9], LOW);
}

}
//------------------------------------------------------------//


//____________________/AÇÕES PARA EMOTES/____________________// 
void Emotes(){ 

/*
  o que deve acontecer aqui:

  ao iniciar, a barra de escrita pode começar da linha em que esteve durante a programação
  
  o sistema deverá saber em qual linha está e qual o comando que está naquela linha

  deverá executar o comando e aumentar o valor de Pcomand[1] para passar para o próximo comando

  do codigo os comandos finalizará assim que chegar em qualquer linha de código que esteja sem nenhum comando = 0
 
  */

  if(linhas[Pcomand[0]][Pcomand[1]] == 0){ //finaliza o modo de comandos automatico
  //select = 0;
  At_Frame = 0; // desativa a função de emote
  Pcomand[1] = 0; //reseta Pcomand[1] para executar um novo emote

  }
  if(linhas[Pcomand[0]][Pcomand[1]] == 1){ //verifica se o comando é um delay
  if (Rcomand == 1){ //programa de configuração de tempo
  Delay_comand.set(Tempo[Pcomand[0]][Pcomand[1]]); //verifica o valor guardado em Tempo[][] adiciona no Neotimer: Delay_Comand
  Delay_comand.repeatReset(); //reseta a repetição do delay para que o programa espere um tempo enquanto faz outras
  Rcomand = 0; //altera o valor de Rcomand para o programa de configuração não se repetir
  }
  if(Delay_comand.repeat(1)){ //laço que se repete uma vez após um tempo determinado
 
  Rcomand = 1; //permite que outro comando de tempo seja configurado
  Pcomand[1]++;
  }
  }

 if (linhas[Pcomand[0]][Pcomand[1]] == 2){ //verifica se o comando muda o olhar

  Eye_Memory = Eyes[Pcomand[0]][Pcomand[1]]; //guarda um valor de Eyes em set
  Number_Eye[1] = Eye_Memory;
  Pcomand[1]++;
 }


  if(linhas[Pcomand[0]][Pcomand[1]] == 3){ //controle de servos
  
  if (srv[Pcomand[0]][Pcomand[1]] == 1){
    ServoS.write(angulo[Pcomand[0]][Pcomand[1]]);
    //ServoS.slowmove(angulo[Pcomand[0]][Pcomand[1]], velocidade[Pcomand[0]][Pcomand[1]]);
  }
  if (srv[Pcomand[0]][Pcomand[1]] == 2){
    ServoC.write(angulo[Pcomand[0]][Pcomand[1]]);
    //ServoC.slowmove(angulo[Pcomand[0]][Pcomand[1]], velocidade[Pcomand[0]][Pcomand[1]]);
  }
  if (srv[Pcomand[0]][Pcomand[1]] == 3){
    ServoP.write(angulo[Pcomand[0]][Pcomand[1]]);
    //ServoP.slowmove(angulo[Pcomand[0]][Pcomand[1]], velocidade[Pcomand[0]][Pcomand[1]]);
  }

  Pcomand[1]++; //aumenta seu valor para poder executar o próximo programa
  }


  if(linhas[Pcomand[0]][Pcomand[1]] == 4){ //controle de motores
  MotorC = Motor[Pcomand[0]]; //diz ao sistema qual comando enviar ao motores

if (MotorC == 1){ //frente + direita
for(int i = 0; i <= 7; i++){
digitalWrite(PortasM[i], Motor[2][i]);
}
} else if (MotorC == 2){ //frente + esquerda
for(int i = 0; i <= 7; i++){
digitalWrite(PortasM[i], Motor[3][i]);
}
} else if (MotorC == 3){ //frente 
for(int i = 0; i <= 7; i++){
digitalWrite(PortasM[i], Motor[1][i]);
}
} else if (MotorC == 4){ //ré + Direita
for(int i = 0; i <= 7; i++){
digitalWrite(PortasM[i], Motor[5][i]);
}
} else if (MotorC == 5){ //ré + esquerda
for(int i = 0; i <= 7; i++){
digitalWrite(PortasM[i], Motor[6][i]);
}
} else if (MotorC == 6){ //ré
for(int i = 0; i <= 7; i++){
digitalWrite(PortasM[i], Motor[4][i]);
}
} else if (MotorC == 7){ //direita
for(int i = 0; i <= 7; i++){
digitalWrite(PortasM[i], Motor[7][i]);
}
} else if (MotorC == 8){ //Esquerda
for(int i = 0; i <= 7; i++){
digitalWrite(PortasM[i], Motor[8][i]);
}
} else { //desligado
for(int i = 0; i <= 7; i++){
digitalWrite(PortasM[i], Motor[0][i]);
}
}
  Pcomand[1]++;
}

if(linhas[Pcomand[0]][Pcomand[1]] == 5){ // escolha de olhos fechados

  Eyes_Closed = EyesClose[Pcomand[0]][Pcomand[1]]; //guarda um valor de Eyes em set 
  Pcomand[1]++;
}
}
//---------------------------------------------------------------//

//____________________/OPÇÕES DE CONTROLE/____________________//???
void comandos(){

 
 if (Solicitado == 1){ //obtem uma resposta para poder ou não iniciar um evento
  for (int Ne = 0; Ne <= 2; Ne++){
   if (comando == resposta[Ne]){
    Confirmar = Ne;
   }
  }

 if (Confirmar == 1){
  Solicitado = 0;
  Confirmar = 3;
  Eventos();
  }
 if (Confirmar == 0){
  Delay_A.repeatReset();
  Eye_Memory = 13;
  Eyes_Closed = 16;
  Task_2 = LOW;
  Number_Eye[1] = 13;
  }
 }
  if (ValorX != VXA){
  if (limite == LOW){
  ServoC.write(ValorX); //envia o novo comando para o servo-motor
  Serial.print("VelocidadeX: "); Serial.println(Velocidades[1]);
  //ServoC.slowmove(ValorX, Velocidades[1]);
   Task_5 = HIGH; //Ativa a porta que liga/desliga a energia dos Servos-motores
   Delay_0B.repeatReset(); //reseta o contador de tempo em que ficará ligado os servos-motores
   VXA = ValorX; //guarda o novo valor De VAlorX em VXA para que o comando não se repita

  } else if (ValorX >= vxmin && ValorX <= vxmax){ //verifica se ValorX esta dentre os limites do sistema caso os limites estejam ativos
  ServoC.write(ValorX); //envia o novo comando para o servo-motor
  Serial.print("VelocidadeX: "); Serial.println(Velocidades[1]);
  //ServoC.slowmove(ValorX, Velocidades[1]);
   Task_5 = HIGH; //Ativa a porta que liga/desliga a energia dos Servos-motores
   Delay_0B.repeatReset(); //reseta o contador de tempo em que ficará ligado os servos-motores
   VXA = ValorX; //guarda o novo valor De VAlorX em VXA para que o comando não se repita
  }
 }
 if (ValorZ != VZA){
   if (limite == LOW){
    ServoP.write(ValorZ); //envia o novo comando para o servo-motor
   Serial.print("VelocidadeZ: "); Serial.println(Velocidades[2]);
   //ServoP.slowmove(ValorZ, Velocidades[2]);
   Task_5 = HIGH; //Ativa a porta que liga/desliga a energia dos Servos-motores
   Delay_0B.repeatReset(); //reseta o contador de tempo em que ficará ligado os servos-motores
   VZA = ValorZ; //guarda o novo valor De VAlorZ em VZA para que o comando não se repita

  } else if (ValorZ >= vzmin && ValorZ <= vzmax){ //verifica se ValorZ esta dentre os limites do sistema caso os limites estejam ativos
   ServoP.write(ValorZ); //envia o novo comando para o servo-motor
   Serial.print("VelocidadeZ: "); Serial.println(Velocidades[2]);
   //ServoP.slowmove(ValorZ, Velocidades[2]);
   Task_5 = HIGH; //Ativa a porta que liga/desliga a energia dos Servos-motores
   Delay_0B.repeatReset(); //reseta o contador de tempo em que ficará ligado os servos-motores
   VZA = ValorZ; //guarda o novo valor De VAlorZ em VZA para que o comando não se repita
  }
 }

  if (ValorY != VYA){ //verifica se um novo valor foi colocado em ValorY
  if (limite == LOW){ //verifica se os limites de posições estão desligado
  ServoS.write(ValorY); //envia o novo comando para o servo-motor
   Serial.print("VelocidadeY: "); Serial.println(Velocidades[0]); //imprime o valor da velocidade que foi enviada ao servo-motor
   //ServoS.slowmove(ValorY, Velocidades[0]);
   Task_5 = HIGH; //Ativa a porta que liga/desliga a energia dos Servos-motores
   Delay_0B.repeatReset(); //reseta o contador de tempo em que ficará ligado os servos-motores
   VYA = ValorY; //guarda o novo valor De VAlorY em VYA para que o comando não se repita

  } else  if (ValorY >= vymin && ValorY <= vymax){ //verifica se ValorY esta dentre os limites do sistema caso os limites estejam ativos
   ServoS.write(ValorY); //envia o novo comando para o servo-motor
   Serial.print("VelocidadeY: "); Serial.println(Velocidades[0]); //imprime o valor da velocidade que foi enviada ao servo-motor
   //ServoS.slowmove(ValorY, Velocidades[0]);
   Task_5 = HIGH; //Ativa a porta que liga/desliga a energia dos Servos-motores
   Delay_0B.repeatReset(); //reseta o contador de tempo em que ficará ligado os servos-motores
   VYA = ValorY; //guarda o novo valor De VAlorY em VYA para que o comando não se repita
  }
 }
 if (Delay_0B.repeat(1)){//desliga o ventilador após 5 segundos de inatividade
    Task_5 = LOW;
 }
 
}
//------------------------------------------------------------//

//____________________/AÇÕES PARA ESP8266/____________________// <- REATIVE O SELETOR DE EVENTOS AQUI
void Serial_3(){ 
 


  if (Serial3.available()){ //serial3
  char Byte = Serial3.read();   //recebe os horários
  Recebido += Byte;             //guarda o primeiro valor que está em milisegundos -> 12345//00:00:00/ em formato de texto
  valorData = Recebido.toInt();
  if (Byte == '/'){ //verifica se comando recebeu um bite equivalente a "/" de 12345//00:00:00/
     valorData = Recebido.toInt(); //transforma textos que contém números em apenas números e guarda em set
     Recebido = ""; //apaga o ultimo texto recebido antes do "/"
    if(msg_Esp == 0){ //verifica se o valor em msg_Esp para imprimir apenas o primeiro valor de 12345//00:00:00/
    Serial.print("Valor em segundos: ");Serial.println(valorData); // imprime 12345 de 12345//00:00:00/
    Serial2.print(valorData); Serial2.print("S");
    }
    msg_Esp++; //almenta msg_Esp para que não sejam impressos os outros valores de 12345//00:00:00/
    if(msg_Esp == 3){ //verifica se msg_Esp alcançou o numero total de barras em 12345//00:00:00/
    msg_Esp = 0; //reseta msg_Esp para imprimir o próximo valor 
    }
    }

  }

    
   //APAGAR O CODIGO ABAIXO PARA O USO DE EVENTOS
   if (Reset == 1){ //verifica se há um novo evento
    Reset = 0;
    valorData = 0;
    Num_Event = 1; //guarda o evento atual 
    Brevia();
    }
   
   //DESMARCAR CODIGO ABAIXO PARA O USO DE EVENTOS
   /*for (int Nt = 0; Nt <= 16; Nt++){ 
    Valor1 = Hora[Nt][0];
    Valor2 = Hora[Nt][1];
    Valor3 = D_Hora[Nt][0];
    Valor4 = D_Hora[Nt][1];
     
   if(valorData >= Valor1 && valorData < Valor2){ //Verifica se o horário atual está dentre os horários de eventos 
    if(valorData >= Valor3 && valorData < Valor4){ //Verifica se o horário atual esta exatamente no início de um evento novo
    Reset = 1;  //Reseta as tarefas para começar um novo evento
    valorData = 0;
  //  Serial.println("Tarefa Resetada");
    }  
    if (Reset == 1){ //verifica se há um novo evento 
    Reset = 0;
    valorData = 0;
   //Serial.print("Valor da coluna = ");Serial.println(Nt);
    Num_Event = Nt; //guarda o evento atual 
    Brevia();
    }
   } 
  }
  */
 
}
//------------------------------------------------------------//

//____________________/AÇÕES PARA MODULO BLUETOOTH/____________________//
void Serial_2(){
if (Serial.available()){ //recebe comandos Via bluetooth
 comando = Serial.read();
 Mensagem += comando;

 /*for (int Nc = 0; Nc <= 4; Nc++){ //cria um loop que se repete 4 vezes, e obtem um valor a cada repetição
  if (comando == Ctrl[Nc]){ //verifica se comando é igual a um dos caracteres em Ctrl[]
    for (int Nf = 0; Nf <= 3; Nf++){ ////cria um loop que se repete 5 vezes, e obtem um valor a cada repetição
      digitalWrite(PortasM[Nf], Motor[Nc][Nf]); //altera apenas os estados dos motores que faz a kin se locomover
      Delay_0A.repeatReset();
    }
    comando = "";
  
  }
  
 } */
  switch(comando){

  case 'W':{ //comando para andar para frente
    digitalWrite(PortasM[0], HIGH); //motor esquerdo
    digitalWrite(PortasM[1], LOW);  //
    digitalWrite(PortasM[2], HIGH); //motor direito
    digitalWrite(PortasM[3], LOW);  //
    Delay_0A.repeatReset();
    break;
  }
    case 'S':{ //comando para andar para trás
    digitalWrite(PortasM[0], LOW);
    digitalWrite(PortasM[1], HIGH);
    digitalWrite(PortasM[2], LOW);
    digitalWrite(PortasM[3], HIGH);
    Delay_0A.repeatReset();
    break;
  }
    case 'A':{ //comando para andar para esquerda
    digitalWrite(PortasM[0], LOW);
    digitalWrite(PortasM[1], HIGH);
    digitalWrite(PortasM[2], HIGH);
    digitalWrite(PortasM[3], LOW);
    Delay_0A.repeatReset();
    break;
  }
    case 'D':{ //comando para andar para diteira
    digitalWrite(PortasM[0], HIGH);
    digitalWrite(PortasM[1], LOW);
    digitalWrite(PortasM[2], LOW);
    digitalWrite(PortasM[3], HIGH);
    Delay_0A.repeatReset();
    break;
  }

   default :{
    
    break;
   }
 
 }

 if (Delay_0A.repeat(1)){ //desliga os motores após um periodo escolhido
    digitalWrite(PortasM[0], LOW);
    digitalWrite(PortasM[1], LOW);
    digitalWrite(PortasM[2], LOW);
    digitalWrite(PortasM[3], LOW);
  }

 if (Mensagem.indexOf("Tl") > 0){ //ativa o limitador de posicionamento do pescoço do robô "Trava ligada"
  limite = HIGH;
  Mensagem = "";
 }
 if (Mensagem.indexOf("Td") > 0){ //desativa o limitador de posicionamento do pescoço do robô "Trava Desligada"
  limite = LOW;
  Mensagem = "";
 }

 if (Mensagem.indexOf("ve") > 0){ //recebe a velocidade que controla o motor Esquerdo "Velocidade esquerda"
 int velE = Mensagem.toInt(); //transforma obtem o valor numerico de Mensagem e guarda em VelE
 analogWrite(PortasM[8], velE);
 Serial.print("Valor do motor E: "); Serial.println(velE);
 Mensagem = "";
 }
 if (Mensagem.indexOf("vd") > 0){ //recebe a velocidade que controla o motor direito "Velocidade direita"
 int velD = Mensagem.toInt(); //transforma obtem o valor numerico de Mensagem e guarda em VelE
 analogWrite(PortasM[9], velD);
 Serial.print("Valor do motor D: "); Serial.println(velD);
 Mensagem = "";
 }
 if (comando == 'V'){ //define a velocidade dos servos
   ComandVel = Mensagem.toInt();
   Velocidades[0] = ComandVel;
   Velocidades[1] = ComandVel;
   Velocidades[2] = ComandVel;

  Serial.print("Velocidades: "); Serial.print(ComandVel); Serial.println(" Obtidas!");
  Mensagem = "";
 }
 if (comando == 'O'){ //define um desenho para os olhos quando abertos
   Eye_Memory = Mensagem.toInt();
  Serial.print("olhos: "); Serial.println(Eye_Memory); Serial.println(" Obtidos!");
  Mensagem = "";
  Number_Eye[1] = Eye_Memory;
 }
 if (comando == 'o'){ //define um desenho para os olhos quando fechados
   Eyes_Closed = Mensagem.toInt();
  Serial.print("olhos Fechados: "); Serial.print(Eyes_Closed); Serial.println(" Obtidos!");
  Mensagem = "";
 }

 if (comando == 'X'){ //Valores que alteram a posição da cabeça para direita/esquerda
 ValorX = Mensagem.toInt();//obtém um texto numérico e o transforma em um valor numérico e guarda em ValorX 
 valorAnteriorX[0] = ValorX; //guarda o valor de "ValorX" em valorAnteriorX[]
 Serial.print("ValorX: "); Serial.print(ValorX); Serial.println(" Obtido!"); //imprime o valor obtido por garantia de funcionamento
  Mensagem = ""; //apaga o comando recebido para que um novo comando possa ser executado
 }
 if(comando == 'Y'){ //Valores que alteram a posição da cabeça para cima/baixo
 ValorY = Mensagem.toInt();//obtém um texto numérico e o transforma em um valor numérico e guarda em ValorY
 valorAnteriorY[0] = ValorY; //guarda o valor de "ValorY" em valorAnteriorY[]
 Serial.print("ValorY: "); Serial.print(ValorY); Serial.println(" Obtido!"); //imprime o valor obtido por garantia de funcionamento
 Mensagem = ""; //apaga o comando recebido para que um novo comando possa ser executado
 }
 if(comando == 'H'){ //Valores que alteram a posição da estrutura do pescoço para frente/tras
 ValorZ = Mensagem.toInt();//obtém um texto numérico e o transforma em um valor numérico e guarda em ValorZ 
 valorAnteriorZ[0] = ValorZ; //guarda o valor de "ValorZ" em valorAnteriorZ[]
 Serial.print("ValorZ: "); Serial.print(ValorZ); Serial.println(" Obtido!"); //imprime o valor obtido por garantia de funcionamento
 Mensagem = ""; //apaga o comando recebido para que um novo comando possa ser executado
 }
 }
}
//---------------------------------------------------------------------//

//____________________/AÇÕES PARA CONECT/____________________//
void Conect(){

 int count = 0; //conta o numero de barras que aparece em 12345//00:00:00/
 String Mensagem_A = "";  
 String Mensagem_B = ""; 
 int vMinA; //obtem o valor minimo de tolerancia para algum movimento expecífico
 int vMaxA; //obtem um valor máximo de tolerancia para algum movimento expecífico
 int vMinB; //
 int vMaxB; //
 int antBotton; //guarda o valor anterior do botão
 int bot_confirm = LOW; //confirma os ajustes manuais quando o botão é apertado
 int bot; //obtem os valores digitais do botão

 Serial.println("Config Modew");
 
 while (ok_Esp <= 2){
 Olhos();

 bot = digitalRead(botton);
  
  if (Serial3.available()){ //Serial3 controle do Esp8266
    comando = Serial3.read();
    Mensagem_A += comando;

    //Serial.print(comando);
    Serial2.print(comando);

    
    if (Mensagem_A.indexOf("SS") > 0){ //confirma a conexão com a internet
    ok_Esp = 1; //guarda a confirmação em ok_Esp
    bot_confirm = HIGH;
    Number_Eye[0] = 0; //faz com que os olhos se abram
    Mensagem_A = ""; //apaga a mensagem 
    digitalWrite(Portas[9], HIGH); //ativa os servos
    Serial.print("Conexao confirmada");
    }


    

    if (comando == '/'){ //verifica se comando recebeu um bite equivalente a "/" de 12345//00:00:00/
     int set = Mensagem_A.toInt(); //transforma textos que contém números em apenas números e guarda em set
     Mensagem_A = ""; //apaga o ultimo texto recebido antes do "/"
    if(count == 0){ //verifica se o valor em count para imprimir apenas o primeiro valor de 12345//00:00:00/
    Serial.print("Valor em segundos: ");Serial.println(set); // imprime 12345 de 12345//00:00:00/
    }
    count++; //aumenta count para que não sejam impressos os outros valores de 12345//00:00:00/
    if(count == 3){ //verifica se count alcançou o numero total de barras em 12345//00:00:00/
    count = 0; //reseta count para imprimir o próximo valor 
    }
    }

   }
   if (Serial2.available()){ //cancela verificação de conecxão do esp para iniciar sem internet 
    char Cr = Serial2.read();
    Mensagem_B += Cr;
    if (Mensagem_B.indexOf("Ok") > 0){
     digitalWrite(Portas[9], HIGH); //Ativa os servos
     ok_Esp = 2; 
     Number_Eye[0] = 0; //faz com que os olhos se abram
     bot_confirm = HIGH; //inicia os comandos de posicionamento
    }
   }

if(bot == HIGH && antBotton == LOW){ //verifica se o botão foi pressionado
 Number_Eye[0] = 0; //faz com que os olhos se abram
 bot_confirm = HIGH;// confirma o pressionamento do botão
 ok_Esp = 2; // inicia Kin de forma manual offline
digitalWrite(Portas[9], HIGH); //Ativa os servos
}
antBotton = bot; //guarda o estado anterior do botão
   
  /*
  o que deve acontecer aqui:

  ao iniciar, a barra de escrita pode começar da linha em que esteve durante a programação
  
  o sistema deverá saber em qual linha está e qual o comando que está naquela linha

  deverá executar o comando e aumentar o valor de Pcomand[1] para passar para o próximo comando

  do codigo os comandos finalizará assim que chegar em qualquer linha de código que esteja sem nenhum comando = 0
 
  */
  if (bot_confirm == HIGH){
 
  if(linhas[Pcomand[0]][Pcomand[1]] == 0){ //finaliza o modo de comandos automatico
  if (ok_Esp == 1 ){ //finaliza os ajustes de posição da cabeça e verifica se o esp está conectado 
    bot_confirm == LOW;
    digitalWrite(PortasM[8], HIGH);
    digitalWrite(PortasM[9], HIGH);
    Pcomand[1] = 0; //reinicia Pcomand[1] para poder iniciar um novo emote
    Task_1 = HIGH; // Ativa o modo piscar
    Task_2 = HIGH; // ativa o modo Observar
    Task_0 = HIGH; // ativa os comandos
    ok_Esp = 4;
  }
  if (ok_Esp == 2 ){ //finaliza os ajustes sem a verificação do esp8266, possivelmente bloqueando o modo wifi
    bot_confirm == LOW;
    digitalWrite(PortasM[8], HIGH);
    digitalWrite(PortasM[9], HIGH);
    Pcomand[1] = 0; //reinicia Pcomand[1] para poder iniciar um novo emote
    Task_1 = HIGH; // Ativa o modo piscar
    Task_2 = HIGH; // ativa o modo Observar
    Task_0 = HIGH; // ativa os comandos
    ok_Esp = 3;
  }

  }
 if(linhas[Pcomand[0]][Pcomand[1]] == 1){ //verifica se o comando é um delay
  if (Rcomand == 1){ //programa de configuração de tempo
  Delay_comand.set(Tempo[Pcomand[0]][Pcomand[1]]); //verifica o valor guardado em Tempo[][] adiciona no Neotimer: Delay_Comand
  Delay_comand.repeatReset(); //reseta a repetição do delay para que o programa espere um tempo enquanto faz outras
  Rcomand = 0; //altera o valor de Rcomand para o programa de configuração não se repetir
  }
  if(Delay_comand.repeat(1)){ //laço que se repete uma vez após um tempo determinado
 
  Rcomand = 1; //permite que outro comando de tempo seja configurado
  Pcomand[1]++;
  }
  }

 if (linhas[Pcomand[0]][Pcomand[1]] == 2){ //verifica se o comando muda o olhar

  Eye_Memory = Eyes[Pcomand[0]][Pcomand[1]]; //guarda um valor de Eyes em set
  Number_Eye[1] = Eye_Memory;
  
  Pcomand[1]++;
 }


  if(linhas[Pcomand[0]][Pcomand[1]] == 3){ //controle de servos
  
  if (srv[Pcomand[0]][Pcomand[1]] == 1){
    ServoS.write(angulo[Pcomand[0]][Pcomand[1]]);
    //ServoS.slowmove(angulo[Pcomand[0]][Pcomand[1]], velocidade[Pcomand[0]][Pcomand[1]]);
  }
  if (srv[Pcomand[0]][Pcomand[1]] == 2){
    ServoC.write(angulo[Pcomand[0]][Pcomand[1]]);
    //ServoC.slowmove(angulo[Pcomand[0]][Pcomand[1]], velocidade[Pcomand[0]][Pcomand[1]]);
  }
  if (srv[Pcomand[0]][Pcomand[1]] == 3){
    ServoP.write(angulo[Pcomand[0]][Pcomand[1]]);
    //ServoP.slowmove(angulo[Pcomand[0]][Pcomand[1]], velocidade[Pcomand[0]][Pcomand[1]]);
  }

  Pcomand[1]++; //aumenta seu valor para poder executar o próximo programa
  }


  if(linhas[Pcomand[0]][Pcomand[1]] == 4){ //controle de motores
  MotorC = Motor[Pcomand[0]]; //diz ao sistema qual comando enviar ao motores

/*if (MotorC == 1){ //frente + direita
for(int i = 0; i <= 7; i++){
digitalWrite(PortasM[i], Motor[2][i]);
}
} else if (MotorC == 2){ //frente + esquerda
for(int i = 0; i <= 7; i++){
digitalWrite(PortasM[i], Motor[3][i]);
}
} else if (MotorC == 3){ //frente 
for(int i = 0; i <= 7; i++){
digitalWrite(PortasM[i], Motor[1][i]);
}
} else if (MotorC == 4){ //ré + Direita
for(int i = 0; i <= 7; i++){
digitalWrite(PortasM[i], Motor[5][i]);
}
} else if (MotorC == 5){ //ré + esquerda
for(int i = 0; i <= 7; i++){
digitalWrite(PortasM[i], Motor[6][i]);
}
} else if (MotorC == 6){ //ré
for(int i = 0; i <= 7; i++){
digitalWrite(PortasM[i], Motor[4][i]);
}
} else if (MotorC == 7){ //direita
for(int i = 0; i <= 7; i++){
digitalWrite(PortasM[i], Motor[7][i]);
}
} else if (MotorC == 8){ //Esquerda
for(int i = 0; i <= 7; i++){
digitalWrite(PortasM[i], Motor[8][i]);
}
} else { //desligado
for(int i = 0; i <= 7; i++){
digitalWrite(PortasM[i], Motor[0][i]);
}
}*/
  Pcomand[1]++;
}

if(linhas[Pcomand[0]][Pcomand[1]] == 5){ // escolha de olhos fechados

  Eyes_Closed = EyesClose[Pcomand[0]][Pcomand[1]]; //guarda um valor de Eyes em set
  
  Pcomand[1]++;
}

  }

 }

}
//-----------------------------------------------------------//

//____________________/OBSERVAR/______________________//
void Observar(){

if (Delay_2.repeat()){ //repete os comandos dentro dele a cada 5 segundos após um periodo de espera

  if (Chances == 0){
    Chances = random(1, 5); //escolhe um numero de 1 a 4 e guarda o valor em "Chances"
     valorAnteriorY[0] = ValorY; //guarda os valores da ultima posição que a cabeça esteve
     valorAnteriorX[0] = ValorX; //guarda os valores da ultima posição que a cabeça esteve
     valorAnteriorZ[0] = ValorZ; //guarda os valores da ultima posição que a cabeça esteve
     
     valorAnteriorY[1] = Velocidades[0];
     valorAnteriorX[1] = Velocidades[1];
     valorAnteriorZ[1] = Velocidades[2];
     
     Serial.print("VLX_Guardado = "); Serial.println(ValorX); //imprime os valores X da antiga posição 
     Serial.print("VLY_Guardado = "); Serial.println(ValorY); //imprime os valores Y da antiga posição 
     Serial.print("VLZ_Guardado = "); Serial.println(ValorZ); //imprime os valores Y da antiga posição 
     Serial.print("Chances: "); Serial.println(Chances); //imprime o valor que foi guardado em "Chances"
  }

  Delay_2.set(5000); //define o tempo da animação dos olhos para 5 segundos em milis

  Number1++; //altera a posição dos "FRAMES" a cada 5 segundos
 if (Number1 == 1){// FRAME 1 
  int eye = random(1,3); // escolhe entre 1 e 2 para decidir se começará olhando para esquerda/direita
  Number_Eye[1] = Eye_Memory + eye; //guarda em "Number_Eye" o valor do olhar memorizado e adiciona um valor escolhido;
  
  if (Chances == 4 && Task_0 == HIGH){ //verifica se "Chances" é igual a 4 e se os comandos estão ativos

  //escolhe um valor dentre os limites definiddos em vxmin e vymax, com uma limitação de 2 para que não escolha um valor limitado 
   int PosicaoX = random(vxmin + 2, vxmax - 2); //escolhe e guarda um valor que move o motor do pescoço em PosicaoX
   int PosicaoY = random(vymin + 2, vymax - 30); //escolhe e guarda um valor que move o Servo do pescoço em PosicaoY
   int PosicaoZ = random(vzmin + 20, vzmax - 50); //escolhe e guarda um valor que move o Servo do pescoço em PosicaoZ
   int VelX = random(10, 150); //escolhe um valor aleatório velocidade
   int VelY = random(10, 150); //-
   int VelZ = random(10, 150); //- 

   Velocidades[1] = VelX; // Guarda o valor da ultima velocidade para obter-lo novamente depois
   Velocidades[0] = VelY; // -
   Velocidades[2] = VelZ; // -

   int mov = random(0,4); //esccolhe um valor de 0 a 3
   ValorX = PosicaoX; //guarda o valor escolhido em ValorX, fazendo o pescoço se mover para direita/esquerda
   ValorY = PosicaoY; //guarda o valor escolhido em ValorY, fazendo o pescoço se mover para cima/baixo
  if (mov == 2){ //verifica se mov equivale a 2
   ValorZ = PosicaoZ; //guarda o valor escolhido em ValorZ, fazendo o pescoço se mover para frente/tras
  }
  Serial.print("VLX_escolhidoA = "); Serial.println(ValorX); //imprime quais valores X foram escolhidos pelo random
  Serial.print("VLY_escolhidoA = "); Serial.println(ValorY); //imprime quais valores Y foram escolhidos pelo random
  Serial.print("VLZ_escolhidoA = "); Serial.println(ValorZ); //imprime quais valores Z foram escolhidos pelo random
  }
  Number1++; //impede que o frame atual se repita e aguarda mais 5 segundos em milis
 }
 if (Number1 == 3){ // FRAME 2
  int eye = random(1,3); // escolhe entre 1 e 2 para decidir se começará olhando para esquerda/direita
  Number_Eye[1] = Eye_Memory + eye; //guarda em "Number_Eye" o valor do olhar memorizado e adiciona um valor escolhido;
 
  if (Chances == 4 && Task_0 == HIGH){ //verifica se "Chances" é igual a 4 e se os comandos estão ativos
   digitalWrite(PortasM[6], LOW); //garante que ambos os sentidos de rotação do motor esteja desligado
   digitalWrite(PortasM[7], LOW); //garante que ambos os sentidos de rotação do motor esteja desligado
   digitalWrite(PortasM[2], LOW); //garante que ambos os sentidos de rotação do motor esteja desligado
   digitalWrite(PortasM[3], LOW); //garante que ambos os sentidos de rotação do motor esteja desligado

    //escolhe um valor dentre os limites definiddos em vxmin e vymax, com uma limitação de 2 para que não escolha um valor limitado 
   int PosicaoX = random(vxmin + 2, vxmax - 2); //escolhe e guarda um valor que move o motor do pescoço em PosicaoX
   int PosicaoY = random(vymin + 2, vymax - 30); //escolhe e guarda um valor que move o Servo do pescoço em PosicaoY
   int PosicaoZ = random(vzmin + 20, vzmax - 50); //escolhe e guarda um valor que move o Servo do pescoço em PosicaoZ
   int mov = random(0,4); //esccolhe um valor de 0 a 3
   int VelX = random(10, 150); //escolhe um valor aleatório velocidade
   int VelY = random(10, 150); //-
   int VelZ = random(10, 150); //- 

   Velocidades[1] = VelX; // Guarda o valor da ultima velocidade para obter-lo novamente depois
   Velocidades[0] = VelY; // -
   Velocidades[2] = VelZ; // -

   ValorX = PosicaoX; //guarda o valor escolhido em ValorX, fazendo o pescoço se mover para direita/esquerda
   ValorY = PosicaoY; //guarda o valor escolhido em ValorY, fazendo o pescoço se mover para cima/baixo
  if (mov == 2){      //verifica se mov equivale a 2 para poder mover Servo Y do pescoço
   ValorZ = PosicaoZ; //guarda o valor escolhido em ValorZ, fazendo o pescoço se mover para frente/tras
  }
  Serial.print("VLX_escolhidoB = "); Serial.println(ValorX); //imprime quais valores X foram escolhidos pelo random
  Serial.print("VLY_escolhidoB = "); Serial.println(ValorY); //imprime quais valores Y foram escolhidos pelo random
  Serial.print("VLZ_escolhidoB = "); Serial.println(ValorZ); //imprime quais valores Z foram escolhidos pelo random
  }
  Number1++; //impede que o frame atual se repita e aguarda mais 5 segundos em milis
  }
 if (Number1 == 5){ // FRAME 3
  Number_Eye[1] = Eye_Memory; //guarda em "Number_Eye" o valor do olhar memorizado  

if (Chances == 4 && Task_0 == HIGH){ //verifica se "Chances" é igual a 4 e se os comandos estão ativos
  digitalWrite(PortasM[6], LOW); //garante que ambos os sentidos de rotação do motor esteja desligado
  digitalWrite(PortasM[7], LOW); //garante que ambos os sentidos de rotação do motor esteja desligado
  digitalWrite(PortasM[2], LOW); //garante que ambos os sentidos de rotação do motor esteja desligado
  digitalWrite(PortasM[3], LOW); //garante que ambos os sentidos de rotação do motor esteja desligado
  
  Velocidades[0] = valorAnteriorY[1]; //desvolve as antiga velocidade de operação dos servos
  Velocidades[1] = valorAnteriorX[1]; //-
  Velocidades[2] = valorAnteriorZ[1]; //-
  ValorX = valorAnteriorX[0]; //Envia para ValorX a antiga posição da cabeça
  ValorY = valorAnteriorY[0]; //Envia para ValorY a antiga posição da cabeça
  ValorZ = valorAnteriorZ[0]; //Envia para ValorZ a antiga posição da cabeça
  Serial.print("VLX_reset = "); Serial.println(ValorX); //imprime o valor em que a cabeça esteve antes
  Serial.print("VLY_reset = "); Serial.println(ValorY); //imprime o valor em que a cabeça esteve antes
  Serial.print("VLZ_reset = "); Serial.println(ValorZ); //imprime o valor em que a cabeça esteve antes
}
  int set1 = random(10, 31); //guarda em set1 um valor de 10 a 30 segundos
  int Valor = set1 * 1000; //transforma o valor de set1 em milisegundos e guarda em "Valor"
  Number1 = 0; //redefine "Number1" para ser usado novamente
  Chances = 0; //redefine "Chances" para ser usado novamente
  Serial.println("Observar: Ok"); //imprime a confirmação da finalização de "Observation"
  Serial.print("Proximo tempo:"); Serial.println(Valor); //imprime qual será o tempo de espera para que tudo se repita
  Delay_2.set(Valor); //define o tempo escolhido em milisegundos
  }
 }
 
}
//--------------------------------------------------------//

//____________________/Video_Animations/____________________// Alterar comandos para nova biblioteca: ???

//----------------------------------------------------------//
NOCOMNCVCCGNDINLED1PWRRelay Module