Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 14 of 14

Thread: non blocking Ethernet.begin() with cable disconnected & static IP ?

  1. #1
    Junior Member
    Join Date
    Dec 2020
    Posts
    9

    non blocking Ethernet.begin() with cable disconnected & static IP ?

    Hello,

    I just received the wonderful new Teensy 4.1 + native ethernet kit.
    I'm working on a project which aims to transfer data on a local ethernet network as long as physical serial interfaces. I use static IPs for now.

    Question is : is there a way to avoid the "Ethernet.begin(mac, ip);" function to lock down the program if no ethernet cable is connected ? With DHCP I see there is a timeout of 60 seconds, but it doesn't seem to be the case with static IPs. How to test if a cable is there ? Set up a timeout ? Bypass Ethernet.begin(mac, ip) when no cable is there ?

    My device should be able to run and do stuff on the physical interfaces even if it is not connected to any ethernet network.

    Any clue ?

    Baptistou

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,093
    Look for the other thread or so that discusses this, seems there was a similar question recently that might have a ready answer.

  3. #3
    Junior Member
    Join Date
    Dec 2020
    Posts
    9
    Hello, sorry I went through the forums and never found the answer yet. Most of threads talk about DHCP and not fixed IP.

  4. #4
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,093
    The post I saw was found it with forum search on : "Ethernet.begin"

    Second link : T4.1 Ethernet Library , this post pjrc.com/threads/60857-T4-1-Ethernet-Library Suggests the one sample has a way to detect an active link?
    "For example the link-status example doesn't work apart if you add the ethernet begin before testing for the link."

  5. #5
    Junior Member
    Join Date
    Dec 2020
    Posts
    9
    I did that search already. Also, the second post you link to mentions the same issue which has not been solved apparently.
    Digging into NativeEthernet.cpp, I can see that the Ethernet.begin() in manual mode has this line at the bottom of the function :
    Code:
    while(!link_status){
    }
    which definitely locks the program until a cable is connected. I just removed the line, and put link_status checks inside my main program instead, to allow me to do further things while disabling all ethernet related stuff until link_status comes true. This seems to work OK. But is there a better way of doing this instead of modifying libraries inside teensyduino (which I hate to do, as it may make things become unstable - I'm a bad programmer - and also make things not portable from a computer to another, or in case of update / reinstallation) ?

  6. #6
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    15,093
    Quote Originally Posted by Baptistou View Post
    I did that search already. Also, the second post you link to mentions the same issue which has not been solved apparently.
    Digging into NativeEthernet.cpp, I can see that the Ethernet.begin() in manual mode has this line at the bottom of the function :
    Code:
    while(!link_status){
    }
    which definitely locks the program until a cable is connected. I just removed the line, and put link_status checks inside my main program instead, to allow me to do further things while disabling all ethernet related stuff until link_status comes true. This seems to work OK. But is there a better way of doing this instead of modifying libraries inside teensyduino (which I hate to do, as it may make things become unstable - I'm a bad programmer - and also make things not portable from a computer to another, or in case of update / reinstallation) ?
    You did what that post hinted at it seems with link_status.

    And indeed nothing else has been posted - other than THAT as w solution/work around.

    A better way may be out there or arrive - but until then ...

  7. #7
    Senior Member vjmuzik's Avatar
    Join Date
    Apr 2017
    Posts
    822
    Admittedly that is a draw back with the NativeEthernet library, but I’ve tried to keep its functionality as close to how the W5500 works as I can remember. Being that it is blocking in nature I strongly suggest anyone wanting more control to learn FNET by itself since for true non-blocking behavior all around things have to be coded in just right. Which to anyone who was familiar with using Ethernet.h it’s completely different in every way. I’m not sure if it makes sense to implement non-blocking functions into NativeEthernet directly when the functions are already available when FNET is used directly. If anything I would consider adding a non-blocking Ethernet.begin so at least people don’t have to worry about setting it up since that sequence won’t change from sketch to sketch.

  8. #8
    Junior Member
    Join Date
    Dec 2020
    Posts
    9
    Hello Vjmuzik, thanks for your explanations. Yes it makes sense to keep NativeEthernet equivalent and fully compatible with former ethernet libraries. Maybe a #ifndef NON_BLOCKING_ETHERNET could be added, to allow to easily pass through the loop mentionned above. If I have the time I'll try to learn FNET more deeply. Thanks again !

  9. #9
    Junior Member
    Join Date
    Apr 2021
    Posts
    4
    I modified the wait for link status loop with a timeout counter. If it fails, it times out with an enet_ready flag set. In the main program loop, I have a timer that causes it to retry the init periodically. Additionally, ethernet related TX and RX code looks at that enet_ready flag as a condition of execution to prevent getting into timeouts for hardware that is not ready now but may be ready later. Even if the link is here at init, it may not be there later.

    In my usage the ethernet is only a requirement for remote monitor and control. It has to operate 24/7 controlling local equipment with or without ethernet.

  10. #10
    Junior Member
    Join Date
    May 2021
    Posts
    6
    Are you re-calling begin() from that timer in the loop? I have the same problem and am wondering whether your solution is what I should also do. I assume that the enet_ready flag is something you added and you just query it before any ethernet activity?

  11. #11
    Junior Member
    Join Date
    Apr 2021
    Posts
    4
    Correct, I added the flag and check it at each enet usage. If it is not ready, and see that it should be (hardware was found, library started), then I start a timer and try to reinit the connection if possible. I have implemented on 3 projects, 2 are basically the same and quick testing it seems to work to There are some delays encountered during reinit as I recall. MY latest SDR project I went a bit further and have user profiles that add a setting to ignore enet functions also - so even if the enet functionality is #defined, it won't use any of the functions including enet.begin(). This is to cover the case of portable use and bypass startup or retry delays since there will be no wired connection on a tripod mounted radio in the field.

    You can look at the code for these projects are on GitHub at
    Rotator Controller
    RF Wattmeter
    The SDR project is here, most of the enet related code is in SDR_Network.cpp and Radio_Config.h.

    The description of the simple library patch I made is at the end of SDR_Network.cpp. I posted it below here. Use of a real timer would be better. The enet_flag is in my code only.

    /* Mod required for NativeEthernet.cpp file in Ethernet.begin class.
    * At end of the function is a statement that hangs if no ethernet cable is connected.
    *
    * while(!link_status){ // original loop
    * return;
    * }
    *
    * You can never progress to use the link status function to query if a cable is connected and the program is halted.
    *
    * Add the below to let it escape. Use the enet_ready flag to signal if enet started OK or not.
    *
    uint16_t escape_counter = 0;
    while(!link_status && escape_counter < 200){ // modified loop with escape counter
    escape_counter++;
    Serial.println("Waiting for Link Status");
    delay(10);
    return;
    }
    *
    */

    - Mike

  12. #12
    Junior Member
    Join Date
    May 2021
    Posts
    6
    Thanks Mike, that's really useful and something like that may be the way forward. I am working on a device that controls data sampling and acquisition from a number of sensors. A number of ethernet clients can connect, or critically, none and in the latter case there may be no cable connected either.

  13. #13
    Junior Member
    Join Date
    Nov 2020
    Posts
    9
    Would it be possible to get link status (via a new method) and we can code around this locking behavior?

  14. #14
    Senior Member
    Join Date
    Mar 2017
    Location
    Oakland, CA, USA
    Posts
    315
    I have another Ethernet library you can try:
    https://github.com/ssilverman/QNEthernet

    Itís based on lwIP instead of FNET, as an alternative for those who are more familiar with that stack.

    Its Ethernet.begin() is non-blocking and you can poll linkStatus() for changes. Iím thinking of adding a link-status callback in a near-future release. Also, it doesnít use timers; instead, it uses yield() to call things (via EventResponder). Any callbacks (currently) would not be called from an ISR context.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •