Ismét... ethernet kártya fagyás

Processing/Wiring (illetve C) nyelvű programozási fogások, tippek. (AVR-Duino, Arduino, EthDuino, Diecimila, Severino, Nano, LilyPad)
Válasz küldése
Avatar
spotlite
DrótVégénSzéndarab
Hozzászólások: 19
Csatlakozott: 2011. február 23. szerda, 7:00

Ismét... ethernet kártya fagyás

Hozzászólás Szerző: spotlite »

Sziasztok.
Keresgéltem már a témával kapcsolatban csevegéseket, de az egyetlen megoldás amit találtam számomra kínai, így szeretném megkérdezni az általam használt wizznet kártya miért fagy le időnként, és hogy lehet ezt kicselezni.

Jelenleg egy kliens wizznet hívogat meg másodpercenként 3-4-szer egy php-t ami válaszol is neki. Tesztként beleraktam egy számlálót ami kiírja a lekérdezések számát. A legtöbb eddig 3241 lekérdezés volt, ezután megállt.

A használt kód a következő:
#include <SPI.h>
#include <Ethernet.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

//-----------------------------------------------------------

byte mac[] = {0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 }; //mac azonosító
IPAddress ip (192,168,0,77); //ip cím, ha nincs dhcp
char server[] = "spotlite.dyndns-server.com"; //szerver címe
char dir[] = "Myweb/admin/NET/arduino/online.php"; //kapcsolattartó php címe
int web=0; //állapotjelző változó 1-es értéke a szerver felől érkező adat feldolgozását jelzi
char kar; //pufferekből beolvasott aktuális érték
String netdata; //webes pufferből beolvasott értékek összerakva szöveggé
String netsend= "ping"; //weben küldött adat
unsigned long i=1; // ping számláló (ideiglenes)

LiquidCrystal_I2C lcd(0x27, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE);
EthernetClient client;

//*******************************************************************

void i2c_lcd_setup()
{
byte a1[8] = {B10,B100,B1110,B1,B1111,B10001,B1111}; // 'á' 225
byte e1[8] = {B10,B100,B1110,B10001,B11111,B10000,B1110}; // 'é' 233
byte i1[8] = {B10,B100,B0,B1110,B100,B100,B1110}; // 'í' 237
byte o1[8] = {B100,B100,B0,B1110,B10001,B10001,B1110}; // 'ó' 243
byte o2[8] = {B1010,B0,B1110,B10001,B10001,B10001,B1110}; // ''
byte o3[8] = {B1010,B1010,B0,B1110,B10001,B10001,B1110}; // ''
byte u1[8] = {B10,B100,B10001,B10001,B10001,B10011,B1101}; // ''
byte u2[8] = {B1010,B0,B0,B10001,B10001,B10011,B1101}; // ''
byte u3[8] = {B1010,B1010,B0,B10001,B10001,B10011,B1101}; // ''

lcd.createChar(0, a1);
lcd.createChar(1, e1);
lcd.createChar(2, i1);
lcd.createChar(3, o1);
lcd.createChar(4, o3);
lcd.createChar(5, u1);
lcd.createChar(6, u2);
lcd.createChar(7, u3);

lcd.begin(16, 2);
lcd.setBacklight(1);
}

//*******************************************************************

void setup()
{
i2c_lcd_setup();
//--------------------DHCP vagy fixIP--------------------------------

if (Ethernet.begin(mac) == 0)
{
lcd.write("DHCP error");
Ethernet.begin(mac, ip);
lcd.setCursor(0,1);
lcd.write ("Kapcs fix ip");
delay (5000);lcd.clear();
}
//-----------------Kapcsolódás a megadott szerverhez-----------------

client.connect(server, 80);
while (!client.connected()){}
lcd.clear();
lcd.write ("Connect OK!");
lcd.setCursor(0,1);
lcd.print (Ethernet.localIP());
}

//***********************************************************

void loop()
{


//----------------Webes adat beolvasás------------------------------------------------

if (client.available())
{
if (web==0) {web=1; netdata="";}
kar = client.read();
netdata += kar;
}

else
{
//----------------Webes adat feldolgozás---------------------

if (web==1)
{
netdata=netdata.substring(6);
client.stop();
lcd.clear();
lcd.print (netdata);
netsend="p";
web=0;
}

//-----------------Bemenetek olvasása---------------------------------------




//-----------------Webes hívás---------------------------------------

client.connect(server, 80);
while (!client.connected()) {}
client.print("POST /");
client.print (dir);
client.print("?adat=");
client.print (netsend); client.println(i++);
client.print("Host: ");
client.println (server);
while (!client.available()) {}
delay (200);



}

}
Az adatbázis tartalma online a következő címen tekinthető meg:
http://spotlite.dyndns-server.com/Myweb ... nitor.html

Egy másik tesztnél nincs fagyás, ott a sorosporton bevitt adat kerül ugyanebbe az adatbázisba, és küldi vissza eredményként a php feldolgozó:
#include <SPI.h>
#include <Ethernet.h>

//-----------------------------------------------------------

byte mac[] = {0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 }; //mac azonosító
IPAddress ip (192,168,0,77); //ip cím, ha nincs dhcp
char server[] = "spotlite.dyndns-server.com"; //szerver címe
char dir[] = "Myweb/admin/NET/homesys/sql_monitor/index.php"; //a meghívott fájl
int seri=0; //állapotjelző változó 1-es értéke a sorosporti adat feldolgozását jelzi
int web=0; //állapotjelző változó 1-es értéke a szerver felől érkező adat feldolgozását jelzi
char kar; //pufferekből beolvasott aktuális érték
String szoveg; //sorosporti pufferből beolvasott értékek összerakva szöveggé
String net; //webes pufferből beolvasott értékek összerakva szöveggé


EthernetClient client;

//*******************************************************************

void setup()
{

//---------Sorosport csatlakozással indul az alkalmazás--------------

Serial.begin(9600);
while (!Serial) {}
Serial.println("Sorosporti monitor csatlakoztatva");

//--------------------DHCP vagy fixIP--------------------------------

if (Ethernet.begin(mac) == 0)
{
Serial.println("DHCP cimkiosztas sikertelen");
Ethernet.begin(mac, ip);
Serial.println("Kapcsolodas fix ip-vel");
}
Serial.print ("Sikeres halozati csatlakozas... Ip-cim: ") ;
Serial.println (Ethernet.localIP());

//-----------------Kapcsolódás a megadott szerverhez-----------------

client.connect(server, 80);
Serial.print ("Varakozas a kiszolgalora ");
while (!client.connected())
{
Serial.print ("."); // a várakozás "folyamat jelzője" ... normál esetben nem nagyon látható
delay (800); // ha nincs kapcsolódás a program ezen a szakaszon nem megy tovább
}
Serial.println ("\n");
Serial.print ("Sikeres kapcsolodas a - ");
Serial.print (server);
Serial.println (" - szerverhez");
}

//***********************************************************

void loop()
{
//----------------Soros adat beolvasás---------------------------------------------


if (Serial.available()) // figyelem a serial porton bejövő adatot, ha van akkor:
{
if (seri==0) {seri=1; szoveg="";} // ha az első karakter kiolvasása előtt áll akkor nullázza a 'szoveg' változót és a 'seri' állapot változót 1-re állítja.
kar = (Serial.read()); // beolvasom a soros adat pufferból az aktuális karaktert a 'kar' változóba.
if (kar==' ') {szoveg += "%20"; }// szóközök átalakítása '%20'-á
else {szoveg += kar; } // a 'kar' értéke hozzáadódik a 'szoveg' változóhoz
delay (2); // ez a várakozás azért kell mert a sorosporti memória puffer hardveresen nem vált elég hamar a következő kiolvasandó értékre. Ennél az értéknél már biztonsággal vált, és nem hibásan a rossz értéket olvasom be.
} // ebben az esetben a loop ciklus itt véget is ér. Az újabb loop ciklusban újabb karakter olvasható be a soros pufferből, amennyiben van benne még.

else
{
//----------------Soros adat feldolgozás---------------------------------------------
if (seri==1) // ha már nincs sorosporti adat, de a 'seri' változó még 1 értékű akkor átvitelre kész a 'szoveg' változó:
{
client.connect(server, 80);
while (!client.connected()) {}
client.print("POST /"); // a GET-es küldés első szakasza.
client.print (dir); // a feldolgozó PHP címének a küldése
client.print("?adat="); //
client.println (szoveg); // A változó értékének a küldése
client.print("Host: "); //
client.println (server); // A szerver nevének a küldése (ez számomra ismeretlen sorrend, de hát így működik. :-)

Serial.print (szoveg); // Serial portos visszajelzés az eseményről
Serial.println (" elkuldve a szervernek.");
seri=0; // A 'seri' változót nullára állítom, és a loop ciklus ismét újraindul
}
//----------------Webes adat beolvasás------------------------------------------------
else
{
if (client.available()) // ha nincs sorosporti adat, és a 'seri' változó nem 1 viszont van a szerver felől adat, vagyis a php adatot küld akkor:
{
if (web==0) {web=1; net="";} // Ha a 'web' állapot változó 0 akkor 1-re állítja, és a 'net' változót nullázza
kar = client.read(); // a 'c' helyi változóba olvasom a webes adatpufferből az aktuális adatot
net += kar; // a 'net' változóhoz hozzáadom a beolvasott karaktert
} // ebben az esetben a loop ciklus itt véget is ér. Az újabb loop ciklusban újabb karakter olvasható be a webes pufferből, amennyiben van benne még.
}
//----------------Webes adat feldolgozás---------------------------------------------
if (!client.available() && web==1) // Ha már nincs adat a szerver felöl, de a 'web' állapot jelző még 1 értéken van akkor:
{
Serial.print("A szerver uzenete: "); // Kiíratom a serial porton
Serial.println(net); // a szerver által küldött 'net' változó tartalmát
web=0; // A szerver által küldött adat feldolgozása véget ért, a 'web' változót 0 ra állítom.
client.stop();
}
//---------------------------------------------------------------------------------

}

//-----------------------------------------------------------

}
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Re: Ismét... ethernet kártya fagyás

Hozzászólás Szerző: Robert »

Hol állt meg? Debug? Lekérdezés? Csomagsérülés?
PHP nem válaszolt?
Memóriakezelés és túlcsordulás?

A hibakezelés hiányzik - szerintem - a kódból. Watchdog vagy reset vagy valami más.
Avatar
spotlite
DrótVégénSzéndarab
Hozzászólások: 19
Csatlakozott: 2011. február 23. szerda, 7:00

Re: Ismét... ethernet kártya fagyás

Hozzászólás Szerző: spotlite »

Hmmmm....
hát egy ilyen válasz után jövök rá, hogy mit is keresek én itt. :(
Van amit a kérdésekből álló válaszodból értek, például, hogy a "php nem válaszolt", vagy, hogy a lekérdezésnél állt-e le. :?
Sajna a "debug" nem tudom mi, csomagsérülést nem tudom hogy lehet látni analizálni, ehhez tudni kéne az egész működését.
Memóriakezelés és túlcsordulást meg főképp nem tudom hogy lehetne kifürkészni. Nekem a memóriakezelés abból áll, hogy létrehozom a változót és utána használom. Ennél többet nem tudok róla.
A hibakezelés pedig nem tudom pontosan mit is jelent. Ezzel az a gondom, hogyha hiba lesz az általában megöli a program működését, ami kezelné a hibát, vagy esetleg arról van szó, hogy mondjuk bizonyos időn belül nem jön válasz akkor kiíratom, hogy "nem válaszol a szerver". Ebben az esetben nem a program működésében, hanem egy körülménynél lett probléma, tehát ezt még lehet detektálni.
.... na mindegy, megyek nyomozgat debug ügyben.
Üdv.
Avatar
Robert
Elektronbűvölő
Hozzászólások: 10213
Csatlakozott: 2005. december 9. péntek, 7:00

Re: Ismét... ethernet kártya fagyás

Hozzászólás Szerző: Robert »

Szerszámok nélkül ne akarjunk semmit javítani....

Csomagsérülés: Etherreal / Wireshark szoftver mutatja meg az ethernetes csomagokat. Miket küld/fogad a PC. Vagy ha a rendszerben van egy régi HUB (vagy a Arduino közvetlenül megy a PC LAN csatijába), akkor a küldött/fogadott összes Ethernetcsomag ellenőrizhető.

DeBug: Bogárirtás. A programkódban pl. soros kiírások elhelyezve: Itt vagyok, erre járok. Fagyáskor látom mi volt az utolsó kiírás, azaz a fagyás mindig ugyanott van-e.

Memóriakezelés: a memfree vagy hasonló lib-ek/utasítások használatával nézhető, hogy van e valahol memóriaszivárgás, ami véletlen adatfelülírásokat okoz a chip SRAM-ban.

PHP nem válaszol: PC oladli log állomány, és látod, hogy az Arduino is mikor fagyott le. Időben a PHP szállt-e el, vagy az Arduino lekérdezésnél nincs lekezelve a válasz hiánya. Pl. javítsd át a lekérdezési utat (hibásra) illetve a LAN-ról húzd le, a PHPszervert állítsd le. Ezek a hibák Arduino oldalon kezeltek-e, vagy megy végtelen ciklusba (fagyásnak látszik).

WatchDog: Chipfagyáskor újraindítja magát.

Ezek a programírás elején tanulandóak. Az ethernetre sajna az Arduinoban mindenki úgy néz, hogy megy/nemmegy jellegű valami és 1-2 oldalon el lehet intézni. Miközben egy vacak LED villogóról 10...30 oldalakat lehet találni. Az Ethernetes hibakeresés komplexebb, és így lehetne 70...200 oldalakat írogatni róla. Csak persze senki nem foglalkozik vele... :(
Válasz küldése