Соединение 2 arduino nano через ethernet

Dump
Offline
Зарегистрирован: 01.06.2015

Доброго дня всем.  Имеются 2 модуля enc28j60 и две ардуины ) Нужно их подружить по сети, для решения простейшей задачи, на клиенте замкнулись контакты, на сервере сработало реле. В инете везде в основном описание, как поднять вебсервер. А мне вебка не нужна, чистое общение ардуинок по сети ! Ещё нигде в примерах не видел, чтобы на enc28j60 использовали шлюз по умолчанию, этот модуль и библиотека к нему умеют работать в сети полноценно ?  Может кто-то поможет ссылками, направит в нужное русло так сказать ?

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

 Вы хотите соединить платы по сети, но не использовать сетевые протоколы?
Чем вам клиент-сервер не угодил?

Dump
Offline
Зарегистрирован: 01.06.2015

Ну как же без сетевых протоколов, без них никуда )
Клиент-Сервер, отличное решение, просто я не могу найти примеров именно такого использования

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

Dump пишет:

 В инете везде в основном описание, как поднять вебсервер.

Одна Ардуино сервер, другая -  клиент.

У Осипова смотрели?

https://www.youtube.com/watch?v=PPB2Xvubt4s

Dump
Offline
Зарегистрирован: 01.06.2015

Да смотрел. Собственно с клиентом проблема, как и что там. Сейчас вроде нашел информацию, читаю изучаю. Плохо что взял 2860 , надо было wiznet5100 брать, у него tcp стек реализован железно, на 2860 я так понял стек реализован программно в библиотеке

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

Dump пишет:

... Плохо что взял 2860 , надо было wiznet5100 брать, у него tcp стек реализован железно, на 2860 я так понял стек реализован программно в библиотеке

Не переживайте - все через это прошли...

Dump
Offline
Зарегистрирован: 01.06.2015

Пока попробую на этом модуле, если не будет стабильно работать, что ж придётся переделывать )

Dump
Offline
Зарегистрирован: 01.06.2015

Доброго времени суток всем. Снова вернулся к этой теме, ибо припекло )))) Вообще подразумевается сделать такую конструкцию: Одна Ардуина(1) подключенная к ethernet - контроллирует цепь на замыкание/размыкание , вторая Ардуина(2) подключенная к ethernet на другом конце города, управляет релюшкой в соответствии с условиями полученными от первой. На данный момент я пытаюсь разобраться с сетевой составляющей программы. Так как не требуется никакого подтверждения прохождения пакетов, решил использовать для этих целей протокол UDP. В голове картинка такая: В зависимости от того, замкнута или разомкнута цепь на первом контроллере, он отправляет в сеть UDP пакет "true" или "false". Второй контроллер принимает пакет, обрабатывает его и в случае изменения состояния, замыкает или размыкает реле. Возможно идея изначально неправильная, тогда подскажите как сделать лучше, но на данный момент я имею вот что:

1 Ардуина, код:

#include <EtherCard.h>

static byte mymac[] = { 
  0x5A,0x5B,0x1A,0x2A,0x5A,0x5A };

// ip статический / постоянный Address нашей Web страницы.  
static byte myip[] = { 
  192,168,10,226 };
  
static byte hisip[] = { 
  192,168,10,227 };

// Буфер, чем больше данных на Web странице, тем больше понадобится значения буфера.
byte Ethernet::buffer[900];
BufferFiller bfill;

static uint32_t timer;

const int dstPort PROGMEM = 1234;

const int srcPort PROGMEM = 4321;

void setup()
{
  Serial.begin(9600);

  if (ether.begin(sizeof Ethernet::buffer, mymac,10) == 0);

  if (!ether.dhcpSetup()); 

  // Выводим в Serial монитор IP адрес который нам автоматический присвоил наш Router. 
  // Динамический IP адрес, это не удобно, периодический наш IP адрес будет меняться. 
  // Нам придётся каждый раз узнавать кой адрес у нашей страницы.
  ether.printIp("My Router IP: ", ether.myip); // Выводим в Serial монитор IP адрес который нам присвоил Router. 

  // Здесь мы подменяем наш динамический IP на статический / постоянный IP Address нашей Web страницы.
  // Теперь не важно какой IP адрес присвоит нам Router, автоматический будем менять его, например на "192.168.1.222". 
  ether.staticSetup(myip);

  ether.printIp("My SET IP: ", ether.myip); // Выводим в Serial монитор статический IP адрес.
  ether.printIp("SRV: ", ether.hisip);
 }
  char textToSend[] = "PRIVET KOT";
 
 void loop()
{

  delay(1); // Дёргаем микроконтроллер.
  
  word len = ether.packetReceive();   // check for ethernet packet / проверить ethernet пакеты.
  word pos = ether.packetLoop(len);   // check for tcp packet / проверить TCP пакеты.

  if (millis() > timer) {
      timer = millis() + 5000;  
     //static void sendUdp (char *data,uint8_t len,uint16_t sport, uint8_t *dip, uint16_t dport);      
     ether.sendUdp(textToSend, sizeof(textToSend), srcPort, hisip, dstPort );   
  }
  
}

2 Ардуина код:

#include <EtherCard.h>
#include <IPAddress.h>

#define STATIC 1  // set to 1 to disable DHCP (adjust myip/gwip values below)

#if STATIC
// ethernet interface ip address
static byte myip[] = { 192,168,10,227 };
// gateway ip address
static byte gwip[] = { 192,168,10,1 };
#endif

// ethernet mac address - must be unique on your network
static byte mymac[] = { 0x70,0x69,0x69,0x2D,0x30,0x31 };

byte Ethernet::buffer[500]; // tcp/ip send and receive buffer

//callback that prints received packets to the serial port
void udpSerialPrint(word port, byte ip[4], const char *data, word len) {
  IPAddress src(ip[0], ip[1], ip[2], ip[3]);
  Serial.println(src);
  Serial.println(port);
  Serial.println(data);
  Serial.println(len);
}

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

  if (ether.begin(sizeof Ethernet::buffer, mymac, 10) == 0)
    Serial.println(F("Failed to access Ethernet controller"));
#if STATIC
  ether.staticSetup(myip, gwip);
#else
  if (!ether.dhcpSetup())
    Serial.println(F("DHCP failed"));
#endif

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

  //register udpSerialPrint() to port 1234
  ether.udpServerListenOnPort(&udpSerialPrint, 1234);

  //register udpSerialPrint() to port 42.
  ether.udpServerListenOnPort(&udpSerialPrint, 42);
}

void loop(){

  delay(1); // Дёргаем микроконтроллер.

  ether.packetLoop(ether.packetReceive());
   
}

В итоге я ожидал увидеть в консоли второго контроллера, UDP пакеты, но не увидел ))))

Коды созданы из общедоступных примеров, поэтому комментарии там немного не в тему )

То, что UDP пакеты ходят, я вижу на компе: http://i017.radikal.ru/1507/1b/ba91b5975cd4.png

 

vankenshtein
Offline
Зарегистрирован: 15.04.2014

Здравствуйте долго мучался с клиентом на enc 28j60, в итоге нашел библиотеку arduino_uip. Все сразу заработало

Dump
Offline
Зарегистрирован: 01.06.2015

vankenshtein пишет:

Здравствуйте долго мучался с клиентом на enc 28j60, в итоге нашел библиотеку arduino_uip. Все сразу заработало

А можно по подробнее  ? 

vankenshtein
Offline
Зарегистрирован: 15.04.2014

https://github.com/ntruchsess/arduino_uip  вот, сам не програмист поэтому помочь мало чем могу((

Dump
Offline
Зарегистрирован: 01.06.2015

Спасибо, буду курить эту ветку )

Dump
Offline
Зарегистрирован: 01.06.2015

vankenshtein пишет:

https://github.com/ntruchsess/arduino_uip  вот, сам не програмист поэтому помочь мало чем могу((

Спасибо, библиотека помогла, по крайней мере пакеты ходят правильно и я их вижу )

vankenshtein
Offline
Зарегистрирован: 15.04.2014

Отлично, рад что помог

gragert
Offline
Зарегистрирован: 29.11.2020

добрый день.
Интересует точно такая же задача, общение двух ардуино через ethernet.
Реализовал web сервер и настроил web клиента, и при подключении через роутер (по проводам) всё работает хорошо. Но при подключении в свою собственную сеть, две ардуинки через маршрутизатор, они не подключаются.

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

Код сервера (ардуино с реле) 


#include <SPI.h>
#include <Ethernet.h>

#define OUT 8   //номер выхода для шлагбаума

byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDA, 0x02 };    
uint16_t k=0; 

IPAddress ip(192,168,0,100);  // IP адрес сервера

EthernetServer server(80);

void setup()
{
  pinMode(OUT, OUTPUT);       //инициализируем 8 пин как выход для шлагбаума     
  digitalWrite(OUT, HIGH);           
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.begin(9600);
  delay(5);
  Serial.println("start");  
}

void loop()
{
  EthernetClient client = server.available();
  if(client){                                      
    while (client.connected()) {  
      if (client.available()) {  
        char c = client.read();       
        Serial.print(c);                                             
                              
        if(c == '$' && k<100){   
          k=0;                           
            c = client.read();
            Serial.println(c);
            if(c == '1'){                        
            Serial.println("ON");
            digitalWrite(OUT, HIGH);                
            }
            
            if(c == '2'){                            
            Serial.println("OFF");
            digitalWrite(OUT, LOW);               
            }    
          client.println("HTTP/1.1 200 OK");          //заголовочная информация
          client.println("Content-Type: text/html");
          client.println("Connection: close");  
          client.println("Refresh: 30");              //автоматическое обновление каждые 30 сек
          client.println();
          client.println("<!DOCTYPE HTML>");          //HTML тип документа
          client.println("<html>");                   //открытие тега HTML 
          client.print("<title>My web Server</title>");                  //название страницы
          client.print("<H1>My web Server</H1>");                        //заголовк на странице
          client.print("<a href=\"/$1\"><button>Up</button></a>");       //кнопка включить
          client.print("<a href=\"/$2\"><button>Down</button></a>");      //кнопка выключить
          client.println("<br />");       
          client.println("</html>");                  //закрываем тег HTML
          break;                                      //выход
        }else{
          k++;  
        }
         
      }
      
    }
  
    delay(1);  
    client.stop(); 
  }
}

Код клиента (ардуино с кнопкой):

#include <SPI.h>
#include <Ethernet.h>

#define BUT 2     //пин для кнопки
#define LED A0

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress server(192,168,0,100);   //IP сервера 
IPAddress ip(192, 168, 0, 105);    //IP этого устройства
EthernetClient client;

int i=0;
uint32_t Time=0;

void setup() {
  pinMode(LED, OUTPUT);
  pinMode(BUT, INPUT);
  Serial.begin(9600);
  Ethernet.begin(mac, ip);
  digitalWrite(LED, 0);
  delay(1000);
  digitalWrite(LED, i);
  
  Serial.println("connecting...");
  if (client.connect(server, 80)) {
    Serial.println("---------------");
    // Создаем HTTP-запрос
    client.println("GET /utc/now HTTP/1.1");
    client.println("Host: http://192.168.0.100/$1");
    client.println("User-Agent: arduino-ethernet");
    client.println("Connection: close");
    client.println();
    digitalWrite(LED, i);
  } 
  else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
  Time=millis();
}

void loop() {

  if(!digitalRead(BUT) && millis()-Time>3000)
    delay(9);
    if(!digitalRead(BUT) && millis()-Time>3000){
        Serial.println("connecting...");
        if (client.connect(server, 80)){
          Serial.println("---------------");
          // Создаем HTTP-запрос
          client.println("GET /utc/now HTTP/1.1");
          if(i){
            client.println("Host: http://192.168.0.100/$1");
            i=0;
            digitalWrite(LED, i);
          }else{
            client.println("Host: http://192.168.0.100/$2");
            i=1;
            digitalWrite(LED, i);
          }  
          client.println("User-Agent: arduino-ethernet");
          client.println("Connection: close");
          client.println();
        } 
        else {
          // if you didn't get a connection to the server:
          Serial.println("connection failed");
        } 
        Time=millis();
    }
  delay(150);
  if (client.available()) {
    while(client.available()){
      char c = client.read();
      Serial.print(c);
    }
  }
  
  if(millis()-Time<0)       //если millis обнулился, то надо обнулить и переменную Time (примерно раз в 50 дней)
    Time=millis();
  
  // Если соединение прервано, отключаем клиент
  if (!client.connected()) {
 //   Serial.println();
 //   Serial.println("---------------");
 //   Serial.println("disconnecting");
    client.stop();
    // Останавливаем выполнение программы
    // while (true);
  }
}