ENC28J60 + openweathermap Нужна помощь

gospodenkods
Offline
Зарегистрирован: 05.05.2016

Ребят нужна помощь. 

Я  конечно экономист наверное не плохой но   программист  видимо  скверный ну  или тупой. Поэтому прошу  помощи у  неравнодушных .

Увлекся  я тут  штукой под названием Arduino ну  и прикупил я к ней ethernet на  чипе который  обозначен  в заголовке темы.

Собрал все в кучу  , залил тестовые скетчи , работает. 

Решил  забрать погоду с сайта http://api.openweathermap.org ,  зарегистрировался , поправил   скетч из примера WebClient следующим образом 

// Demo using DHCP and DNS to perform a web client request.

// 2011-06-08 <jc@wippler.nl> http://opensource.org/licenses/mit-license.php

#include <EtherCard.h>

// ethernet interface mac address, must be unique on the LAN
//static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
byte mymac[] = { 0x10, 0xBE, 0xF5, 0xA7, 0x45, 0x7A };

byte Ethernet::buffer[700];
static uint32_t timer;
// Сервер погоды
const char website[] PROGMEM = "api.openweathermap.org";

// called when the client request is complete
static void my_callback (byte status, word off, word len) {
  Serial.println(">>>");
  Ethernet::buffer[off+500] = 0;
  Serial.print((const char*) Ethernet::buffer + off);
  Serial.println("...");
}

void setup () {
  Serial.begin(9600);
  Serial.println(F("\n[webClient]"));

  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0) 
    Serial.println(F("Failed to access Ethernet controller"));
  if (!ether.dhcpSetup())
    Serial.println(F("DHCP failed"));

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

#if 1
  // use DNS to resolve the website's IP address
  if (!ether.dnsLookup(website))
    Serial.println("DNS failed");
#elif 2
  // 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[] = "192.168.1.1";
  ether.parseIp(ether.hisip, websiteIP);
#else
  // or provide a numeric IP address instead of a string
  byte hisip[] = { 192,168,1,1 };
  ether.copyIp(ether.hisip, hisip);
#endif
    
  ether.printIp("SRV: ", ether.hisip);
}

void loop () {
  ether.packetLoop(ether.packetReceive());
  
  if (millis() > timer) {
    timer = millis() + 5000;
    Serial.println();
    Serial.print("<<< REQ ");
   // Отправка запроса на сервер
   ether.browseUrl(PSTR("/data/2.5/"), "weather?&q=kalyazin&units=metric&appid=75abee7082ee7ccc6b02a20f6f5fb826", website, my_callback);

    
  }
}

 

Вызов  осуществляеься и сервер  мне  отвечает . 

Причем если в броузере  вызвать строку то  просто возвращяет ответ  в формате  json 

Вот ответ

{"coord":{"lon":37.84,"lat":57.24},"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04d"}],"base":"stations","main":{"temp":-5.72,"pressure":1006.68,"humidity":85,"temp_min":-5.72,"temp_max":-5.72,"sea_level":1023.51,"grnd_level":1006.68},"wind":{"speed":1.41,"deg":164.001},"clouds":{"all":80},"dt":1521613254,"sys":{"message":0.0028,"country":"RU","sunrise":1521602872,"sunset":1521647093},"id":553884,"name":"Kalyazin","cod":200}

Из Arduino  возвращяет   ответ вместе с заголовками сервера , причем не  полную строку ответа т.е  обрезает.

Вот тако ответ в  мониторе порта. 

<<< REQ >>>
HTTP/1.1 200 OK
Server: openresty
Date: Wed, 21 Mar 2018 06:44:03 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 458
Connection: close
X-Cache-Key: /data/2.5/weather?q=kalyazin&units=metric
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST

{"coord":{"lon":37.84,"lat":57.24},"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04d"}],"base":"stations","main":{"temp":-5.72,"pressure":10...

Как  видим , строка не  полная. 

Увеличение  размера  буфера  никчему не  привело.

Вопрос: Куда копать моим кривым рукам и почему    ответ приходит  порезанный ??? 

Буду  крайне признателен  если ткнете  носом. 

 

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

копать в сторону увеличения буфера Serial.print, во встроеной библиотеке

#if !defined(SERIAL_TX_BUFFER_SIZE)
#if ((RAMEND - RAMSTART) < 1023)
#define SERIAL_TX_BUFFER_SIZE 16
#else
#define SERIAL_TX_BUFFER_SIZE 64
#endif
#endif
#if !defined(SERIAL_RX_BUFFER_SIZE)
#if ((RAMEND - RAMSTART) < 1023)
#define SERIAL_RX_BUFFER_SIZE 16
#else
#define SERIAL_RX_BUFFER_SIZE 64
#endif
#endif
#if (SERIAL_TX_BUFFER_SIZE>256)
typedef uint16_t tx_buffer_index_t;
#else
typedef uint8_t tx_buffer_index_t;
#endif
#if  (SERIAL_RX_BUFFER_SIZE>256)
typedef uint16_t rx_buffer_index_t;
#else
typedef uint8_t rx_buffer_index_t;
#endif

 

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

Что Вы сделали в строке 19? Вы влепили '\0' в 500-ый элемент буфера.

А теперь посчитайте сколько символов Вы получили в своём ответе - ровно 500 (учитывая переводы строк и возвраты каретки). Вот оно и есть. Зачем Вы это делали? Что делали, то и получили. Т.е. Вы просто (на кой-то хрен) обрезали ответ сервера, ограничив его 500 знаками, а теперь возмущаетесь :)

Кстати, на Ваш нынешний ответ буфера в 700 символов мало (если хотите за раз получить). Надо почти 800.

gospodenkods
Offline
Зарегистрирован: 05.05.2016

ЕвгенийП пишет:

Что Вы сделали в строке 19? Вы влепили '\0' в 500-ый элемент буфера.

А теперь посчитайте сколько символов Вы получили в своём ответе - ровно 500 (учитывая переводы строк и возвраты каретки). Вот оно и есть. Зачем Вы это делали? Что делали, то и получили. Т.е. Вы просто (на кой-то хрен) обрезали ответ сервера, ограничив его 500 знаками, а теперь возмущаетесь :)

Кстати, на Ваш нынешний ответ буфера в 700 символов мало (если хотите за раз получить). Надо почти 800.

Спасибо  за ответ  и что  не остались равнодушным. 

 

Я  увеличил буфер по вашему совету до 800 (  ну  потестить) . 

В ответ  получил  строку  несколько удлиненную в итоге 512  символов.  Но никак не 800 . 

Вот мне  и не понятно .. 

 

gospodenkods
Offline
Зарегистрирован: 05.05.2016

Спасибо   большое за  ответ .  

Увеличил до 100 .

#define SERIAL_TX_BUFFER_SIZE 100
#define SERIAL_RX_BUFFER_SIZE 100

К сожалению ..  эфекта нет.

 

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

gospodenkods пишет:

В ответ  получил  строку  несколько удлиненную в итоге 512  символов.  Но никак не 800 . 

Свежий код?

gospodenkods
Offline
Зарегистрирован: 05.05.2016


ЕвгенийП пишет:

gospodenkods пишет:

В ответ  получил  строку  несколько удлиненную в итоге 512  символов.  Но никак не 800 . 

Свежий код?

В  настройках 

byte Ethernet::buffer[800];

В процедуре ответа.

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

Убрал присвоение 0. 

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Любят же люди за 200-300р и себе мозги поканифолить и другим. Возьмите шилд на W5100 и не мучайтесь.

gospodenkods
Offline
Зарегистрирован: 05.05.2016

sadman41 пишет:

Любят же люди за 200-300р и себе мозги поканифолить и другим. Возьмите шилд на W5100 и не мучайтесь.

Спасибо , крайне дельный совет. 

 

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

gospodenkods пишет:

byte Ethernet::buffer[800];

В процедуре ответа.

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

1. Что за строка 3? Убирайте нафиг.

2. Поставьте сюда вывод в сериал переменных off и len и скажите чему они равны. Только, опять же сразу давайте код.

gospodenkods
Offline
Зарегистрирован: 05.05.2016

Вот тут  вы дали интересную пищу для мыслей.

static void my_callback (byte status, word off, word len) {
  Serial.println(">>>");
  Serial.println(off); // вывод = 54 
  Serial.println(len); // вывод 512 
  Serial.print((const char*) Ethernet::buffer + off);
  Serial.println("...");
}

Получается , что   передается 512  символов  в самом ответе . Странно . 

Получается , что  вызов  

ether.browseUrl(PSTR("/data/2.5/"), "weather?&q=kalyazin&units=metric&appid=75abee7082ee7ccc6b02a20f6f5fb826", website, my_callback);

Возвращает как  раз 512  символов. 

 

 

 
sadman41
Offline
Зарегистрирован: 19.10.2016
gospodenkods
Offline
Зарегистрирован: 05.05.2016

Спасибо большое ,что  откликнулись. 

Из  прочтенного форума выходит , что  сама по себе бибилиотека , не  предназначена для  полноценного общения по TCP 

sadman41
Offline
Зарегистрирован: 19.10.2016

gospodenkods пишет:

Из  прочтенного форума выходит , что  сама по себе бибилиотека , не  предназначена для  полноценного общения по TCP 

Как и ENC28J60 для работы потоковыми данными.  Десяток-два байт покидать туда-сюда по модбасу какому-нить - вот ее назначение. Дешево, незамысловато. Продукт для своей ниши.

Причем, заметьте, кто отвечает на arduino.cc - ntruchsess. Это автор мощной либы UIPEthernet. Которая, конечно, тоже не без проблем, однако совместима с Ethernet.h (которая для W5100). 

gospodenkods
Offline
Зарегистрирован: 05.05.2016

Ребят , всем  спасибо за неравнодушие !!!!

Переисал скетч  с использованием библиотеки  UIPEthernet от автора ntruchsess.

Все заработало !!!!

 

gospodenkods
Offline
Зарегистрирован: 05.05.2016

Спасибо друг за  наводку на библиотечку!