#include <PID_v2.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <EEPROM.h>


//oled
// Initialize the OLED display
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_WIDTH 128
#define OLED_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define MAX_DATA_POINTS 128 // Número máximo de pontos de dados no gráfico
int graphData[MAX_DATA_POINTS]; // Array para armazenar os dados do gráfico
int graphData1[MAX_DATA_POINTS]; // Array para armazenar os dados do gráfico
int dataCount = 0; // Contador de dados

int disparo=0;
int SAC=0;
int idx;
int y;
int s=50;
int mostraT=0; 

int salva=11;
int menu=0;
int select1=0;
int select2=0;
int SET=0;
int DIV34=400;
int DIV35=100;
int DIVpul=20;

int SELECTM=0;
int SELECT_menu=0;
int inicio = 1;
int Setpoint1 = 200;
int Kp1 = 1;
int Ki1 = 1;
int Kd1 = 1;
// Endereços da EEPROM onde os valores serão armazenados
int enderecoValor1 = 0;
int enderecoValor2 = sizeof(int);
int enderecoValor3 = 2 * sizeof(int);
int enderecoValor4 = 3 * sizeof(int);
int enderecoValor5 = 4 * sizeof(int);
int enderecoValor6 = 5 * sizeof(int);
int enderecoValor7 = 6 * sizeof(int);
int enderecoValor8 = 7 * sizeof(int);
int enderecoValor9 = 8 * sizeof(int);
int enderecoValor10 = 9 * sizeof(int);
bool botaoSel = HIGH;     // Estado atual do botão
bool ibotaoSel = HIGH; // Estado anterior do botão


const int numLeituras = 10; // Número de leituras para a média móvel
int leituras[numLeituras];  // Array para armazenar as leituras
int mostra;
// Defina os pinos
const int sensorPin = 34; // Pino do sensor de temperatura
const int pwmPin = 18;     // Pino PWM para controlar o aquecedor

#define triac 19     // triac para disparo da senoide

///############ Contador de RPM ##################
#define LED_PIN 2   // Pino para o LED de teste
#define PULSE_PIN 15  // Use o pino desejado para a entrada dos pulsos
#define ON_PIN 12  // Pino para o botão de liga
#define up_PIN 23
#define DOWN_PIN 5
#define SELECT_B 33


volatile int pulseCount = 0;  // Contador de pulsos
unsigned long lastTime = 0;
unsigned long lastTime1 = 0;
float rpm = 0;
float frequency = 0;
int Ent=0;

void IRAM_ATTR handlePulse() {
  pulseCount++;
}

// Parâmetros PID
double Setpoint = 25.0; // Temperatura desejada em graus Celsius
double Kp = 25.0;        // Ganho Proporcional
double Ki = 0.1;        // Ganho Integral
double Kd = 1.0;        // Ganho Derivativo

// Variáveis PID
double mediaMovel, Output;
PID myPID(&mediaMovel, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);

bool on=0;

const int zerocross = 4; // Pino conectado ao optoacoplador
volatile int delayMicros = 0;
int ciclo = 50;

void zerocross_ISR() {
  delayMicros=0;
  }

//############### inicio do nucleo 2 ##################

void taskCore1(void *pvParameters) {

  int tsenoide=660;//tempo total de uma meia onda 60hz

  while (true) {
          lastTime1++;
           if (lastTime1 >= 700) { 
        digitalWrite(LED_PIN, HIGH);  //
          lastTime1 = 0;
            }
        else {
        digitalWrite(LED_PIN, LOW);  // 
             }
disparo = map(delayMicros, 0, tsenoide, 255, 0); // 1667 micros = 60Hz (um semiciclo)
delayMicros++;
if(delayMicros>tsenoide){delayMicros=tsenoide;}//Output
if(inicio==1||on==1){
if(ciclo>0){
   if (disparo == ciclo) {
    digitalWrite(triac, HIGH); 
    mostraT = disparo;
    delayMicroseconds(1); // Ajuste conforme necessário
    digitalWrite(triac, LOW);
       }
      } 
    }
  }
  //############### fim do nucleo 2 #####################
}

void setup() {
 EEPROM.begin(512); // Inicializa a EEPROM com 512 bytes de tamanho
  pinMode(zerocross, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(zerocross), zerocross_ISR, FALLING);
    // Inicialize o Arduino e a porta serial se necessário
  Serial.begin(9600);
  // Inicialize o sensor, PWM e PID SELECT_B
  pinMode(sensorPin, INPUT);
  pinMode(pwmPin, OUTPUT);
  pinMode(13, INPUT_PULLUP);
  pinMode(14, INPUT_PULLUP);
  pinMode(26, INPUT_PULLUP);
  pinMode(27, INPUT_PULLUP); 
  pinMode(SELECT_B, INPUT_PULLUP);

  pinMode(up_PIN,OUTPUT);
  pinMode(DOWN_PIN,OUTPUT);

  pinMode(PULSE_PIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(PULSE_PIN), handlePulse, RISING);
  pinMode(LED_PIN, OUTPUT);
  pinMode(ON_PIN, INPUT_PULLUP);
  pinMode(triac, OUTPUT);

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // Adjust parameters if necessary
  
  display.display();
 delay(50);

 dacWrite(25, 0); // DAC1

  for (int i = 0; i < numLeituras; i++) {
    leituras[i] = 0; // Inicialize todas as leituras como zero
  }
  // Inicia a tarefa no núcleo 1
  xTaskCreatePinnedToCore(
    taskCore1,    // Função da tarefa
    "TaskCore1",  // Nome da tarefa
    10000,        // Tamanho da pilha
    NULL,         // Parâmetros da tarefa
    1,            // Prioridade da tarefa
    NULL,         // Identificador da tarefa
    1             // Núcleo 1
  );



  myPID.SetMode(AUTOMATIC);
 //DADOS DA EEPROM
  //DESMARCAR NO PROGRAMA DO ESP
  /*
   EEPROM.get(enderecoValor1, Setpoint1);
   EEPROM.get(enderecoValor2, Kp1);
   EEPROM.get(enderecoValor3, Ki1);
   EEPROM.get(enderecoValor4, Kd1);
   EEPROM.get(enderecoValor5, Ent);
   EEPROM.get(enderecoValor6, DIV34);
   EEPROM.get(enderecoValor7, DIVpul);
   EEPROM.get(enderecoValor8, DIV35);
   EEPROM.get(enderecoValor9, inicio);
   EEPROM.get(enderecoValor10, SAC);
   */
}

void loop() {
  if(DIV34<0){DIV34=0;}
  if(DIVpul<0){DIVpul=0;}
  if(DIV35<0){DIV35=0;}





 botaoSel = digitalRead(SELECT_B);
  if (botaoSel== LOW && ibotaoSel == HIGH) {
    //GERA UM PULSO
SELECT_menu++;
  
    }
  ibotaoSel = botaoSel; 
if(SELECT_menu>1){SELECT_menu=0;}



if(SELECTM>5){SELECTM=0;}
if(SELECTM<0){SELECTM=5;}

 if(SELECT_menu==0){
         if (digitalRead(14) == LOW){SELECTM++;delay(10);}
         if (digitalRead(13) == LOW){SELECTM--;delay(100);}
         display.clearDisplay(); 
        display.setTextColor(WHITE, BLACK);       
        display.setCursor(10, 2);
       if(SELECTM==0) {display.setTextColor(BLACK,WHITE);}
        display.print("AJUSTE PID");
        display.setTextColor(WHITE, BLACK);
        display.setCursor(10, 12);
        if(SELECTM==1) {display.setTextColor(BLACK,WHITE);}
        display.print("GRAFICO PWM");
        display.setTextColor(WHITE, BLACK);
        display.setCursor(10, 22);
        if(SELECTM==2) {display.setTextColor(BLACK,WHITE);}
        display.print("AJUSTE DIVISAO");
        display.setTextColor(WHITE, BLACK);
        display.setCursor(10, 32);
        if(SELECTM==3) {display.setTextColor(BLACK,WHITE);}
        display.print("GRAFICO AC");
        display.setTextColor(WHITE, BLACK);
        display.setCursor(10, 42);
        if(SELECTM==4) {display.setTextColor(BLACK,WHITE);}
        display.print("FREQUENCIA RPM");
        display.setTextColor(WHITE, BLACK);
        display.setCursor(10, 52);
        if(SELECTM==5) {display.setTextColor(BLACK,WHITE);}
        display.print("SALVAR");
        display.setTextColor(WHITE, BLACK);
        display.display();




 }





  if(SAC==0){ciclo = round(Output);}
  
  if(Output>255){Output=255;}
  if(Output<0){Output=0;}

  // Verifica se o botão de reset foi pressionado
  if (digitalRead(ON_PIN) == LOW) {
    on=1;
  }
  else {on=0;}

  int Input = analogRead(sensorPin);
  int novaLeitura = map(Input, 0, 4096, 0, DIV34); // Mapeie a leitura analógica para graus Celsius
  int novaLeitura1 = map(analogRead(35), 0, 4096, 0, DIV35);
  
  mostra++;

//###########  contador de pulsos ################
  unsigned long currentTime = millis();
  unsigned long elapsedTime = currentTime - lastTime;
      if (elapsedTime >= 1000) {
          rpm = (float)pulseCount * 60.0 / DIVpul;  // Calcula RPM
          frequency = (float)pulseCount / elapsedTime * 1000.0;  // Calcula Frequência
          pulseCount = 0;
         lastTime = currentTime;
  }
  if(mediaMovel<Setpoint) {digitalWrite(up_PIN, HIGH);} else{digitalWrite(up_PIN, LOW);} 

 if(mediaMovel>Setpoint)digitalWrite(DOWN_PIN, HIGH);else{digitalWrite(DOWN_PIN,LOW);}

///############# senoide AC ################

   if(SELECTM==3 && SELECT_menu==1){    
         // Draw the sine wave
      drawSineWave();
         // Display the frame
      }

  
               if(SELECTM==2 && SELECT_menu==1){
     if(menu>4){menu=4;}
     if(menu<3){menu=3;}
                display.clearDisplay();

                //display.setCursor(10, 20);display.print("Senoide:");
                //display.print(ciclo);
                   if(select2==0) {display.setCursor(0, 0);display.print("> ");}
                   if(select2==1) {display.setCursor(0, 10);display.print("> ");}
                   if(select2==2) {display.setCursor(0, 20);display.print("> ");}
                   if(select2==3) {display.setCursor(0, 30);display.print("> ");}
                   if(select2==4) {display.setCursor(0, 40);display.print("> ");}
                   if(select2==5) {display.setCursor(0, 50);display.print("> ");}
             if(menu==3 && SELECT_menu==1) {  
                if (digitalRead(14) == LOW){select2++;delay(100);}
                if (digitalRead(13) == LOW){select2--;delay(100);}
                if(select2>5 || select2<0){select2=0;}
                     }
                if(select2==0 && menu==4){display.setTextColor(BLACK, WHITE);
                     if (digitalRead(13) == LOW){inicio++;delay(10);}
                     if (digitalRead(14) == LOW){inicio--;delay(100);}
                     if(inicio>1){inicio=1;}if(inicio<0){inicio=0;}
                     }
               display.setCursor(10, 0);display.print("Inicia:");
               display.print(inicio);
               display.setTextColor(WHITE, BLACK); 

              if(select2==1 && menu==4){display.setTextColor(BLACK, WHITE);
                     if (digitalRead(13) == LOW){DIV34++;delay(10);}
                     if (digitalRead(14) == LOW){DIV34--;delay(100);} 
              }
               display.setCursor(10, 10);display.print("Div p/ D34:");
               display.print(DIV34);
               display.setTextColor(WHITE, BLACK);
              if(select2==2 && menu==4){display.setTextColor(BLACK, WHITE);
                     if (digitalRead(13) == LOW){DIVpul++;delay(10);}
                     if (digitalRead(14) == LOW){DIVpul--;delay(100);} 
              }
               display.setCursor(10, 20);display.print("Div Pulsos:");
               display.print(DIVpul);
               display.setTextColor(WHITE, BLACK);

               if(select2==3 && menu==4){display.setTextColor(BLACK, WHITE);
                     if (digitalRead(13) == LOW){DIV35++;delay(10);}
                     if (digitalRead(14) == LOW){DIV35--;delay(100);}  
               }
               display.setCursor(10, 30);display.print("Div p/ D34:");
               display.print(DIV35);
               display.setTextColor(WHITE, BLACK);
        if(select2==4 && menu==4){display.setTextColor(BLACK, WHITE);
                     if (digitalRead(13) == LOW){SAC++;delay(100);}
                     if (digitalRead(14) == LOW){SAC--;delay(100);}  
                     if(SAC>1){SAC=1;}if(SAC<0){SAC=0;}
               }
               if(SAC==0){display.setCursor(10, 40);display.print("Comando AC PID:");}
               if(SAC==1){display.setCursor(10, 40);display.print("Comando AC manual:");}
               display.print(SAC);
               display.setTextColor(WHITE, BLACK);
        display.display();
        }
//########### fim do contador de pulsos ########




if (digitalRead(27) == LOW){menu++;
delay(100);
}
if (digitalRead(26) == LOW){menu--;

delay(100);
}
if(SELECTM==4 && SELECT_menu==1){
                display.clearDisplay();
                display.setCursor(0, 2);
                display.print("RPM: ");
                display.print(rpm);
                display.setCursor(0, 12);
                display.print("Frequencia: ");
                display.print(frequency);
                display.print("Hz");


 display.display();
}

//############# menu salvar ###################


if(SELECTM==5 && SELECT_menu==1){
  salva++;
  if(salva>11){salva=11;}

        display.clearDisplay();
        display.setCursor(0, 2);
        display.setTextColor(BLACK,WHITE);
        display.print(" SALVAR > ");
        display.setTextColor(WHITE, BLACK);
//salva dados na EEPROM AQUI
        display.setCursor(0, 12);
display.print(" Set:"+String(Setpoint1)+" Kp:"+String(Kp1)+" Ki:"+String(Ki1)+"  ");
        display.setCursor(0, 22);
display.print(" Ki:"+String(Ki1)+" Ent:"+String(Ent)+" Div34:"+String(DIV34)+"  ");
        display.setCursor(0, 32);
display.print(" DivRPM:"+String(DIVpul)+" Div35:"+String(DIV35)+"  ");
       display.setCursor(0, 42);
display.print(" inicia:"+String(inicio)+" comando AC:"+String(SAC)+"  ");

 if (digitalRead(27) == LOW){salva=0;
delay(100);
}   
   if(salva==10){
     display.setCursor(0, 12);
     display.print("PARAMETROS SALVOS");
     EEPROM.put(enderecoValor1, Setpoint1);
     EEPROM.put(enderecoValor2, Kp1);
     EEPROM.put(enderecoValor3, Ki1);
     EEPROM.put(enderecoValor4, Kd1);
     EEPROM.put(enderecoValor5, Ent);
     EEPROM.put(enderecoValor6, DIV34);
     EEPROM.put(enderecoValor7, DIVpul);
     EEPROM.put(enderecoValor8, DIV35);
     EEPROM.put(enderecoValor9, inicio);
     EEPROM.put(enderecoValor10, SAC);
     EEPROM.commit(); // Grava os dados na EEPROM
     delay(1250);
         ESP.restart();  // Reinicia o ESP32 usando o reset interno
    }
  display.display();
}



if(menu>5){menu=5;}
if(menu<0){menu=0;}
///  ajuste de set //////////////////

     Setpoint = (Setpoint1/10.0);
      Kp = (Kp1/10.0);
      Ki = (Ki1/10.0);
      Kd = (Kd1/10.0);

   if(Ent>2){Ent=2;}
   if(Ent<0){Ent=0;}


 if(SELECTM==0 && SELECT_menu==1){
     if(select1==0 && menu==1){
     if (digitalRead(13) == LOW){Setpoint1++;
      myPID.SetTunings(Kp, Ki, Kd); // Atualizar os parâmetros do PID
      myPID.SetMode(AUTOMATIC); 
     }
     if (digitalRead(14) == LOW){Setpoint1 --;
      myPID.SetTunings(Kp, Ki, Kd); // Atualizar os parâmetros do PID
     }
     }
     if(select1==1 && menu==1){
     if (digitalRead(13) == LOW){Ent ++;
      myPID.SetTunings(Kp, Ki, Kd); // Atualizar os parâmetros do PID
     }
     if (digitalRead(14) == LOW){Ent --;
      myPID.SetTunings(Kp, Ki, Kd); // Atualizar os parâmetros do PID
   }

  } 
     if(select1==2 && menu==1){
    ///ajuste de kp ////////////

     if (digitalRead(13) == LOW){  Kp1 ++;
     myPID.SetTunings(Kp, Ki, Kd); // Atualizar os parâmetros do PID
     }
    if (digitalRead(14) == LOW){Kp1 --;
     myPID.SetTunings(Kp, Ki, Kd); // Atualizar os parâmetros do PID
     }
     }
      //// ajuste de Ki ////////////////////
     if(select1==3 && menu==1){
     if (digitalRead(13) == LOW){Ki1 ++;
     myPID.SetTunings(Kp, Ki, Kd); // Atualizar os parâmetros do PID
     }
     if (digitalRead(14) == LOW){Ki1 --;
     myPID.SetTunings(Kp, Ki, Kd); // Atualizar os parâmetros do PID
     }
     }
     ////////// ajuste de kd /////////////////////
     if(select1==4 && menu == 1){
     if (digitalRead(13) == LOW){Kd1 ++;
     myPID.SetTunings(Kp, Ki, Kd); // Atualizar os parâmetros do PID
     }
     if (digitalRead(14) == LOW){Kd1 --;
    myPID.SetTunings(Kp, Ki, Kd); // Atualizar os parâmetros do PID
   }
  }

}//fim de menu inicial

    if(SELECTM==0 && SELECT_menu==1){
     if(menu>1){menu=1;}
     if(menu<0){menu=0;}
         display.clearDisplay();
         display.setTextSize(1);//TAMANHO DA FONTE
         display.setTextColor(WHITE, BLACK);
         display.setCursor(110, 0);display.print(salva);
         if(select1==0) {display.setCursor(0, 0);display.print("> ");}
         if(select1==1) {display.setCursor(0, 20);display.print("> ");}
         if(select1==2) {display.setCursor(0, 30);display.print("> ");}
         if(select1==3) {display.setCursor(0, 40);display.print("> ");}
         if(select1==4) {display.setCursor(0, 50);display.print("> ");}
   

  if(select1 == 0 && menu==1){display.setTextColor(BLACK, WHITE);}
  else display.setTextColor(WHITE, BLACK);
       display.setCursor(10, 0);
       display.print("SET: ");
       display.print(Setpoint);//SELECTM
       display.setCursor(80, 0);
       display.print(SELECTM);

       display.setTextColor(WHITE, BLACK);
       display.setCursor(10, 10);
       display.print("Saida PWM:");
       display.print(Output);
       display.setCursor(10, 20);
       display.print("LEITURA:");
  if(Ent==0){display.print(mediaMovel);
  display.print("*C");
  }
  if(Ent==2){display.print(mediaMovel);
  display.print(" Vcc");
  }
  if(Ent==1){display.print(rpm);display.print(" RPM");}
  if(select1 == 1 && menu==1){display.setTextColor(BLACK, WHITE);
  display.setCursor(10, 20);
 if(Ent==0) {display.print("Ent.ANALOGICA D34");}
 if(Ent==1) {display.print("Ent.Pulsos D15 ");} 
 if(Ent==2) {display.print("Ent.analogica D35 ");} 
  }
    if(select1 == 2 && menu==1){display.setTextColor(BLACK, WHITE);}
  else display.setTextColor(WHITE, BLACK);
       display.setCursor(10, 30);
       display.print("AJ. Kp:");
       display.print(Kp);
    if(select1 == 3 && menu==1){display.setTextColor(BLACK, WHITE);}
    else display.setTextColor(WHITE, BLACK);
       display.setCursor(10, 40);
       display.print("AJ. Ki:");
       display.print(Ki);//mostraT 
       display.setCursor(100, 40);
       display.print(mostraT);

   if(select1 == 4 && menu==1){display.setTextColor(BLACK, WHITE);}
  else display.setTextColor(WHITE, BLACK);//ciclo
      display.setCursor(10, 50);
      display.print("AJ. Kd:");
      display.println(Kd);
      display.setCursor(85, 50);
      display.print("dly:");
      display.println(disparo);
      display.setTextColor(WHITE, BLACK);
      display.display();
}//menu 0 e 1 delayMicros



//########### grafico ################
    if(SELECTM==1 && SELECT_menu==1){
     menu=2;
      display.clearDisplay();  // Limpa a tela
      display.setCursor(2, 2);       
      display.print(" Grafico ");
      display.print(mediaMovel);
      display.print(" ");
      display.print(Output);
      display.drawRect(0,0,128,64, SSD1306_WHITE);//desenha quadrado

    //// LINHA DO SET  
      int vrt = map(Setpoint1, 1023, 0,0, 64);
      //( inicio > ,inicio v, tamanha horizontal, tamanho vertical,)
      display.drawRect(0,vrt, 128, 1, SSD1306_WHITE);//desenha linha
      display.setCursor(3, (vrt-10));       
      display.print(Setpoint);
    /////
       // Mapeia o valor lido para o intervalo do display OLED
      int displayValue = map(mediaMovel, 100, 0,0, OLED_HEIGHT);
      int displayValue1 = map(novaLeitura1, 300, 0,0, OLED_HEIGHT);
     // Move o gráfico para a esquerda
      for (int i = 1; i < OLED_WIDTH; i++) {
      graphData[i - 1] = graphData[i];
       }
      for (int i = 1; i < OLED_WIDTH; i++) {
      graphData1[i - 1] = graphData1[i];
       }
        // Adiciona o novo valor ao gráfico
      graphData[OLED_WIDTH - 1] = displayValue;
      graphData1[OLED_WIDTH - 1] = displayValue1;
      drawGraph();      // Desenha o gráfico
      drawGraph1();      // Desenha o gráfico
      display.display();// Atualiza o display
}




  if(mostra>20){
  // Exiba a média móvel no Monitor Serial
  Serial.print("Media Movel:"); 
  Serial.println(mediaMovel);// valor da media movel
  Serial.print("Pwm:");
  Serial.println(Output);// valor do pwm
  Serial.print("Kp:");
  Serial.println(Kp);// valor do pwm
  Serial.print("Kd:");
  Serial.println(Kd);// valor do pwm
  
  mostra=0;
  }

      if(menu==0 && SELECT_menu==1){
        if (digitalRead(14) == LOW){select1++;delay(100);}
        if (digitalRead(13) == LOW){select1--;delay(100);}
        if(select1>4 || select1<0){select1=0;}
                 }

if(inicio==1||on==1){
     // Controle PID
     myPID.Compute();
     analogWrite(pwmPin, Output);
     dacWrite(25, Output);//saida analogica
     // Aguarde um curto período de tempo antes da próxima leitura
     
  // Média móvel
  // Adicione a nova leitura ao array e remova a leitura mais antiga
  for (int i = 0; i < numLeituras - 1; i++) {
    leituras[i] = leituras[i + 1];
  }
    if(Ent==0) {leituras[numLeituras - 1] = novaLeitura;}
    if(Ent==2) {leituras[numLeituras - 1] = novaLeitura1;}

  // Calcule a média móvel
  long soma = 0;
  for (int i = 0; i < numLeituras; i++) {
    soma += leituras[i];
  }
 if(Ent==0 || Ent==2) {mediaMovel = ((soma / numLeituras)*0.1);}
 if(Ent==1) {mediaMovel = rpm;}

  }
  else {analogWrite(pwmPin, 0);
  dacWrite(25, 0);//saida analogica
  }

  delay(1);

}//############### fim do loop ###################

  void drawGraph() {// FUNÇÃO GRAFICO
  for (int i = 1; i < OLED_WIDTH; i++) {
    int y1 = graphData[i - 1];
    int y2 = graphData[i];
    display.drawLine(i - 1, y1, i, y2, SSD1306_WHITE);
  }
}
  void drawGraph1() {// FUNÇÃO GRAFICO
  for (int i = 1; i < OLED_WIDTH; i++) {
    int y3 = graphData1[i - 1];
    int y4 = graphData1[i];
    display.drawLine(i - 1, y3, i, y4, SSD1306_WHITE);
  }
}

///############# desenha uma senoide
void drawSineWave() {
  if(SAC==0){
        if (digitalRead(13) == LOW){Setpoint1++;delay(100);}
        if (digitalRead(14) == LOW){Setpoint1--;delay(100);}
            }
        else{        
          if (digitalRead(13) == LOW){ciclo++;delay(1);}
          if (digitalRead(14) == LOW){ciclo--;delay(1);}
          if(ciclo>255){ciclo=255;}if(ciclo<0){ciclo=0;}
          }



       int s = map(ciclo, 255, 0,32,63); 
       int senoide = map(s, 32, 63,100,0); 
       
       display.clearDisplay();
       display.setTextColor(WHITE, BLACK);
       display.setCursor(2, 2);
       display.print("Ciclo");
       display.setCursor(5, 10);
       display.print(senoide);
       display.print("%");
       display.setCursor(2, 22);
       display.print("Set");
       display.setCursor(3, 30);
       display.print(Setpoint);
       display.setCursor(2, 42);
       display.print(" Out");
       display.setCursor(3, 50);
     if(Ent==0){display.print(mediaMovel);
  }
     if(Ent==1){display.print(mediaMovel);
  }
     if(Ent==2){display.print(mediaMovel);
  }
         for ( idx = 0; idx < 128; idx += 1) {
       y = 32 + 32 * sin(float(idx) / 10.0);
        display.drawPixel(idx, y, SSD1306_WHITE);
      if((idx > 1 && idx<32)||(idx > 31 && idx<s)||(idx>62 && (idx<s+32))|| (idx>94 && (idx<s+64))){
        display.drawRect(idx,y,1,3, SSD1306_BLACK);//apaga senoide
         }else {display.drawRect(idx,y,1,6, SSD1306_WHITE);}//senoide
        } 
   display.drawRect(0,0,128,64, SSD1306_WHITE);//desenha quadrado

   display.drawRect(s,1,1,32, SSD1306_WHITE);//vertical
   display.drawRect(s+32,32,1,64, SSD1306_WHITE);//vertical
   display.drawRect(32,0,1,64, SSD1306_WHITE);//vertical
   display.drawRect(s+64,1,1,32, SSD1306_WHITE);//vertical

   display.drawRect(32,32,128,64, SSD1306_WHITE);//horizontal  

    display.display();// Atualiza o display
  }