My project reads a reed switch connected to a meter, the switch activates every time a 0.01 measurement has been used, i can therefore tell home much i am using in a day. This is then uploaded to Cosm and to my local MQTT server, this is then processed further.
Although I am using in this instance a MQTT server this in actual fact uses the underlying Arduino ethernet library. So any suggestions you may give me will also work in my MQTT server (so I have been told).
I check about every .1 second if the switch has changed state and debounce it, if it has, i increment a counter.
The switch will be high for about 3/4 second then returns to a low this repeats every 20 seconds and continually repeats this pattern while the meter is running.
This all works well until I turn off my PC which has the MQTT server on it, in my code the Arduino then keeps trying to reconnect, until the PC is next switched back On. When it is it reconnects it works normally again.
PROBLEM
The problem is the Arduino library takes just over 1 second to try and reconnect, and it seems to be a blocking routine, so I then miss about 2 out of every 3 pulses.
Is there a quicker way of checking if ethernet is connected or something else I can try ?
Regards
Gary
Here is part of the code:
EthernetClient MQTT_ethclient;
Ethernet.begin(mac, ip, dns_server, gateway);
void loop(void)
{
Check_MQTT_Ethernet_Connected();
Check_Cosm_Ethernet_Connected();
Check_reed_switch(); // Detect a pulse via Reed Switch
Check_timers();
Check_for_any_uploads();
Cosm_client.loop();
MQTT_client.loop();
}
void Check_MQTT_Ethernet_Connected() // Needs improving as 'LCD Menu' gets sluggish do to the Ethernet trying to reconnect
{
if ( !MQTT_client.connected())
{
Serial.println("MQTT disconnected ...");
Intialise_MQTT(); // Setup Publish and Subscribe.
MQTT_ethernet_connected_flag = false;
}
if (MQTT_client.connected())
{
if (MQTT_ethernet_connected_flag == false)
{
Serial.println("MQTT Connected");
MQTT_ethernet_connected_flag = true;
}
}
}
void Intialise_MQTT(void)
{
if (MQTT_client.connect("arduinoClient_MQTT_02")) // Arduino NAME shown on MQTT Broker
{
Serial.println("MQTT_client Intialised");
MQTT_client.publish("sensor/002/mqtt_server_in","MQTT OK"); // This is Data to be SENT from the Arduino to the MQTT MQTT_server
MQTT_client.subscribe("sensor/002/mqtt_server_out"); // This is RECEIVED from MQTT MQTT_server to this Arduino.
}
}
Is there a quicker way of checking if ethernet is connected or something else I can try ?
No, but you could use an interrupt to read the switch, instead of polling it. Then, even though the Arduino is waiting for a response from the Ethernet shield, it will still register the switch event.
Thanks for that, I always avoiding using interrupts as I thought they were hard to use, but that was so easy to setup, seems to be working now, just running checks on it for the rest of today.
Just thinking about the future, as I plan to make other devices and I may run into some other software problem, my original idea was to have a 'heartbeat' sent from my pc say every 5 seconds to the ethernet on the arduino and when the Arduino did not receive this it would then omit checking the void Intialise_MQTT(void) until the Arduino once again received the heartbeat.
I do have code that runs on my PC, when the PC is ON it sends the text 'heartbeat' to the arduino ethernet every 5 seconds.
As far as I know the Wiznet ethernet board will look for a ethernet connection (without the arduino doing anything)and when it finds the correct address of my PC the link will once again be established.
If this is correct then when it gets the 'heartbeat' text again it would then know to call the void Intialise_MQTT(void) again.
If the Arduino has to be connected to the PC anyway, why is it wearing an Ethernet shield? The PC can send data to the server far faster than the Arduino can.
Brief overview: I am monitoring my energy usage in my home, which consists of a UK gas meter that outputs a pulse for every 0.01 unit of gas used to heat my home. Also I collect outside air temperature and indoor temperature. Eventually it will monitor and action more. The temperatures and gas used are sent to my browser and displayed for m
y reference and also sending commands to the arduino.
The arduino's are situated in various rooms and garages, these are a long way from my PC, hence using ethernet. Hope that explains what I am trying to do.
The arduino is collecting data and then sends it to COSM (a place for storing data as well as displaying in a graphical format) https://cosm.com/
The arduino also sends data to my PC that gives me temperatures and gas usage.
The Cosm data does not need my PC to be ON as the arduino ethernet board sends this via my router to COSM, but the MQTT part does need my PC. (http://mqtt.org/) Eventually the PC will be on all day and turn of at 12.00 am and back on at 6.00am.
I don't know if this will do it for you, but I had a similar problem with connecting to internet servers. Sometimes they would take quite a while to respond and my little Arduino would patiently set there waiting for them until my watchdog timer expired and rebooted the machine. Initially I put a timer in the ethernet code to support passing a timeout on connection with the connect. That worked really well, but when I updated the code to IDE version 1.0.3 I looked around for another solution.
There are two parameters you can play with that will change the timeout period in your code and this is how I use them:
#include <utility/w5100.h> // add this up where your includes are
//Then later in the code where appropriate put these two lines in
W5100.setRetransmissionTime(2000); // sets up a short timeout for ethernet connections
W5100.setRetransmissionCount(3);
So, take a look at the ethernet code and play with these. They totally solved the problem for me by reducing the attempted time for connection (or connection failure) so I can deal with it before my watchdog times out.