Komunikace přes Arduino Mega + enc28j60
Napsal: 29 pro 2017, 10:46
Přátelé, může se někdo z vás mrknout na tento sketch? Modul enc28j60 slouží jak pro načtení NTP, tak pro odesílání zpráv na ThingSpeak a na NotifyMy Android v případě havarijního stavu. Čas od času se ale komunikace "kousne" a program zůstane viset "na mrtvém bodě". S ohledem na to, že se to stává jednou za několik dní, trvalý monitoring přes serial port tak nedává asi smysl ...
Mám podezření, že to může souviset s nějakým "mikrovýpadkem" připojení na straně ISP, protože stejná "modrá smrt " nastává ve chvíli, kdy odpojím zařízení od sítě natrvalo. Může to být důvod? A pokud ano, jak by se dal sketch vylepšit tak, aby v případě výpadku ISP k blokaci nedocházelo?
To co posílám je součástí poměrně velkého programu pro řízení technologie, proto jsem zbytek vyházel nebo nahradil maskami "xxx" a upravil. Smyčka se ve standardním programu točí jednou za vteřinu, odesílání zpráv na ThingSpeak je řešeno časovou podmínkou jednou za 60 vteřin, na notify pak v případě havárie.
Díky za pomoc a radu.
Dig
.............................................................................................................................
//library
#include <EtherCard.h>
//def NTP
static byte ntpServer[] = {204,9,54,119}; //NTP server
uint8_t ntpMyPort = 123; // NTP port
//def net
byte Ethernet::buffer[900];
static byte mymac[] = {0x70,0x69,0x69,0x2D,0x30,0x31}; //MAC adress enc28j60
boolean networkOK; // net status
//def table of message for NotifyMyAndroid
const char apihost[] PROGMEM = "www.notifymyandroid.com";
const char message0[] PROGMEM = "error type 1";
const char message1[] PROGMEM = "error type 2";
const char * const message_table[] PROGMEM = {message0, message1};
char buff[38];
//def ThingSpeak
const char website[] PROGMEM = "api.thingspeak.com";
#define APIKEY "****************"
// def class stash
Stash stash; // Class to build request to Notify My Android.
static byte session;
//def fake value
boolean fake_test;
void setup()
{
Serial.begin(9600);
//start ethercard
ether.begin(sizeof Ethernet::buffer, mymac, 53);
//first control connection and try NTP read
networkOK = networkConnection();
if (networkOK) nacteni_NTP();
}
void loop()
{
/* read NTP, in real sketch once per day in defined time */
networkOK = networkConnection();
if (networkOK) nacteni_NTP;
/* send message to thingspeak - in real sketch every 60 seconds */
byte sd = stash.create();
stash.print("field1=");
stash.print(fake_test);
stash.save();
ether.dnsLookup(website);
ether.hisip;
Stash::prepare(PSTR("POST /update HTTP/1.0" "\r\n"
"Host: $F" "\r\n"
"Connection: close" "\r\n"
"X-THINGSPEAKAPIKEY: $F" "\r\n"
"Content-Type: application/x-www-form-urlencoded" "\r\n"
"Content-Length: $D" "\r\n"
"\r\n"
"$H"),
website, PSTR(APIKEY), stash.size(), sd);
session = ether.tcpSend();
int freeCount = stash.freeCount();
if (freeCount <= 3) Stash::initMap(56);
// in real sketch only in case of damage
notifyMyAndroid(fake_test%2);
const char* reply = ether.tcpReply(session);
ether.packetLoop(ether.packetReceive());
//delay and making fake_test only for disputate, in standard case loop every second - driving by RTC module
fake_test++;
delay (60000);
}
//================================================== user´s functions ========================================
/* ... try connection ...................................................*/
boolean networkConnection()
{if (ether.dhcpSetup()) return 1; else return 0;}
/* ... read NTP time ................................................*/
byte nacteni_NTP()
{
unsigned long timeFromNTP;
const unsigned long seventy_years = 2208988800UL;
int net_count = 16; //Number of attempts
while(net_count > 0) // 60x try read NTP
{
ether.ntpRequest(ntpServer, ntpMyPort);
word length = ether.packetReceive();
ether.packetLoop(length);
if(length > 0 && ether.ntpProcessAnswer(&timeFromNTP,ntpMyPort)) // pokud zdárně načte, přenastaví RTC
{
Serial.println("NTP OK");
}
delay(500);
net_count --;
}
return 0;
}
/* ... message for NotifyMyAndroid http://www.vwlowen.co.uk/arduino/router ... onitor.htm */
static void notifyMyAndroid (const byte msg)
{
ether.dnsLookup(apihost);
ether.hisip;
strcpy_P(buff, (char*) pgm_read_word(&(message_table[msg]))); // Retrieve message from Program Memory into buffer.
byte sd = stash.create();
stash.print("apikey=");
stash.print("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); // API key www.notifymyandroid.com
stash.print("&application=");
stash.print(buff);
stash.print("&event=");
stash.print("message from engine");
stash.print("&description=");
stash.print("error - engine stoped");
stash.print("&priority=");
stash.print("0");
stash.save();
int stash_size = stash.size();
Stash::prepare(PSTR("POST /publicapi/notify HTTP/1.1" "\r\n"
"Host: $F" "\r\n"
"Content-Length: $D" "\r\n"
"Content-Type: application/x-www-form-urlencoded" "\r\n"
"\r\n"
"$H"),
apihost, stash_size, sd);
session = ether.tcpSend();
}
// ========================================================== end of functions ========================================
Mám podezření, že to může souviset s nějakým "mikrovýpadkem" připojení na straně ISP, protože stejná "modrá smrt " nastává ve chvíli, kdy odpojím zařízení od sítě natrvalo. Může to být důvod? A pokud ano, jak by se dal sketch vylepšit tak, aby v případě výpadku ISP k blokaci nedocházelo?
To co posílám je součástí poměrně velkého programu pro řízení technologie, proto jsem zbytek vyházel nebo nahradil maskami "xxx" a upravil. Smyčka se ve standardním programu točí jednou za vteřinu, odesílání zpráv na ThingSpeak je řešeno časovou podmínkou jednou za 60 vteřin, na notify pak v případě havárie.
Díky za pomoc a radu.
Dig
.............................................................................................................................
//library
#include <EtherCard.h>
//def NTP
static byte ntpServer[] = {204,9,54,119}; //NTP server
uint8_t ntpMyPort = 123; // NTP port
//def net
byte Ethernet::buffer[900];
static byte mymac[] = {0x70,0x69,0x69,0x2D,0x30,0x31}; //MAC adress enc28j60
boolean networkOK; // net status
//def table of message for NotifyMyAndroid
const char apihost[] PROGMEM = "www.notifymyandroid.com";
const char message0[] PROGMEM = "error type 1";
const char message1[] PROGMEM = "error type 2";
const char * const message_table[] PROGMEM = {message0, message1};
char buff[38];
//def ThingSpeak
const char website[] PROGMEM = "api.thingspeak.com";
#define APIKEY "****************"
// def class stash
Stash stash; // Class to build request to Notify My Android.
static byte session;
//def fake value
boolean fake_test;
void setup()
{
Serial.begin(9600);
//start ethercard
ether.begin(sizeof Ethernet::buffer, mymac, 53);
//first control connection and try NTP read
networkOK = networkConnection();
if (networkOK) nacteni_NTP();
}
void loop()
{
/* read NTP, in real sketch once per day in defined time */
networkOK = networkConnection();
if (networkOK) nacteni_NTP;
/* send message to thingspeak - in real sketch every 60 seconds */
byte sd = stash.create();
stash.print("field1=");
stash.print(fake_test);
stash.save();
ether.dnsLookup(website);
ether.hisip;
Stash::prepare(PSTR("POST /update HTTP/1.0" "\r\n"
"Host: $F" "\r\n"
"Connection: close" "\r\n"
"X-THINGSPEAKAPIKEY: $F" "\r\n"
"Content-Type: application/x-www-form-urlencoded" "\r\n"
"Content-Length: $D" "\r\n"
"\r\n"
"$H"),
website, PSTR(APIKEY), stash.size(), sd);
session = ether.tcpSend();
int freeCount = stash.freeCount();
if (freeCount <= 3) Stash::initMap(56);
// in real sketch only in case of damage
notifyMyAndroid(fake_test%2);
const char* reply = ether.tcpReply(session);
ether.packetLoop(ether.packetReceive());
//delay and making fake_test only for disputate, in standard case loop every second - driving by RTC module
fake_test++;
delay (60000);
}
//================================================== user´s functions ========================================
/* ... try connection ...................................................*/
boolean networkConnection()
{if (ether.dhcpSetup()) return 1; else return 0;}
/* ... read NTP time ................................................*/
byte nacteni_NTP()
{
unsigned long timeFromNTP;
const unsigned long seventy_years = 2208988800UL;
int net_count = 16; //Number of attempts
while(net_count > 0) // 60x try read NTP
{
ether.ntpRequest(ntpServer, ntpMyPort);
word length = ether.packetReceive();
ether.packetLoop(length);
if(length > 0 && ether.ntpProcessAnswer(&timeFromNTP,ntpMyPort)) // pokud zdárně načte, přenastaví RTC
{
Serial.println("NTP OK");
}
delay(500);
net_count --;
}
return 0;
}
/* ... message for NotifyMyAndroid http://www.vwlowen.co.uk/arduino/router ... onitor.htm */
static void notifyMyAndroid (const byte msg)
{
ether.dnsLookup(apihost);
ether.hisip;
strcpy_P(buff, (char*) pgm_read_word(&(message_table[msg]))); // Retrieve message from Program Memory into buffer.
byte sd = stash.create();
stash.print("apikey=");
stash.print("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); // API key www.notifymyandroid.com
stash.print("&application=");
stash.print(buff);
stash.print("&event=");
stash.print("message from engine");
stash.print("&description=");
stash.print("error - engine stoped");
stash.print("&priority=");
stash.print("0");
stash.save();
int stash_size = stash.size();
Stash::prepare(PSTR("POST /publicapi/notify HTTP/1.1" "\r\n"
"Host: $F" "\r\n"
"Content-Length: $D" "\r\n"
"Content-Type: application/x-www-form-urlencoded" "\r\n"
"\r\n"
"$H"),
apihost, stash_size, sd);
session = ether.tcpSend();
}
// ========================================================== end of functions ========================================