enc28j60 проблема с получением ответа http

sergey1880
Offline
Зарегистрирован: 25.11.2016

Добрый день.

Подскажите кто знает. Использую enc28j60 + Mega, программа должна отправлять POST запрос на сайт и получать в ответ сообщение.

Сообщение отправляется и даже приходит ответ, но в нем только заголовок, а тела ответа нет:

HTTP/1.1 200 OK
Server: nginx/1.11.4
Date: Fri, 25 Nov 2016 20:10:08 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/5.6.11-1ubuntu3.2
Cache-Control: max-age=0
Expires: Fri, 25 Nov 2016 20:10:08 GMT


Часть кода отвечающая за отправку и получение ответа:

#include <EtherCard.h>
#include <OneWire.h>

#define DS18B20PIN1 31


#define BUFFER_SIZE 550

typedef char PROGMEM prog_char;


byte Ethernet::buffer[BUFFER_SIZE];
BufferFiller bfill;
static uint8_t mymac[6] = { 0x54,0x55,0x58,0x10,0x00,0x25};
// IP and netmask allocated by DHCP
static uint8_t myip[4] = { 0,0,0,0 };
static uint8_t mynetmask[4] = { 0,0,0,0 };
static uint8_t gwip[4] = { 0,0,0,0 };
static uint8_t dnsip[4] = { 0,0,0,0 };
static uint8_t dhcpsvrip[4] = { 0,0,0,0 };

static byte session_id;
Stash stash;
const char apihost[] PROGMEM = "mysite.ru";
uint32_t lastSend = 0;

void(* callReset) (void) = 0;

OneWire ds1(DS18B20PIN1);


String ds1_s;

int buttonpin = 24;

void setup(){
  Serial.begin(19200);
  uint8_t rev = ether.begin(sizeof Ethernet::buffer, mymac,48);
  Serial.print(getTimeDateFull());
  Serial.print( F("\nENC28J60 Revision ") );
  Serial.println( rev, DEC );
  if ( rev == 0) 
    Serial.println( F( "Failed to access Ethernet controller" ) );

  Serial.println( F( "Setting up DHCP" ));
  if (!ether.dhcpSetup())
    Serial.println( F( "DHCP failed" ));
  
  ether.printIp("My IP: ", ether.myip);
  ether.printIp("GW IP: ", ether.gwip);
  ether.printIp("DNS IP: ", ether.dnsip);
  currentTimeserver = 0;
  lastUpdate = millis();
  lastSend = millis();
}

void loop(){
  int val = digitalRead (buttonpin); // digital interface will be assigned a value of 3 to read val
  if (val == LOW)   // When the key switch when the sensor detects a signal, LED flashes
  {
    lastSend = millis();
    ds1_s=getDSTemp(ds1);
    sendPOST();
  }
 
  uint16_t pos;
  int plen = 0;
  plen = ether.packetReceive();
  pos=ether.packetLoop(plen);

 
  const char* reply = ether.tcpReply(session_id);
  if (reply != 0) 
    {
      Serial.println("Got a response!");
      Serial.println(reply);
      if (strncmp("HTTP/1.1 200 OK", reply, 15) == 0)
      {
        Serial.println("Send ether.browseUrl");
        cnt_err_send=0;
        ether.browseUrl(PSTR("/ins_sens.php"), "", apihost, my_callback);
      }
    }
}

static void my_callback (byte status, word off, word len) {
  Serial.println(">>>");
  Ethernet::buffer[off+300] = 0;
  Serial.print((const char*) Ethernet::buffer + off);
  Serial.println("...");
}

String getDSTemp(OneWire ds)
  {
    int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract;
    byte i;
    byte present=0;
    byte data[12];
    byte addr[8];
    
    String rezult=String('-100');
    if (!ds.search(addr))
     {
      Serial.print("No more addresses.\n");
      ds.reset_search();
      delay(250);
      return rezult;
     }
    /*Serial.print("R=");
    for (i=0;i<8;i++)
      {
        Serial.print(addr[i],HEX);
        Serial.print(" ");
      }*/
    if (OneWire::crc8(addr,7)!=addr[7])
      {
        Serial.print("CRC is not valid!\n");
        return rezult;
      }
    if (addr[0]!=0x28)
      {
        Serial.print("Device is not a DS18B20 family device.\n");
        Serial.println(addr[0],HEX);
        return rezult;
      }
    ds.reset();
    ds.select(addr);
    ds.write(0x44,1);
    delay(1000);
    present=ds.reset();
    ds.select(addr);
    ds.write(0xBE);

   // Serial.print("P=");
   // Serial.print(present,HEX);
   // Serial.print(" ");
    for (i=0;i<9;i++)
      {
        data[i]=ds.read();
   //     Serial.print(data[i],HEX);
   //     Serial.print(" ");
      }
   // Serial.print(" CRC=");
   // Serial.print( OneWire::crc8(data,8),HEX);
   // Serial.println();

    //Conversion of raw data to C
    LowByte=data[0];
    HighByte=data[1];
    TReading=(HighByte<<8)+LowByte;
    SignBit=TReading & 0x8000; // test most sig bit
    if (SignBit) //negative
      {
        TReading=(TReading ^ 0xffff)+1;
      }
    Tc_100=(6 * TReading) + TReading / 4;// multiply by (100 * 0.0625) or 6.25
    Whole=Tc_100/100;
    Fract=Tc_100 % 100;
    rezult = "";
  
    if (SignBit)
      {
      //  Serial.print("-");
        rezult = "-";
      }
   // Serial.print(Whole);
    rezult = rezult + Whole+".";
   // Serial.print(".");
    if (Fract<10)
      {
      //  Serial.print("0");
        rezult = rezult + "0";
      }
    //Serial.println(Fract);
    rezult = rezult + Fract;
    char char1[rezult.length()+1];
    return rezult;
    //End conversion to C
  }

static void sendPOST () 
{
  byte sd = stash.create();
  stash.print("&sensor_temp1=");
  stash.print(ds1_s);
  stash.print("&sensor_hum1=0");
  stash.save();
  int stash_size = stash.size();
  Stash::prepare(PSTR("POST /ins_sens.php 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_id = ether.tcpSend();
}

Весть код программы:

#include <EtherCard.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <OneWire.h>

#define DS18B20PIN1 31


#define SECS_YR_1900_2000  (3155673600UL)
#define GETTIMEOFDAY_TO_NTP_OFFSET 2208988800UL
#define EPOCH_YR  1970
#define SECS_DAY  86400UL  
#define LEAPYEAR(year)  (!((year) % 4) && (((year) % 100) || !((year) % 400)))
#define YEARSIZE(year)  (LEAPYEAR(year) ? 366 : 365)
#define NUM_TIMESERVERS 5
#define UTCOFSET 10800

#define BUFFER_SIZE 550

typedef char PROGMEM prog_char;


byte Ethernet::buffer[BUFFER_SIZE];
BufferFiller bfill;
static uint8_t mymac[6] = { 0x54,0x55,0x58,0x10,0x00,0x25};
// IP and netmask allocated by DHCP
static uint8_t myip[4] = { 0,0,0,0 };
static uint8_t mynetmask[4] = { 0,0,0,0 };
static uint8_t gwip[4] = { 0,0,0,0 };
static uint8_t dnsip[4] = { 0,0,0,0 };
static uint8_t dhcpsvrip[4] = { 0,0,0,0 };

static byte session_id;
Stash stash;
const char apihost[] PROGMEM = "mysite.ru";
uint32_t lastSend = 0;

const prog_char ntp0[] PROGMEM = "ntp2d.mcc.ac.uk";
const prog_char ntp1[] PROGMEM = "ntp2c.mcc.ac.uk";
const prog_char ntp2[] PROGMEM = "ntp.exnet.com";
const prog_char ntp3[] PROGMEM = "ntp.cis.strath.ac.uk";
const prog_char ntp4[] PROGMEM = "clock01.mnuk01.burstnet.eu";
const prog_char* const ntpList[] PROGMEM = { ntp0, ntp1, ntp2, ntp3, ntp4 };
uint8_t clientPort = 123;
static int currentTimeserver = 0;  
uint32_t lastUpdate = 0;
uint32_t timeLong;
int cnt_err_send=0;

void(* callReset) (void) = 0;

OneWire ds1(DS18B20PIN1);


String ds1_s;

int buttonpin = 24;

void setup(){
  Serial.begin(19200);
  setSyncProvider(RTC.get);
  uint8_t rev = ether.begin(sizeof Ethernet::buffer, mymac,48);
  Serial.print(getTimeDateFull());
  Serial.print( F("\nENC28J60 Revision ") );
  Serial.println( rev, DEC );
  if ( rev == 0) 
    Serial.println( F( "Failed to access Ethernet controller" ) );

  Serial.println( F( "Setting up DHCP" ));
  if (!ether.dhcpSetup())
    Serial.println( F( "DHCP failed" ));
  
  ether.printIp("My IP: ", ether.myip);
  ether.printIp("GW IP: ", ether.gwip);
  ether.printIp("DNS IP: ", ether.dnsip);
  currentTimeserver = 0;
  lastUpdate = millis();
  lastSend = millis();
}

void loop(){
  int val = digitalRead (buttonpin); // digital interface will be assigned a value of 3 to read val
  if (val == LOW)   // When the key switch when the sensor detects a signal, LED flashes
  {
    lastSend = millis();
    Serial.print(getTimeDateFull());
    Serial.println( F( " try send post" ));
    ether.dnsLookup( apihost );
    ether.printIp("SRV: ", ether.hisip);
    ds1_s=getDSTemp(ds1);
    sendPOST();
  }
  if ((lastSend + 60000L < millis()) &&(minute()%5==0))  // When the key switch when the sensor detects a signal, LED flashes
  {
    lastSend = millis();
    Serial.print(getTimeDateFull());
    Serial.println( F( " try send post" ));
    ether.dnsLookup( apihost );
    ether.printIp("SRV: ", ether.hisip);
    ds1_s=getDSTemp(ds1);
    sendPOST();
  }
  uint16_t pos;
  int plen = 0;
  plen = ether.packetReceive();
  pos=ether.packetLoop(plen);
  if (plen>0)
  {
    timeLong = 0L;
    if (ether.ntpProcessAnswer(&timeLong,clientPort)) 
    {
      Serial.print( F( "Time:" ));
      Serial.println(timeLong); // secs since year 1900
      if (timeLong) 
      {
        timeLong -= GETTIMEOFDAY_TO_NTP_OFFSET;
        getDateTimeNTP(timeLong+UTCOFSET);
      }
    }
  }
  if (pos) 
  {
    
    bfill=ether.tcpOffset();
    char* data = (char *) Ethernet::buffer + pos;
    if ((strncmp("GET / HTTP/1.1", data, 14) == 0) ||(strncmp("GET /favicon.ico HTTP/1.1", data, 25) == 0))
    {
    //  Serial.println("homePage");
      ether.httpServerReply(homePage()); // send web page
    }
    else
    {
      Serial.print("plen=");
    Serial.println(plen);
    Serial.print("pos=");
    Serial.println(pos);
    Serial.print("data:");
      Serial.println(data);
    }
  }
  if( (lastUpdate + 20000L < millis()) && ((year()==1970)||(hour()==21 && minute()==00)))
  {
    lastUpdate = millis();
    Serial.print( F("TimeSvr: " ) );
    Serial.println( currentTimeserver, DEC );
    if (!ether.dnsLookup( (char*)pgm_read_word(&(ntpList[currentTimeserver])) )) 
    {
      Serial.println( F("DNS failed" ));
    } 
    else 
    {
      ether.printIp("SRV: ", ether.hisip);
      Serial.print( F("Send NTP request " ));
      Serial.println( currentTimeserver, DEC );
      ether.ntpRequest(ether.hisip, ++clientPort);
      Serial.print( F("clientPort: "));
      Serial.println(clientPort, DEC );
    }
    if( ++currentTimeserver >= NUM_TIMESERVERS )
      currentTimeserver = 0; 
  }

  const char* reply = ether.tcpReply(session_id);
  if (reply != 0) 
    {
      Serial.println("Got a response!");
      Serial.println(reply);
      if (strncmp("HTTP/1.1 200 OK", reply, 15) == 0)
      {
        Serial.println("Send ether.browseUrl");
        cnt_err_send=0;
        ether.browseUrl(PSTR("/iHouse/ins_sens.php"), "", apihost, my_callback);
      }
    }
}

static void my_callback (byte status, word off, word len) {
  Serial.println(">>>");
  Ethernet::buffer[off+300] = 0;
  Serial.print((const char*) Ethernet::buffer + off);
  Serial.println("...");
}

static word homePage() 
{
  String ds1_s=getDSTemp(ds1);
  char ds1_c[ds1_s.length()+1];
  ds1_s.toCharArray(ds1_c, ds1_s.length()+1); 

  
  String dt=getTimeDateFull();
  char dt1[dt.length()+1];
  dt.toCharArray(dt1, dt.length()+1); 
  
  long t = millis() / 1000;
  word h = t / 3600;
  byte m = (t / 60) % 60;
  byte s = t % 60;
  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='10'/>"
    "<title>SS server</title>" 
    "<h2>DS1307: $S</h2>"
    "<h1>$D$D:$D$D:$D$D</h1>"
    "<h2>Sens_id_1= $S</h2>"
    ),
      dt1,h/10, h%10, m/10, m%10, s/10, s%10,ds1_c
      );
  return bfill.position();
}

void setTimeNTP(String date1,String time1)
 {
  int day = date1.substring(8, 10).toInt();
  int month = date1.substring(5, 7).toInt();
  int year = date1.substring(2, 4).toInt();
  int hours = time1.substring(0, 2).toInt();
  int minutes = time1.substring(3, 5).toInt();
  int seconds = time1.substring(6, 8).toInt();
  TimeElements te;
  te.Second = seconds;
  te.Minute = minutes;
  te.Hour = hours;
  te.Day = day;
  te.Month = month;
  te.Year = year + 30; //год в библиотеке отсчитывается с 1970. Мы хотим с 2000
  time_t timeVal = makeTime(te);
  RTC.set(timeVal);
  setTime(timeVal);
 }


String getTimeDateFull()
  {
    String result="";
    result=String(year())+"."+printDigits(month())+"."+printDigits(day())+" "+printDigits(hour())+":"+printDigits(minute())+":"+printDigits(second());
    return result;
  }
String printDigits(int digits)
  {
    String result="";
    if (digits < 10)
    result='0';
    result+=digits; 
    return result;
  }
uint8_t monthlen(uint8_t isleapyear,uint8_t month)
{
  const uint8_t mlen[2][12] = {
    { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
    { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
  };
  return(mlen[isleapyear][month]);
}
uint8_t getDateTimeNTP(const uint32_t time1)
{
  uint8_t i;
  uint32_t dayclock;
  uint16_t dayno;
  uint16_t tm_year = EPOCH_YR;
  uint8_t tm_sec,tm_min,tm_hour,tm_wday,tm_mon;
  char day1[22];
  char clock1[22];

  dayclock = time1 % SECS_DAY;
  dayno = time1 / SECS_DAY;

  tm_sec = dayclock % 60UL;
  tm_min = (dayclock % 3600UL) / 60;
  tm_hour = dayclock / 3600UL;
  tm_wday = (dayno + 4) % 7;  /* day 0 was a thursday */
  while (dayno >= YEARSIZE(tm_year)) {
    dayno -= YEARSIZE(tm_year);
    tm_year++;
  }
  tm_mon = 0;
  while (dayno >= monthlen(LEAPYEAR(tm_year),tm_mon)) {
    dayno -= monthlen(LEAPYEAR(tm_year),tm_mon);
    tm_mon++;
  }
  sprintf_P(day1,PSTR("%u-%02u-%02u"),tm_year,tm_mon+1,dayno + 1);
  sprintf_P(clock1,PSTR("%02u:%02u:%02u"),tm_hour,tm_min,tm_sec);
  if((abs(tm_min-minute())>1)||(abs(tm_hour-hour())>1))
  {
    setTimeNTP(day1,clock1);
  }
  return(tm_min);
}

String getDSTemp(OneWire ds)
  {
    int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract;
    byte i;
    byte present=0;
    byte data[12];
    byte addr[8];
    
    String rezult=String('-100');
    if (!ds.search(addr))
     {
      Serial.print("No more addresses.\n");
      ds.reset_search();
      delay(250);
      return rezult;
     }
    /*Serial.print("R=");
    for (i=0;i<8;i++)
      {
        Serial.print(addr[i],HEX);
        Serial.print(" ");
      }*/
    if (OneWire::crc8(addr,7)!=addr[7])
      {
        Serial.print("CRC is not valid!\n");
        return rezult;
      }
    if (addr[0]!=0x28)
      {
        Serial.print("Device is not a DS18B20 family device.\n");
        Serial.println(addr[0],HEX);
        return rezult;
      }
    ds.reset();
    ds.select(addr);
    ds.write(0x44,1);
    delay(1000);
    present=ds.reset();
    ds.select(addr);
    ds.write(0xBE);

   // Serial.print("P=");
   // Serial.print(present,HEX);
   // Serial.print(" ");
    for (i=0;i<9;i++)
      {
        data[i]=ds.read();
   //     Serial.print(data[i],HEX);
   //     Serial.print(" ");
      }
   // Serial.print(" CRC=");
   // Serial.print( OneWire::crc8(data,8),HEX);
   // Serial.println();

    //Conversion of raw data to C
    LowByte=data[0];
    HighByte=data[1];
    TReading=(HighByte<<8)+LowByte;
    SignBit=TReading & 0x8000; // test most sig bit
    if (SignBit) //negative
      {
        TReading=(TReading ^ 0xffff)+1;
      }
    Tc_100=(6 * TReading) + TReading / 4;// multiply by (100 * 0.0625) or 6.25
    Whole=Tc_100/100;
    Fract=Tc_100 % 100;
    rezult = "";
  
    if (SignBit)
      {
      //  Serial.print("-");
        rezult = "-";
      }
   // Serial.print(Whole);
    rezult = rezult + Whole+".";
   // Serial.print(".");
    if (Fract<10)
      {
      //  Serial.print("0");
        rezult = rezult + "0";
      }
    //Serial.println(Fract);
    rezult = rezult + Fract;
    char char1[rezult.length()+1];
    return rezult;
    //End conversion to C
  }

static void sendPOST () 
{
  byte sd = stash.create();
  stash.print("&sensor_temp1=");
  stash.print(ds1_s);
  stash.print("&sensor_hum1=0");
  stash.save();
  int stash_size = stash.size();
  Stash::prepare(PSTR("POST /ins_sens.php 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_id = ether.tcpSend();
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Столов chunked в строке 10 Вы не заметили? Вам пришел фрагментированный запрос и это только его фрагмент. Ищите по этому слову в гугле - информации много что с этим делать.