Se vocês perderam algum dos posts anteriores, podem acessá-los pela lista abaixo:
1- MiWi: Dispositivos e topologias de rede;
2- MiWi: Endereçamento;
3- MiWi: Relatórios de protocolo;
4- MiWi: Mensagens de Stack e Serviços
5- MiWi: Segurança
Como a biblioteca da Microchip para o MiWi foi desenvolvida recentemente, há ainda alguns bugs e também muitas atualizações. Ela é fornecida com o Microchip Application Libraries, e a última versão disponível agora, enquanto escrevo este artigo, é a versão de junho de 2011 (Stack MiWi 4.2). Quem estiver com sua versão desatualizada, é bom atualizar.
Hardware do projeto
Desenhamos o circuito do projeto no KiCad, que pode ser visto abaixo:Criamos o componente MRF24J40MA, já que o KiCad não o possui. Você poderá obter todos os datasheets relacionados a este módulo no site da Microchip.
O módulo MRF24J40MA é o módulo que fará todo o trabalho de transmissão e recepção de pacotes. Você o controla via barramento SPI. Ele na verdade é um transceiver feito pela Microchip para os protocolos ZigBee ou MiWi... Mas como um transceiver, você poderá criar qualquer protocolo de comunicação com ele. O Stack MiWi não está no módulo, mas é implementado pelas bibliotecas da Microchip.
Para você ter uma visão geral dos registradores disponíveis deste módulo, procure pelo datasheet do circuito integrado principal dele, o MRF24J40. Há ainda uma versão deste módulo de maior alcance, chamado de MRF24J40MB.
A alimentação do módulo é de 3.3V. Para simplificar o desenho acima, não incluímos a fonte. Portanto, quando você for implementar este projeto, lembre-se de incluí-la.
Incluindo os arquivos do projeto
Vamos agora ao PCAD, e vamos criar um novo projeto com PICF4550. Os arquivos que devemos incluir são os arquivos abaixo:Arquivo | Pasta |
---|---|
Console.c | \Microchip Solutions\Microchip\WirelessProtocols\ |
MSPI.c | \Microchip Solutions\Microchip\WirelessProtocols\ |
SymbolTime.c | \Microchip Solutions\Microchip\WirelessProtocols\ |
MiWi.c | \Microchip Solutions\Microchip\WirelessProtocols\MiWi\ |
MRF24J40.c | \Microchip Solutions\Microchip\Transceivers\MRF24J40\ |
MiWi.c | \Microchip Solutions\Microchip\WirelessProtocols\MiWi\ |
Os cabeçalhos relacionados com estes arquivos podem ser adicionados para facilitar a visualização. Por fim, devemos copiar três arquivos que serão necessários para o projeto: ConfigApp.h, HardwareProfile.h, SystemProfile.h. Para o projeto de um dispositivo End Device, nós vamos copiar estes arquivos do diretório Microchip Solutions\MiWi DE Demos\Node 2. Para Coordinators, devemos copiar estes arquivos do diretório Microchip Solutions\MiWi DE Demos\Node 1. São eles que conterão as configurações de rede do projeto, bem como o esquema de ligação deste projeto.
Assim que copiar estes arquivos para a pasta do projeto, inclua-os. Fazendo isto, vamos editar o arquivo HardwareProfile.h, para que ele reflita o nosso esquemático:
#ifndef _HARDWARE_PROFILE_H #define _HARDWARE_PROFILE_H #include "GenericTypeDefs.h" #include "ConfigApp.h" #include <p18cxxx.h> #define CLOCK_FREQ 48000000 #define RFIF INTCON3bits.INT2IF #define RFIE INTCON3bits.INT2IE #define PHY_CS LATCbits.LATC2 #define PHY_CS_TRIS TRISCbits.TRISC2 #define RF_INT_PIN PORTBbits.RB2 #define RF_INT_TRIS TRISBbits.TRISB2 #define SPI_SDI PORTBbits.RB0 #define SDI_TRIS TRISBbits.TRISB0 #define SPI_SDO LATCbits.LATC7 #define SDO_TRIS TRISCbits.TRISC7 #define SPI_SCK LATBbits.LATB1 #define SCK_TRIS TRICBbits.TRISB1 #define PHY_RESETn LATCbits.LATC0 #define PHY_RESETn_TRIS TRISCbits.TRISC0 #define PHY_WAKE LATCbits.LATC1 #define PHY_WAKE_TRIS TRISCbits.TRISC1 #define LED_1 PORTEbits.RE0 #define LED_1_TRIS TRISEbits.TRISE0 #define LED_2 PORTEbits.RE1 #define LED_2_TRIS TRISEbits.TRISE1 #define LED_3 PORTEbits.RE2 #define LED_3_TRIS TRISEbits.TRISE2 #define TMRL TMR0L #define TOOGLE(c) c = ~c #endifAqui nós definimos todas as ligações feitas com o módulo MRF24J40MA. Se alguma destas definições faltar, o compilador gerará erros. O clock e o registrador do timer usado também devem ser definidos aqui, para que o Stack MiWi possa fazer as temporizações corretamente. Portanto, você não poderá usar este timer.
Configurando o projeto
A configuração do projeto é feita no arquivo ConfigApp.h. Veja quais opções você poderá selecionar neste arquivo:Configuração | Descrição |
---|---|
ENABLE_CONSOLE | Habilita a impressão de mensagens pela serial do microcontrolador. Comente esta definição, para desabilitá-la. |
SIMPLE_EXAMPLE | Desabilita todas as funções mais avançadas do Stack. Insira esta definição no projeto, para habilitá-la. |
ENABLE_NETWORK_FREEZER | Grava todos os dados mais importantes de uma conexão em memória não volátil, para rápido restabelecimento da rede. É necessário ter esta memória no projeto. |
HARDWARE_SPI | Utiliza o módulo SPI nativo do microcontrolador para comunicação. Comentando-se esta definição, o Stack tentará emular uma SPI. Recomendável usar o SPI nativo. |
PROTOCOL_P2P | Habilita a rede P2P. Não pode ser definido juntamente com PROTOCOL_MIWI |
PROTOCOL_MIWI | Habilita a rede MiWi Mesh. Não pode ser definido juntamente com PROTOCOL_P2P |
NWK_ROLE_COORDINATOR | Define o dispositivo como Coordinator. Não pode ser definido juntamente com NWK_ROLE_END_DEVICE. |
NWK_ROLE_END_DEVICE | Define o dispositivo como End Device. Não pode ser definido juntamente com NWK_ROLE_COORDINATOR. |
MRF24J40 | Define que o módulo MRF24J40MA de 2.4GHz será usado. Não pode ser definido junto com outros transceivers. |
MRF49XA | Define que o módulo subGHz MRF49XA da Microchip será usado. Não pode ser definido junto com outros transceivers. |
MRF89XA | Define que o módulo subGHz MRF89XA da Microchip será usado. Não pode ser definido junto com outros transceivers. |
MY_ADDRESS_LENGTH | Define o tamanho do endereço permanente do nó, em bytes. |
EUI_0 - EUI_7 | Esta é a definição do endereço EUI do módulo. Cada dígito é um byte do endereço. |
TX_BUFFER_SIZE | Define o tamanho do buffer de transmissão. |
RX_BUFFER_SIZE | Define o tamanho do buffer de recepção. |
MY_PAN_ID | Define o PANID do dispositivo. |
ADDITIONAL_NODE_ID_SIZE | Define o tamanho dos dados adicionais que serão anexados à requisição P2P. Estas são informações que os dispositivos querem compartilhar com outros pontos na conexão. Estes dados serão definidos pela aplicação. |
CONNECTION_SIZE | Define o máximo de conexões P2P que este dispositivo permite ao mesmo tempo. |
TARGET_SMALL | Remove algumas funcionalidades para diminuir o código gerado. |
ENABLE_PA_LNA | Habilita o amplificador de potência em transceivers que o possuem. |
ENABLE_HAND_SHAKE | Habilita o hand-shake antes da comunicação. Sem isto, os transceivers RF só poderão fazer broadcast, ou possuir o endereço de destino programado no firmware para comunicação com um dispositivo. |
ENABLE_SLEEP | Permite que o dispositivo vá para o modo sleep e volte dele. |
ENABLE_ED_SCAN | Habilita a detecção de energia, para descobrir qual o canal que possui menos ruído. |
ENABLE_ACTIVE_SCAN | Habilita o Active Scan, para detectar as conexões atualmente existentes. |
ENABLE_SECURITY | Habilita a encriptação de dados na transmissão. |
ENABLE_INDIRECT_MESSAGE | Fará com que o dispositivo guarde mensagens para dispositivos que estão em modo sleep, até que eles retornem ao funcionamento normal. |
ENABLE_BROADCAST | Fará com que o dispositivo envie broadcasts aos dispositivos em modo sleep, até que eles retornem ao funcionamento normal. |
RFD_WAKEUP_INTERVAL | Define o intervalo de wakeup para dispositivos RFD em segundos. Esta definição no entanto não é utilizada pelos dispositivos RFD, mas pelos dispositivos FFD, para calcular seus vários timeouts. |
ENABLE_FREQUENCY_AGILITY | Faz com que o dispositivo possa mudar de canal, quando houver uma súbita mudança no ruído. |
Arquivo principal do projeto
No arquivo principal, você precisará definir algumas coisas também. Vamos ao esqueleto básico deste arquivo:#include <stdio.h> #include "GenericTypeDefs.h" #include "Compiler.h" #include "WirelessProtocols/MSPI.h" #include "WirelessProtocols/MCHP_API.h" #include "HardwareProfile.h" #if ADDITIONAL_NODE_ID_SIZE > 0 BYTE AdditionalNodeID[ADDITIONAL_NODE_ID_SIZE] = {0x01}; #endif BYTE myChannel = 11; #pragma config FOSC=HSPLL_HS #pragma config CPUDIV=OSC1_PLL2 #pragma config PLLDIV=5 #pragma config USBDIV=2 #pragma config CCP2MX=ON #pragma config WDT=OFF #pragma config WDTPS=32768 #pragma config MCLRE=ON #pragma config LVP=OFF #pragma config VREGEN=ON #pragma config IESO=OFF #pragma config PWRT=ON #pragma config BOR=OFF #pragma config CP0=OFF #pragma config CP1=OFF #pragma config CP2=OFF #pragma config CP3=OFF #pragma config CPB=OFF #pragma config CPD=OFF #pragma config WRT0=OFF #pragma config WRT1=OFF #pragma config WRT2=OFF #pragma config WRT3=OFF #pragma config WRTB=OFF #pragma config WRTC=OFF #pragma config WRTD=OFF #pragma config EBTR0=OFF #pragma config EBTR1=OFF #pragma config EBTR2=OFF #pragma config EBTR3=OFF #pragma config EBTRB=OFF #pragma config DEBUG=ON #pragma config XINST=ON void UserInterruptHandler(void) { } void main(void) { BYTE i=0xFF; RCON = 0x80; // Habilita prioridades para interrupções ADCON0 = 0x00; ADCON1 = 0x0F; // PORTA só como entradas e saídas digitais. CMCON = 0x07; // Comparadores desligados. TRISA = 0xFF; TRISB = 0x05; TRISC = 0x00; PORTC = 0x06; TRISD = 0x00; PORTD = 0x00; TRISE = 0x07; PORTE = 0xFF; INTCON = 0x00; INTCON2 = 0x00; INTCON3 = 0x00; // Configura o módulo SPI SSPSTAT = 0xC0; SSPCON1 = 0x20; INTCONbits.GIEH = 1; RFIF = 0; // Limpa o interrupt flag do chip. RFIE = 1; INTCON2bits.INTEDG2 = 0; MiApp_ProtocolInit(FALSE); if(MiApp_SetChannel(myChannel) == FALSE) { return; } MiApp_ConnectionMode(ENABLE_ALL_CONN); while((i = MiApp_EstablishConnection(0xFF, CONN_MODE_DIRECT)) == 0xFF); #ifdef ENABLE_DUMP DumpConnection(0xFF); #endif LED_2 = 1; for(;;) { if(MiApp_MessageAvailable()) { // Aqui tratamos a mensagem recebida. MiApp_DiscardMessage(); } } }O código acima é de um arquivo prinpipal para o projeto de dispositivo End Device. A diferença entre o End Device e o Coordinator é apenas a função main. Duas definições devem ser feitas no arquivo principal. A primeira é a definição da variável AdditionalNodeID, conforme pode ser visto acima. Os arquivos do Stack MiWi usam esta variável, portanto é necessário pelo menos definí-la. A segunda definição é a da função UserInterruptHandler. Esta função é chamada depois que a interrupção do MiWi for executada, e precisa também ser declarada, mesmo que nada seja feito ali.
Além destas declarações, você deverá ainda configurar o módulo SPI e habilitar a interrupção que você definiu para o módulo MRF24J40MA (o Stack não faz isto como acontece em outras bibliotecas Microchip). Feito isto, seu projeto está pronto para funcionar.
As diferenças existentes neste arquivo acima, para o projeto do Coordinator são poucas. Compare com o código abaixo (do Coordinator):
MiApp_ProtocolInit(FALSE); if(MiApp_SetChannel(myChannel) == FALSE) { return; } MiApp_ConnectionMode(ENABLE_ALL_CONN); MiApp_StartConnection(START_CONN_DIRECT, 10, 0); #ifdef ENABLE_DUMP DumpConnection(0xFF); #endif LED_2 = 1; for(;;) { if(MiApp_MessageAvailable()) { MiApp_DiscardMessage(); } }Pode-se observar que o End Device usa a função MiApp_EstablishConnection, enquanto o Coordinator usa a função MiApp_StartConnection. Esta função inicializa a rede MiWi, e somente com uma rede estabelecida, é que os dispositivos End Device podem estabelecer conexões.
Gustavo, tem alguma limitação que impeça este projeto de trabalhar com o pic 18f2550?
ResponderExcluirBem, não existe, pois a única limitação que poderia existir é limitações de memória. Neste ponto, a memória do PIC18F4550 é igual à do PIC18F2550.
ResponderExcluirGustavo fiz todo o passo a passo, aparentemente tudo certo, mas o mplab ta me dando erro "syntax error", no arquivo hardware profile.h, o que posso ter feito errado? casso seja possivel me manda um email para que eu possa entrar em contato com você. dayvsonleandro@gmail.com , obrigado pela atenção.
ResponderExcluirNós temos que ver o motivo que o MPLAB dá para o erro... Além do "syntax error", o que mais ele avisa?
ResponderExcluirOlá, Tenho alguns modulos MRF24J40MA para ultilizar em um sistema de comunicação de fultebol de robôs, Categoria Small-Size. Estou com bastante dificuldades em implementar o protocolo ZigBee, Vc está me ajudando muito, e agora vou tentar implementar o miwi. Vou usar o computador via USB como PAN coordinator e os robos seram End devices q só recebem os dados.
ResponderExcluirO protocolo Miwi Pelo visto é bem mais facil de ser implementado, possuo algumas duvidas ainda e tbm como fazer uma interface dos dados via USB para o MRF24J40MA.
Se puder me ajudar mais um pouco ficaria muito agradecido.
meu e-mail: victorcastro89@hotmail.com
Obrigado
Olá. Tenho 2 módulos MRF24J40MB. Você poderia me enviar os aquivos do projeto en C que descreve neste post? Meu endereço de e-mail:
ResponderExcluircarlos-seoane@hotmail.es Regards. Obrigado.
AMIGO GOSTEI DO SITE, ESTOU COMEÇANDO A USAR O ZIGBEE E COMPREI UMA PLACA DA MICROCHIP COM ESSE QUE VOCÊ ESTA DEMOSTRANDO, COMPREI A PLACA COM O PIC18F4520 GOSTARIA QUE VOCÊ PUDESSE ME ENVIAR ALGUNS PROGRAMAS EXEMPLOS DE CONFIGURAÇÃO DESSE ZIGBEE, NO CASO DE VOCÊ TIVER ALGUMA SUGESTÃO.
ResponderExcluirvicksonricarte@hotmail.com
Olá, no datasheet diz que este módulo pode ser usado também com a família 16f, você já utilizou na 16f? Tem algum exemplo no 16f?
ResponderExcluirOlá, Oséias.
ResponderExcluirPeço perdão pelo atraso na resposta... Provavelmente você poderá sim usar este módulo com o PIC16F, mas eu não cheguei a tentar usá-lo. É necessário ver se as bibliotecas da Microchip cabem na memória de código desta família, do contrário, será necessário codificar as próprias rotinas de MiWi para o módulo.
Viva, parabéns pelo blog.
ResponderExcluirTenho tentado há algum tempo utilizar o 4550/2550 por causa do USB, mas nem com este tutorial eu consegui. Ele não estabelece ligação.
Eu resolvi este problema utilizando 2 PICs, 1 para comunicar com a antena e outro com o USB e de seguida comunico por USART entre os dois. Isto funciona e já tenho uma pequena aplicação no computador a funcionar.
Se me pudesse ajudar a perceber porque não consigo colocar o 4550 a funcionar agradecia. Eu fui colocando o LED_1 = 1; e verifiquei que ele fica retido aqui: while( (i = MiApp_EstablishConnection(0xFF, CONN_MODE_DIRECT)) == 0xFF );
Tenho esta comunicação a funcionar com o 18LF2431, 4620 e 26k20.
Obrigado.
Olá Gustavo, estou iniciando o estudo sobre o miwi, porém tentei seguir todos os seus passos e não consigo fazer a comunicação, você pode me ajudar? Se preferir pode entrar em contado pelo meu e-mail (andre.luiz.p.ferreira@gmail.com). Grato
ResponderExcluirOlá para todos e desde já, perdão pela demora em responder.
ResponderExcluirEmbora eu tenha colocado a documentação acima e até tenha conseguido me comunicar, detectei algo muito errado nas bibliotecas fornecidas pela Microchip para o uso do MiWi. Provavelmente será necessário reescrever o código, pois pelo menos comigo, a comunicação é intermitente. Investiguei por um bom tempo e não consegui achar os motivos. Por falta de tempo não pude prosseguir com os testes. Assim que puder testar mais e descobrir qualquer falha, eu estarei atualizando este post.
Abraços.