Проблема загрузки WIZnet LAN

Добрый день! Направьте в правильную сторону. Есть Arduino Uno + Shild WIZnet, загружаю скетч, и вроде все работает, сеть появляется, но при отключении питания и заново подачи шилд не поднимается, сети нет, причем физически нет линка. Помогает только кнопка резет на плате или включение Монитора порта в VSCode, после чего все начинает работать и сеть поднимается…

void setup() {
  delay(10000);
 
 
  Serial.begin(9600);
  // dht.begin();
    // настройка выводов
  pinMode(gpioRelay1, OUTPUT);
  // Сброс реле в исходное состояние
  digitalWrite(gpioRelay1, lvlReleayOff);
  // Ethernet.begin(mac, ip, myDns, gateway, subnet);
  // Проверка, подключен ли кабель сети
  if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP, using static IP");
    Ethernet.begin(mac, ip, myDns, gateway, subnet);
  }
  // else{
  //   delay(5000);
  //   Ethernet.begin(mac);
  // }
  digitalWrite(gpioRelay1, 0x1);
  delay(2000);
  digitalWrite(gpioRelay1, 0x0);


  Serial.print("Server address:");
  Serial.println(Ethernet.localIP()); 
}
void loop() {
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    // while (true) {
    //   delay(1); 
    // }
    asm volatile ("  jmp 0");
  }
 
  if (mqttConnected())
  {
    mqttClient.loop();
  };
 
  relayControl();
  //  Чтение температуры и отправка в mqtt
  static unsigned long lastTempRead = 0;
  if ((millis() - lastTempRead) >= 10000)
  {
    lastTempRead = millis();
    GetSensorsToPublishMqtt();
  }
}

Это так модно? В любой непонятной ситуации делать сброс. Недавно где-то подобное видел. Если завис ethernet-модуль, то как может помочь перезагрузка МК?

Какой источник питания используете?

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

Пробовал

  1. от USB
  2. БП 5V-2.1A type-c
  3. БП 5V-2A 10W or 5V-6A 30W

А где начало скетча? Где описаны gpioRelay1 и тд?

А просто Serial все закомментировать пробовал?

#include <Arduino.h>
#include <Adafruit_Sensor.h>
#include "DHT.h"
#include <Ethernet.h>
#include <PubSubClient.h>


byte mac[] = {0xAE, 0xB2, 0x26, 0xE4, 0x4A, 0x5C};
byte ip[] = {192, 168, 4, 16};
byte myDns[] = {192, 168, 4, 254};
byte gateway[] = {192, 168, 4, 254};
byte subnet[] = {255, 255, 255, 0};

bool lan = 0;

const char* mqttServer = "192.168.4.221";
const int mqttPort = 1883;
const char* mqttClientID = "UNO1";
const char* mqttUser = "user";
const char* mqttPass = "password";

const char* mqttTopicDeviceStatus = "demo/status";
const char* mqttDeviceStatusOn = "online";
const char* mqttDeviceStatusOff = "offline";
const int   mqttDeviceStatusQos = 1;
const bool  mqttDeviceStatusRetained = true;


const char* mqttTopicTemperatureInSquare1     = "demo/temperature/square1";
const bool  mqttTemperatureStatusRetained     = false;

//  Номер выводов для подключения реле
const int gpioRelay1                          = 9;

// Логические уровни включения реле
const int lvlReleayOn                         = 0x1;
const int lvlReleayOff                        = 0x0;

// Топики внешнего управления реле
const char* mqttTopicControlRelay1            = "demo/relay1/control";
const int mqttRelaysControlQos                = 1;

// Текстовое отображение для состояния реле
const char* mqttRelay1StatusOn1               = "On";
const char* mqttRelay1StatusOn2               = "0";
const char* mqttRelay1StatusOff1              = "Off";
const char* mqttRelay1StatusOff2              = "1";
const bool mqttRelaysStatusRetained           = true;

// Топики для публикации состояния реле
const char* mqttTopicStatusRelay1             = "demo/relay1/status";

// Текущее состояние реле
char relayStatus1 = lvlReleayOff;

// Полученное с MQTT ("новое") состояние реле
char releayCommand1 = lvlReleayOff;

EthernetClient ethClient;
PubSubClient mqttClient(ethClient);


void GetTemperatureAndHumidity(int pinPort, uint8_t dhtType, float& temperature, float& humidity);
void GetSensorsToPublishMqtt();
void mqttOnIncomingMsg(char* topic, byte* payload, unsigned int length);
void relayControl();


bool mqttConnected()
{
  if (!mqttClient.connected())
  {
    Serial.println("Connecting to MQTT broker");
    mqttClient.setServer(mqttServer, mqttPort);
    mqttClient.setCallback(mqttOnIncomingMsg);

    if (mqttClient.connect(mqttClientID, mqttUser, mqttPass,
                          mqttTopicDeviceStatus, mqttDeviceStatusQos, mqttDeviceStatusRetained, mqttDeviceStatusOff))
    {
      Serial.println("OK");
      mqttClient.publish(mqttTopicDeviceStatus, mqttDeviceStatusOn, mqttDeviceStatusRetained);
      // подписываемя на топики управления реле
      mqttClient.subscribe(mqttTopicControlRelay1, mqttRelaysControlQos);
      // Публикуем текущее состояние реле
      mqttClient.publish(mqttTopicStatusRelay1, (relayStatus1 == 1 ? mqttRelay1StatusOn2 : mqttRelay1StatusOff2), mqttRelaysStatusRetained);

    }
    else{
      Serial.print("failed, error code: ");
      Serial.print(mqttClient.state());
      Serial.println("!");
    };
    return mqttClient.connected();
  };
  return true;
}

void setup() {
  // delay(10000);
  Serial.begin(9600);
  pinMode(gpioRelay1, OUTPUT);
  // Сброс реле в исходное состояние
  digitalWrite(gpioRelay1, lvlReleayOff);

  Ethernet.begin(mac, ip, myDns, gateway, subnet);
  // Проверка, подключен ли кабель сети
  if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }

  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP, using static IP");
    Ethernet.begin(mac, ip, myDns, gateway, subnet);
  }
  else{
    delay(5000);
  Ethernet.begin(mac);
  }
  // digitalWrite(gpioRelay1, 0x1);
  // delay(2000);
  // digitalWrite(gpioRelay1, 0x0);

  Serial.print("Server address:");
  Serial.println(Ethernet.localIP());  

}

void loop() {
  
  static unsigned long lastIpRead = 0;
  if ((millis() - lastIpRead) >= 5000)
  {
    lastIpRead = millis();
    Ethernet.begin(mac);
    Serial.print("Server address:");
    Serial.println(Ethernet.localIP());
    lan = 1;
  }
  
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    while (true) {
      delay(1);  
    }
    // asm volatile ("  jmp 0");
  }
  

  if (lan = 1){
    if (mqttConnected())
    {
      mqttClient.loop();
    };
    relayControl();
    //  Чтение температуры и отправка в mqtt
    static unsigned long lastTempRead = 0;
    if ((millis() - lastTempRead) >= 10000)
    {
      lastTempRead = millis();
      GetSensorsToPublishMqtt();
    }
  }
}

void GetTemperatureAndHumidity(int pinPort, uint8_t dhtType, float& temperature, float& humidity) {
  DHT d1(pinPort, dhtType);

  d1.begin();
  delay(3000);
  float t = 0;
  float h = 0;

  t = d1.readTemperature();
  if (!isnan(t)) {
    int tempInt = static_cast<int>(round(t * 10.0));
    temperature = static_cast<float>(tempInt) / 10.0;
  }
  else {
    temperature = -1;
  }

  h = d1.readHumidity();
  if (h!=0){
    int humInt = static_cast<int>(round((h + 7) * 10.0));
    humidity = static_cast<float>(humInt) / 10.0;
  }
  else {
    humidity = -1;
  }
}


void GetSensorsToPublishMqtt()
{
  float tt;
  float hh;
  GetTemperatureAndHumidity(3,DHT11,tt,hh);
  Serial.print("Temperature: ");
  Serial.print(tt);
  Serial.print(" H: ");
  Serial.println(hh);
  String str_temp(tt);
  mqttClient.publish(mqttTopicTemperatureInSquare1, str_temp.c_str(), mqttTemperatureStatusRetained);
}

// Функция обратного вызова при поступлении входящего сообщения от брокера
void mqttOnIncomingMsg(char* topic, byte* payload, unsigned int length)
{
  String _payload;
  for (unsigned int i = 0; i < length; i++)
  {
    _payload += String ((char) payload[i]);
  };
  _payload.toLowerCase();
  _payload.trim();

  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("]");
  Serial.print(_payload.c_str());
  Serial.println();

  // Сравниваем с топиами
  String _topic(topic);
  if (_topic.equals(mqttTopicControlRelay1)){
    if (_payload.equals(mqttRelay1StatusOn1) || _payload.equals(mqttRelay1StatusOn2)){
      // digitalWrite(gpioRelay1, lvlReleayOn);
      releayCommand1 = lvlReleayOn;
    };
    if (_payload.equals(mqttRelay1StatusOff1) || _payload.equals(mqttRelay1StatusOff2)){
      // digitalWrite(gpioRelay1, lvlReleayOff);
      releayCommand1 = lvlReleayOff;
    };
  } 
  else {
    Serial.println("Failed to recognize incoming topic!");
  };

};

void relayControl()
{
  if (releayCommand1 != relayStatus1)
  {
    relayStatus1 = releayCommand1;
    digitalWrite(gpioRelay1, relayStatus1);

    mqttClient.publish(mqttTopicStatusRelay1, (relayStatus1 == 1 ? mqttRelay1StatusOn2 : mqttRelay1StatusOff2), mqttRelaysStatusRetained);

    Serial.print("Relay 1 has changed its state ");
    Serial.println(relayStatus1 == 1 ? mqttRelay1StatusOn2 : mqttRelay1StatusOff2);
  }
}



Попробовал. Ничего не изменилось. После подачи питания не поднимается сеть, физики нет. Нажимаю резет и все начинает работать.

Схема где?

Схемы нет. Есть ардуина уно + шилд WIZnet к 3-му пину подключен датчик DHG11, к 9-му реле SRD-05VDC

Отключи реле и попробуй.

Тогда и обсуждать нечего.
Подождем, пока Вы опубликуете схему.

Словесное описание не заменяет схему.
Или Вы всерьез думаете, что это описание поможет понять, как разведены земля и питание?

Ведь ежу понятно, что, когда в описании проблемы встречается “но при отключении питания и заново подачи”, ничего нельзя сказать без информации о том, как питается схема.

Отключал. Даже закомментил все, что связано с реле. К сожалению нифига. Я просто не могу понять, почему при заливки кода все работает нормально, при отключении и включении перестает, но вот помогает резет или если к ПК подключен, то Start Serial Monitor тоже помогает…

Даже когда загружен код с закомментированными Serial ???


вот схема, только пины подключения 3 и 9 используются. Все остальное так же

Ну, тогда и работает так же

Но есть нюанс…

1 лайк

значит проблема в сигнале RESET, что тут непонятного

Как не странно да… Проверил, с закомментированными строками Serail, при включении монитора начинает работать!

Что значит в сигнале резет? После подачи питания как раз начинает работать после нажатия кнопки резет