Boa noite!
Bom, tentarei ser o mais sucinto e claro possível na minha dúvida. É o seguinte, estou fazendo um projeto que consiste no Arduino com uma Ethernet Shield e uma NFC Shield ( esta aqui: NFC Shield V2.0 | Seeed Studio Wiki), que deverá ser usada para ler um cartão RFID e enviar a ID do cartão para um servlet em Java para que este execute as operações de banco de dados necessárias. A ideia é fazer com que o servlet retorne um valor inteiro para o Arduino e, de acordo com tal valor, acender um led que será usado para indicar se houve erro ou sucesso na operação. Já consegui fazer com que as duas shields funcionem juntas (ambas usam o pino 10 para SS da comunicação SPI, porém na shield NFC é possível alterar para o pino 9) e envie os dados para o servlet. O grande problema é na hora de receber os dados do servlet. Usei como base a aplicação deste link : http://www.lauridmeyer.com/2012/04/simple-arduino-tcp-client-using-the-ethernetshield-dhcp-and-a-java-server/, porém quando adapto para a minha, não consigo ler os dados enviados pelo servlet corretamente. Aqui vai o código do Arduino (é um tanto extenso)
#include <PN532.h>
#include <SPI.h>
#include <Ethernet.h>
/* Define os pinos CS para a Shield NFC e Ethernet */
#define PN532_CS 9
#define ETHNET_CS 10
PN532 nfc(PN532_CS);
/* COnfiguração de rede */
byte mac[] = {
0x90, 0xA2, 0xDA, 0x0D, 0x3B, 0xB9 }; // MAC
IPAddress ip(192,168,1,110); // IP do Arduino
IPAddress server(192,168,1,104); // IP do Servidor
byte netmask[] = {
255,255,255,0}; // Mascara
EthernetClient client;
/* defino os pinos para os leds */
int redPin =5;
int greenPin = 6;
int bluePin = 7;
/* Rotina para seleção da shield a ser usada */
void spiSelect(int CS) {
// desativa todas as shields c/ comun. SPI
pinMode(PN532_CS,OUTPUT);
pinMode(ETHNET_CS,OUTPUT);
digitalWrite(PN532_CS,HIGH);
digitalWrite(ETHNET_CS,HIGH);
// ativa a shield desejada, através do pino passado por parametro
digitalWrite(CS,LOW);
}
/* Rotina que efetua a conexão ao servidor na porta 8080 */
boolean conecta(){
client.connect(server, 8080);
Serial.println(client.read());
}
void setup(void) {
/* Define os pinos dos LEDs como saídas */
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
/* Inicia conexão serial */
Serial.begin(57600);
Serial.println("Arduino Powered On");
// desativa o SPI da shield NFC, deixando somente a Ethernet ativa
spiSelect(ETHNET_CS);
// ethernet uses the default MSB first so making sure that is set
SPI.setBitOrder(MSBFIRST);
/* Inicializa a rede */
Ethernet.begin(mac, ip, netmask);
Serial.print("Arduino IP is ");
Serial.println(Ethernet.localIP());
// Desativa o SPI da shield Ethernet, deixando só a NFC ativa
spiSelect(PN532_CS);
// NFC uses LSB first so we have to explicitly set that
SPI.setBitOrder(LSBFIRST);
/* Inicializa o leitor NFC */
nfc.begin();
uint32_t versiondata = nfc.getFirmwareVersion();
if (! versiondata) {
Serial.print("Didn't find PN53x board");
digitalWrite(redPin,HIGH); //acende o LED vermelho caso não encontre a shield NFC
while (1); // halt
}
Serial.print("Found chip PN5");
Serial.println((versiondata>>24) & 0xFF, HEX);
Serial.print("Firmware ver. ");
Serial.print((versiondata>>16) & 0xFF, DEC);
Serial.print('.');
Serial.println((versiondata>>8) & 0xFF, DEC);
Serial.print("Supports ");
Serial.println(versiondata & 0xFF, HEX);
nfc.SAMConfig();
}
/* Main program loop */
void loop(void) {
// disable the ethernet SPI here so just NFC is active
spiSelect(PN532_CS);
// NFC uses LSB first so we have to explicitly set that
SPI.setBitOrder(LSBFIRST);
/* look for MiFare type cards */
uint32_t id;
id = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A);
if (id != 0) {
Serial.print("Read card #");
Serial.println(id);
//delay(5000);
/* Acende o LED verde quando ler o cartão e depois de 2s apaga e acende apenas o LED azul */
digitalWrite(bluePin,LOW);
digitalWrite(greenPin,HIGH);
delay(2000);
digitalWrite(greenPin,LOW);
digitalWrite(bluePin,HIGH);
}
// disable the NFC SPI here so just network is active
spiSelect(ETHNET_CS);
// ethernet uses the default MSB first so we need to switch back
SPI.setBitOrder(MSBFIRST);
// check ethernet is still working
Serial.print("Arduino IP is ");
Serial.println(Ethernet.localIP());
if (id != 0) { //se a ID lida pela shield NFC for diferente de zero
if (conecta()) { //se houver a conexão com o servidor
Serial.println("\n");
//se houver conexão com o servidor, o led azul é ativado
Serial.println("Conectado ao servidor");
Serial.println(client.read()); //lê os dados enviados do servidor, usado apenas para verificação pois não foi enviado nada ainda p/ o Arduino
digitalWrite(bluePin, HIGH);
boolean currentLineIsBlank = true;
/* Inicialmente estava enviando os dados como num formulário, mantive desta maneira*/
client.print("GET /TG/inserePresenca?id_tag=="); //envia o texto
Serial.print("GET /TG/inserePresenca?id_tag=="); //replica para a Serial
Serial.println(client.read()); //lê os dados enviados do servidor, usado apenas para verificação pois não foi enviado nada ainda p/ o Arduino
client.print(id); //envia a ID lida
Serial.print(id); //replica para a Serial
Serial.println(client.read()); //lê os dados enviados do servidor, nesse momento já deveria mostrar o que o servidor enviou
Serial.println();
Serial.println();
/* mantém o LED verde apagado e o azul aceso */
digitalWrite(greenPin,LOW);
digitalWrite(bluePin,HIGH);
client.stop(); //interrompe a conexão
/* aqui deveria exibir corretamente o que o servidor enviou, idem acima */
Serial.println("e o que ele leu eh");
}
/* se não houver conexão, o led vermelho fica piscando */
else{
digitalWrite(bluePin,LOW);
while(true){
digitalWrite(redPin,HIGH);
delay(250);
digitalWrite(redPin,LOW);
}
}
}
}
E aqui o código do Servlet. Estou usando o do link que mostrei anteriormente, por hora só estou testnado o envio dos dados do servlet para o Arduino:
import java.io.*;
import java.net.*;
public class Server {
//defining the Port on which the Server runs
private static final int port=8080;
private static int i=0;
public static void main(String argv[]) throws Exception
{
String clientMsg;//incoming Message from Client
ServerSocket mySocket = new ServerSocket(port);//the socket
System.out.println("TCP-Server started");
while(true)
{
Socket connectionSocket = mySocket.accept();//aceitando conexões de entrada
//Bufferedreader para ler o que o cliente envia
BufferedReader clientInput = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
//Outputstream para enviar as mensagens ao cliente
DataOutputStream clientOutput = new DataOutputStream(connectionSocket.getOutputStream());
clientMsg = clientInput.readLine();//reading the Message that was just recieved
System.out.println(i+"--Client says: " + clientMsg);//print that message
clientMsg="";
clientMsg+=i;
System.out.println(clientMsg);
clientOutput.writeBytes(clientMsg);
i++;
}
}
}
Durante a execução, a saída de console do servlet é esta:
TCP-Server started
0--Client says: GET /TG/inserePresenca?id_tag==1538968478
0
1--Client says: GET /TG/inserePresenca?id_tag==1538968478
1
e a saída de console do Arduino é:
Arduino Powered On
Arduino IP is 192.168.1.110
Found chip PN532
Firmware ver. 1.6
Supports 7
Arduino IP is 192.168.1.110
Arduino IP is 192.168.1.110
Found 1 tags
Sens Response: 0x4
Sel Response: 0x8
0x5B 0xBA 0xCB 0x9ERead card #1538968478
Arduino IP is 192.168.1.110
-1Conectado ao servidor
-1
GET /TG/inserePresenca?id_tag==-1
1538968478**-1**e o que ele leu eh ______
Arduino IP is 192.168.1.110
O que marquei em negrito é o que ele teoricamente lê do servidor. Reparem que em todos obtenho a leitura -1, mesmo antes de enviar a ID do cartão, e no último (marcado com ___ ) não é recebido nada.
Verificando com o Wireshark, pude constatar que quando o servlet envia a resposta, a conexão TCP foi fechada pelo Arduino, mesmo antes de chegar no client.stop(); no código
Alguém sabe me ajudar a resolver isso?
É meu primeiro post aqui, então já peço desculpas de antemão caso não tenha sido claro o suficiente
Obrigado!