Search code examples
tcparduinoclient-serverethernet

Arduino Ethernet Client Server communication problem


This is my code:

#include <Keypad.h>
#include <LiquidCrystal.h>
#include <Ethernet.h>
#include <SPI.h>



bool hands = false;
bool result = true;
char Key;
unsigned int Number=0;
String weight;
String path;
bool alreadyConnected = false; // whether or not the client was connected previously
int cnt=0;


byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 1, 2 }; // ip in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask

LiquidCrystal lcd(35, 34, 33, 32, 31, 30);

EthernetServer server(9639); //server port
EthernetClient client;

char keys[4][4] = {
  {'1', '2', '3','A'},
  {'4', '5', '6','B'},
  {'7', '8', '9','C'},
  {'*', '0', '#','D'},
};
byte rowpins[4] = {22, 23, 24, 25};
byte colpins[4] = {26, 27, 28, 29};

Keypad mykeypad = Keypad(makeKeymap(keys), rowpins, colpins, 4, 4);

String readString;

void setup()
{

  lcd.begin(20, 4);


  Ethernet.begin(mac, ip, gateway, subnet);
  
  if (Ethernet.linkStatus() == LinkOFF) {
  lcd.setCursor(0, 0);
  lcd.print("       :Error:       ");
  lcd.setCursor(0, 1);
  lcd.print("Ethernet Cable");
  lcd.setCursor(0, 2);
  lcd.print("Not Connected!");    
    Serial.println("Ethernet cable is not connected.");
    while(true);
  }
   
  Serial.begin(19200);
  Serial1.begin(19200);
  EthernetClient client = server.available();
  
  lcd.setCursor(0, 1);
  lcd.print("    Connecting...    ");
  delay(5000);
  if (client.connect(gateway, 9639))
  {
    client.print("A");
    Serial.println("Connecting MilkyWeigh Server...");
  }
  else
  { lcd.clear();
    lcd.setCursor(0, 1);
    lcd.print("1.Check LAN Cable");
    lcd.setCursor(0, 2);
    lcd.print(" --Reset MilkoSol-- ");
    while (true);
  }
  
  server.begin();
  
  while (true) {
    client = server.available();  // wait for a new client:
    if (client)
    {
      while (client.connected())
      {
        if (client.available())
        {
          char b = client.read();
          if (b == 'B')
          {
            lcd.setCursor(0, 2);
            lcd.print("     Connected!     ");
            Serial.println("Successfully Connected!");
            delay(1500);
            hands = true;
            b = "";
          } //if B comes, handshaking done
        } // if client available
      } //while client connected
    } //if (client)
    if (hands == true)
    {
      lcd.clear();
      client.stop();
      break;
    }
  } //while true
  lcd.setCursor(0, 0);
  lcd.print ("Input Code: ");
  lcd.print (Number);
} // void setup

void loop()
{
  while (Key == NO_KEY){
    Key = mykeypad.getKey();
  }
  DetectButtons();
  if (Key == '4')
  {
   SaveToServer();
   delay(200);
   SaveToServer();
  }
    if (Key == '#')
  {   
      if (Number > 0)
      {
        GetName();
      }
      Getweight();
  }
 Key=NO_KEY;
}

void Getweight(){
  while (Serial1.available()>0)
  {
    weight = Serial1.readStringUntil('\r');
    Serial1.flush();
  }
  Serial.print(weight);
}

void SaveToServer()
  {
   if (client.connect(gateway, 9639))
  {
    client.print('@'+String(Number)+','+weight);
    //client.stop();
  }
  else
  { lcd.clear();
    lcd.setCursor(0, 2);
    lcd.print(" Save Error ");
    Serial.println("Try again!");
    Number=0;
    readString="";
  //  weight="";
    alreadyConnected=false;
    return 0;
  }

  server.begin();

      EthernetClient client = server.available(); // Listening for client (i.e. server) response

    if (client)
    {
     if (!alreadyConnected)
     {
      // clear out the input buffer:
      client.flush();
      alreadyConnected = true;
    }
      while (client.connected())
      {
        if (client.available())
        {
          if (client.available()>0)
          {
          char z = client.read();
          if (z == 'K')
          {
            Serial.print("Success: Data Saved!");
            lcd.clear();
            lcd.setCursor(6, 2);
            lcd.print("Success!");
            delay(1500);
            Number=0;
            weight="";
            readString="";
            DisplayResult();
            }
            client.flush();
            client.stop();
          }
        }
      }
    } // if client
  }// SaveToServer

void GetName()
  {
   if (client.connect(gateway, 9639))
  {
    client.print(Number);
    //client.stop();
  }
  else
  { lcd.clear();
    lcd.setCursor(0, 2);
    lcd.print(" Connection Failed! ");
    Serial.println("Connection Failed!");
    Number=0;
    readString="";
  //  weight="";
    alreadyConnected=false;
    return 0;
  }

  server.begin();

      EthernetClient client = server.available(); // Listening for client (i.e. server) response

    if (client)
    {
     if (!alreadyConnected)
     {
      // clear out the input buffer:
      client.flush();
      alreadyConnected = true;
    }
      while (client.connected())
      {
        if (client.available())
        {
          readString="";
          while (client.available()>0)
          {
          //client.readStringUntil('?');
          readString = client.readStringUntil('?');
            client.flush();
            client.stop();
          }
        }
      }
          if (readString == "err")
          {
            lcd.clear();
            lcd.setCursor(0, 2);
            lcd.print("Not found,Try again!");
            Serial.println("Not found,Try again!");
            delay(1500);
            Number=0;
            readString="";
            hands = true;
            DisplayResult();
          }
          else
          {
          lcd.clear();
          DisplayResult();
            Serial.println(readString);
            hands = true;
          }
    } // if client
  }// GetName


void DetectButtons()
{
 // path = path + "DetectButtons";
  //Serial.println(path);
  
  if (Key == '*') //If cancel Button is pressed
  {
    Serial.println ("Button Cancel");
    Number = 0;
    weight = "";
    readString="";
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Input Code:        ");
    lcd.setCursor(0, 1);
    lcd.print("                    ");
    lcd.setCursor(0, 2);
    lcd.print("                    ");
    lcd.setCursor(0, 3);
    lcd.print("                    ");
  }

  if (Key == '1') //If Button 1 is pressed
  { Serial.println ("Button 1");
    if (Number == 0)
      Number = 1;
    else
      Number = (Number * 10) + 1; //Pressed twice
  }
/*
  if (Key == '4') //If Button 4 is pressed
  { Serial.println ("Button 4");
    if (Number == 0)
      Number = 4;
    else
      Number = (Number * 10) + 4; //Pressed twice
  }
*/
  if (Key == '7') //If Button 7 is pressed
  { Serial.println ("Button 7");
    if (Number == 0)
      Number = 7;
    else
      Number = (Number * 10) + 7; //Pressed twice
  }


  if (Key == '0')
  { Serial.println ("Button 0"); //Button 0 is Pressed
    if (Number == 0)
      Number = 0;
    else
      Number = (Number * 10) + 0; //Pressed twice
  }

  if (Key == '2') //Button 2 is Pressed
  { Serial.println ("Button 2");
    if (Number == 0)
      Number = 2;
    else
      Number = (Number * 10) + 2; //Pressed twice
  }

  if (Key == '5')
  { Serial.println ("Button 5");
    if (Number == 0)
      Number = 5;
    else
      Number = (Number * 10) + 5; //Pressed twice
  }

  if (Key == '8')
  { Serial.println ("Button 8");
    if (Number == 0)
      Number = 8;
    else
      Number = (Number * 10) + 8; //Pressed twice
  }

  if (Key == '3')
  { Serial.println ("Button 3");
    if (Number == 0)
      Number = 3;
    else
      Number = (Number * 10) + 3; //Pressed twice
  }

  if (Key == '6')
  { Serial.println ("Button 6");
    if (Number == 0)
      Number = 6;
    else
      Number = (Number * 10) + 6; //Pressed twice
  }

  if (Key == '9')
  { Serial.println ("Button 9");
    if (Number == 0)
      Number = 9;
    else
      Number = (Number * 10) + 9; //Pressed twice
  }
  DisplayResult();
} // end of detect buttons function

void DisplayResult()
{
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print ("Input Code: ");
  lcd.print (Number);
  lcd.setCursor(0, 1);
  lcd.print (readString);
  lcd.setCursor(0, 2);
  lcd.print ("Weight :");
  lcd.print (weight);
  lcd.setCursor(0, 3);
  lcd.print ("*=Cncl,#=Wght,A=Save");
}

The problem is when '#' key is pressed first time with input_code =111, client.read somehow miss or skip the response (name) from server and shows blank. But when i press '#' key second time with input_code = 222, it shows previous response (name) from server.


Solution

  • The EthernetClient can be used to connect to remote server as in WebClient example or it is used by the EthernetServer as a peer for remote client as in ChatServer example.

    If you use both, use different names. Now your client 'client' is global and clients returned from server are local but with the same name. And you can make the global client variable local too.

    The variable alreadyConnected is used with local client and with server's client.

    You don't stop the local client.

    You have redundant while/if (client.available()) to test the request (server's client).

    Why while (client.available() > 0) around readStringUntil('?')?

    EthernetServer should by started with begin only once in setup().