Iniciando com CC3000: Seu microcontrolador com Wi-Fi - Parte 2

Iniciando com CC3000
Este post faz parte da série Iniciando com CC3000. Leia também os outros posts da série:

Na primeira parte dessa série, eu dei uma breve explicação sobre o CC3000 e destaquei algumas de suas principais características. Nesta segunda parte, vou dar um pequeno tutorial introdutório de como fazer um projeto bem simples utilizando o CC3000.

 

Ferramentas Necessárias

 

Apesar de existirem diversas Launch Pads da Texas Instruments, eu optei por utilizar a tradicional LaunchPad da Value Line do MSP430. Além de ser a LaunchPad menos custosa, serve para provar o conceito que é possível implementar uma comunicação Wi-Fi com placas com pouquíssimos recursos e microcontroladores de baixo custo. 

 

Como hardware, será necessário para implementar este projeto:

  • Uma LaunchPad com um MSP430G2553;
  • Um Boosterpack do CC3000;
  • Um roteador Wi-Fi;
  • Um computador com conexão Wi-FI.

 

Como software será necessário:

 

ATENÇÃO: Abaixo você pode fazer download de um .zip contendo o projeto do Code Compoder 5, o Hercules SETUP utility, o Java Smart Config desktop client e o patch 1.11.1 do CC3000.

 

Pack_Tutorial_CC3000

 

Descrição do Projeto

 

Conceitualmente, o projeto que vamos implementar é basicamente um termômetro Wi-Fi, com apenas um botão de interface, e nada mais. Basicamente, o termômetro vai se conectar à uma rede Wi-Fi e começar a fazer broadcast do valor da temperatura medido através de um Socket UDP em uma porta específica (no caso foi escolhida a porta 4444). O computador que estiver interessado na informação do sensor deve monitorar pacotes UDP na porta em questão. De forma a poder passar as informações para o sensor de que rede ele deve se conectar, deve-se segurar o botão por pelo menos 5 segundos para o mesmo começar o procedimento do SmartConfig. 

 

thermometer_project

 

Tendo definido o projeto conceitualmente, podemos, então, organizar como é lógica interna que rege o termômetro. Ela pode ser representada por uma máquina de estados simplificada, como abaixo.

 

FSM_WifiThermometer

 

Após alimentado, o termômetro realiza todas as rotinas de inicialização internas e tenta se conectar à alguma rede pré-configurada. Caso nenhuma rede ainda tenha sido configurada, o mesmo vai ficar tentando se conectar, porém não vai conseguir. Depois de conseguir se conectar à rede, ele abre o Socket UDP com o IP xxx.xxx.xxx.255, que normalmente é utilizado para broadcast. Com o Socket aberto, ele começa a enviar o valor da temperatura amostrado a cada 5 segundos. Depois da inicialização, o procedimento do SmartConfig pode ser utilizado em qualquer um dos estados. Depois de realizado o SmartConfig o termômetro deve tentar se conectar na rede configurada.

 

Descrição do Firmware

 

Para não lotar o projeto de arquivos de código fonte eu já estou distribuindo o projeto com as bibliotecas CC3000HostDriver e CC3000 Spi pré-compiladas. Os códigos das bibliotecas são distribuídos pela Texas. Se você tiver interesse em portar o código para outra plataforma, vai ter modificar apenas o CC3000 Spi, porém obviamente recompilar todos os códigos.

 

O código está razoavelmente comentado, porém irei dar uma breve descrição sobre a estrutura do mesmo. Eu tenho o costume de separar o acesso específico de hardware em arquivos separados, no caso identificados por HAL. Isto simplifica o processo de portabilidade para outras plataformas. Não vou entrar em detalhes sobre a configuração do hardware do MSP430G2553. Os três periféricos que merecerem algum destaque no caso são a SPI, o ADC e o Timer A1. O SPI foi inicializado com as rotinas da biblioteca CC3000. O Timer A1 foi configurado para gerar uma interrupção a cada ~500ms e o ADC foi configurado para fazer a leitura do sensor de temperatura interno do MSP430.

 

Na função main (corpo do programa) incialmente é realizada a inicialização do Watchdog (muito importante no caso do MSP430), é assinalado qual será o callback da interrupção do Timer A, configura todo o hardware do MSP430, roda a função de inicialização do servidor e finalmente habilita as interrupções. No loop principal do programa é processada a função UServer_asyncProcess, que basicamente cuida dos processos assíncronos (ao timer) da comunicação do servidor.

 

void main (void)
{
	/*
	 * Inicializa o WatchDog Timer
	 */
	HAL_wdInit();

	/*
	 * Assinala qual será a função de callback do ISR to Timer
	 */
	timer0.cb = Timer0_cb;

	/*
	 * Configura o Hardware
	 */
	HAL_hardwareConfig();

	/*
	 * Inicializar o Servidor
	 */
	UServer_init();

	/*
	 * Habilita Interrupções Globais
	 */
	HAL_enableInterrupts();
    for(;;)
    {
    	/*
    	 * Processa a rotina assícrona do servidor
    	 */
    	UServer_asyncProcess();
    }
}

 

Dentro do callback do ISR do timer, temos basicamente um monitor do botão da placa, que gera um request para o processo do SmartConfig se o mesmo for pressionado por mais de 5 segundos. Fora isso temos a rotina UServer_syncProcess, que cuida dos processos síncronos (ao timer) do CC3000. 

 

static uint8_t Timer0_cb(void)
{
	/*
	 * Aqui é verificado se o botão está apertado.
	 * Se estiver, é inicializada uma contagem decrescente.
	 * Se o botão for segurado por pelo menos 5 segundos,
	 * é requisitado ao servidor realizar o SmartConfig.
	 * A rotina só começa o SmartConfig quando o botão é solto.
	 */
	static uint8_t swPressedCntr = 10;
	if(sw.read())
	{
		if(!swPressedCntr)
		{
			UServer_requestSmartConfig();
		}
		swPressedCntr = 10;
	}
	else
	{
		if(swPressedCntr)
			swPressedCntr--;
	}
	/*
	 * Processa a rotinas sícrona do servidor a cada 500ms
	 */
	UServer_syncProcess();

	return(0);
}

 

Com a função main e o callback to timer, temos basicamente o esqueleto de funcionamento do programa. Agora entramos nas rotinas específicas ao servidor, que lidam com o CC3000. Dentro da rotina de inicialização do servidor acontece a configuração incial do módulo CC3000 e do CC3000HostDriver. Primeiro sempre temos que chamar a função wlan_init, que passa para o CC3000HostDriver qual será a função de callback de eventos assíncronos do CC3000, e algumas rotinas de acesso ao hardware do seu microcontrolador. O nome das rotinas é bem autoexplicativo, porém as funcionalidades que precisam ser passadas são para ler o pino de interrupção do CC3000, habilitar e desabilitar a interrupção referente a este mesmo pino e uma função para controlar o pino que habilita e desabilita o CC3000.É importante ressaltar que, apesar de essas rotinas estarem implementadas no HAL, eu não nomeei as mesmas corretamente de forma a manter compatibilidade com os exemplos fornecidos pela Texas Instruments (que utilizam os mesmos nomes para tais funções).

 

Depois de configurado o CC3000HostDriver, temos que chamar a rotina wlan_start, que propriamente implementa toda a  pré-inicialização do CC3000. Posteriormente temos que chamar a função wlan_set_event_mask, que configura quais serão os eventos do CC3000 que serão "mascarados' ou seja, ou seja, não irão gerar eventos para a nossa aplicação. Para finalizar é feita a configuração da rede com a função netapp_dhcp. Como vamos utilizar IP dinâmico, temos que passar o IP, Default Gateway, endereço DNS como zero. O único que é especificado no caso é a máscara de rede configurada como 255.255.255.0 (filtrar pelos bytes 3 bytes mais significativos).

 

void UServer_init(void)
{
	/*
	 * Inicializa as flags de controle de estado
	 */
	g_CC3000DHCP = 0;
	g_CC3000Connected = 0;
	g_Socket = 0;
	g_SmartConfigFinished=0;

	/*
	 * Inicializa o Driver do CC3000
	 */
	wlan_init( 	UServer_cc3000UsynchCallback,
				0,
				0,
				0,
				ReadWlanInterruptPin,
				WlanInterruptEnable,
				WlanInterruptDisable,
				WriteWlanPin);

	/*
	 * Inicializa o CC3000
	 */
	wlan_start(0);

	/*
	 * Configura quais eventos não serão necessários
	 */
	wlan_set_event_mask(HCI_EVNT_WLAN_KEEPALIVE|HCI_EVNT_WLAN_UNSOL_INIT|HCI_EVNT_WLAN_ASYNC_PING_REPORT);

	/*
	 * Configura IP, Subnet Mask e Gateway
	 * Para IP Dinâmico devemos configurar Gateway e IP como 0.0.0.0
	 */
	netapp_dhcp((unsigned long *)g_IP_Addr, (unsigned long *)g_SubnetMask, (unsigned long *)g_IP_DefaultGWAddr, (unsigned long *)g_DNS);
}

 

 A biblioteca CC3000HostDriver precisa que a aplicação do usuário forneça um callback de eventos do CC3000, no caso implementado na função UServer_cc3000USynchCallback. Quando um evento (que não mascaramos durante a inicialização) ocorrer, esta função vai ser chamada com três argumentos: o tipo do evento, um ponteiro para os dados relacionados ao evento e o comprimento destes dados. No caso implementamos um switch/case básico para lidar com os diferentes tipos de eventos.

 

Quando o evento HCI_EVNT_WLAN_SIMPLE_CONFIG_DONE é gerado, quer dizer que o procedimento do SmartConfig foi finalizado, logo mudamos o valor da flag g_SmartConfigFinished para 1.

 

Quando o evento HCI_EVNT_USOL_CONNECT é gerado, quer dizer que o CC3000 se conectou à alguma rede. Logo, neste caso modificamos a flag g_CC3000Connected para 1.

 

Quando o evento HCI_EVNT_USOL_DISCONNECT é gerado, quer dizer que o CC3000 se desconectou da conexão com a qual ele estava conectado. Este evento pode ser gerado tanto por uma desconexão voluntária, tanto por uma desconexão involuntária (e.g. perda de sinal). Neste caso modificamos as flag g_CC3000Connected e g_CC3000DHCP para 0.

 

E para finalizar, temos o evento HCI_EVNT_USOL_DHCP, que é gerado quando o IP dinãmico é assinalado ao CC3000 com sucesso. Neste caso neste caso modificamos a flag g_CC3000DHCP para 1 e armazenamos o IP em questão na variável g_IP_Addr.

 

static void UServer_cc3000UsynchCallback(long lEventType, char * data, unsigned char length)
{
	switch(lEventType)
	{
	/*
	 * Evento gerado quando o SmartConfig é finalizado
	 */
	case HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE:
		g_SmartConfigFinished = 1;
		break;

	/*
	 * Evento gerado quando o CC3000 consegue se conectar à uma WAN
	 */
	case HCI_EVNT_WLAN_UNSOL_CONNECT:
		g_CC3000Connected = 1;
		break;

	/*
	 * Evento gerado quando o CC3000 é desconectado de uma WAN
	 */
	case HCI_EVNT_WLAN_UNSOL_DISCONNECT:
        g_CC3000Connected = 0;
        g_CC3000DHCP      = 0;
		break;

	/*
	 * Evento gerado quando um IP dinâmico é gerado com sucesso.
	 */
	case HCI_EVNT_WLAN_UNSOL_DHCP:
		/*
		 * Seta a flag informando que o DHCP foi finalizado
		 */
		g_CC3000DHCP = 1;
		/*
		 * Salva o número do IP
		 */
		g_IP_Addr[3] = data[0];
		g_IP_Addr[2] = data[1];
		g_IP_Addr[1] = data[2];
		g_IP_Addr[0] = data[3];
		break;
	default:
		break;
	}
}

 

A função UServer_syncProcess implementa as chamadas síncronas ao timer do servidor. No caso ela implementa um contador para gerar um pedido de envio de temperatura.

 

void UServer_syncProcess(void)
{
	static uint8_t sendTemperatureCntr = TEMPERATURE_BROADCAST_PERIOD;
	sendTemperatureCntr--;
	if(!sendTemperatureCntr)
	{
		sendTemperatureCntr = TEMPERATURE_BROADCAST_PERIOD;
		UServer_requestSendTemperature();
	}
}

 

A função Userver_startSmartConfig é utilizada para inicializar o procedimento do SmartConfig. Nela basicamente passamos qual será o prefixo utilizado nas comunicações do SmartConfig (sempre TTT) e chamamos a função que inicializar o processo propriamente dito.

 

static void UServer_startSmartConfig(void)
{

	/*
	 * Informa o prefixo utilizado pelo SmartConfig
	 */
	wlan_smart_config_set_prefix((char*)g_CC3000_prefix);

	/*
	 * Inicializa o SmartConfig
	 */
	wlan_smart_config_start(0);
}

 

Para finalizar, a função UServer_asyncProcess implementa a lógica básica do nosso servidor a ser processada ciclicamente, incluindo a máquina de estados projetada. Basicamente inicialmente executamos a função hci_unsolicited_event_handler para eventos do CC3000 pendentes. Depois verificamos se há alguma solicitação de efetuar o procedimento do SmartConfig feita pelo usuário. Se sim, verifica se o procedimento já está sendo executado e se estiver ignora a requisição. Caso não esteja sendo executado, configura a politica de conexão para não se auto-conectar por hora, deleta as redes armazenadas para garantir que o CC3000 sempre ira se conectar na rede desejada (no caso esse passo é dependente da aplicação) e muda o estado do sistema para pre-inicialização do SmartConfig. Depois do processamento das requisições do SmartConfig, temos a máquina de estados do sistema.

 

No estado USERVER_CONNECTING o servidor está tentando se conectar a alguma rede, logo as variáveis g_CC3000DHCP e g_CC3000Connected são monitoradas para avaliar quando isto acontecer. No caso de uma conexão bem sucedida,  informamos o dispositivo que está realizando o SmartConfig que houve sucesso na conexão através da função mDNSAdvertiser. A função recebe como argumento algum string que queira ser informado, e no caso é o nome do nosso dispositivo "Termometro Wi-Fi". Em seguida, seguimos nossa máquina de estados descrita anteriormente e mudamos para o estado USERVER_OPEN_SOCKET.

 

No estado USERVER_PRE_SMART_CONFIG o servidor espera o CC3000 se desconectar de alguma possível rede que ele estivesse conectado. Quando isto acontece, a função UServer_startSmartConfig é chamada e a máquina de estados muda para o estado USERVER_SMART_CONFIG.

 

No estado USERVER_SMART_CONFIG o servidor monitora a variável g_SmartConfigFinished para avaliar quando o procedimento do SmartConfig finalizou. Quando isto acontece, a função wlan_ioctl_set_connection_policy é chamada configurando o CC3000 para utilizar uma rede armazenada e se conectar na útima rede previamente conectada, se disponível. Depois desta configuração o CC3000 é reinicializado, chamando a função wlan_stop, fazendo um delay de alguns microsegundos e reiniciando o o CC3000 chamando a função wlan_start. No caso foi utilizado um delay gastando ciclos do processador. Esta prática não é recomendada pois basicamente bloqueia o processamento do seu sistema. Além disso foi utilizado um valor muito mair de tempo do que o necessário. Isto foi feito para simplificar a visualização do led na placa piscando com o CC3000 é resetado. Depois disso, novamente configuramos a máscara de eventos que não queremos ser informados com a função wlan_set_event_mask. Para finalizar o estado do servidor é modificado para USERVER_CONNECTING, esperando o CC3000 se conectar na rede configurada.

 

No estado USERVER_OPEN_SOCKET o servidor abre um Socket UDP chamando a função socket, e armazena um identificador do mesmo na variável g_Socket. Caso a função socket retorne um valor negativo, quer dizer que não houve sucesso na abertura do Socket por um erro de conexão. Caso o Socket tenha sido aberto com sucesso, o servidor muda para o estado USERVER_CONNECTED. Por redundância, é verificado se o servidor continua conectado, e caso negativo o mesmo volta para o estado USERVER_CONNECTING.

 

No estado USERVER_CONNECTED o servidor fica ciclicamente enviando um string com o valor da temperatura interna do MSP430 lida. Para tal é utilizada um estrutura de dados do tipo sockaddr, que armazena no campo sa_data a porta e o IP a serem endereçados. No caso estamos configurando com a porta 4444 e o IP xxx.xxx.xxx.255, que é o IP de broadcast da maior parte das redes. Os campos com xxx são configurados de acordo com o IP assinalado ao CC3000 pelo DHCP. Com a função sendto, a mensagem é enviada pelo Socket previamente aberto. Caso a função retorne um valor negativo, significa um erro de conexão do Socket e o mesmo tem que ser reaberto, logo  fechamos o Socket e mudamos par ao estado USERVER_OPEN_SOCKET.

 

void UServer_asyncProcess(void)
{
	static userver_state_e uServer_state = USERVER_CONNECTING;
	sockaddr socketAddr;
	char sendData[10];
	int32_t temperature;
	long dataLenght;

	/*
	 * Gerencia eventos do CC3000 pendentes
	 */
	hci_unsolicited_event_handler();

	/*
	 * Verifica se o SmartConfig foi solicitado
	 */
	HAL_disableInterrupts();
	if(g_RequestSmartConfig)
	{
		g_RequestSmartConfig = 0;
		HAL_enableInterrupts();

		/*
		 * Verifica se o SmartConfig já não está sendo executado
		 */
		if(uServer_state != USERVER_SMART_CONFIG && uServer_state != USERVER_PRE_SMART_CONFIG)
		{
			/*
			 * Coloca o valor das flags como zero.
			 */
		    g_SmartConfigFinished = 0;
		    g_CC3000DHCP = 0;

		    /*
		     * Configura política de conexão para não se auto-conectar
		     */
			wlan_ioctl_set_connection_policy(0, 0, 0);

		    /*
		     * Deleta todos os profiles armazenados para garantir que o servidor sempre
		     * irá se conectar na rede especificada
		     */
			wlan_ioctl_del_profile(255);

			uServer_state = USERVER_PRE_SMART_CONFIG;
		}
	}
	HAL_enableInterrupts();

	switch(uServer_state)
	{
	case USERVER_CONNECTING:
		/*
		 * Espera até o CC3000 se conectar e o DHCP ser finalizado
		 */
		if(g_CC3000DHCP && g_CC3000Connected)
		{
			mdnsAdvertiser(1,g_DeviceName,strlen(g_DeviceName));
			mdnsAdvertiser(1,g_DeviceName,strlen(g_DeviceName));
			mdnsAdvertiser(1,g_DeviceName,strlen(g_DeviceName));

			uServer_state = USERVER_OPEN_SOCKET;
		}
		break;
	case USERVER_PRE_SMART_CONFIG:
		/*
		 * Espera até o C3000 ser desconectado e então inicializa
		 * o SmartConfig.
		 */
		if(!g_CC3000Connected)
		{
			UServer_startSmartConfig();
			uServer_state = USERVER_SMART_CONFIG;
		}
		break;
	case USERVER_SMART_CONFIG:
		/*
		 * Espera até o SmartConfig ser finalizado.
		 */
		if(g_SmartConfigFinished == 1)
		{
			/*
			 * Configura a politica de conexão do CC3000 para utilizar
			 * um profile armazenado e se conectar na última rede conectada,
			 * se disponível
			 */
		    wlan_ioctl_set_connection_policy(0, 1, 1);

		    /*
		     * Reseta o CC3000
		     */
		    wlan_stop();


		    HAL_delayCycles(6000000);

		    /*
		     *  Inicializa o CC3000
		     */
		    wlan_start(0);

		    /*
		     *  Desabilita os eventos que não estamos interessados
		     */
		    wlan_set_event_mask(HCI_EVNT_WLAN_KEEPALIVE|HCI_EVNT_WLAN_UNSOL_INIT|HCI_EVNT_WLAN_ASYNC_PING_REPORT);


		    uServer_state = USERVER_CONNECTING;
		}
		break;
	case USERVER_OPEN_SOCKET:
		/*
		 * Abre um socket UDP
		 */
		g_Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
		if(g_Socket > -1)
		{
			uServer_state = USERVER_CONNECTED;
		}
		/*
		 * Verifica se o CC3000 ainda está conectado na WAN
		 */
		if(!g_CC3000DHCP || !g_CC3000Connected)
		{
			uServer_state = USERVER_CONNECTING;
			break;
		}
		break;
	case USERVER_CONNECTED:
		/*
		 * Verifica se o CC3000 ainda está conectado na WAN
		 */
		if(!g_CC3000DHCP || !g_CC3000Connected)
		{
			uServer_state = USERVER_CONNECTING;
			break;
		}
		/*
		 * Se for requisitado enviar a temperatura, é realizada a
		 * leitura. Depois transformamos o valor em um string e
		 * enviamos pelo socket UDP.
		 */
		if(g_RequestSendTemperature)
		{
			int ret;
			g_RequestSendTemperature = 0;
			temperature = HAL_readTemperatureCelcius();
			dataLenght = itoa(temperature, sendData);
			sendData[dataLenght-1] = '\n';
			/*
			 * Configura o socket para a porta 4444 e para realizar broadcast
			 */
			socketAddr.sa_family = AF_INET;
			socketAddr.sa_data[0] = 0x11;
			socketAddr.sa_data[1] = 0x5c;
			socketAddr.sa_data[2] = g_IP_Addr[0];
			socketAddr.sa_data[3] = g_IP_Addr[1];
			socketAddr.sa_data[4] = g_IP_Addr[2];
			socketAddr.sa_data[5] = 0xFF;
			ret = sendto(g_Socket, sendData, dataLenght, 0, &socketAddr, sizeof(sockaddr));
			if(ret < 0)
			{
				closesocket(g_Socket);
				uServer_state = USERVER_OPEN_SOCKET;
			}
		}
		break;
	default: uServer_state = USERVER_CONNECTING;
		break;
	}
}

 

 

Colocando para Funcionar

 

Eu recomendo fortemente atualizar a versão do firmware do CC3000. Para tal, conecte o CC3000 na Launchpad e entre na pasta PatchProgrammer\MSP flashing tools\MSP430Flasher_1.1.3.

 

Clique em download_cc3000_patch_programmer_driver.bat e espere o procedimento terminar. Clique em download_cc3000_patch_programmer_firmware.bat e espere o procedimento terminar.

 

Se você não tem prática em como criar um projeto no Code Composer Studio, você pode utilizar o projeto pronto, distribuído neste tópico. Basta selecionar a pasta workspace quando for pedido o workspace, e o projeto já estará pronto para uso. Caso ainda não o tenha feito, conecte o booster pack do CC3000 na LaunchPad e conecte a mesma no computador via porta USB. No CCS clique em debug e espere o firmware ser gravado na placa. Quando o procedimento estiver finalizado, clique em run

 

No pacote de arquivos, abra a pasta Java Smart Config desktop client\net.betaengine.smartconfig-2013-10-03. Dentro dela clique em repackage.jar. Depois de finalizado clique em net.betaengine.smartconfig-ui.jar. Vai abrir uma janela igual à da figura abaixo.

 

 

CC3000SmartConfigSetup

 

 

Em tese o Network Name e o Gateway Adress já devem vir preenchidos. Caso não seja o caso, preencha com os dados de sua rede. Preencha também o Password (se houver) e mude o Device Name para Termometro Wi-Fi. Aperte Send e espere o procedimento do SmartConfig terminar. Se tudo der certo, após o procedimento, o CC3000 irá se conectar à rede configurada, abrir o Socket e começar a fazer broadcast da temperatura. 

 

Para visualizar os dados enviados, abra o hercules_3-2-4.exe. Dentro do programa, navegue para a aba UDP, preencha o campo Local port com 4444 e clique em Listen. Como na imagem abaixo, você deve começar a receber o valor da temperatura enviado pelo MSP430 (o valor muito provavelmente vai apresentar um offset de temperatura, que deve ser calibrado).

 

HerculesSetup

 

Conclusão

 

Aqui foi demonstrada uma aplicação simplória utilizando o CC3000, porém serve como uma boa referência para começar um projeto. Na minha opinião a ferramenta desenvolvida pela Texas é bastante poderosa pois permite que um microcontrolador consiga se conectar em uma rede Wi-Fi sem muito esforço e custo: a gama de aplicações é muito grande.

 

 

Outros artigos da série

<< Iniciando com CC3000: Seu microcontrolador com Wi-Fi - Parte 1
Este post faz da série Iniciando com CC3000. Leia também os outros posts da série:
NEWSLETTER

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Obrigado! Sua inscrição foi um sucesso.

Ops, algo deu errado. Por favor tente novamente.

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Luis Filipe Rossi
Engenheiro eletricista (POLI-USP 2008) e mestre em engenharia (POLI-USP 2012), e especialista em projetos de sistemas embarcados, atuando tanto no desenvolvimento de hardware como firmware. É sócio fundador da Condor Instruments Ltda e já trabalhou como consultor em diversos produtos comerciais.

2
Deixe um comentário

avatar
 
2 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
1 Comment authors
Edgar Dos ReisIniciando com CC3000: Seu microcontrolador com Wi-Fi - Parte 1 - Embarcados - Sua fonte de informações sobre Sistemas Embarcados Recent comment authors
  Notificações  
recentes antigos mais votados
Notificar
Edgar Dos Reis
Visitante
Edgar Dos Reis

Olá,
Eu tenho um MSP430F5529, sabe me dizer se é possível fazer este projeto
Com esta placa?

Obrigado
Edgar dos Reis

trackback

[…] Na Parte II deste artigo eu dou um pequeno tutorial introdutório de como fazer um código para o CC3000 utilizando a LaunchPad do MSP430. […]