Ir ao conteúdo
  • Cadastre-se

CeDahmer

Membro Pleno
  • Posts

    210
  • Cadastrado em

  • Última visita

Reputação

1
  1. Estive precisando comunicar dois projetos independentes, um deles que tem tem inúmeras outras funções e utiliza da porta USB para comunicação com supervisórios, sendo composto por um microcontrolador 18F4550, já com a função meste pois utilizava outros dispositivos I2C como memórias, relógios. E outro projeto sendo um pequeno web servidor com o microcontrolador PIC18F4620. Este último com a função simples de hospedar uma página HTML que na verdade é a forma do supervisório acessar as informações e, afinal de contas interagir através de um browser. Bem, é fácil de imaginar o porque de integrar os dois projetos. E como é possível de várias formas, preferi fazer por I2C, pois não preciso fazer grandes modificações no hardware desenvolvido, apenas um novo plugue para a conexão. Deixando essa explicação de lado, e explicando o porque desta postagem: O mestre (18F4550), envia as informações dos estados das entradas (sensores) e saídas (equipamentos), para o escravo (18F4620), que imediatamente disponibilizará para o browser na web, da mesma forma o escravo enviará ao mestre as alterações que o usuário fizer. Assim desenvolvi um código simples tanto ao mestre como ao escravo, com um esquemático simples, onde tudo funciona perfeitamente, como teste apenas: o mestre envia ao escravo uma sequencia numérica, onde o escravo o lê e imprime em um LCD, já o escravo envia ao mestre a informação de um simplório sensor de temperatura (LM35), claro que precisa de 2 bytes para isso, ao menos, pois não utilizei float, apenas uma multiplicação por 10, assim abrangendo qualquer valor possível, dentro de 16 bits. No início de cada informação transmitida é enviado a barra invertida "\" para sinalização do início, conforme o protocolo"zinho", que desenvolvi para isso. Neste pequeno teste tudo funciona perfeitamente transmissão/recepção e vice versa, porém quando coloco este código a rodar dentro de um programa maior com muitas outras funções, a recepção não encontra valores corretos, e muitas vezes "se perde". Portanto gostaria muito de uma boa alma para fazer uma análise do código e me ajudar a sair desse embaraço. Abaixo está os códigos, primeiro do mestre e em seguida do escravo, também coloquei em anexo os arquivos do proteus (versão 8) e os código em C (compilador CCS). Se algum administrador puder colocar os códigos dentro daquelas caixinhas "bonitinhas", pois não sei fazer isso. //=====================firmware para o mestre com PIC18F4550==================// #include <18F4550.H> #device adc=8 #fuses HSPLL,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV4,VREGEN,NOMCLR,PUT #use delay(clock=48000000) #use i2c(MASTER,sda=pin_b0, scl=pin_b1) #include <lcd_flex20X4.c> int8 dadoM; int8 matrizEscravo[6]; int8 adc_result; int8 matrizMestre[10]; int8 indiceMestre=0; int8 indiceEscravo=0; int8 a; void enviar_i2c(){ if (indiceMestre==0) matrizMestre[indiceMestre]="/"; else matrizMestre[indiceMestre]=indiceMestre; indiceMestre++; if (indiceMestre>9) indiceMestre=0; i2c_start(); i2c_write(0x12); dadoM=matrizMestre[indiceMestre]; i2c_write(dadoM); i2c_stop(); delay_ms(10); } void receber_i2c(){ i2c_start(); i2c_write(0x13); a = i2c_read(0); if (a=='/') { indiceEscravo=0; matrizEscravo[0]="/";} else { //if (g>0 && g%2==0) { matrizEscravo[indiceEscravo]=a; //} } indiceEscravo++; i2c_stop(); delay_ms(10); } //==================================== void main() { setup_adc_ports(AN0); setup_adc(ADC_CLOCK_DIV_8); set_adc_channel(0); lcd_init(); lcd_putc("Master"); delay_ms(10); while(1){ adc_result=read_adc()*2; receber_i2c(); enviar_i2c(); printf(lcd_putc,"\fMestre %u\nEscravo %c%u%u - %lu \n%u",dadoM,matrizEscravo[0],matrizEscravo[1],matrizEscravo[2],((matrizEscravo[1]*256)+matrizEscravo[2]),a); } } Aqui código para o escravo. //=================firmware para o escravo com PIC18F4620====================// #include <18F4620.h> #device adc=10 #fuses XT,NOWDT,PUT,BROWNOUT,NOLVP #use delay(clock=4000000) #use i2c(SLAVE, SDA=PIN_c4, SCL=PIN_c3, address=0x12,force_hw) #include <lcd_flex20X4.c> int16 adc_result; int8 dadoM; int8 matrizEscravo[4]; int8 matrizMestre[10]; int8 indiceEscravo=0; int8 indiceMestre=0; int8 state; #INT_SSP void comunicacao_i2c(){ if(i2c_poll()){ state=i2c_isr_state(); dadoM = i2c_read(0); if (dadoM=='/') {indiceMestre=0; } else {indiceMestre++;} if (dadoM!=18 && indiceMestre%2==0) {matrizMestre[indiceMestre/2]=dadoM;} } } void enviar_i2c(){ if (indiceEscravo==0) { matrizEscravo[0]="/";} if (indiceEscravo==1) { matrizEscravo[1]=make8(adc_result,1);} if (indiceEscravo==2) { matrizEscravo[2]=make8(adc_result,0);} i2c_write(matrizEscravo[indiceEscravo]); delay_ms(10); indiceEscravo++; if (indiceEscravo>3) { indiceEscravo=0;} } //====================================== void main() { setup_adc_ports(AN0); setup_adc(ADC_CLOCK_DIV_8); set_adc_channel(0); delay_us(10); enable_interrupts(INT_SSP); enable_interrupts(GLOBAL); lcd_init(); lcd_putc("Slave"); while(1){ adc_result = (float)(read_adc()/2.0)*10; delay_ms(10); enviar_i2c(); printf(lcd_putc,"\f%c%u%u%u%u%u%u%u%u%u \n\nEscravo %c%u%u \n%lu",matrizMestre[0],matrizMestre[1],matrizMestre[2],matrizMestre[3],matrizMestre[4],matrizMestre[5],matrizMestre[6],matrizMestre[7],matrizMestre[8],matrizMestre[9],matrizEscravo[0],matrizEscravo[1],matrizEscravo[2],adc_result); } } I2C_1.rar
  2. Obrigado mais uma vez projetos_afg e vtrx por terem colaborado. Localizei uma fonte provável dos problemas: Ao aquecer a parte posterior do LCD os problemas começar (mais ou menos 25 graus celsius), ao afastá-lo da fonte de calor, o LCD funciona normalmente. A rotina lcd_init(); eu uso na inicialização do programa, agora posso usá-lo de tempos em tempos para reinicar o LCD? infelizmente não tenho mais pinos suficientes para poder usar a função RW do LCD. Bom pelo que sei a função usb_task é necessária para manter a comunicação USB ativa, mas pelo que li aqui mesmo no fórum, não poderia estar dentro de um timer, agora não sei o porquê, e realmente depois que fiz isso coloquei-o dentro do loop principal, a comunicação ficou totalmente estável, comunicando com o PC por mais de semanas. Eu uso HID. Desta forma se for dado um time, a conexão cairá. Acredito que isso não seja verdade, mas eu não gostaria de mudar, pois demorou muito tempo para testar, e não possuo mais tempo para testar a comunicação USB. Me preocupou bastante a falta de qualidade do displays, pois os dois são exatamente iguais, e um deles apresenta esse problema por aquecimento, agora se eu for usar em escala, precisarei testar um a um antes para ver se apresenta problemas. Mas esses são os percalços. Mas uma vez obrigado, e caso puderem me dar mais idéias me será muito útil.
  3. Obrigado projetos_afg pela colaboração... Agora que você comentou da alimentação regulada e estável, verifiquei um detalhe na placa que está apresentando o problema estou usando um capacitor de 16V após os diodos, e na outra um de 25V, ambos por 1000uF, sendo que o transformador é de 12V, mas após a retificação, a corrente sobe para 16V, antes do regulador. Acho que este capacitor possa estar em curto por estar no limite, mas vou testar isso. Em qual local você recomenda o delay? na inicialização do mesmo ou toda vez que escrever algo no LCD, pois não posso travar a aplicação por esse tempo senão a porta USB se desconecta. O pino RW eu aterei por estar usando todos os pinos do PIC, e desculpe minha ignorância mas não sei o que é busy flag. Uso no modo 4 bits tambérm por economia de pinos. Uso a biblioteca padrão do CCS, com algumas adaptações que achei na internet, para funcionar com RW aterado e com as quatro linhas. Não estou usando nada indutivo, apenas o transformador, 4 diodos em ponte, um capacitor e um regulador LM7812 e em seguida um LM7805 para formar a fonte. Como eu posso fazer para reiniciar o LCD sem reinicar o PIC? Acho que isso solucionaria o problema.
  4. Boa tarde. Montei um sistema que utiliza um display de LCD de 20X4 que ao ligar funciona perfeitamente. Mas ao passar o tempo, dois ou mais dias ligado, o mesmo começa a mostrar caracteres estranhos, no local de algumas letras começa a piscar estes caracteres. O mais estranho é que montei outro sistema igual, pois a placa é fresada em uma fresadora CNC, usei os mesmos componentes e o mesmo firmware no PIC, e este segundo não mostrar esta alteração. Sendo que tanto o display como os outros componentes são iguais, e comprados do mesmo fornecedor. Como linguagem estou usando o C pelo CCS, e o uC é o 18F4550, a marca do LCD não sei mas tem o código MGD2004D-FL-YBS-02. Se alguém tiver a solução ou uma ideia do que pode ser este problema, por favor comparti-lhe.
  5. Boa noite... Desculpem minha ignorância, mas estou precisando modificar um projeto, onde uso como sensor de temperatura o LM35, e estou pensando em utilizar um termitor NTC, mas o problema é que o mesmo não é linear, e apesar de várias horas de pesquisa na internet não consegui encontrar uma forma de anexar a fórmula do termistor no programa do pic. Encontrei a seguinte fórmula: R(T) = R(T0) * [ 1 + a(T - T0) ] Precissaria da ajuda para entender como montá-la. Eu utilizo o microprocessador PIC 16F877A, na linguagem C com o compilador CCS. Aproveitando o tópico, como o produto do termistor é resistência, é possível conectá-lo no pic, da mesma forma que o LM35? Colocando uma ponta no +5V e a outra diretamente no PIC? Obrigado...
  6. Martins eu tive o mesmo problema, e de tanto tentar usar interrupções desisti e consegui fazer sem... Vou descrever mais ou menos como fiz Declarei esta variável de escopo global, para receber, só consegui sendo do tipo char, e recebendo um caracter por vez. char xx[1]=0; Criei um função fora do Main, antes dele. Void Receber_RS232() //Função para comunicação com o PC { if (kbhit()) { gets(xx,1); } } E dentro do main mais precisamente, dentro do loop infinito faço uma chamada a função: Receber_rs232(); Ele testa se tem alguma coisa pra receber, caso positivo joga na variável xx o caracter recebido pelo pic. Como a variável é de escopo global, posso utilizá-la em qualquer ponto do programa para testa-la. Obs. Ainda não criei a rotina para receber uma string inteira, mas para minha aplicação é necesário apenas de 0 a 9, e neste caso ele recebe o abc completo. Ah... ainda para facilitar os testes você pode converter a variável xx para valores inteiros, mas só funciona de 0 a 9. SE = atol(xx); SE é uma variável inteiro de 8 bits, mas é necessário estar marcado a biblioteca: #include "stdlib.h" Conheço pouco e a pouco tempo sobre PIC, mas no meu caso funcionou.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...