,

Simular um 555 com Arduino

Posted by

Hoje você vai ver algo inédito, no mínimo difícil de encontrar, vamos simular um 555 com Arduino. Vamos implementar a lógica do 555 com código do Arduino.

Claro que essa ideia não é prática, não faz sentido usar um microcontrolador que custa vários reais para simular um chip como o 555, que custa centavos. Mas vamos fazer isso pelo desafio, pela beleza de fazer o código funcionar.

Primeiro vamos entender o funcionamento do 555, neste caso como astável (oscilador pisca-pisca). Utilizaremos o diagrama esquemático interno do componente (imagem abaixo), disponível no seu datasheet.

Diagrama esquemático do 555
Diagrama esquemático do 555

Considere os três resistores da imagem como tendo o mesmo valor. Então a tensão que será comparada com THRES (threshold) é 66% da tensão Vcc; já com TRIG (trigger) é 33% de Vcc.

O diagrama esquemático de um oscilador com 555 é visto abaixo e neste link.

oscilador pisca-pisca com 555
Oscilador com 555

O capacitor C1 é carregado através de R1 e R4. Então quando a tensão em TRIG (trigger) ultrapassar 33% da nominal de alimentação a saída (pino 3) vai a nível alto. Quando a tensão em THRES (threshold) passar de 66% da tensão nominal, o pino 3 vai a nível baixo. O pino DIS (discharge) é ativado, começando a descarga do capacitor.

O ciclo então se reinicia, a carga de C1 começa a acontecer. Eu implementei o circuito acima no TinkerCAD, abaixo.

O Circuito com Arduino

Oscilador 555 com Arduino
Oscilador 555 com Arduino

O equacionamento é conforme abaixo. Utilizei resistores de 47k (x2) e capacitor de 10uF. os dois resistores de 100R nas entradas analógicas são para evitar curtos devido á carga e descarga do capacitor. O transistor é para descarga do capacitor, já que o pino 0 do Arduino não suporta fazer esta descarga sozinho.

t1 (alto)= 0,693 * (R1 + R4) * C1

Com os valores que eu calculei para o circuito, fica:

t1 (alto) = 0,693 * (47000 + 47000) * 0,00001 = 0,651 segundos

Já o tempo em baixo (t2) fica:

t2 (baixo) = 0,693 * R4 * C1

substituindo os valores o tempo vai ficar:

t2 (baixo) = 0,693 * 47000 * 0,00001 = 0,325 segundos

O tempo total é 0,651 + 0,325 segundos, total de 0,976 segundos. A frequência de oscilação portanto é F= 1/t(t1+t2) :: F= 1/0,976 = 1,02Hz.

O código do Arduino

Eu não utilizei delay() neste código, já que eu queria um código rápido. Utilizei um sketch que inventei baseado no blinkWithoutDelay, neste link.

// Variables used on this code
unsigned long times;
unsigned long previousTime;
boolean enterFunction= true;
//-----------------------

const int trigger_pin2 = A0;
const int output_pin3 = 1;
const int reset_pin4 = 2;
const int threshold_pin6 = A1;
const int discharge_pin7 = 0;
bool dischargeOn = false;


void setup() {
    pinMode(trigger_pin2, INPUT);
    pinMode(output_pin3, OUTPUT);
    pinMode(reset_pin4, INPUT);
    pinMode(threshold_pin6, INPUT);
    pinMode(discharge_pin7, OUTPUT);
}

void loop() {
  times = micros();
  if (enterFunction == true){
    previousTime= times;
    Serial.println(previousTime); // for debugging

    // Start your code below 
    //-----------------------


    if(analogRead(trigger_pin2) > 3.333){

        digitalWrite(discharge_pin7, HIGH);
        digitalWrite(output_pin3, LOW);

    } else if(analogRead(trigger_pin2) > 1.666){

        digitalWrite(output_pin3, HIGH);
        digitalWrite(discharge_pin7, LOW);

    } else if(analogRead(trigger_pin2) < 0.2){

        digitalWrite(discharge_pin7, LOW);
      	digitalWrite(output_pin3, LOW);
    }

    //-----------------------
    // End of your code
  }
  
  // The DELAY time is adjusted in the constant below >> 
  if (times - previousTime < 9999){ // 1 million microsencods= 1 second delay
    /* I have actually used 0.999990 seconds, in a trial to compensate the time that
       this IF function takes to be executed. this is really a point that
       need improvement in my code */   
    enterFunction= false;
  } 
  else {
    enterFunction= true;
  }
}

Basicamente o código depende das linhas abaixo.

if(analogRead(trigger_pin2) > 3.333){

        digitalWrite(discharge_pin7, HIGH);
        digitalWrite(output_pin3, LOW);

    } else if(analogRead(trigger_pin2) > 1.666){

        digitalWrite(output_pin3, HIGH);
        digitalWrite(discharge_pin7, LOW);

    } else if(analogRead(trigger_pin2) < 0.2){

        digitalWrite(discharge_pin7, LOW);
      	digitalWrite(output_pin3, LOW);
    }
  • Eu verifico se a tensão é maior que 3,3V (66,6% de 5V); caso for, desligo a saída e ligo a descarga.
  • Verifico então se a tensão é maior que 1,66V (33,3% de 5V); caso for eu ligo a saída e desligo a descarga.
  • Caso a tensão de comparação for menor que 0,2V (capacitor descarregado) eu desligo a descarga e a saída para reiniciar o ciclo.

Lembrando que você pode ver a simulação funcionando neste link.

Resultados e discussões

Em termos de limitações, o circuito é “executado” a cada 10mS, então não é possível obter frequências de piscada de muitos kHz. Também para utilizar o circuito e código para um temporizador o código teria que ser modificado.

Fora isso a experiência é interessante, conseguimos fazer um LED piscar “simulando” um 555 com Arduino. Como trabalho futuro eu quero fazer um código para temporizador.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *