Контекст

Я работал над очень конкретным случаем Arduino UNO, который ДОЛЖЕН подключаться напрямую через Ethernet к локальному (LAN) серверу Windows, на котором размещена база данных MySQL. Задача действительно проста, просто проверьте некоторые идентификаторы в этой базе данных с помощью Arduino.

Сложность заключается в том, что мне абсолютно НЕ разрешен доступ или изменение сервера, что сводит на нет любую надежду на размещение мини-скрипта API/PHP, локальную обработку соединения MySQL с этим ПК и выполнение HTTP-запросов. к этому.

Поэтому я решил использовать Arduino/MySQL Connector, который предназначен именно для этого. Однако после некоторых исследований я обнаружил, что он использует библиотеку Ethernet по умолчанию, которая не поддерживает ENC28J60 Mini Eth-Shield.

Дальнейшие исследования привели меня к маленькому совету, который должен сделать Arduino/MySQL Connector совместимым с Библиотека UIPEthernet, которая также совместима с вышеупомянутым шилдом.

Проблема

ОБНОВЛЕНИЕ 3

Github Issue

Я немного подправил программу и библиотеки, настроив UIPEthernet на отключение UDP и начав подключение к программе как статическое, что сэкономило много памяти.

Sketch использует 19182 байта (59%) пространства для хранения программ. Максимум 32256 байт. Глобальные переменные используют 1346 байт (65%) динамической памяти, оставляя 702 байта для локальных переменных. Максимум 2048 байт.

Теперь, когда программа работает без утечек памяти до смерти, я вижу, что явно столкнулся с проблемой подключения. Если это происходит из-за неизвестной несовместимости между двумя библиотеками, я не знаю.

18:00:47.074 -> Connecting
18:00:47.074 -> ...trying...
18:01:12.049 -> ...got: 0 retrying...
18:01:12.546 -> ...trying...
18:01:37.607 -> ...got: 0 retrying...
18:01:38.104 -> ...trying...
18:02:03.165 -> ...got: 0 retrying...
18:02:03.661 -> Connection Failed

Я проверил соединение всеми возможными способами с других устройств в локальной сети, и оно работает отлично.

Текущее состояние программы:

#include <UIPEthernet.h>
#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>
byte mac_addr[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

IPAddress server_addr(192, 168, 1, 8);
char user[] = "god";
char password[] = "ishallpass";
char default_db[] = "databasename";
char query[] = "SELECT nombre_cliente FROM databasename.clientes WHERE id = 1";

EthernetClient client;
MySQL_Connection conn((Client *)&client);

void setup() {
  Serial.begin(115200);
  while (!Serial);
  Ethernet.begin(mac_addr, server_addr);
  Serial.println(F("Connecting"));
  if (conn.connect(server_addr, 3306, user, password, default_db)) {
    delay(1000);
    row_values *row = NULL;
    char* nombre_cliente;
    delay(1000);
    Serial.println(F("Querying"));
    MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
    cur_mem->execute(query);
    column_names *columns = cur_mem->get_columns();
    do {
      row = cur_mem->get_next_row();
      if (row != NULL) {
        nombre_cliente = row->values[0];
      } else {
        Serial.println(F("Error querying"));
      }
    } while (row != NULL);
    delete cur_mem;
    Serial.print(F("name: "));
    Serial.println(nombre_cliente);
    delay(500);
  }
  else
    Serial.println(F("Connection Failed"));
}

void loop() {
}

ИЗМЕНИТЬ: Это полное ведение журнала UIPEthernet с ACTLOGLEVEL, установленным на LOG_DEBUG.

(LOG_DEBUG_V3 кажется бесконечным, лол)

18:40:42.573 -> Connecting
18:40:42.573 -> ...trying...
18:40:43.003 -> uip_tcpchksum(void) DEBUG:uip_buf[34-58]: 70FA
18:40:43.003 -> UIPEthernetClass::network_send() DEBUG:uip_buf (uip_len): 42, packet: 1
18:40:43.003 -> Enc28J60Network::sendPacket(memhandle handle) DEBUG:sendPacket(1) [800-82A]: 0 FF FF FF FF FF FF DE AD BE EF FE ED 8 6 0 1 8 0 6 4 0 1 DE AD BE EF FE ED C0 A8 1 8 0 0 0 0 0 0 C0 A8 1 8 
18:40:43.500 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [6-42], next: 46, stat: C0, Packet count: 1 -> OK
18:40:43.533 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=60
18:40:43.533 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:40:43.533 -> UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: 60
18:40:43.533 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:40:43.533 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:45
18:40:43.996 -> uip_tcpchksum(void) DEBUG:uip_buf[34-58]: 70FA
18:40:43.996 -> UIPEthernetClass::network_send() DEBUG:uip_buf (uip_len): 42, packet: 1
18:40:43.996 -> Enc28J60Network::sendPacket(memhandle handle) DEBUG:sendPacket(1) [800-82A]: 0 FF FF FF FF FF FF DE AD BE EF FE ED 8 6 0 1 8 0 6 4 0 1 DE AD BE EF FE ED C0 A8 1 8 0 0 0 0 0 0 C0 A8 1 8 
18:40:44.162 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [4C-96], next: 9A, stat: C0, Packet count: 1 -> OK
18:40:44.162 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=74
18:40:44.195 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:40:44.195 -> UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: 74
18:40:44.195 -> uip_tcpchksum(void) DEBUG:uip_buf[34-74]: FFFF
18:40:44.195 -> uip_tcpchksum(void) DEBUG:uip_buf[34-54]: 99F3
18:40:44.195 -> UIPEthernetClass::network_send() DEBUG:uip_buf (uip_len): 54, packet: 1
18:40:44.195 -> Enc28J60Network::sendPacket(memhandle handle) DEBUG:sendPacket(1) [800-836]: 0 AE 84 C6 A9 5D 15 DE AD BE EF FE ED 8 0 45 0 0 28 0 3 0 0 40 6 F7 65 C0 A8 1 8 C0 A8 1 F D6 24 1F 49 3 24 2C C5 C6 A 34 A1 50 14 FF FF C 66 0 0 
18:40:44.228 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:40:44.228 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:99
18:40:45.188 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [A0-EA], next: EE, stat: C0, Packet count: 1 -> OK
18:40:45.188 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=74
18:40:45.188 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:40:45.221 -> UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: 74
18:40:45.221 -> uip_tcpchksum(void) DEBUG:uip_buf[34-74]: FFFF
18:40:45.221 -> uip_tcpchksum(void) DEBUG:uip_buf[34-54]: DA90
18:40:45.221 -> UIPEthernetClass::network_send() DEBUG:uip_buf (uip_len): 54, packet: 1
18:40:45.221 -> Enc28J60Network::sendPacket(memhandle handle) DEBUG:sendPacket(1) [800-836]: 0 AE 84 C6 A9 5D 15 DE AD BE EF FE ED 8 0 45 0 0 28 0 4 0 0 40 6 F7 64 C0 A8 1 8 C0 A8 1 F D6 24 1F 49 3 24 2C C5 C6 FC D0 EF 50 14 FF FF 6F 25 0 0 
18:40:45.254 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:40:45.254 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:ED
18:40:45.751 -> uip_tcpchksum(void) DEBUG:uip_buf[34-58]: 70FA
18:40:45.751 -> UIPEthernetClass::network_send() DEBUG:uip_buf (uip_len): 42, packet: 1
18:40:45.751 -> Enc28J60Network::sendPacket(memhandle handle) DEBUG:sendPacket(1) [800-82A]: 0 FF FF FF FF FF FF DE AD BE EF FE ED 8 6 0 1 8 0 6 4 0 1 DE AD BE EF FE ED C0 A8 1 8 0 0 0 0 0 0 C0 A8 1 8 
18:40:45.784 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [F4-1A4], next: 1A8, stat: C0, Packet count: 1 -> OK
18:40:45.784 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=176
18:40:45.784 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:40:45.817 -> UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: 176
18:40:45.817 -> uip_tcpchksum(void) DEBUG:uip_buf[34-66]: 267B
18:40:45.817 -> uip_tcpchksum(void) DEBUG:uip_packet(255)[66-176]: FFFF
18:40:45.817 -> uip_tcpchksum(void) DEBUG:uip_buf[34-54]: 20D3
18:40:45.817 -> UIPEthernetClass::network_send() DEBUG:uip_buf (uip_len): 54, packet: 1
18:40:45.817 -> Enc28J60Network::sendPacket(memhandle handle) DEBUG:sendPacket(1) [800-836]: 0 54 60 9 0 4 CE DE AD BE EF FE ED 8 0 45 0 0 28 0 6 0 0 40 6 F7 67 C0 A8 1 8 C0 A8 1 A B0 7E 1F 49 F3 6E 5E 68 B9 F1 22 C8 50 14 1 36 2C DF 0 0 
18:40:45.850 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:40:45.850 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:1A7
18:40:45.949 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [1AE-1EA], next: 1EE, stat: C0, Packet count: 1 -> OK
18:40:45.982 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=60
18:40:45.982 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:40:45.982 -> UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: 60
18:40:45.982 -> uip_tcpchksum(void) DEBUG:uip_buf[34-54]: FFFF
18:40:45.982 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:40:46.015 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:1ED
18:40:46.181 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [1F4-230], next: 234, stat: C0, Packet count: 1 -> OK
18:40:46.181 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=60
18:40:46.181 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:40:46.181 -> UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: 60
18:40:46.181 -> uip_tcpchksum(void) DEBUG:uip_buf[34-54]: FFFF
18:40:46.214 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:40:46.214 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:233
18:40:46.578 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [23A-276], next: 27A, stat: C0, Packet count: 1 -> OK
18:40:46.611 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=60
18:40:46.611 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:40:46.611 -> UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: 60
18:40:46.611 -> uip_tcpchksum(void) DEBUG:uip_buf[34-54]: FFFF
18:40:46.611 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:40:46.611 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:279
18:40:47.075 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [280-2BC], next: 2C0, stat: C0, Packet count: 1 -> OK
18:40:47.075 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=60
18:40:47.075 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:40:47.075 -> UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: 60
18:40:47.108 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:40:47.108 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:2BF
18:40:47.207 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [2C6-310], next: 314, stat: C0, Packet count: 1 -> OK
18:40:47.207 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=74
18:40:47.207 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:40:47.207 -> UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: 74
18:40:47.207 -> uip_tcpchksum(void) DEBUG:uip_buf[34-74]: FFFF
18:40:47.207 -> uip_tcpchksum(void) DEBUG:uip_buf[34-54]: 75C2
18:40:47.240 -> UIPEthernetClass::network_send() DEBUG:uip_buf (uip_len): 54, packet: 1
18:40:47.240 -> Enc28J60Network::sendPacket(memhandle handle) DEBUG:sendPacket(1) [800-836]: 0 AE 84 C6 A9 5D 15 DE AD BE EF FE ED 8 0 45 0 0 28 0 7 0 0 40 6 F7 61 C0 A8 1 8 C0 A8 1 F D6 24 1F 49 3 24 2C C5 C8 DD 0 AA 50 14 FF FF 3D 8A 0 0 
18:40:47.273 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:40:47.273 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:313
18:40:47.406 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [31A-356], next: 35A, stat: C0, Packet count: 1 -> OK
18:40:47.439 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=60
18:40:47.439 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:40:47.439 -> UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: 60
18:40:47.439 -> uip_tcpchksum(void) DEBUG:uip_buf[34-54]: FFFF
18:40:47.439 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:40:47.439 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:359
18:40:49.032 -> uip_tcpchksum(void) DEBUG:uip_buf[34-58]: 70FA
18:40:49.032 -> UIPEthernetClass::network_send() DEBUG:uip_buf (uip_len): 42, packet: 1
18:40:49.032 -> Enc28J60Network::sendPacket(memhandle handle) DEBUG:sendPacket(1) [800-82A]: 0 FF FF FF FF FF FF DE AD BE EF FE ED 8 6 0 1 8 0 6 4 0 1 DE AD BE EF FE ED C0 A8 1 8 0 0 0 0 0 0 C0 A8 1 8 
18:40:49.098 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [360-39C], next: 3A0, stat: C0, Packet count: 1 -> OK
18:40:49.098 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=60
18:40:49.098 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:40:49.098 -> UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: 60
18:40:49.098 -> uip_tcpchksum(void) DEBUG:uip_buf[34-54]: FFFF
18:40:49.098 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:40:49.131 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:39F
18:40:51.283 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [3A6-3F0], next: 3F4, stat: C0, Packet count: 1 -> OK
18:40:51.283 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=74
18:40:51.283 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:40:51.283 -> UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: 74
18:40:51.283 -> uip_tcpchksum(void) DEBUG:uip_buf[34-74]: FFFF
18:40:51.283 -> uip_tcpchksum(void) DEBUG:uip_buf[34-54]: 9C5F
18:40:51.316 -> UIPEthernetClass::network_send() DEBUG:uip_buf (uip_len): 54, packet: 1
18:40:51.316 -> Enc28J60Network::sendPacket(memhandle handle) DEBUG:sendPacket(1) [800-836]: 0 AE 84 C6 A9 5D 15 DE AD BE EF FE ED 8 0 45 0 0 28 0 9 0 0 40 6 F7 5F C0 A8 1 8 C0 A8 1 F D6 24 1F 49 3 24 2C C5 CC A7 9A 6 50 14 FF FF A0 63 0 0 
18:40:51.316 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:40:51.349 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:3F3
18:40:52.541 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [3FA-436], next: 43A, stat: C0, Packet count: 1 -> OK
18:40:52.541 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=60
18:40:52.541 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:40:52.574 -> UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: 60
18:40:52.574 -> uip_tcpchksum(void) DEBUG:uip_buf[34-54]: FFFF
18:40:52.574 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:40:52.574 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:439
18:40:54.097 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [440-47C], next: 480, stat: C0, Packet count: 1 -> OK
18:40:54.097 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=60
18:40:54.097 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:40:54.130 -> UIPEthernetClass::tick() DEBUG:readPacket type ARP, uip_len: 60
18:40:54.130 -> UIPEthernetClass::network_send() DEBUG:uip_buf (uip_len): 42, packet: 1
18:40:54.130 -> Enc28J60Network::sendPacket(memhandle handle) DEBUG:sendPacket(1) [800-82A]: 0 54 60 9 0 4 CE DE AD BE EF FE ED 8 6 0 1 8 0 6 4 0 2 DE AD BE EF FE ED C0 A8 1 8 54 60 9 0 4 CE C0 A8 1 A 
18:40:54.130 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:40:54.163 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:47F
18:40:55.289 -> uip_tcpchksum(void) DEBUG:uip_buf[34-58]: 70FA
18:40:55.289 -> UIPEthernetClass::network_send() DEBUG:uip_buf (uip_len): 42, packet: 1
18:40:55.289 -> Enc28J60Network::sendPacket(memhandle handle) DEBUG:sendPacket(1) [800-82A]: 0 FF FF FF FF FF FF DE AD BE EF FE ED 8 6 0 1 8 0 6 4 0 1 DE AD BE EF FE ED C0 A8 1 8 0 0 0 0 0 0 C0 A8 1 8 
18:40:55.785 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [486-4C2], next: 4C6, stat: C0, Packet count: 1 -> OK
18:40:55.785 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=60
18:40:55.785 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:40:55.785 -> UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: 60
18:40:55.785 -> uip_tcpchksum(void) DEBUG:uip_buf[34-54]: FFFF
18:40:55.785 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:40:55.819 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:4C5
18:40:55.819 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [4CC-516], next: 51A, stat: C0, Packet count: 1 -> OK
18:40:55.819 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=74
18:40:55.819 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:40:55.852 -> UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: 74
18:40:55.852 -> uip_tcpchksum(void) DEBUG:uip_buf[34-74]: FFFF
18:40:55.852 -> uip_tcpchksum(void) DEBUG:uip_buf[34-54]: 6F85
18:40:55.852 -> UIPEthernetClass::network_send() DEBUG:uip_buf (uip_len): 54, packet: 1
18:40:55.852 -> Enc28J60Network::sendPacket(memhandle handle) DEBUG:sendPacket(1) [800-836]: 0 54 60 9 0 4 CE DE AD BE EF FE ED 8 0 45 0 0 28 0 B 0 0 40 6 F7 62 C0 A8 1 8 C0 A8 1 A B0 86 1F 49 80 8C F A5 1 DE 17 6E 50 14 38 90 7A 90 0 0 
18:40:55.885 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:40:55.885 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:519
18:40:56.448 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [520-55C], next: 560, stat: C0, Packet count: 1 -> OK
18:40:56.448 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=60
18:40:56.481 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:40:56.481 -> UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: 60
18:40:56.481 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:40:56.481 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:55F
18:40:56.481 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [566-5A2], next: 5A6, stat: C0, Packet count: 1 -> OK
18:40:56.481 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=60
18:40:56.514 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:40:56.514 -> UIPEthernetClass::tick() DEBUG:readPacket type ARP, uip_len: 60
18:40:56.514 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:40:56.514 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:5A5
18:40:56.812 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [5AC-5F6], next: 5FA, stat: C0, Packet count: 1 -> OK
18:40:56.812 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=74
18:40:56.812 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:40:56.812 -> UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: 74
18:40:56.845 -> uip_tcpchksum(void) DEBUG:uip_buf[34-74]: FFFF
18:40:56.845 -> uip_tcpchksum(void) DEBUG:uip_buf[34-54]: C5A9
18:40:56.845 -> UIPEthernetClass::network_send() DEBUG:uip_buf (uip_len): 54, packet: 1
18:40:56.845 -> Enc28J60Network::sendPacket(memhandle handle) DEBUG:sendPacket(1) [800-836]: 0 54 60 9 0 4 CE DE AD BE EF FE ED 8 0 45 0 0 28 0 C 0 0 40 6 F7 61 C0 A8 1 8 C0 A8 1 A B0 86 1F 49 80 8C F A5 2 D4 3A CE 50 14 38 90 56 3A 0 0 
18:40:56.878 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:40:56.878 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:5F9
18:40:58.798 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [600-64A], next: 64E, stat: C0, Packet count: 1 -> OK
18:40:58.798 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=74
18:40:58.798 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:40:58.831 -> UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: 74
18:40:58.831 -> uip_tcpchksum(void) DEBUG:uip_buf[34-74]: FFFF
18:40:58.831 -> uip_tcpchksum(void) DEBUG:uip_buf[34-54]: 534B
18:40:58.831 -> UIPEthernetClass::network_send() DEBUG:uip_buf (uip_len): 54, packet: 1
18:40:58.831 -> Enc28J60Network::sendPacket(memhandle handle) DEBUG:sendPacket(1) [800-836]: 0 54 60 9 0 4 CE DE AD BE EF FE ED 8 0 45 0 0 28 0 D 0 0 40 6 F7 60 C0 A8 1 8 C0 A8 1 A B0 86 1F 49 80 8C F A5 4 AE DA 81 50 14 38 90 B4 AC 0 0 
18:40:58.864 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:40:58.864 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:64D
18:40:59.195 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [654-690], next: 694, stat: C0, Packet count: 1 -> OK
18:40:59.195 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=60
18:40:59.228 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:40:59.228 -> UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: 60
18:40:59.228 -> uip_tcpchksum(void) DEBUG:uip_buf[34-54]: FFFF
18:40:59.228 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:40:59.228 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:693
18:40:59.990 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [69A-6D6], next: 6DA, stat: C0, Packet count: 1 -> OK
18:40:59.990 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=60
18:40:59.990 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:40:59.990 -> UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: 60
18:40:59.990 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:41:00.023 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:6D9
18:41:03.035 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [6E0-72A], next: 72E, stat: C0, Packet count: 1 -> OK
18:41:03.035 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=74
18:41:03.068 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:41:03.068 -> UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: 74
18:41:03.068 -> uip_tcpchksum(void) DEBUG:uip_buf[34-74]: FFFF
18:41:03.068 -> uip_tcpchksum(void) DEBUG:uip_buf[34-54]: 79E8
18:41:03.068 -> UIPEthernetClass::network_send() DEBUG:uip_buf (uip_len): 54, packet: 1
18:41:03.068 -> Enc28J60Network::sendPacket(memhandle handle) DEBUG:sendPacket(1) [800-836]: 0 54 60 9 0 4 CE DE AD BE EF FE ED 8 0 45 0 0 28 0 E 0 0 40 6 F7 5F C0 A8 1 8 C0 A8 1 A B0 86 1F 49 80 8C F A5 8 A1 73 B5 50 14 38 90 17 86 0 0 
18:41:03.101 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:41:03.101 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:72D
18:41:04.293 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [734-77E], next: 782, stat: C0, Packet count: 1 -> OK
18:41:04.293 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=74
18:41:04.326 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:41:04.326 -> UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: 74
18:41:04.326 -> uip_tcpchksum(void) DEBUG:uip_buf[34-74]: FFFF
18:41:04.326 -> uip_tcpchksum(void) DEBUG:uip_buf[34-54]: C043
18:41:04.326 -> UIPEthernetClass::network_send() DEBUG:uip_buf (uip_len): 54, packet: 1
18:41:04.326 -> Enc28J60Network::sendPacket(memhandle handle) DEBUG:sendPacket(1) [800-836]: 0 AE 84 C6 A9 5D 15 DE AD BE EF FE ED 8 0 45 0 0 28 0 F 0 0 40 6 F7 59 C0 A8 1 8 C0 A8 1 F D6 28 1F 49 F4 1B 40 B6 24 82 21 63 50 14 FF FF BC 3F 0 0 
18:41:04.359 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:41:04.359 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:781
18:41:05.320 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [788-7D2], next: 7D6, stat: C0, Packet count: 1 -> OK
18:41:05.320 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=74
18:41:05.320 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:41:05.353 -> UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: 74
18:41:05.353 -> uip_tcpchksum(void) DEBUG:uip_buf[34-74]: FFFF
18:41:05.353 -> uip_tcpchksum(void) DEBUG:uip_buf[34-54]: 33BF
18:41:05.353 -> UIPEthernetClass::network_send() DEBUG:uip_buf (uip_len): 54, packet: 1
18:41:05.353 -> Enc28J60Network::sendPacket(memhandle handle) DEBUG:sendPacket(1) [800-836]: 0 AE 84 C6 A9 5D 15 DE AD BE EF FE ED 8 0 45 0 0 28 0 10 0 0 40 6 F7 58 C0 A8 1 8 C0 A8 1 F D6 28 1F 49 F4 1B 40 B6 25 73 9B E5 50 14 FF FF 40 CC 0 0 
18:41:05.386 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:41:05.386 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:7D5
18:41:05.750 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [7DC-26], next: 2A, stat: C0, Packet count: 1 -> OK
18:41:05.783 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=74
18:41:05.783 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:41:05.783 -> UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: 74
18:41:05.783 -> uip_tcpchksum(void) DEBUG:uip_buf[34-74]: FFFF
18:41:05.783 -> uip_tcpchksum(void) DEBUG:uip_buf[34-54]: C83E
18:41:05.783 -> UIPEthernetClass::network_send() DEBUG:uip_buf (uip_len): 54, packet: 1
18:41:05.783 -> Enc28J60Network::sendPacket(memhandle handle) DEBUG:sendPacket(1) [800-836]: 0 54 60 9 0 4 CE DE AD BE EF FE ED 8 0 45 0 0 28 0 11 0 0 40 6 F7 5C C0 A8 1 8 C0 A8 1 A B0 8A 1F 49 3 9 F9 A0 B7 D0 AE 57 50 14 38 90 C1 37 0 0 
18:41:05.817 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:41:05.817 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:29
18:41:06.776 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [30-7A], next: 7E, stat: C0, Packet count: 1 -> OK
18:41:06.776 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=74
18:41:06.809 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:41:06.809 -> UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: 74
18:41:06.809 -> uip_tcpchksum(void) DEBUG:uip_buf[34-74]: FFFF
18:41:06.809 -> uip_tcpchksum(void) DEBUG:uip_buf[34-54]: 10AF
18:41:06.809 -> UIPEthernetClass::network_send() DEBUG:uip_buf (uip_len): 54, packet: 1
18:41:06.809 -> Enc28J60Network::sendPacket(memhandle handle) DEBUG:sendPacket(1) [800-836]: 0 54 60 9 0 4 CE DE AD BE EF FE ED 8 0 45 0 0 28 0 12 0 0 40 6 F7 5B C0 A8 1 8 C0 A8 1 A B0 8A 1F 49 3 9 F9 A0 B8 C4 1D AC 50 14 38 90 50 EF 0 0 
18:41:06.842 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:41:06.842 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:7D
18:41:07.339 -> Enc28J60Network::receivePacket(void) DEBUG:receivePacket [84-CE], next: D2, stat: C0, Packet count: 1 -> OK
18:41:07.339 -> Enc28J60Network::receivePacket(void) DEBUG: rxstat OK. receivePkt.size=74
18:41:07.339 -> UIPEthernetClass::tick() DEBUG:receivePacket: 255
18:41:07.339 -> UIPEthernetClass::tick() DEBUG:readPacket type IP, uip_len: 74
18:41:07.339 -> uip_tcpchksum(void) DEBUG:uip_buf[34-74]: FFFF
18:41:07.372 -> uip_tcpchksum(void) DEBUG:uip_buf[34-54]: 10C0
18:41:07.372 -> UIPEthernetClass::network_send() DEBUG:uip_buf (uip_len): 54, packet: 1
18:41:07.372 -> Enc28J60Network::sendPacket(memhandle handle) DEBUG:sendPacket(1) [800-836]: 0 AE 84 C6 A9 5D 15 DE AD BE EF FE ED 8 0 45 0 0 28 0 13 0 0 40 6 F7 55 C0 A8 1 8 C0 A8 1 F D6 28 1F 49 F4 1B 40 B6 27 54 9A E1 50 14 FF FF 3F EF 0 0 
18:41:07.405 -> UIPEthernetClass::tick() DEBUG:freeing packet: 255
18:41:07.405 -> Enc28J60Network::setERXRDPT(void) DEBUG:Set actnextPacketPtr:D1
18:41:07.637 -> uip_tcpchksum(void) DEBUG:uip_buf[34-54]: 7AE6
18:41:07.637 -> UIPEthernetClass::network_send() DEBUG:uip_buf (uip_len): 42, packet: 1
18:41:07.670 -> Enc28J60Network::sendPacket(memhandle handle) DEBUG:sendPacket(1) [800-82A]: 0 FF FF FF FF FF FF DE AD BE EF FE ED 8 6 0 1 8 0 6 4 0 1 DE AD BE EF FE ED C0 A8 1 8 0 0 0 0 0 0 C0 A8 1 8 
18:41:07.670 -> ...got: 0 retrying...
18:41:08.166 -> ...trying...
0
Pra3t0r5 30 Апр 2020 в 05:10
Вы пробовали библиотеку UIPEthernet с некоторыми простыми примерами, такими как веб-сервер?
 – 
Juraj
30 Апр 2020 в 08:19
После еще нескольких тестов ему каким-то образом удалось подключиться. Однако теперь я получаю предупреждение о нехватке памяти от arduino и ошибку памяти от соединителя mysql, см. ответ
 – 
Pra3t0r5
30 Апр 2020 в 22:26
Я мало знаю ни об архитектуре Arduino, ни о внутренностях коннектора MySQL, но внутреннее чувство подсказывает мне, что его слишком тяжело использовать на такой встроенной платформе.
 – 
mukunda
30 Апр 2020 в 23:17
Да, я разделяю это чувство. Однако это можно исправить, потому что это переменная буфера, которая получает то, что кажется логическим шумом, исходящим от соединения. Может быть, только может быть, если мы найдем причину этого, мы также сможем решить проблему с динамической памятью одним махом. Прямо здесь есть вызов выделенной памяти, возможно, это простая проблема жизненного цикла кодирования/потока, даже проблема доступа к ответу при попытке получить целевую строку (кстати, это «фернандо»)
 – 
Pra3t0r5
1 Май 2020 в 01:03
Используйте MySQL_Cursor cur_mem(&conn);. использовать макрос F() для строк
 – 
Juraj
1 Май 2020 в 07:23

1 ответ

Для потомков..

МНОГО тестов и ошибок, сделанных мной и даже с разработчиком Arduino/MySQL Connection, ясно указали, что ENC28J60 недостаточно мощный и быстрый для обработки таких соединений, и его следует избегать.

Обходной путь был достаточно простым: используйте совместимые с Arduino Ethernet Shields.

Мой обходной путь

Дальнейшее развитие проекта привело к рефакторингу прямого соединения MySQL/Ethernet на чистое соединение HTTP API:REST с использованием:

  • Arduino Sketch, который использует только Ethernet.h по умолчанию в сочетании с очень полезным ArduinoHttpClient.h библиотека.
  • Очень тщательный контроль HTTP-запросов/ответов.
  • На стороне сервера размещены PHP-скрипты, которые, в свою очередь, отвечают за подключение к базе данных и возврат данных в Arduino.

В результате один Arduino теперь может размещать простой веб-сайт панели управления, который также записывает данные в реальном времени на SD и удаленную базу данных и управляет несколькими периферийными устройствами.

Примеры

  • Сторона Ардуино

    //... IMPORTS AND CONFIG
    byte MAC_ADDR[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
    char DB_SERVER_ADDR[] = "192.168.0.21";
    IPAddress ARDUINO_IP(192, 168, 0, 19);
    EthernetClient arduinoClient;
    EthernetServer arduinoServer(80);
    HttpClient arduinoHttpClient = HttpClient(arduinoClient, DB_SERVER_ADDR, 80);
    
    //... DATA DOWNLOAD
    void downloadClients()
    {
      printlnData(F("INFO Downloading data..."), true);
      arduinoHttpClient.get("/arduino.php");
      if (arduinoHttpClient.responseStatusCode() == 200)
      {
        String response = arduinoHttpClient.responseBody();
        printlnData(response, true);
        if (response.length() > 0)
        {
          clients = response;
        }
        printlnData(String("INFO downloaded data size = ") + sizeof(clients) + "bytes", true);
      }
      else
      {
        delay(1000);
        reconnect(true);
      }
    }
    
    //... REMOTE CHECKS
    boolean checkRemotely()
    {
      char url[30];
      sprintf(url, "%s%s", "/arduino.php?pass=", password);
      // TODO: Fix requests not begin completed most of the time
      printlnData(url, true);
      if (arduinoHttpClient.get(url) == 0)
      {
        if (arduinoHttpClient.responseStatusCode() == 200)
        {
          arduinoHttpClient.responseBody();
          printlnData(F("INFO Password accepted."), true);
          return true;
        }
        else if (arduinoHttpClient.responseStatusCode() == 404)
        {
          arduinoHttpClient.responseBody();
          printlnData(F("INFO Password rejected."), true);
          digitalWrite(LED_PIN_RED, HIGH);
          return false;
        }
      }
      delay(500);
    }
    
    //... MAIN PROGRAM
    void setup()
    {
      Ethernet.begin(MAC_ADDR, ARDUINO_IP /*, gateway, subnet*/);
      arduinoServer.begin();
      initSD();
      initKeypad();
      door(DOOR_CLOSE);
      if (DEBUG != 0)
      {
        printlnData(F("INFO Version 1.3.1"), true);
        printData(F("INFO Arduino IP = "), true);
        IPAddress ip = Ethernet.localIP();
        printlnData(String() + ip[0] + "." + ip[1] + "." + ip[2] + "." + ip[3], false);
      }
    
      arduinoHttpClient = HttpClient(arduinoClient, DB_SERVER_ADDR, 80);
      delay(100);
      if (arduinoHttpClient.available())
      {
        printlnData(F("INFO Initial Connection Succeded!"), true);
        if (MODE == 0)
        {
          printlnData(F("INFO Initialized as Data Download Mode"), true);
          downloadClients();
        }
        else
        {
          printlnData(F("INFO Initialized as Remote Check Mode"), true);
        }
      }
      else
      {
        printlnData(F("WARN Initial Connection Failed!"), true);
        if (MODE == 0)
          reconnect(true);
      }
      cute.play(S_MODE3);
    }
    
    void loop()
    {
      websitePresentation();
      keypadInputProccessor();
      if (MODE == 0)
        updateLocalData();
    }
    
  • Сценарии на стороне сервера, обратите особое внимание на организацию данных и начало набора заголовков и сравните их с приведенной выше функцией downloadClients.

    <?php
        $dbhost = 'localhost';
        $dbuser = 'yourUser';
        $dbpass = 'yourPass';
        $dbname = 'yourDB';
    
    $data = "";
    $conexion = mysqli_connect($dbhost, $dbuser, $dbpass, $dbname);
        $ingresos = $_GET['ingresos'];
            $resultados = mysqli_query($conexion, "SELECT p.id AS '*', pa.id_cliente AS 'ID Paciente', concat(pa.nombre, pa.apellido) AS 'Nombre', pa.cuil AS 'CUIL', p.momento AS 'Marca Temporal' FROM pases p INNER JOIN pacientes pa ON pa.id_cliente = p.paciente ORDER BY p.id DESC LIMIT " . $ingresos);
        }
    
        if (!empty($resultados) and mysqli_num_rows($resultados) > 0) {
            $total_registros = mysqli_num_rows($resultados);
    
            $index = 1;
            while ($index <= $total_registros) {
                $fila = mysqli_fetch_array($resultados);
                if (!$debug) {
                    $data .= '<tr>';
                    $data .= '<td>' . $fila['*'] . '</td>';
                    $data .= '<td>' . $fila['ID Paciente'] . '</td>';
                    $data .= '<td>' . $fila['Nombre'] . '</td>';
                    $data .= '<td>' . $fila['CUIL'] . '</td>';
                    $data .= '<td>' . $fila['Marca Temporal'] . '</td>';
                    $data .= '</tr>';
                } else {
                    $data .= '<tr>';
                    $data .= '<td>' . $fila['*'] . '</td>';
                    $data .= '<td>' . $fila['Nombre Cliente'] . '</td>';
                    $data .= '<td>' . $fila['CUIL'] . '</td>';
                    $data .= '<td>' . $fila['Estado'] . '</td>';
                    $data .= '<td>' . $fila['Abono'] . '</td>';
                    $data .= '</tr>';
                }
                $index++;
            }
            mysqli_free_result($resultados);
            header('X-PHP-Response-Code: 200', true, 200);
            header('Access-Control-Allow-Origin: *');
        } else {
            header('X-PHP-Response-Code: 404', true, 404);
            header('Access-Control-Allow-Origin: *');
        }
        mysqli_close($conexion);
        echo $data;
    
0
Tomerikoo 11 Янв 2022 в 20:55