Hi to all,
I have a Arduino MEGA running a program that receives data from two sensors over the net and save them to a SD card.
Each sensor runs a TCP server, so I use the Ethernet shield to connect to them and receive the data.
In particular, these two sensors uses the same public IP, but they have different ports (I'm using a VPN server, so the public IP is the same for both devices, but the ports are different).
The sensors send data by terminating them with \n, so the program check them and when it reaches the "\n", it saves the data on the SD card.
The problem is that the program runs fine sometimes, other times it gets stuck (does it crash somehow?) and I need to manually restart the program to make it work again.
Other times, it connects to both the TCP server, but prints only the data coming from one of them.
For example, sometimes it prints also the data from the wind_sensor, then I reboot it, and it prints only the Svs60 sensor, other times, it prints both correctly.
I really can't understand why this happens!
Can you please help me trying to find the error?
Is it because the sensors have the same IP and so the ethernet library is not able to handle it correctly? I use different variable names to connect to the TCP servers.
// 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, 1, 100);
IPAddress netmask(255, 255, 255, 0);
IPAddress server(2, 45, 150, 21);
byte server_svs60[] = { 188, 34, xxx, xxx}; // same ip
int tcp_port_svs60 = 18627;
byte server_wind[] = { 188, 34, xxx, xxx}; // same ip
int tcp_port_wind = 18625;
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;
// 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");
}
udp.begin(udpPort);
sendRequest();
}
// Loop function
void loop() {
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();
}
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);
if (client_svs60.available()) {
char c = client_svs60.read();
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);
// memset(0, receivedChars, sizeof(receivedChars));
}
}
if (client_wind.available()) {
char c1 = client_wind.read();
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(100);
}
// 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");
}
}
}
This is what I get when the program works correctly:
I got this from SVS60:
VOLTAGE: 4.95\n
Saving SVS60 to SD
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