Ethernet Verbindung mit ENC28J60

Moin Moin,

Ich stehe hier vor einem kleinen Problem.

Ich habe hier 2 Atmegas 328 die über 2 Enc28j60 mit dem Netzwerk
verbunden sind.
Der eine Misst die Temperatur und gibt dann, wenn ein bestimmter
Sollwert erreicht ist auf seiner Website "Status1" bzw. "Status0" aus,
der 2. Atmega schaltet dann ein Relais. Das ganze funktioniert so weit
auch ganz gut. Nur möchte ich noch 2 weitere Buttons einfügen, die GPIO
Pins am Server High bzw. Low schalten.
Das überschreitet aber anscheinend die Größe der const char "reply" des
Clients.
Bis 3 Buttons geht es gerade so noch, darüber werden die Daten zwar
empfangen, aber das Relais wird nicht mehr geschalten.

Das komische ist, dass ich die "Website" fast beliebig "groß" machen kann, am PC wird sie vernünftig dargestellt.

Wenn ich mir die char reply im Seriellen Monitor ankucke, wird der Rest ab einer bestimmten Länge einfach abgeschnitten.

Was könnte ich tun, damit das irgendwie funktioniert ?

Danke und viele Grüße

Peter

Der Server:

#include <EtherCard.h>
#include "DHT.h"
#include <EEPROM.h>

#define DHTPIN 4
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
unsigned long previousMillis = 0;
int Tsoll;
int t;
float Tmp;
byte value;
int Status;
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x38,0x31 };
static byte myip[] = { 192,168,10,199 };


byte Ethernet::buffer[1000];
BufferFiller bfill;

void setup (){ 
  // Change 'SS' to your Slave Select pin, if you arn't using the default pin
  if (ether.begin(sizeof Ethernet::buffer, mymac, 8) == 0)
    Serial.println(F("Failed to access Ethernet controller"));
  ether.staticSetup(myip);
  dht.begin();
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);
  value = EEPROM.read(1);
  Tsoll = value;
  
}

static word homePage() {
  bfill = ether.tcpOffset();
  bfill.emit_p(PSTR(
    "HTTP/1.0 200 OK\r\n"
    "Content-Type: text/html\r\n"
    "Pragma: no-cache\r\n"
    "\r\n"
    "<meta http-equiv='refresh' content='1'/>"
    "<title>SH</title>"
    "<h1>Ti $D</h1>"
    "<h1>Ts $D</h1>"
    "<h1>Status$D</h1>"
    "<input type=submit value='+' style=width:90px;height:45px onClick=location.href'/?1'>"
    "<input type=submit value='-' style=width:90px;height:45px onClick=location.href'/?2'>"
    "<input type=submit value='R' style=width:90px;height:45px onClick=location.href'/?3'>"
    "<input type=submit value='H' style=width:90px;height:45px onClick=location.href'/?5'>"
    ),
      t, Tsoll, Status);
  return bfill.position();
}

void loop () {
    word len = ether.packetReceive();
    word pos = ether.packetLoop(len);
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= 3000) {
    previousMillis = currentMillis;
    Tmp = dht.readTemperature();
    value = EEPROM.read(1);
    }
    t = Tmp;

    if (Tsoll-2>=t){Status=1;}
    if (Tsoll-2<=t){Status=0;} 


    // IF LED10=ON turn it ON
    if(strstr((char *)Ethernet::buffer + pos, "GET /?1") != 0) {
    Tsoll++;
    EEPROM.write(1, Tsoll);
    };

    // IF LED10=OFF turn it OFF
    if(strstr((char *)Ethernet::buffer + pos, "GET /?2") != 0) {
    Tsoll--;
    EEPROM.write(1, Tsoll);
    };
    
    // IF LED10=ON turn it ON
    if(strstr((char *)Ethernet::buffer + pos, "GET /?3") != 0) {
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    digitalWrite(5, HIGH);
    };
    // IF LED10=ON turn it ON
    if(strstr((char *)Ethernet::buffer + pos, "GET /?4") != 0) {
    digitalWrite(5, LOW);
    digitalWrite(7, LOW);
    digitalWrite(6, HIGH);
    };
    // IF LED10=ON turn it ON
    if(strstr((char *)Ethernet::buffer + pos, "GET /?5") != 0) {
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, HIGH);
    };

    if (pos)  // check if valid tcp data is received
    ether.httpServerReply(homePage()); // send web page data
}

Der Client

#include <EtherCard.h>

// change these settings to match your own setup
//#define FEED "000"
#define APIKEY "beef1337beef1337" // put your key here
#define ethCSpin 8 // put your CS/SS pin here.

// ethernet interface mac address, must be unique on the LAN
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x37 };
const char website[] PROGMEM = "192.168.10.199";  //Change to your domain name 
byte Ethernet::buffer[1000];
uint32_t timer;
Stash stash;
byte session;
String d1;
//timing variable
int res = 100; // was 0
int analog=0;
unsigned long previousMillis = 0;

void(* resetFunc) (void) = 0;

void setup () {
  pinMode(3,INPUT_PULLUP);
  pinMode(7,OUTPUT);
  pinMode(4,OUTPUT);
  Serial.begin(9600);
  Serial.println("\n[ThingSpeak example]");

  //Initialize Ethernet
  initialize_ethernet();

    #if 1

  // if website is a string containing an IP address instead of a domain name,
  // then use it directly. Note: the string can not be in PROGMEM.
  char websiteIP[] = "http://192.168.10.199/";
  ether.parseIp(ether.hisip, websiteIP);
#else
  // or provide a numeric IP address instead of a string
  byte hisip[] = {192.168.10.199};
  ether.copyIp(ether.hisip, hisip);
#endif

  ether.printIp("SRV: ", ether.hisip);


}


void loop () { 
  //if correct answer is not received then re-initialize ethernet module
  if (res > 220){
    initialize_ethernet(); 
  }
  
  res = res + 1;
  
  ether.packetLoop(ether.packetReceive());
  
  //200 res = 30 seconds (150ms each res)
  if (res == 200) {

    analog = analogRead(A0);
    if(digitalRead(3)) {d1 = "OFF";} else {d1 = "ON";}  

    // generate 3 values as payload - by using a separate stash,
    // we can determine the size of the generated message ahead of time
    
    byte sd = stash.create();

    stash.print("field1=");
    stash.print(highByte(analog));
    stash.print("&field2=");
    stash.print(lowByte(analog));
    stash.print("&field3=");
    stash.print(d1);
    
    stash.save();

    // generate the header with payload - note that the stash size is used,
    // and that a "stash descriptor" is passed in as argument using "$H"
    Stash::prepare(PSTR("POST /a21.php HTTP/1.1" "\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);

    // send the packet - this also releases all stash buffers once done
    session = ether.tcpSend(); 

  }
  
   const char* reply = ether.tcpReply(session);
   
   if (reply != 0) {
     res = 0;
     Serial.println(F(" >>>REPLY recieved...."));
     Serial.println(reply);
      if(find(reply,"Status1")){digitalWrite(7, HIGH);digitalWrite(4, HIGH);delay(300);Serial.println("4+7HIGH");}
      if(find(reply,"Status0")){digitalWrite(7, LOW);digitalWrite(4, LOW);delay(300);}
      previousMillis = millis();
   }
   else {
      if (millis() - previousMillis > 50000) {
      previousMillis = millis();
      digitalWrite(7, LOW);digitalWrite(4, LOW);
      initialize_ethernet();
      resetFunc();
      }
   }
   delay(150);
}

boolean find(String string, String value){
  if(string.indexOf(value)>=0)
    return true;
  return false;
}

void initialize_ethernet(void){  
  for(;;){ // keep trying until you succeed 

    if (ether.begin(sizeof Ethernet::buffer, mymac, ethCSpin) == 0){ 
      Serial.println( "Failed to access Ethernet controller");
      digitalWrite(7, LOW);digitalWrite(4, LOW);
      
      continue;
    }
    
    if (!ether.dhcpSetup()){
      Serial.println("DHCP failed");
      digitalWrite(7, LOW);digitalWrite(4, LOW);
      continue;
    }

    ether.printIp("IP:  ", ether.myip);
    ether.printIp("GW:  ", ether.gwip);  
    ether.printIp("DNS: ", ether.dnsip);  

    if (!ether.dnsLookup(website))
      Serial.println("DNS failed");
      digitalWrite(7, LOW);digitalWrite(4, LOW);

    ether.printIp("SRV: ", ether.hisip);
    

    //reset init value
    res = 180;
    break;
  }
}

Hi

Spontan würde mir buffer[1000]; ins Auge fallen.
Ist Es möglich, daß Deine jetzige versendete Page knapp unter den 1000 Byte beinhaltet, sobald Du 'MEHR' machen willst, aber genau bei den 1000 abgeschnitten wird?

MfG

Hi,

habe ich anfangs auch schon probiert (auf 1300 hochgesetzt oder auf 700 herunter) aber bewirkt leider nichts :-(.

Ich denke dass das irgendwie an der char liegen muss. Dass irgendwie die größe davon überschritten wird, weil es ja am pc auch vernünftig dargestellt wird.

Ich habe auch versucht das auf 2 mal zu senden , habe ich aber nicht hinbekommen.

Danke und viele Grüße

Peter

Der ENC28J60 hat wenig eingebaute intelligenz darum wird der Controller zum Mitdenken verdonnert. Daß frißt Speicher. Da passiert es leicht daß der Controller blockiert.

Nimm einen W5100 Ethernet Adapter.
Grüße Uwe

stelle für den arduino-client eine minimale Seite zur Verfügung mit den Daten die dort benötigt werden. Das muss ja gar nicht so umfangreich sein, wie du es für einen Menschen im Browser benötigst.