0% acharam este documento útil (0 voto)
2 visualizações31 páginas

Modulo RaspberryPi Socket

O documento aborda a automação utilizando Raspberry Pi, introduzindo conceitos de socket e programação em C no ambiente Unix/Linux. Ele fornece instruções para configurar a IDE Geany, além de apresentar códigos para um sistema cliente-servidor que controla relés. O texto também discute a diferença entre sockets e HTTP, destacando o uso de sockets em aplicações que requerem desempenho e segurança.

Enviado por

Sydney Correa
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
2 visualizações31 páginas

Modulo RaspberryPi Socket

O documento aborda a automação utilizando Raspberry Pi, introduzindo conceitos de socket e programação em C no ambiente Unix/Linux. Ele fornece instruções para configurar a IDE Geany, além de apresentar códigos para um sistema cliente-servidor que controla relés. O texto também discute a diferença entre sockets e HTTP, destacando o uso de sockets em aplicações que requerem desempenho e segurança.

Enviado por

Sydney Correa
Direitos autorais
© All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd

Por Fernando Koyanagi

Recursos usados
• 18 jumpers fêmea x fêmea
• Módulo de 16 relés com optoacoplador
• Raspberry Pi 3
• Rede interna (TCP/IP)
Intenção dessa aula
1. Iniciar automação com Raspberry Pi
PI

2. Introduzir conceitos de socket e Layer

3. Mostrar um cliente-servidor

4. Introduzir programação em C Unix /


Linux

5. Utilizar funções da Lib WiringPI


Configuração Geany
É necessário configurar a IDE do Raspberry
antes de compilar os códigos.
1. Clique no menu
Build -> Set Build Commands
(Construir -> Definir Comandos de Construção);

2. Adicione os seguintes comandos:

Em “Compile” adicione: “-lwiringPi” e “-lpthread”


Em “Build” adicione: “-lwiringPi” e “-lpthread”
Em “Execute” adicione: “sudo” como na imagem
Programas Client.c e Server.c

"[Link]"
Client

Server Client

Os dois vão rodar dentro do Raspberry PI


Compilados no C do Linux (gcc) com WiringPI
Rodam dentro do próprio Raspberry e o Client pode rodar
fora mudando o IP "[Link]"
Ligação dos jumpers...
Seu e-mail
Em [Link]

7
Socket ou http ?
É preferivelmente usado em sistemas orientados para o desempenho e
segurança , nos setores militar ou financeiro.

Prot:IP:port Prot:IP:port

Executável Executável
SO Menor quantidade de Layers
Socket Dados Binários
Camada física
Da rede

Aplicação Aplicação
Maior quantidade de Layers
SO Dados texto

http
Camada física
Da rede

8
Socket ou HTTP ?
Performance ?
Segurança ?

9
Diagrama de estado do modelo Client / Server
Server Client
Criação do Socket Criação do Socket

Prepara Socket
Client

Bind
Connetc Client

Listen

Server
Accept
Client

Send / Recv Send / Recv

Close Close Client 10


Código Servidor main()
Server Client
int main(int argc , char *argv[]) Criação do Socket Criação do Socket
{
int socket_servidor;
setaPinos(); //seta os pinos dos reles
//cria e prepara o socket Bind
if(!preparaSocket(&socket_servidor))
return 0;
iniciaServidor(socket_servidor); Connect
//inicia o servidor e executa Listen
um loop de recepção de mensagens
}
Accept

Send / Recv Send / Recv

Close Close
Código Servidor
Server Client
bool preparaSocket(int *conexao)
Criação do Socket Criação do Socket
{
struct sockaddr_in servidor;
//cria conexão socket
*conexao = socket(AF_INET, SOCK_STREAM , 0);
if (*conexao == -1)
{ Bind
puts("Não foi possível criar o socket");
return false;
} Connect
puts("Socket criado");
Listen
//Prepara a estrutura sockaddr_in
servidor.sin_family = AF_INET;
servidor.sin_addr.s_addr = INADDR_ANY;
servidor.sin_port = htons(PORTA); Accept

domínio: inteiro, domínio de comunicação, por exemplo, Send / Recv Send / Recv
protocolo AF_INET (protocolo IPv4), AF_INET6 (protocolo IPv6)
Quando INADDR_ANY é especificado na chamada de ligação,
o soquete será vinculado a todas as interfaces locais Close Close
Código Servidor
Server Client
Criação do Socket Criação do Socket

int bind (int sockfd, const struct sockaddr * addr, socklen_t addrlen);

Bind
//efetua ligação
if(bind((*conexao),(struct sockaddr *)&(servidor) , sizeof(servidor)) < 0)
{ Connect
puts("Falha na ligaçao");
return false; Listen
}
puts("Ligação efetuada");
return true;
Accept

Send / Recv Send / Recv

Close Close
Código Servidor void iniciaServidor(int socket_servidor) Server Client
Criação do Socket Criação do Socket
void iniciaServidor(int socket_servidor)
{
int socket_cliente, *novo_socket;
//inicia a recepção de mensagens
listen(socket_servidor , 3);
puts("Aguardando novas conexões...");
//loop infinito, para cada conexão é criada uma thread que recebe Bind
as mensagens
while((socket_cliente = accept(socket_servidor, (struct sockaddr *)0, (socklen_t*)0)))
{
Connect
puts("Conexão aceita");
//cria thread
pthread_t thread;
Listen
novo_socket = malloc(1);
*novo_socket = socket_cliente;
Accept

Send / Recv Send / Recv

Close Close
Código Servidor void iniciaServidor(int socket_servidor) Server Client
void iniciaServidor(int socket_servidor) Criação do Socket Criação do Socket
{
int socket_cliente, *novo_socket;
//inicia a recepção de mensagens
listen(socket_servidor , 3);
puts("Aguardando novas conexões...");
//loop infinito, para cada conexão é criada uma thread que recebe
as mensagens Bind
while((socket_cliente = accept(socket_servidor, (struct sockaddr *)0, (socklen_t*)0)))
{
puts("Conexão aceita");
//cria thread Connect
pthread_t thread;
novo_socket = malloc(sizeof(*novo_socket)); Listen
*novo_socket = socket_cliente;
//caso ocorra algum erro neste momento o loop é abortado
if(pthread_create(&thread,NULL , comunicacaoSocket,
(void*) novo_socket) < 0) Accept
{
puts("Não foi possível criar a thread.");
close(*novo_socket);
Send / Recv Send / Recv
free(novo_socket);
return;
}
puts("Thread criada"); Close Close
}
Código Servidor threads
Server Client
if(pthread_create(&thread,NULL , comunicacaoSocket, Criação do Socket Criação do Socket
(void*) novo_socket) < 0)
{
puts("Não foi possível criar a thread.");
close(*novo_socket);
free(novo_socket);
return;
} Bind
puts("Thread criada");
}

Connect
Main()
Listen

Accept
thread1 thread2 thread3

Recv Send

void *comunicacaoSocket(void *conexao)


Close Close
Código Servidor void *comunicacaoSocket(void *conexao)
Server Client
void *comunicacaoSocket(void *conexao) Criação do Socket Criação do Socket
{
puts("Thread de conexão iniciada");
int tamanhoMensagemRecebida;
char mensagem[TF_MENSAGEM];
mensagem[0] = '\0';
//enquanto não for recebida nenhuma mensagem, permanece em loop
while(1) Bind
{
//recebe mensagem
tamanhoMensagemRecebida = recv(*(int*)conexao ,&mensagem, sizeof(mensagem), MSG_PEEK);
// MSG_PEEK Os dados são tratados como não lidos e a próxima função recv ()
ou similar ainda deve retornar esses dados Connect
//define o final da mensagem (este comando impede que o 'lixo' de memória
fique junto à mensagem) Listen
mensagem[tamanhoMensagemRecebida] = '\0';

//imprime mensagem recebida


printf("\nRecebido: %s\n",mensagem); Accept
//deixa a mensagem em maíusculo, assim tanto faz "a1" ou "A1"
for(int i=0; i<tamanhoMensagemRecebida; i++)
{
mensagem[i] = toupper(mensagem[i]); Recv Send
}

Close Close
Código Servidor void *comunicacaoSocket(void *conexao)
Server Client
Criação do Socket Criação do Socket

//acende ou apaga reles de acordo com a mensagem recebida


if(strcmp(mensagem,"A1")==0)
ativaRele(PINORELE_1);
else
Bind
if(strcmp(mensagem,"D1")==0)
desativaRele(PINORELE_1);
else
if(strcmp(mensagem,"A2")==0) Connect
ativaRele(PINORELE_2);
else Listen
if(strcmp(mensagem,"D2")==0)
desativaRele(PINORELE_2);
else Accept
if(strcmp(mensagem,"A3")==0)
ativaRele(PINORELE_3);
else
if(strcmp(mensagem,"D3")==0) Recv Send
desativaRele(PINORELE_3);
// continua assim até o A16 e D16
Close Close
Código Servidor void *comunicacaoSocket(void *conexao)
Server Client
//acende ou apaga reles de acordo com a mensagem recebida
Criação do Socket Criação do Socket
if(strcmp(mensagem,"A1")==0)
ativaRele(PINORELE_1);
else
if(strcmp(mensagem,"D1")==0)
desativaRele(PINORELE_1);
else Bind
if(strcmp(mensagem,"A2")==0)
ativaRele(PINORELE_2);
else
if(strcmp(mensagem,"D2")==0) Connect
desativaRele(PINORELE_2);
else Listen
if(strcmp(mensagem,"A3")==0)
ativaRele(PINORELE_3);
else Accept
if(strcmp(mensagem,"D3")==0)
desativaRele(PINORELE_3);
// continua assim até o A16 e D16 e termina com um break;
Recv Send
puts("Thread finalizada e socket fechado.");
//libera memória desta conexão
free(conexao);
Close Close
return 0;
}
Código Servidor void ativaEmSequencia()
Server Client
void ativaEmSequencia()
{ Criação do Socket Criação do Socket
int vet[16]; if(strcmp(mensagem,"SEQ")==0)
vet[0] = PINORELE_1;
vet[1] = PINORELE_2; ativaEmSequencia();
vet[2] = PINORELE_3;
vet[3] = PINORELE_4;
vet[4] = PINORELE_5;
vet[5] = PINORELE_6; Bind
vet[6] = PINORELE_7;
vet[7] = PINORELE_8;
vet[8] = PINORELE_9;
vet[9] = PINORELE_10;
vet[10] = PINORELE_11; Connect
vet[11] = PINORELE_12;
vet[12] = PINORELE_13; Listen
vet[13] = PINORELE_14;
vet[14] = PINORELE_15;
vet[15] = PINORELE_16;

for(int i=0; i<16; i++) Accept


{
digitalWrite(vet[i],LOW);
delay(200);
digitalWrite(vet[i],HIGH); Recv Send
delay(200);
}
}
Close Close
Código Servidor void ativaEmSequencia()
Server Client
void ativaEmSequencia()
{ Criação do Socket Criação do Socket
int vet[16]; if(strcmp(mensagem,"SEQ")==0)
vet[0] = PINORELE_1;
vet[1] = PINORELE_2; ativaEmSequencia();
vet[2] = PINORELE_3;
vet[3] = PINORELE_4;
vet[4] = PINORELE_5;
vet[5] = PINORELE_6; Bind
vet[6] = PINORELE_7;
vet[7] = PINORELE_8;
vet[8] = PINORELE_9;
vet[9] = PINORELE_10;
vet[10] = PINORELE_11; Connect
vet[11] = PINORELE_12;
vet[12] = PINORELE_13; Listen
vet[13] = PINORELE_14;
vet[14] = PINORELE_15;
vet[15] = PINORELE_16;

for(int i=0; i<16; i++) Accept


{
digitalWrite(vet[i],LOW);
delay(200);
digitalWrite(vet[i],HIGH); Recv Send
delay(200);
}
}
Close Close
Código do Client
Dica de filme!
Código Cliente conecta() Server Client

//cria socket e conecta, Criação do Socket Criação do Socket


bool conecta(int *conexao)
{
struct sockaddr_in client;

//cria conexão socket


Bind
*conexao = socket(AF_INET , SOCK_STREAM , 0);

//AF_INET faz parte de uma família de endereços que é


usada para designar o tipo de endereços com os quais seu Connect
soquete pode se comunicar (neste caso, os endereços do
Internet Protocol v4) Listen

//caso ocorra um erro na criação, aborta a conexão


if (*conexao == -1) Accept
return false;

//imprime mensagem
Recv Send
puts("Socket criado");

Close Close
Código Cliente conecta() Server Client
Criação do Socket Criação do Socket

//prepara estrutura do cliente para conexão


client.sin_addr.s_addr = inet_addr("[Link]");
client.sin_family = AF_INET;
client.sin_port = htons(PORTA);
Bind
//conecta o cliente
if (connect(*conexao , (struct sockaddr *)&client, sizeof(client)) < 0)
return false; Connect

//imprime mensagem Listen


puts("Conectado\n");

return true; Accept


}

Recv Send

Close Close
Código Cliente main() Server Client
int main()
{ Criação do Socket Criação do Socket
int conexao;
char msg[TF_MENSAGEM];

//recebe mensagem
puts("Digite a mensagem:\n[1] - Para sair\n");
fflush(stdin);
gets(msg);

//envia mensagens até que "1" seja recebido Bind


while(strcmp(msg,"1")!=0)
{
//conecta cliente
if(!conecta(&conexao))
{ Connect
puts("Erro de conexão");
break;
} Listen
//envia mensagem
if(send(conexao ,&msg, TF_MENSAGEM, 0) < 0)
puts("Falha no envio\n");
else
puts("Enviada!\n"); Accept
puts("Digite a mensagem:\n[1] - Para sair\n");
fflush(stdin);
gets(msg);
} Recv Send
//fecha o socket
close(conexao);
return 0;
}
Close Close
Tratamento de pinos A sequência dos relés
(biblioteca wiringPi.h) usados neste exemplo se
dá a partir do pino 8 e até o
pino 10, respeitando a
#define PINORELE_1 8 seguinte sequência:
#define PINORELE_8 2
#define PINORELE_2 9
#define PINORELE_3 7
#define PINORELE_4 15
#define PINORELE_5 16
#define PINORELE_6 0
#define PINORELE_7 1
#define PINORELE_9 3
#define PINORELE_10 4
#define PINORELE_11 5
#define PINORELE_12 12
#define PINORELE_13 13
#define PINORELE_14 6
#define PINORELE_15 14
#define PINORELE_16 10
Ligação dos jumpers...
Pinagem Raspberry x Módulo
Entrada do Módulo
Saída do Raspberry de Relés Função
3 1 GPIO
5 2 GPIO
7 3 GPIO
8 4 GPIO
10 5 GPIO
11 6 GPIO
12 7 GPIO
13 8 GPIO
15 9 GPIO
16 10 GPIO
18 11 GPIO
18 12 GPIO
21 13 GPIO
22 14 GPIO
23 15 GPIO
24 16 GPIO
Alimentação (5
2 5 VDC VDC)
6 GND Ground
Iniciando o Servidor
Após compilar deve-se executar o programa com o comando
“./servidor”, assim o servidor já será iniciado e todas as
mensagens recebidas serão informadas no console
Enviando comandos pelo putty...

Digite o ip do Raspberry pi (para descobrir este


ip digite ‘ifconfig’ no console) e a mesma porta
utilizada no algorítmo.

30
Em [Link]
Download arquivos PDF e do código fonte

31

Você também pode gostar