-
Posts
5 -
Cadastrado em
-
Última visita
Reputação
1-
PIC PIC 18F4550 com Bússola Eletrônica HMC5883L
Mario Henrique Luchiari respondeu ao tópico de Mario Henrique Luchiari em Microcontroladores
Boa tarde, .if e pessoal do clube! Desculpem a minha demora em continuar postando. Estou com uma carga grande de trabalho. A carga ainda está grande mas, reservei um tempinho para dizer que resolvi o problema. Eram os registradores que estavam errados, inclusive o endereço I2C. Isso eu desconfiava desde o começo... Em primeiro lugar o módulo que comprei é uma enganação. Tomem cuidado! Vem apresentado como HMC5883 mas na verdade é QMC5883. A diferença? É brutal! Até o datasheet do QMC é chato de achar. Quando comparar os dois, verá que está tudo diferente. Acertei o endereço e os registradores e pufff! O trem funcionou! Em segundo lugar descobri o endereço na marra. Como? Fiz um programa que testa endereço por endereço até o módulo, que é escravo, responder. Deu certo! Aí que eu fui me tocar que o chip podia ser outro. Pesquisei e descobri que quando o chip tem a inscrição DA5883 é QMC5883 e quando tem L883 é HMC5883L. Vejam nas fotos. Em terceiro, acabei aprendendo muito sobre I2C, a ponto de colocar num osciloscópio para analisar o protocolo! Cheguei à conclusão que, quando o endereço está errado e o chip não responde, a linha do clock que é a amarela só completa a primeira parte (observe que esta possui (quase) três partes sutilmente separadas). Esta primeira parte é o envio do endereço do mestre para o escravo. Quando não obtém resposta do escravo, a sequência termina. A linha azul é a linha de dados, que é o SDA. A sequência desta foto está completa. Ela é de uma comunicação bem sucedida entre mestre e escravo com endereço 0x1A. Quem tiver interesse no código vou postar aqui e considerar esse tópico encerrado! Muito obrigado, .if! você ajudou bastante! Atenção! Este código é para o QMC5883 e não para o HMC5883. /*Apesar de ter requisitado o HMC5883 e na placa do módulo estar escrito isso, o módulo possui o CI QMC5883 cujos endereços de registradores diferem do HMC. Após muita luta e pesquisa, consegui descobrir isso. Este código faz o QMC funcionar de maneira básica, apenas indicando os valores dos eixos X, Y e Z no display LCD 16 x 2 selecionados por um botão no PORTB.F2. A sequência apresenta X, Y, Z e por último a situação de todos os registradores, de 0x00 a 0x0D. Reconheço que consegui com a ajuda, a graça e pela glória de Deus! Versão: e São Carlos, 26 de novembro de 2020. ------------------------------------------------------------------------------*/ //Habilitar as bibliotecas: // I2C, Conversions, C_String e C_Math // RB0 -> SDA e RB1 -> SDL #define QMC5883_ADDRESS 0x1A #define DATA_OUTPUT_REG 0x00 // São de 0x00 a 0x05 #define STATUS_REG 0x06 #define TEMPL_OUTPUT_REG 0x07 #define TEMPH_OUTPUT_REG 0x08 #define CONTROL1_REG 0x09 #define CONTROL2_REG 0x0A #define SETRESET_REG 0x0B #define IDENTIFICATION_REG 0x0D #define botao PORTB.F2 // LCD module connections sbit LCD_RS at RE0_bit; sbit LCD_EN at RE1_bit; sbit LCD_D4 at RD0_bit; sbit LCD_D5 at RD1_bit; sbit LCD_D6 at RD2_bit; sbit LCD_D7 at RD3_bit; sbit LCD_RS_Direction at TRISE0_bit; sbit LCD_EN_Direction at TRISE1_bit; sbit LCD_D4_Direction at TRISD0_bit; sbit LCD_D5_Direction at TRISD1_bit; sbit LCD_D6_Direction at TRISD2_bit; sbit LCD_D7_Direction at TRISD3_bit; // End LCD module connections signed int tmp, tmpx, tmpy, tmpz, tmpr; char tmp1, tmp2, valor, trava, eixo, trava2, hexa; char txt[7], *hexindic = "0x00"; void QMC5883L_Inicio(void){ PORTB.F4 = 1; //Indica entrada no modo inicialização I2C1_Start(); I2C1_Wr( QMC5883_ADDRESS ); I2C1_Wr( CONTROL1_REG ); //I2C1_Wr( 0x1D ); //OSR 512, Scale Range 8 Gauss, ODR 200Hz, Continuous mode I2C1_Wr( 0x0D ); //OSR 512, Scale Range 2 Gauss, ODR 200Hz, Continuous mode I2C1_Stop(); I2C1_Start(); I2C1_Wr( QMC5883_ADDRESS ); I2C1_Wr( CONTROL2_REG ); I2C1_Wr( 0x41 ); I2C1_Stop(); PORTB.F4 = 0; //Indica entrada no modo inicialização } signed int QMC5883_Leitura(void){ PORTB.F5 = 1; //Indica entrada no modo leitura I2C1_Start(); I2C1_Wr( QMC5883_ADDRESS ); if(eixo == 3) I2C1_Wr( valor ); //Ler o valor dos registradores else I2C1_Wr( DATA_OUTPUT_REG ); I2C1_Repeated_Start(); I2C1_Wr( QMC5883_ADDRESS | 1 ); if(eixo == 3) tmpr = I2C1_Rd(0); //Ler o valor dos registradores else{ tmpx = I2C1_Rd(1); tmpx |= I2C1_Rd(1) << 8; tmpy = I2C1_Rd(1); tmpy |= I2C1_Rd(1) << 8; tmpz = I2C1_Rd(1); tmpz |= I2C1_Rd(0) << 8; } I2C1_Stop(); PORTB.F5 = 0; //Indica saída do modo leitura } char hexadec(char hexanum){ if((hexanum >> 4) < 10) hexindic[2] = (hexanum >> 4) +48; else hexindic[2] = (hexanum >> 4) +55; if((hexanum & 0x0F) < 10) hexindic[3] = (hexanum & 0x0F) +48; else hexindic[3] = (hexanum & 0x0F) +55; Lcd_Out_CP(hexindic); //Escreve hexindic depois do texto } void main() { ADCON1 = 0x0F; //desativa o canal analogico CMCON = 7; //desativa os comparadores analogicos TRISB = 0x0F; PORTB = 0x00; valor = 0; trava = 0; eixo = 0; trava2 = 0; //RBPU_bit = 0; Lcd_Init(); //inicia o display Lcd_Cmd(_LCD_CLEAR); //Limpa a tela do LCD Lcd_Cmd(_LCD_CURSOR_OFF); //Desliga o cursor piscante Delay_ms(100); Lcd_Out(1,1,"QMC5883e-Simples"); Delay_ms(500); I2C1_Init(100000); //Inicializa comunicação I2C Delay_ms(50); QMC5883L_Inicio(); //Inicializa o módulo QMC5883. Engraçado que sem... Delay_ms(50); //... inicializar pela segunda vez, às vezes falha! QMC5883L_Inicio(); //Inicializa o módulo QMC5883 novamente !!! while(1) { QMC5883_Leitura(); //Lê o módulo if(!eixo){ if(trava2){ Lcd_Out(1,1,"QMC5883e-Simples"); Lcd_Out(2,1," "); } Lcd_Out(2,5,"X:"); IntToStr(tmpx, txt); Lcd_Out_CP(txt); valor = 0; trava2 = 0; } if(eixo == 1){ Lcd_Out(2,5,"Y:"); IntToStr(tmpy, txt); Lcd_Out_CP(txt); } if(eixo == 2){ Lcd_Out(2,5,"Z:"); IntToStr(tmpz, txt); Lcd_Out_CP(txt); } if(eixo == 3){ if(!trava2) Lcd_Cmd(_LCD_CLEAR); trava2 = 1; Lcd_Out(1,3,"Reg: "); hexadec(valor); Lcd_Out(2,3,"Valor: "); hexadec(tmpr); valor++; if(valor > 0x0D) valor = 0; Delay_ms(1000); } Delay_ms(500); if(!botao && !trava){ trava = 1; eixo++; if(eixo > 3) eixo = 0; } if(botao) trava = 0; } } -
PIC PIC 18F4550 com Bússola Eletrônica HMC5883L
Mario Henrique Luchiari respondeu ao tópico de Mario Henrique Luchiari em Microcontroladores
Boa noite .if! Obrigado por suas considerações. Vamos lá... Vou postar aqui o sketch do Arduino que funciona para darmos uma olhada. Já fiz a sequência de acionamento dos registradores conforme está nela, na esperança que desse resultado. Não funcionou. É a pasta Teste_Mhl.zip em anexo. Você tem razão, ainda não enviei para o LCD na função secundária HMC5883_Leitura(), seria o próximo passo se ela não travasse naquele comando de leitura. Sim a sequência de comandos está coerente com o datasheet e com vários outros programas que encontrei nos sites, embora nenhum deles tenha funcionado. Tenho dúvidas sobre esta sequência e sobre a sequência de inicialização. Porém, estas estão iguais às que tenho visto em outros exemplos. Estou encanado com estas sequências desde o começo... Este é o código do CCS que eu estou debatendo há dias. O original envia dados pela UART, adaptei este para escrever no LCD. Segue anexo o arquivo HMC5883L-Base.zip com o código. Esperava que ele indicasse os valores dos eixos, azimute e tal. Em vez disso, ele sempre dá uma mensagem de que o sensor não foi detectado, como se o sensor não estivesse lá mas, se eu remover o sensor o programa não passa da mensagem "Inicializando...". Acredito que, de alguma forma, o sensor esteja sendo lido. A batalha continua... Um forte abraço, Mario Teste_Mhl.zip HMC5883L-Base.zip -
PIC PIC 18F4550 com Bússola Eletrônica HMC5883L
Mario Henrique Luchiari respondeu ao tópico de Mario Henrique Luchiari em Microcontroladores
Boa noite .if! Obrigado por retornar. Esse registro 0x03 é o registro de leitura dos eixos. Teoricamente é pra posicionar nele e fazer leituras consecutivas (6) para extrair os 3 eixos (6 bytes). Pegar o MSB, deslocar 8 posições e sobrepor com o LSB. Depois é só tratar isto como uma variável de 16 bits. Já olhei a biblioteca do Arduino e tentei adaptar mas, ainda não tenho conhecimento pra isso, por enquanto... Eu tenho mais experiência com PIC, fico frustrado quando algo funciona no ATMEL e não no PIC. Meu hardware está praticamente pronto, por isso gostaria muito que funcionasse. Repetir o Start é uma dica interessante, já fiz algumas tentativas neste sentido, vou tentar mais. Pode ser que a temporização esteja comprometendo a comunicação I2C e isso dê certo. O interessante é que eu coloco outros módulos como o BMP180, MPU6050 (como já disse) e funciona muito bem... Esse bandido tá me zoando e isso já tá virando ponto de vista e honra!!! Fiz a pesquisa que você citou no post anterior, até encontrei um código do CCS e estava testando até agora, é bem interessante mas ainda não deu resultado. A briga continua... Um forte abraço e mais uma vez, obrigado. -
PIC PIC 18F4550 com Bússola Eletrônica HMC5883L
Mario Henrique Luchiari respondeu ao tópico de Mario Henrique Luchiari em Microcontroladores
Olá meu caro .if! Já "googlei" até cansar... kkkk Está montado. Verifiquei as conexões, resistores pull-up, já coloquei outro módulo (no caso o MPU6050) e o hardware funcionou. Este módulo funciona no Arduino, então o módulo está operacional. Quero fazer funcionar no PIC pois estou montando um veículo autônomo que o utilizaria como referência de direção. Já testei com o Mplab, CCS e nada funcionou. Estou intrigado, quando tento fazer a leitura do registro 0x03 ele trava aí. Coloquei um led que acende na entrada da função de leitura (HMC5883_Leitura()) e apaga na saída, fiz o mesmo na função de inicialização (HMC5883L_Inicio()). O led da inicialização indica que ele entra e sai o da de leitura fica aceso. Quando comento a função I2C1_Rd a função funciona e o led apaga. Estou a pesquisar mas está difícil... Obrigado pela dica e pela atenção. Um grande abraço. -
PIC PIC 18F4550 com Bússola Eletrônica HMC5883L
Mario Henrique Luchiari postou um tópico em Microcontroladores
Olá, pessoal! Estou com problemas para conseguir ler os registradores de um módulo bússola eletrônica. Estou usando compilador Mikroc, PIC 18F4550 e o módulo HMC5883L. A comunicação é I2C mas a instrução de leitura I2C1_Rd trava o código. Não consigo descobrir se o módulo está sendo inicializado corretamente ou se apenas não estou conseguindo ler o registrador do módulo. Será que alguém pode me ajudar? Vou postar meu código anexo para darem uma olhada, é só alterar a extensão de .txt para .c. Desde já obrigado! //Habilitar as bibliotecas: // I2C, Conversions, C_String e C_Math // RB0 -> SDA e RB1 -> SDL // LCD module connections sbit LCD_RS at RE0_bit; sbit LCD_EN at RE1_bit; sbit LCD_D4 at RD0_bit; sbit LCD_D5 at RD1_bit; sbit LCD_D6 at RD2_bit; sbit LCD_D7 at RD3_bit; sbit LCD_RS_Direction at TRISE0_bit; sbit LCD_EN_Direction at TRISE1_bit; sbit LCD_D4_Direction at TRISD0_bit; sbit LCD_D5_Direction at TRISD1_bit; sbit LCD_D6_Direction at TRISD2_bit; sbit LCD_D7_Direction at TRISD3_bit; // End LCD module connections signed int tmp; void HMC5883L_Inicio(){ PORTB.F4 = 1; //Indica entrada no modo inicialização I2C1_Start(); I2C1_Wr( 0x3C ); I2C1_Wr( 0x00 ); I2C1_Wr( 32 ); I2C1_Wr( 0x00 ); //Continuo I2C1_Stop(); Delay_ms(500); PORTB.F4 = 0; //Indica saída do modo inicialização Delay_ms(500); PORTB.F4 = 0; } void HMC5883_Leitura(){ PORTB.F5 = 1; //Indica entrada no modo leitura I2C1_Start(); I2C1_Wr( 0x3C ); I2C1_Wr( 0x03 ); I2C1_Repeated_Start(); I2C1_Wr( 0x3D ); tmp = I2C1_Rd(1)<<8 | I2C1_Rd(0); I2C1_Stop(); Delay_ms(500); PORTB.F5 = 0; //Indica saída do modo leitura } void main() { ADCON1 = 0x0F; //desativa o canal analogico CMCON = 7; //desativa os comparadores analogicos Lcd_Init(); //inicia o display Lcd_Cmd(_LCD_CLEAR); //Limpa a tela do LCD Lcd_Cmd(_LCD_CURSOR_OFF); //Desliga o cursor piscante Lcd_Out(1,1,"HMC5883L-Simples"); TRISB.F4 = 0; TRISB.F5 = 0; TRISB.F6 = 0; TRISB.F7 = 0; Delay_ms(500); I2C1_Init(100000); //Inicializa o módulo I2C PORTB.F4 = 0; PORTB.F5 = 0; PORTB.F6 = 0; PORTB.F7 = 0; Delay_ms(50); HMC5883L_Inicio(); //Inicializa o módulo HMC5883 while(1) { HMC5883_Leitura(); //Lê o módulo Delay_ms(500); } } Mario hmc5883-Simples.txt
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