1

I have Arduino MEGA with Ethernet Shield and a SD card connected to a RUT950 GSM router. Then, I also have two sensors connected to the router and they run a TCP server that sends measurements character after character with a "\n" to terminate the measurement.

I got this from the uSonic Wind Sensor:    
    $WIMWV,000.0,R,00.0,M,A*10\n
    $WIMTA,022.8,C*23\n
    $WIMHU,083.3,,019.8,C*05\n
    $WIMMB,,,1006.8,B*0F\n

Sensor 1, local IP: 192.168.1.200, port 1649 Sensor 2, local IP: 192.168.1.201, port 1647 Router: 192.168.10.1 Arduino: 192.168.10.100

My program reads from the two TCP servers, store the readings in a char buf[] and then it saves them into a SD card. Then, the program load the file and sends it to the FTP server.

This works fine sometimes, other times it crashes or it starts receiving the data from the two sensors but after some minute, it appears to received only from one sensors or it receives nothing at all. It is very strange! Sometimes, it sends the file only the first time and so on. It has a really random behaviour and I cannot understand why! Can you help me please? The sensors have only a public ip address so you can try the code on your pc, if you want to (I can give you the public ip address).

// Library includes
#include <SD.h>
#include <FTP.h>
#include <RTC.h>
#include <Ethernet.h>

// Set Ethernet properties of our PLC
uint8_t mac[] = { 0xDE, 0xAD, 0x4E, 0x55, 0xFE, 0xED };
IPAddress ip(192, 168, 10, 100);
IPAddress netmask(255, 255, 255, 0);
IPAddress server(2, 45, 150, 21);

byte server_svs60[] = { 192, 168, 10, 201 };  // Touchberry Pi Server
int tcp_port_svs60 = 4197;
byte server_wind[] = { 192, 168, 10, 200 };  // Touchberry Pi Server
int tcp_port_wind = 4196;
EthernetClient client_svs60;
EthernetClient client_wind;

const byte numChars = 32 * 4;
char receivedChars[numChars + 1];
char tempChars[numChars + 1];  // temporary array for use when parsing

const byte numChars_wind = 32 * 4;
char receivedChars_wind[numChars + 1];
char tempChars_wind[numChars + 1];  // temporary array for use when parsing

byte lineCount = 0;

IPAddress time_server(147, 156, 7, 26);  // es.ntp.pool.org
unsigned int udpPort = 2390;
EthernetUDP udp;
const int NTP_PACKET_SIZE = 48;      // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[NTP_PACKET_SIZE];  //buffer to hold incoming and outgoing packets


// Variable to save the hour and second
int savedHour;
int savedSecond;
char datetime[50];
// Variables to manage the SD card
Sd2Card card;
SdVolume volume;

bool flag_wind = false;
bool flag_svs60 = false;

// Define the variables for FTP management
EthernetClient ftpControl;
EthernetClient ftpData;
FTP ftp(ftpControl, ftpData);

// Setup function
void setup() {
  // Set the speed of the serial port
  Serial.begin(9600);

  // Init the SD Card
  if (!SD.begin(53)) {
    Serial.println("Card failed, or not present");
    while (true)
      ;
  }

  // Configure the ethernet protocol in our PLC
  Ethernet.begin(mac, ip, netmask);
  Serial.print("IP address: ");
  Serial.println(Ethernet.localIP());


  if (client_svs60.connect(server_svs60, tcp_port_svs60)) {
    Serial.println("Connected to the SVS60 server");
    client_svs60.println();
  } else {
    Serial.println("Connection to the SVS60 TCP Server failed");
  }
  delay(1000);

  if (client_wind.connect(server_wind, tcp_port_wind)) {
    Serial.println("Connected to the Wind server");
    client_wind.println();
  } else {
    Serial.println("Connection to the Wind Server failed");
  }

  int c = ftp.connect("2.45.150.21", "geoatlas", "Datiboa2023@");
  while (!c) {
    delay(1000);
    c = ftp.connect("2.45.150.21", "geoatlas", "Datiboa2023@");
  }

  udp.begin(udpPort);
  sendRequest();
}


// Loop function
void loop() {
  Serial.println("parsePacket");
  if (udp.parsePacket()) {

    udp.read(packetBuffer, NTP_PACKET_SIZE);

    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
    unsigned long secsSince1900 = highWord << 16 | lowWord;
    const unsigned long seventyYears = 2208988800UL;
    unsigned long epoch = secsSince1900 - seventyYears;

    RTC.setTime(epoch);
    RTC.write();
  }
  Serial.println("rtc read");
  if (!RTC.read()) {
    Serial.println("Read date error: is time set?");
  } else {
    //filename_sd = String(RTC.getYear() + String("") + RTC.getMonth() + String("") + RTC.getMonthDay() + String(".txt"));

    sprintf(datetime, "%04d-%02d-%02d %02d:%02d:%02d",
            RTC.getYear(), RTC.getMonth(), RTC.getMonthDay(),
            RTC.getHour(), RTC.getMinute(), RTC.getSecond());
  }
  // Serial.println(datetime);
  Serial.println("svs60");
  if (client_svs60.available()) {
    Serial.println("dentro svs60 sensor");
    char c = client_svs60.read();
    Serial.println(c);
    strncat(tempChars, &c, 1);
    if (c == '\n') {
      strcpy(receivedChars, tempChars);
      strcpy(tempChars, "");
      Serial.println("I got this from SVS60: ");
      Serial.println(receivedChars);
      logToSd_svs60(receivedChars);
      sendToFTP();  
     // memset(0, receivedChars, sizeof(receivedChars));
    }
  }
 Serial.println("wind sensor");
  if (client_wind.available()) {
    Serial.println("dentro wind sensor");
    char c1 = client_wind.read();
    Serial.println(c1);
    strncat(tempChars_wind, &c1, 1);
    
    if (c1 == '\n') {
      if (++lineCount == 4) {
        strcpy(receivedChars_wind, tempChars_wind);
        strcpy(tempChars_wind, "");
        lineCount = 0;
        Serial.println("I got this from the uSonic Wind Sensor: ");
        Serial.println(receivedChars_wind);
        logToSd_wind(receivedChars_wind);
       // memset(0, receivedChars_wind, sizeof(receivedChars_wind));
      }
    }
  }

  delay(200);
}


// Function to save information to SD
void logToSd_svs60(char value[]) {
  File dataFile = SD.open("datalog.txt", FILE_WRITE);
  if (dataFile) {
    Serial.println("Saving SVS60 to SD");
    dataFile.println("Sensore Ondametrico: ");
    dataFile.println(datetime);
    dataFile.println(value);
    dataFile.close();
  } else {
    Serial.println("Error opening datalog.txt");
    while (true)
      ;
  }
}

// Function to save information to SD
void logToSd_wind(char value[]) {
  File dataFile = SD.open("datalog.txt", FILE_WRITE);
  if (dataFile) {
    Serial.println("Saving Wind to SD");
    dataFile.println("Dati sistema: ");
    dataFile.println(datetime);
    dataFile.println(value);
    dataFile.close();
  } else {
    Serial.println("Error opening datalog.txt");
    while (true)
      ;
  }
}

unsigned long sendRequest() {
  memset(packetBuffer, 0, NTP_PACKET_SIZE);

  packetBuffer[0] = 0b11100011;  // LI, Version, Mode
  packetBuffer[1] = 0;           // Stratum, or type of clock
  packetBuffer[2] = 6;           // Polling Interval
  packetBuffer[3] = 0xEC;        // Peer Clock Precision
  packetBuffer[12] = 49;
  packetBuffer[13] = 0x4E;
  packetBuffer[14] = 49;
  packetBuffer[15] = 52;

  //Serial.println("I check the time server");

  if (!udp.beginPacket(time_server, 123)) {
    Serial.println("Begin packet error");
  } else {
    udp.write(packetBuffer, NTP_PACKET_SIZE);
    if (!udp.endPacket()) {
      Serial.println("End packet error");
    }
  }
}

void sendToFTP(void)
{
  Serial.println("SD.open");
  // Open the SD file
  File dataFile = SD.open("datalog.txt");
  
  // Check if the file was succesfully open
  if (dataFile) 
  {          
        Serial.println("Sending trough FTP connection");
        ftp.store("datalog.txt", dataFile);            
        dataFile.close();

  }
  else 
  {
        Serial.println("Error opening2 datalog.txt");
        while (true)
          ;
  }
}
4
  • 1
    did you try some recovery like reconnect when connected() returns false?
    – Juraj
    May 13, 2023 at 17:03
  • But the problem is that I'm not sure the problem is related to a loss of connection. Moreover, I call the client.connect() inside the setup() so I do not know if I can check it inside the loop function. Should I check if client is connected inside the loop function just before client.available? But in this way, should I change also the control of the received characters? May 13, 2023 at 18:56
  • I do not know if I can check it inside the loop function. ... examine the example code that is included with the ethernet library ... ask questions after
    – jsotola
    May 13, 2023 at 20:55
  • Probably I solved the system by checking if the client is connected and also by re-connecting it at some time interval. May 14, 2023 at 15:42

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.