Fork me on GitHub

12/03/13

PIC: DataLogger com PIC18F

PIC: DataLogger com PIC18F


DataLogger é um equipamento destinado a coletar dados durante um certo tempo. Esses dados são fornecidos por sensores e seus valores são armazenados numa memória.

Este projeto trata-se de um datalogger que faz a medição de temperatura utilizando o sensor LM35, e armazena seus valores num cartão SD, junto com a hora atual. O relógio utlizado é o RTC DS1307.

O arquivo será salvo no formato ".csv" para poder ser aberto no Excel. Para cada vez que reiniciar o microcontrolador, será criado um novo arquivo.


No caso utilizei o microcontrolador PIC18F4620, mas pode ser utilizado por qualquer PIC da família 18F em diante.

O cartão SD deve estar formatado como FAT16.

Veja também que como o DS1307, comunica-se via I2C e o cartão SD comunica-se via SPI, ambas comunicações utilizam o mesmo pino no microcontrolador. Para facilitar o código, optei por utilizar a função SOFTWARE I2C. Software i2c, é uma emulação da comunicação i2c, utlizando qualquer pino do microcontrolador para essa comunicação.

A imagem do cartão SD para poder simular no Proteus está no formato ".ima". Baixe o programa UltraISO, ou outro semelhante, para poder abrir este arquivo.

Estou incluindo este arquivo no download abaixo.

DOWNLOAD:
Projeto: datalogger.rar;


Caso você queira montar esse projeto, não se esqueça que o cartão SD é alimentado com 3.3V. Isso quer dizer que os pinos CLK, DI e CS devem receber 3.3V. Utilize um divisor de tensão.



CóDIGO:
MikroC PRO PIC
sbit Mmc_Chip_Select at LATC0_bit;
sbit Mmc_Chip_Select_Direction at TRISC0_bit;
sbit Soft_I2C_Scl at RC1_bit;
sbit Soft_I2C_Sda at RC2_bit;
sbit Soft_I2C_Scl_Direction at TRISC1_bit;
sbit Soft_I2C_Sda_Direction at TRISC2_bit;

char temp[16] = "00:00:00;000,0\r";
short segundos, minutos, horas, dia, date, mes, ano;
unsigned long adc;
char filename[11] = "DataXX.csv";//o array nao pode ser maior que 14??

//define os segundos, minutos.. para o ds1307
void ds1307_write(){
Soft_i2c_stop();
Soft_i2c_start();
Soft_i2c_write(0xD0);
Soft_i2c_write(0x00);
Soft_i2c_write(Dec2Bcd(0));//segundos
Soft_i2c_write(Dec2Bcd(0));//minutos
Soft_i2c_write(Dec2Bcd(12));//horas
Soft_i2c_write(Dec2Bcd(1));//dia da semana
Soft_i2c_write(Dec2Bcd(12));//data
Soft_i2c_write(Dec2Bcd(3));//mes
Soft_i2c_write(Dec2Bcd(13));//ano
Soft_i2c_stop();

}

//faz a leitura do ds1307
void ds1307_read(){
Soft_i2c_start();
Soft_i2c_write(0xD0);
Soft_i2c_write(0x00);
Soft_i2c_Start();
Soft_i2c_write(0xD1);
segundos = Bcd2Dec(Soft_i2c_read(1));
minutos = Bcd2Dec(Soft_i2c_read(1));
horas = Bcd2Dec(Soft_i2c_read(1));
dia = Bcd2Dec(Soft_i2c_read(1));
date = Bcd2Dec(Soft_i2c_read(1));
mes = Bcd2Dec(Soft_i2c_read(1));
ano = Bcd2Dec(Soft_i2c_read(0));
Soft_i2c_stop();
}

//Esta funcao cria um novo arquivo
void Create_New_File() 
{
  //cria o arquivo(caso nao exista) com atributo de "arquivo" e abre
  Mmc_Fat_Assign(&filename, 0xA0);
  //define a data de criação do arquivo
  Mmc_Fat_Set_File_Date(ano+2000, mes, date, horas, minutos, segundos);
  Mmc_Fat_Append();//prepara o arquivo para gravação
  Mmc_Fat_Write(temp, 15);//escreve no arquivo
}

//Esta função deleta o arquivo
void Delete_File()
{
  Mmc_Fat_Assign(&filename, 0);
  Mmc_Fat_Delete();
}

short Test_File_Exist() 
{
  //como nao definiu nenhum atributo de criação, caso o arquivo exista 
  //retorna 1, caso contrario retorna 0
  return Mmc_Fat_Assign("DATA00.csv", 0);
}


//abre o arquivo(caso não exista, nao ira ler) e inicia a leitura.
void Open_File_Read()
{
unsigned long i, size;
char caracter;
  Mmc_Fat_Assign(&filename, 0);
  Mmc_Fat_Reset(&size);//recupera o numero de caracteres do arquivo
  for (i = 1; i <= size; i++)
  {
    Mmc_Fat_Read(&caracter);// le um caracter do arquivo
    UART1_Write(caracter);
  }
}


void main()
{
char i;

ADC_Init();//inicia o modulo ADC
ADCON1 = 0B00001110; //define o canal 0 como analogico, o restante como digital.
Soft_i2c_init();//inicia a comunicação software i2c
//inicia a comunicação SPI
SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);
//inicia a comunicaçao com cartão SD
MMc_Fat_Init();

//verifica-se se o arquivo ja existe. caso exista cria um novo arquivo com um nome diferente
for(i=0;i<100;i++)
{
 filename[4] = (i/10) + 48;
 filename[5] = (i%10) + 48;
 if(Mmc_Fat_Assign(&filename, 0)==0)
 {
  break;
 }
 else
 {
  MMC_Fat_Close(); //Bug resolvido
 }
}

while(1)
{
    adc = ADC_Read(0);
    adc = adc * 1000/204;
    temp[9] = (adc/1000) + 48;
    temp[10] = ((adc/100)%10) + 48;
    temp[11] = ((adc/10)%10) + 48;
    temp[13] = (adc%10) + 48;

    ds1307_read();

    temp[0] = horas/10 + 48;
    temp[1] = horas%10 + 48;
    temp[3] = minutos/10 + 48;
    temp[4] = minutos%10 + 48;
    temp[6] = segundos/10 + 48;
    temp[7] = segundos%10 + 48;

    Create_New_File();
    
    delay_ms(500);
}
}

30 comentários:

  1. Boa noite,

    estou a tentar compilar mas dá-me erro na função Bcd2Dec. Qual o compilador utilizado?

    Obrigado,

    Samuel

    ResponderExcluir
  2. Alguma ideia de por que as dados gravados no sd começam a dar erro após repetidas gravações?

    ResponderExcluir
    Respostas
    1. Eu nunca testei esse projeto na prático, mas vou ver se faço o teste. Se o erro persistir, provavelmente é algum bug da biblioteca do MikroC.

      Excluir
    2. Hmm, não tinha pensando nisso. Queria aproveitar pra te perguntar se foi intencional omitir as informações de dia/mês/ano no csv, ou se é por causa desse possível erro de biblioteca, porque aparece somente a leitura da temperatura e a hora/minuto/segundo.

      Excluir
    3. Desculpe, mas o erro foi meu. Na verdade faltou fechar o arquivo aberto com a função MMC_Fat_Close(). Por isso acontecia esse erro!!!

      Excluir
  3. Estou a tentar correr o programa no Proteus,mas usando um PIC18F4550, conectando CS ao pino 15, D0 a 33 , DI a 26 e SCLK a 34. Não consigo criar o ficheiro.

    ResponderExcluir
  4. Como puedo utilizar este software con un pic18f4550. Gracias.

    ResponderExcluir
  5. Olá amigo, primeiramente gostaria de parabenizar pelo blog, ele é excelente, já me ajudou muito em diversos projetos.
    Agora sobre o projeto acima estou com algumas dúvidas, no arquivo que você disponibilizou o código fonte está diferente do mostrado aqui no site, qual dos dois é o certo?? Estou tentando adaptar pra o 18f4550 e não estou conseguindo, será que pode ser algum erro no código??? Grato.

    ResponderExcluir
    Respostas
    1. O código tinha um erro, mas não atualizei o código do arquivo pra download...

      Excluir
  6. No circuito acima, o SD card está conectado diretamente ao PIC, a tensão de saída do PIC 5V, não deveria ser limitado para 3,3V com um divisor de tensão, já que o SD Card trabalha com 3,3V, não há perigo de queimar o SD Card? Grato.

    ResponderExcluir
  7. Isso mesmo, é necessario um divisor de tensao nos pinos CLK, DI e CS.

    ResponderExcluir
  8. Caso eu queira colocar mais de uma coluna para um outro sensor? como ficaria?

    ResponderExcluir
    Respostas
    1. Olá!
      1 - Altera a declaracao da variavel "temp" para char temp[22] = "00:00:00;000,0;000,0\r";
      2 - Na linha 55, altera a quantidade de caracteres escritos para 21: Mmc_Fat_Write(temp, 21);Obs.: acho q ficaria melhor assim:Mmc_Fat_Write(temp, sizeof(temp));
      3 - Na linha 93, configure o ADCON1 para ativar outro canal analógico.
      4 - No código principal faça a leitura do segundo sensor:

      adc = ADC_Read(x); //canal analogico x
      adc = adc * 1000/204;
      temp[15] = (adc/1000) + 48;
      temp[16] = ((adc/100)%10) + 48;
      temp[17] = ((adc/10)%10) + 48;
      temp[19] = (adc%10) + 48;

      Se eu não estiver esquecendo de mais nada, creio que é somente isso.
      Abraços,
      Tiago.

      Excluir
  9. Ao inves de um LM35, estou usando um pot, porem meus numeros estao estranho pela sua conta, gostaia que aparecesse de 0 a 1023, porem soh aprece simbolos.

    ResponderExcluir
  10. Se eu quiser adicionar títulos nas colunas como por exemplo sensor 1 ou tempo, como faço?

    ResponderExcluir
    Respostas
    1. Deixe a primeira linha do arquivo com o nome dos titulos.

      Excluir
  11. Vc pode me disponibilizar a biblioteca mmc_fat_close, pois ela não consta do meu mikroC. O programa . hex não está rodando na minha placa. Estou gravando com o Tiny bootloader.

    ResponderExcluir
    Respostas
    1. Ou o seu compilador está desatualizado ou voce digitou alguma coisa errada.

      Excluir
  12. Thiago,

    Boa noite,

    Como faço para corrigir o erro que você mencionou anteriormente? Em qual linha devo fazer a mudança para corrigir o problema?

    Johnny

    ResponderExcluir
    Respostas
    1. Desculpe, mas nao faço a menor ideia de que erro eu tinha falado antes...

      Excluir
    2. OK, sem problemas. Quais são as configurações necessárias para rodar este programa no MIKROC PRO PIC na tela de edit project?

      Johnny

      Excluir
  13. Olá, como faço para inserir a data (dia, mês e ano)?

    ResponderExcluir
  14. Ola,como faço pra ler uma imagem bmp do cartao sd? vc tem uma ideia.

    ResponderExcluir
  15. Você sabe de algum projeto nestes moldes feito no mplab com compilador c18?

    ResponderExcluir
  16. Olá, onde posso conseguir a biblioteca SOFTWARE I2C.

    ResponderExcluir

Postagens Relacionadas!!