enc28j60 проблема с получением ответа http
- Войдите на сайт для отправки комментариев
Сб, 26/11/2016 - 00:29
Добрый день.
Подскажите кто знает. Использую 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();
}
Столов chunked в строке 10 Вы не заметили? Вам пришел фрагментированный запрос и это только его фрагмент. Ищите по этому слову в гугле - информации много что с этим делать.