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.
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); } }
Boa noite,
ResponderExcluirestou a tentar compilar mas dá-me erro na função Bcd2Dec. Qual o compilador utilizado?
Obrigado,
Samuel
O compilador utilizado é o MIKROC PRO PIC
ExcluirQual a frequência utilizada no cristal do DS1307?
ResponderExcluirO cristal é de 32768 Hz
ExcluirMuito obrigado Tiago!
ExcluirAlguma ideia de por que as dados gravados no sd começam a dar erro após repetidas gravações?
ResponderExcluirEu 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.
ExcluirHmm, 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.
ExcluirDesculpe, mas o erro foi meu. Na verdade faltou fechar o arquivo aberto com a função MMC_Fat_Close(). Por isso acontecia esse erro!!!
ExcluirEstou 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.
ResponderExcluirComo puedo utilizar este software con un pic18f4550. Gracias.
ResponderExcluirOlá amigo, primeiramente gostaria de parabenizar pelo blog, ele é excelente, já me ajudou muito em diversos projetos.
ResponderExcluirAgora 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.
O código tinha um erro, mas não atualizei o código do arquivo pra download...
ExcluirObrigado.
ExcluirNo 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.
ResponderExcluirIsso mesmo, é necessario um divisor de tensao nos pinos CLK, DI e CS.
ResponderExcluirCaso eu queira colocar mais de uma coluna para um outro sensor? como ficaria?
ResponderExcluirOlá!
Excluir1 - 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.
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.
ResponderExcluirSe eu quiser adicionar títulos nas colunas como por exemplo sensor 1 ou tempo, como faço?
ResponderExcluirDeixe a primeira linha do arquivo com o nome dos titulos.
ExcluirVc 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.
ResponderExcluirOu o seu compilador está desatualizado ou voce digitou alguma coisa errada.
ExcluirThiago,
ResponderExcluirBoa 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
Desculpe, mas nao faço a menor ideia de que erro eu tinha falado antes...
ExcluirOK, sem problemas. Quais são as configurações necessárias para rodar este programa no MIKROC PRO PIC na tela de edit project?
ExcluirJohnny
Olá, como faço para inserir a data (dia, mês e ano)?
ResponderExcluirOla,como faço pra ler uma imagem bmp do cartao sd? vc tem uma ideia.
ResponderExcluirVocê sabe de algum projeto nestes moldes feito no mplab com compilador c18?
ResponderExcluirOlá, onde posso conseguir a biblioteca SOFTWARE I2C.
ResponderExcluirComo ficaria este projeto com cartões sd maiores que 2GB? Alguém já fez, alguém tem um exemplo? (com este mesmo pic 18F4620)
ResponderExcluirMuito obrigado por disponibilizar todo esse conteúdo.
ResponderExcluirCódigo muito bem comentado, fácil de entender e adaptar.
Funcionou perfeitamente no 18F4550, única alteração do código postado para que funcionasse no proteus foi "TRISC=0;" logo no início da Main.
Abraço e parabéns pela iniciativa.
Estou tendo rodar o projeto na prática porem não esta criando o arquivo no cartão SD. Fiz as devidas alterações no MickroC para rodar no pic18F45k22. Alguem ain ja testou na prática?
ResponderExcluirbom dia, gostaria de uma consultoria em um projeto parecido utilizando outro sensor, qual seu contato?
ResponderExcluirEste comentário foi removido pelo autor.
ResponderExcluirboa noite ..
ResponderExcluirfiz o projeto so que com modificação para ler tenção so que o rtc não esta granando
o horário e nem a data. se poder alguém poder ajudar agradeço