Postagem em destaque

Controle PID de Potência em Corrente Alternada - Arduino e TRIAC - Parte I

Este post é o primeiro de uma série de seis que escrevi tratando de controle de potência e PID (controle proporcional, integral e derivativo...

segunda-feira, 8 de julho de 2013

Automação no parque, 06/07/2013

Nesse dia apareceu o César Munoz, vindo do ABC para brincar conosco no Parque. Trouxe consigo componentes para fazer um relógio digital com o DS1307. Montamos dois circuitos, simples, que vcs podem achar facilmente na net: um para ligar o DS1307 e outro para ligar o LCD. Aqui no blog mesmo tem um post sobre a ligação de um LCD de 20 colunas X 2 linhas, e a ligação de um 16x2, mais comum, é a mesma.

Aqui, uma imagem ensinando como ligar o DS1307:


A bateria B1 é de 3,3V e X1 é um clock de 32,786 kHz.

O que fizemos de novidade nesse circuito foi colocar botões para acertar data e hora. Esse circuito foi feito com três botões: um que comanda o que vai ser alterado (vc seleciona dia, mês, ano, hora, minuto ou segundo) e os outros dois servem para aumentar/diminuir o valor selecionado. O sistema indica com um * no canto superior esquerdo da tela que está em modo de atualização da hora e com uma letra indica o que está sendo  atualizado no momento, ex: *h indica que se vc mexer nos botões estará alterando a hora.

Os botões são ligados a portas digitais do Arduino na forma de circuito "pull down". Aqui um exemplo de como ligar um botão no Arduino usando-se essa técnica. O resistor pode ser qualquer valor entre 1k e 100k, ou até fora dessa faixa, a se testar. No site do Arduino tem um bom texto que explica a ideia por trás do pull down: http://arduino.cc/en/tutorial/button



No nosso circuito, ligamos o botão que controla o setup no pino 7, o que aumenta o número no pino 8 e o que baixa no pino 9.

É isso. Abaixo, foto do circuito e filme dele funcionando. E, mais abaixo, os fontes.





#include <LiquidCrystal.h>
#include <DS1307RTC.h>
#include <Wire.h>
#include <Time.h>

// Clock set command pins
#define clockSet 7
#define clockUp 9
#define clockDown 8

//Clock states
#define stClockRunning 0
#define stSetDay 1
#define stSetMonth 2
#define stSetYear 3
#define stSetHour 4
#define stSetMinute 5
#define stSetSecond 6

int stat = stClockRunning;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void Print(int number)
{
  lcd.print(number/10);
  lcd.print(number%10);
}

// Fill lcd display
void printTime()
{
  lcd.setCursor(6,1); Print(hour());
  lcd.print(":");     Print(minute());
  lcd.print(":");     Print(second());
  lcd.setCursor(5,0); Print(day());
  lcd.print("/");     Print(month());
  lcd.print("/");     Print(year());
  lcd.setCursor(0,0);
  if (stat != stClockRunning)
     lcd.print("*");
  else  
     lcd.print("  ");
  switch(stat)
  {
    case stSetDay:
      lcd.print("d");
      break;
    case stSetMonth:
      lcd.print("m");
      break;
    case stSetYear:
      lcd.print("a");
      break;
    case stSetHour:
      lcd.print("h");
      break;
    case stSetMinute:
      lcd.print("M");
      break;
    case stSetSecond:
      lcd.print("s");
      break;
  }
}

// Read pin using threshold, as a switch, that is,
// first time pressed switch on, second time switch off
int readPinSwitch(int pin, int threshold)
{
  if (digitalRead(pin))
  {
    unsigned long tt = millis();
    while (digitalRead(pin));
    if ((millis() - tt) > threshold)
       return 1;
    else
       return 0;  
  }
  else
    return 0;
}

//Read pin using threshold
int readPin(int pin, int threshold)
{
  if (digitalRead(pin))
  {
    unsigned long tt = millis();
    while ((digitalRead(pin) && (millis() - tt) <= threshold));
    if (digitalRead(pin))
       return 1;
    else
       return 0;  
  }
  else
    return 0;
}

// Get new status, if any
int getStat()
{
  if (readPinSwitch(clockSet,300))
     if (stat == stSetSecond)
        return stClockRunning;
     else
        return stat+1;
  else
     return stat; 
}

// set Arduino and RTC time
void setRTCTime(int hour, int minute, int second, int day, int month, int year)
{
// set Arduino time 
    setTime(hour,minute,second,day,month,year);
    time_t t = now();    
// set RTC time
    RTC.set(t);
}

void setup()
{
  pinMode(clockUp,INPUT);
  pinMode(clockDown,INPUT);
  pinMode(clockSet,INPUT);

  lcd.begin(16, 2); // Set the display to 16 columns and 2 rows
  setSyncProvider(RTC.get);   // the function to get the time from the RTC
  if(timeStatus()!= timeSet)
  {
     lcd.setCursor(0,0);
     lcd.print("Erro RTC");
  }
}

int oldStat = stat;
unsigned long t=millis();

void loop()
{
  int value = 0;
  printTime();
  delay(100);
  stat=getStat();
  if (stat != oldStat)
  {
    t=millis();
    oldStat = stat;
  }
  else
    if ((stat != stClockRunning) && ((millis() - t) > 5000))
       stat=stClockRunning;
  switch(stat)
  {
    case stClockRunning:
      break;
    case stSetDay:
// init value
      value=day();
//button up pressed
      while(readPin(clockUp,300))
      {
        value++;
        if (value > 31)
          value=1;
        setRTCTime(hour(),minute(),second(),value,month(),year());
        printTime();
      }
//button down pressed
      while(readPin(clockDown,300))
      {
        value--;
        if (value < 1)
          value=31;
        setRTCTime(hour(),minute(),second(),value,month(),year());
        printTime();
      }
      break;
// see comments stSetDay
    case stSetMonth:
      value=month();
      while(readPin(clockUp,300))
      {
        value++;
        if (value > 12)
          value=1;
        setRTCTime(hour(),minute(),second(),day(),value,year());
        printTime();
      }
      while(readPin(clockDown,300))
      {
        value--;
        if (value < 1)
          value=12;
        setRTCTime(hour(),minute(),second(),day(),value,year());
        printTime();
      }
      break;
    case stSetYear:
      value=year();
      while(readPin(clockUp,300))
      {
        value++;
        if (value > 2050)
          value=2000;
        setRTCTime(hour(),minute(),second(),day(),month(),value);
        printTime();
      }
      while(readPin(clockDown,300))
      {
        value--;
        if (value < 2000)
          value=2050;
        setRTCTime(hour(),minute(),second(),day(),month(),value);
        printTime();
      }
      break;
    case stSetHour:
      value=hour();
      while(readPin(clockUp,300))
      {
        value++;
        if (value > 23)
          value=0;
        setRTCTime(value,minute(),second(),day(),month(),year());
        printTime();
      }
      while(readPin(clockDown,300))
      {
        value--;
        if (value < 1)
          value=24;
        setRTCTime(value,minute(),second(),day(),month(),year());
        printTime();
      }
      break;
    case stSetMinute:
      value=minute();
      while(readPin(clockUp,300))
      {
        value++;
        if (value > 59)
          value=0;
        setRTCTime(hour(),value,second(),day(),month(),year());
        printTime();
      }
      while(readPin(clockDown,300))
      {
        value--;
        if (value < 0)
          value=59;
        setRTCTime(hour(),value,second(),day(),month(),year());
        printTime();
      }
      break;
    case stSetSecond:
      value=minute();
      while(readPin(clockUp,300))
      {
        value++;
        if (value > 59)
          value=0;
        setRTCTime(hour(),minute(),value,day(),month(),year());
        printTime();
      }
      while(readPin(clockDown,300))
      {
        value--;
        if (value < 0)
          value=59;
        setRTCTime(hour(),minute(),value,day(),month(),year());
        printTime();
      }
      
  }