Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
soifS

soif

@soif
Plugin Developer
About
Posts
36
Topics
6
Shares
0
Groups
1
Followers
0
Following
0

Posts

Recent Best Controversial

  • NodeManager: plugin for a rapid development of battery-powered sensors
    soifS soif

    It sounds absolutely terrific ! :+1:

    Thank you very much !

    NodeManager

  • MYS Library Startup Control ? After()? OnRegistration()?
    soifS soif

    hi @Boots33

    Thank you for your really helpful answer! :-D

    Following your guidelines, I've succeeded to send MyMessages after registration is completed. Here is the code :

    boolean executeOnce = false;
    
    void setup(){ }
    
    void loop(){
     if ( ! executeOnce  && isTransportReady() ) {
        // code here to be executed once at startup
       // ...
        executeOnce = true;
     }
    }
    

    Regarding 3), here is the behaviour I would like to build:

    • Start MYsensors library
    • if startup registration works, continue to loop
    • if startup registration fails before 5s, continue to the loop
    • every 15 min try to register to the GW (either if initially failed, or if transport have dropped later)

    I've read the helpfull topic you have linked, and started to guess from reading the MyConfig.h : Is this simple code, the right one to act like I wish

    #define MY_TRANSPORT_WAIT_READY_MS 5000
    #define MY_TRANSPORT_SANITY_CHECK
    // already set as default
    //#define MY_TRANSPORT_SANITY_CHECK_INTERVAL_MS (15*60*1000ul)
    

    Obviously, in the loop, I always have to send MyMessages, with the ACK parameter set to false, to NOT wait for ACK replies whenever the GW is not available, right?

    Cheers

    General Discussion

  • MYS Library Startup Control ? After()? OnRegistration()?
    soifS soif

    In v2.0+ (I dont remember if it was the same in 1.5), there seems to be a sort of pseudo multitasking sequence happening in background when Mysensors.h is included in the sketch.

    One of the consequence is that setup() function occurs at the "same" time as the Mysensor launch/presentation/registration process.

    I discovered a before() function, which permits to be sure to launch instructions BEFORE launching MYS, but I did not discovered any after() function wich would allow me to send MyMessages only ONCE the init with the gateway has been completed :
    I mean after the "init complete, id=xx, parent=0, distance=1, registration=1"

    So the questions are :

    1. What is the recommended way to launch (setup) code only ONCE the node is registered at the gateway, ie for sensing state of initial values. Is there some sort of after() function, or OnRegistered() function ?

    2. Is there some documentation (expect reverse engineering the big MYS library) to understand all the steps that are happening in the background, when launching the library as a node.

    3. It seems that since v2.0 , if the node is unable to find a gateway (ie the GW is too far, or offline) the sketch no longer launch... is there any mechanism to controls this behaviour (ie start anyway, being able to determine is the registration was successfull or not, and if not periodically try to register) ?

    Thank you

    General Discussion

  • RFC : Lazy Submission to OpenHardware.io using GitHub
    soifS soif

    Except adding a little bit more work to maintain changes in version, date, description, adding photos, etc... ;-) So as it is not used I this time , I will remove it.

    Anyway, It would be really easy to revert the (clean-up) commit, whenever you'd decide to use this suggested (or another similar) standard.

    Feature Requests

  • RFC : Lazy Submission to OpenHardware.io using GitHub
    soifS soif

    Did you still consider adding the mysensors.json file or some sort of file stucture standardization in the Github repos?

    FYI I have some MySensors projects using the previous proposed standard :

    https://github.com/soif/MySensors_ChristmasTree
    https://github.com/soif/MySensors_MonitorsRelay
    https://github.com/soif/MySensors_HSV_RGB_IR

    and still
    https://github.com/soif/MySensors_Template
    https://github.com/soif/MySensors_Php_API

    But it you finally don't mind (I guess) to use the proposed file structure or json files, I would like to make some clean-up in my repos...

    Feature Requests

  • S_HSV_LIGHT + V_HSV Sensor type
    soifS soif

    The problem is not really concerning RGB to HSV or vice-versa (BTW if you have a working-well RGB to HSV code, i'm interested. I'm currently using the FastLED one ...)

    The idea (and this is the main reason why HSV ever existed) is to get a easy and natural way to describe colors.
    For anyone in the world it is easyer to say "I want a red, pale, not so bright" light, instead of a" #FFAA11" light! ;-) ;-)

    When you are from a controller point of view, talking directly in HSV, allows to easily set a dim level (which is a major feature for a light, isn't it?), and a color (Hue). Devs like the Domoticz ones even dropped the Saturation at this time, but they are currently receiving (and could easily send) H(S)V values.
    Also most (if not all) javascript color pickers are natively talking HSV.

    About HSL vs HSV I think this not really important because it is just a story of different gamma correction / color space (if i understand well), and for devices intended as a Light (not as screen), color deviation is not a big issue. I just vote for the most used in related software (arduino lib + Javascripts color pickers), to try to match the requested color as accuratly as possible.

    Feature Requests

  • MySensors Php API class + command line script + Form
    soifS soif

    If you dont use git just replace the form.php with the one at GitHub

    Let me know if it works flawlessly (eth or serial?).

    cheers

    My Project

  • MySensors Php API class + command line script + Form
    soifS soif

    Seems like Chrome + IE does not like function argument default values in JS, while mozilla does.

    I've just pushed v1.21 which fixes this bug.

    git pull ;-)

    My Project

  • MySensors Php API class + command line script + Form
    soifS soif

    Updated to v1.2 adding Serial gateway experimental support!

    As I don't have any serial gateway to test, I can't figure if it work or not, but I've implemented all the needed components to make it work.

    Would you please test if it work fine for you, and push some PR if some things need to be fixed for the serial connection.
    If you had to modify the "PhpSerial" class, would you please also push it back to the original developer repo

    HTH

    My Project

  • Other Controller get disconnected when sending any command to the Eth. Gateway (v2.0)
    soifS soif

    My GW don't crash while the second controller get a connection, it just throw away the previous connection.
    I've tested this with MYS v1.51, 1.54 and 2.0beta.

    My two controllers are :

    • Domoticz (primary)
    • a simple telenet connection from the terminal

    You can check this by having one controller connected, then from a terminal console type :

      telnet IP_OF_THE_GW 5003
    

    It will launch a telnet session an you will see the GW messages scrolling, but when you send any characters (ie just hit return), boom, the first connected controller is immediately disconnected.

    Troubleshooting

  • S_HSV_LIGHT + V_HSV Sensor type
    soifS soif

    I'm not worried about any losses while converting HSV->RGB : in this direction, it work pretty well (whenever the software is well written). This is in the opposite direction that conversion is happening bad. (FastLed note about this)

    I mean from the node, if I would like to work internally in HSV (in order to be able to support SMOOTH and easy dimmimg of any colors). Geting data from the controller in RGB, then converting in HSV is both approximative and adds some uneeded processing.

    Being able to easely DIM any color (ie just changing HSV.v), is one of the main argument to use HSV against raw RGB. In HSV mode you can aslo easily fade between colors (just changing the hue). This is both easy, and really intuitive.

    IMHOThese 2 features are importants to well suport RGB strips.
    Doing this in HSV, is just a few lines of code (ie using FastLed) while doing this in RGB is a nightmare and absolutely not intuitive.

    Anyway my test node works in both modes, but receiving HSV datas, would be a must and thus allow the controller so expose an HSV parameters in the API/script/GUI.

    Just imagine creating a LUA script ie, in Domoticz (or any controller) to dim an RGB strip in raw RGB mode, vs doing this in HSV.... One is very complicated while the other is really easy. and dimming a RGB strip should be as simple as dimming a single color bulb, isnt it?

    Feature Requests

  • S_HSV_LIGHT + V_HSV Sensor type
    soifS soif

    I'm proposing to add an S_HSV_LIGHT type for controlling Led Strips.

    Why

    • HSV is way more intuitive for humans to set a color than RGB. ie you can easily set a Hue (rainbow color), a Saturation (Color strength) and a brightness Level, rather than fighting against RGB values.
    • Dimming a RGB color, is at least complicated, if not impossible, while setting a HSV.v level is SO simple.
    • Controllers colors palettes are most often build from a HSV palettes, then APPROXIMATELY converted to RGB (ie Domoticz)
    • using the amazing arduino FastLed library makes converting HSV datas to RGB leds Strips (whatever the LedStrip technology) really simple, fast, precise and efficient.
    • converting on the node from HSV to RGB is precise (using FastLed) while the opposite is always approximate.
    • FastLed IS the library to use when you're talking to advanced/modern RGB chipsets, and internally talk HSV before converting to RGB.
    • some Hardware manufacturers did undertsood the interest of HSV and already implemented it this way in their products (ie Philips Hue Lights )
    • this does not prevent to use the S_RGB_LIGHT format when needed

    How

    • Define an S_HSV_LIGHT type
    • The S_HSV_LIGHT type could use the exact same payload format as the V_RGB format (3 byte of datas, encoded as a hexadecimal string): ie instead or RGB(0-255,0-255,0-255) , we would have HSV(0-255,0-255,0-255). This means that instead of having V_RGB + V_HSV , they could be merged into a shared "V_3HEX" format.

    FYI : I already have developed an (almost finished) sketch/proof-of-concept that controls a RGB led strip from HSV messages , and/or RGB messages, using the FastLed library. Obviously, the HSV messages are more intuitives and precises than the RGB messages.

    Feature Requests

  • Chinese Solar Lipo powered PIR led lamp.
    soifS soif

    @gyro
    Keep up the good work debugging this chinese box !

    This box is a really good value for money box to build mysensors projects ( at least box + lipo + solar panel).

    If your investigations let us to also use the built in Charger / PIR / LEDS , it would just be amazing.

    Please keep us in touch ! ;-)

    My Project

  • MySensors Php API class + command line script + Form
    soifS soif

    I've just posted version 1.1, including the form showed above. ;-)

    Any current users ?
    Comments?

    My Project

  • Other Controller get disconnected when sending any command to the Eth. Gateway (v2.0)
    soifS soif

    Issue #398 opened at GitHub.

    Now seeking for a C++ hero ! :-p :-p :-p

    HTH

    Troubleshooting

  • Other Controller get disconnected when sending any command to the Eth. Gateway (v2.0)
    soifS soif

    BTW would you mind if I opened an issue at GH about this, linking to this topic, to help you and others developpers to have a reminder at the right place.

    And maybe another C++ hero would see it, and start working on it! :-p

    Troubleshooting

  • MySensors Php API class + command line script + Form
    soifS soif

    Currently Working (develop branch) on a convenient form to convert/send messages .

    Form

    It should certainly help developers to test their sensors/gateway ;-)

    My Project

  • Other Controller get disconnected when sending any command to the Eth. Gateway (v2.0)
    soifS soif

    Happy if i could have helped you to save you some time to find a way for implementing a solution.

    Let us know when you'd made some progress ;-)

    Troubleshooting

  • Other Controller get disconnected when sending any command to the Eth. Gateway (v2.0)
    soifS soif

    Yep, comments are often useful when we are not that lazy to include them :-D

    BTW I've found a topic telling about modifying the Eth library to get the Source IP, and being then able to support multiple clients. I don't know if it really helps.

    Also found this where the guy says that W5100 supports 4 sockets (so max 4 clients) but the Eth lib can NOT distinguish them if they are on the same port (might be a a workaround, to open 4 port instead of one, ie 5003,5004,5005,5006). He's finally submitted a patch against the Eth lib to allow 4 different sockets on the same port.... But the more interesting seems to be a comment by "Gene" who has posted complete sketch showing how to connect multiple telnet clients . Here is his code:

    /* exampleMultiTelnetServer.ino */
    /* 
     *  Created: May 21, 2015
     *
     *  Created by Gene Reeves to demonstrate how the W5100 eithenet handles multiple connections
     *  using a single server object instance.
     * 
     *  once the sketch is loaded on your arduino and you see the start up banner display in the
     *  Serial Monitor, fire up your favorite telnet client and connect a few instances.
     *  
     *  from the serial monitor you can send text to one or all clients. Use '*" for the ID to send
     *  to all, otherwise use the ID you wish to send to, using this format to send,
     *   "ID:TEDXT_TO_SEND".  That should make everything as clear as mud  :-)
     *
     *  Dependencies:
     *
     *  uses LinkedList class from here https://github.com/ivanseidel/LinkedList
     *  to store list of connected clients.
     *
     *  uses StringStream class from here https://gist.github.com/cmaglie/5883185
     *  Not sure why this was not a part of the StringObject to start with..
     *
     *  uses elapsedMillis class from here http://playground.arduino.cc/Code/ElapsedMillis
     *  much improved version (for Teensy brand mcu's) here https://www.pjrc.com/teensy/td_timing_elaspedMillis.html
     *  Unless I am mistaken, I beleive this code was originated by Paul Stoffregen of www.pjrc.com
     *  If you are not famialar with Paul or his Teensy microcontroller, you would do yourself a 
     *  solid to spend some time reviewing his code and you can't beat the Teensy 3.1 for 
     *  price/performance/support!!!   
     *  Teensy 3.1 - 32bit-ARM  mcu @ 72MHz (overclockable to 168MHz) w/ 256K flash / 64K ram / USB
     *  for under $20.  https://www.pjrc.com/teensy/index.html
     *
     *  BTW, I am in no way affilaited with Paul or PJRC, I just think he built an awesome mcu.
     *
     */
     
     
    #include <SPI.h>
    #include <LinkedList.h>
    #include <elapsedMillis.h>
    #include <StringStream.h>
    #include <Arduino.h>
    #include <EthernetUdp.h>
    #include <EthernetServer.h>
    #include <EthernetClient.h>
    #include <Ethernet.h>
    #include <Dns.h>
    #include <Dhcp.h>
    #include <IPAddress.h>
    #include <Server.h>
    #include <Client.h>
     
     
    /*  DEFINES  */
                          
    /*****************************************************/
    /*  Change the following to suite your environment.  */
    #define TELNET_SERVER_PORT 23
    #define TELNET_SERVER_MAC 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
    #define TELNET_SERVER_IP 192, 168, 1, 177
    #define TELNET_SERVER_GATEWAY 192, 168, 1, 1
    #define TELNET_SERVER_NETMASK 255, 255, 255, 0
    #define SERIAL_BAUD 115200
    #define WELCOME_BANNER_STRING "Welcome to MultiTelnetServer.\r\nType 'exit' to disconnect\r\n"
    #define GOODBYE_BANNER_STRING "Come Back Again,   Goodbye.."
     
    #define APP_BANNER_STRING "\r\n\r\n\tMultiTelnetServer Example\r\n  This example application strives to\r\ndemonstrate using the Wiznet W5x00\r\nEthernet Shield's Arduino library usage\r\nwhen serving mulitple concurrent\r\nconnects using a single 'server object'\r\ninstance."
    #define SERVER_LISTENING_STRING "\tServer Listening on"
     
    /******************************************************/
     
     
    /*
     *  This is required to add RemoteIP, RemotePort support to the EthernetClient class
     *  I stole it from here http://forum.arduino.cc/index.php?topic=210857.0
     */
    //namespace ethernet_fix
    //{
      #include <utility/w5100.h>
     
      template<typename Tag, typename Tag::type M>
      struct AccessMember{
        friend typename Tag::type get(Tag){ return M; }
      };
     
      struct EthernetClient_Socket{
        typedef uint8_t EthernetClient::*type;
        friend type get(EthernetClient_Socket);
      };
     
      template struct AccessMember < EthernetClient_Socket, &EthernetClient::_sock > ;
     
      IPAddress RemoteIP(EthernetClient &c){
        byte remoteIP[4];
        W5100.readSnDIPR(c.*get(EthernetClient_Socket()), remoteIP);
        return (remoteIP);
      }
     
      uint16_t RemotePort(EthernetClient &c){
        return W5100.readSnDPORT(c.*get(EthernetClient_Socket()));
      }
    //} // namespace "ethernet_fix"
    /*
     *  EthernetClientEx - Because there is still no RemoteIP or RemotePort
     *  properties built in to th current EthernetClient!!
     *
     */
     
    class EthernetClientEx :
      public EthernetClient
    {
    protected:
      uint8_t _sock; // hack to get access to socket #
    public:
      EthernetClientEx(const EthernetClient &orig) : EthernetClient(orig) {}
      IPAddress remoteIP() { return RemoteIP((EthernetClient &)(*this)); }
      int16_t remotePort() { return RemotePort((EthernetClient &)(*this)); }
     
      bool isSameSock(const EthernetClientEx &c) { return (_sock == c._sock); }
    };
     
     
    /*
     *  ClientItem is class to wrap EthernetClient for storage on linked list
     *  we will use it to add a ts (millis at connection time) and an index.
     *
     */
    class ClientItem
    {
    public:
      unsigned long timestamp;
      int index;
      size_t recv_cnt;
      String recv_buffer;
      EthernetClientEx *client;
     
      ClientItem() { timestamp = millis(); index = -1; client = (EthernetClientEx *)false; }
      virtual ~ClientItem() { delete client; /* release memory */}
       
      unsigned long elapsed(void) { unsigned long ts = millis(); return (ts - timestamp); }
    };
     
    /*
     *  ClientList is linkedlist for storing connected clients. 
     *  For now, we'll just use it to store our clients, but should
     *  expand this close to include testing all clients for disconnects,
     *  testing all clients for pending recv data and sending data
     *  to all connected clients.
     */
     
    class LinkedClientList :
      public LinkedList<ClientItem*> //ClientList;
    {
    public:
      //EthernetServer *server;
     
      ClientItem *getClientItem(int idx)
      {
        for (ListNode<ClientItem *> *n = root;n;n=n->next)
        { 
          if (n->data->index == idx)
            return n->data;
        }
        return (ClientItem *)0;
      }
       
      bool exists(const EthernetClientEx &ece)
      {
        for (ListNode<ClientItem *> *n = root; n; n = n->next)
          if (n->data->client->isSameSock(ece))
            return true;
        return false;
      }
     
      void drop(int idx)
      {
        ClientItem *cli;
        int real_idx = -1;
        int ci = 0;
        for (ListNode<ClientItem *> *n = root; n; n = n->next)
          if (n->data->index != idx)
            ci++;
          else
          {
            cli = n->data;
            real_idx = ci;
            break;
          }
     
        if (real_idx != -1)
        {
          if (cli->client->connected())
            cli->client->stop();
          cli->index = -1;
          remove(real_idx);
        }
      }
     
      size_t send(const String &s, int idx)
      {
        size_t ret = 0;
        ClientItem * cli = getClientItem(idx);
        if (cli)
        {
          ret = cli->client->print(s);
          cli->client->flush();
        }
        return ret;
      }
     
      size_t send2All(const String &s)
      {
        size_t ret = 0;
        for (ListNode<ClientItem *> *n = root; n; n = n->next)
        {
          ret += n->data->client->print(s);
          n->data->client->flush();
        }
        return ret;
      }
    };
     
    LinkedClientList ClientList;
     
    // Enter a MAC address and IP address for your controller below.
    // The IP address will be dependent on your local network.
    // gateway and subnet are optional:
    byte mac[] = { TELNET_SERVER_MAC };
    IPAddress ip(TELNET_SERVER_IP);
    IPAddress gateway(TELNET_SERVER_GATEWAY);
    IPAddress subnet(TELNET_SERVER_NETMASK);
     
    // buffer to hold input from console
    StringStream con_buffer("");
     
    // telnet defaults to port 23
    EthernetServer server(TELNET_SERVER_PORT);
     
    /* forward's */
    void server_check_new_connections(void);
    void server_check_client_recv(void);
    int server_accept(EthernetClientEx *enetcli);
    bool clientExists(const EthernetClientEx &c);
    bool test_for_cmd(const String &itm, const String &src);
    size_t console_recv(void);
    void proc_line(StringStream &ss);
     
    size_t client_recv(ClientItem *cli);
    void client_disconnecting(ClientItem *cli);
    void client_disconnected(ClientItem *cli);
     
    size_t send_to(int idx, const String &str);
    size_t send_to_all(const String &str);
     
    /*********************************************************/
    void setup()
    {
     
      /* add setup code here */
      // reserve some space for input buffer
      con_buffer.reserve(256);
     
      // Open serial communications and wait for port to open:
      Serial.begin(SERIAL_BAUD);
      delay(3000);  // 3 second delay for Serial to connect.
     
      pinMode(10, OUTPUT);
      digitalWrite(10, HIGH);
      pinMode(4, OUTPUT);
      digitalWrite(4, HIGH);
     
      // initialize the ethernet device
      Ethernet.begin(mac, ip, gateway, subnet);
      // start listening for clients
      server.begin();
     
      // Print "App Banner" and "Server Listening" notice.
      Serial.println(F(APP_BANNER_STRING));
      Serial.println(F(SERVER_LISTENING_STRING));
      Serial.print(F("\t\t"));
      Serial.print(ip);
      Serial.print(':');
      Serial.println(TELNET_SERVER_PORT);
      Serial.println(F("\r\n\r\n"));
     
    }
     
    void loop()
    {
     
      /* add main program code here */
     
      // check for any new clients
      server_check_new_connections();
     
      // give up a timeslice
      yield();
     
      // check to see if any of the clients 
      // have recv data pending
      if (ClientList.size() > 0)
        server_check_client_recv();
     
      // give up a timeslice
      yield();
     
      // check to see if console has any 
      // pending recv data.
      if (Serial.available())
        console_recv();
     
      // give up a timeslice
      yield();
    }
     
    /*********************************************************/
     
    size_t console_recv(void)
    {
      size_t ret = 0;
      int c = 0;
      while ((c = Serial.read()) >= 0)
      {
        if (c == 10)
        {
          proc_line(con_buffer);
          con_buffer = String("");
          con_buffer.begin();
          continue;
        }
        if (c != 13)
        {
          con_buffer += (char)c;
          ret++;
        }
      }
      return ret;
    }
     
    void proc_line(StringStream &ss)
    {
     
      //  Console input should be in the for of
      //  "ID:string_literal"
      //  where: 
      //    ID is client index to send to or "*" (all)
      //    string_literal is string to send
      //
      // check to ensure 2nd char is a ":"
      if ((ss.length() < 3) || (ss.charAt(1) != ':'))
      {
        Serial.print(F("Invalid Console Input \""));
        Serial.print(ss);
        Serial.print(F("\"\r\nPlease use the following format:\r\n\t"));
        Serial.println(F("\"ID:string_literal\"\r\n"));
        Serial.flush();
        return;
      }
      int idx = -1;
      Serial.print(F(" first char is '"));
      Serial.print(ss.charAt(0));
      Serial.print(F("',  "));
      if (ss.charAt(0) != '*')
      {
        idx = ss.parseInt();
      }
      Serial.print(F("idx="));
      Serial.print(idx);
      Serial.print(F(", indexOf(':')="));
      Serial.println(ss.indexOf(':'));
      ss = ss.substring(1 + ss.indexOf(':'));
      ss += F("\r\n");
      if (idx < 0)
        ClientList.send2All(ss);
        //send_to_all(ss);
      else
        ClientList.send(ss, idx);
    }
     
    size_t console_print_connected_count(void)
    {
      size_t ret =
        Serial.print(F("\t\t")) +
        Serial.print(ClientList.size()) +
        Serial.println(F(" connected client(s).\r\n"));
      Serial.flush();
      return ret;
    }
     
    bool test_for_cmd(const String &itm, const String &src)
    {
      String tst(src);
      tst.toLowerCase();
      return tst.startsWith(itm);
    }
     
    void server_check_new_connections(void)
    {
      EthernetClient obj = server.available();  
      if (obj)
      {
        // convert to EthernetClientEx
        EthernetClientEx new_client(obj);
        // is it a new connection?
        if (!ClientList.exists(new_client))
        {
          // accept new connection
          server_accept((EthernetClientEx *)&new_client);
     
          // send welcome banner
          new_client.println(F(WELCOME_BANNER_STRING));
          new_client.flush();
        }
      }
    }
     
    int server_accept(EthernetClientEx *enetcli)
    {
      // add itm to list
      ClientItem *itm = new ClientItem();
      itm->timestamp = millis();
      itm->index = ClientList.size();
      itm->client = new EthernetClientEx((*enetcli));
      ClientList.add(itm);
     
      // print notice on console
      Serial.print(F("Accepted new connection ("));
      Serial.print(itm->index);
      Serial.print(F(") from "));
      Serial.print(enetcli->remoteIP());
      Serial.print(':');
      Serial.println(enetcli->remotePort());
      Serial.println();
      Serial.flush();
     
      // print connected count
      console_print_connected_count();
     
      // return items index
      return itm->index;
    }
     
    void server_check_client_recv(void)
    {
      if (ClientList.size() == 0) return;
      ClientItem *itm;
      for (int idx = ClientList.size() - 1; idx >= 0; idx--)
      {
        itm = ClientList.get(idx);
        if (itm->client->connected()==0)
        {
          client_disconnected(itm);
          continue;
        }
        if (itm->client->available())
        {
          size_t rc = client_recv(itm);
          if (rc > 0)
          {
            // echo to Serial port
            Serial.print(F("Client #"));
            Serial.print(itm->index);
            Serial.print(F(" sent \""));
            Serial.print(itm->recv_buffer);
            Serial.println('\"');
            Serial.flush();
          }
          // rc will == 0 if nothing received
          // rc will == -1 if client entered "exit"
        }
        yield();
      }
    }
     
    size_t client_recv(ClientItem *cli)
    {
      int c;
      EthernetClientEx *cIn = (EthernetClientEx *)cli->client;
      cli->recv_buffer = "\0";
      cli->recv_cnt = 0;
      while ((c = cIn->read()) >= 0)
      {
        cli->recv_buffer += (char)c;
        cli->recv_cnt++;
      }
      // check to see if they typed "exit"
      if (test_for_cmd(String(F("exit")), cli->recv_buffer))
      {
        client_disconnecting(cli);
        delay(1); // give up timeslice
        cli->client->stop();
        Serial.print(F("called client->stop() for #")); Serial.println(cli->index); Serial.flush();
        return -1;
      }
      return cli->recv_cnt;
    }
     
    void client_disconnecting(ClientItem *cli)
    {
      Serial.print(F("Client #"));
      Serial.print(cli->index);
      Serial.println(F(" is disconnecting."));
      // send Goodbye Banner
      send_to(cli->index, String(F(GOODBYE_BANNER_STRING)));
      Serial.flush();
      delay(1);
      cli->client->stop();
    }
     
    void client_disconnected(ClientItem *cli)
    {
      // print notice on console
      Serial.print(F("Client #"));
      Serial.print(cli->index);
      Serial.print(F(" was connected for "));
      Serial.print(cli->elapsed() / 1000);
      Serial.print(F(" seconds, and has disconnected."));
      Serial.flush();
     
      // remove from list of clients
      ClientList.drop(cli->index);
      (*cli) = (*(ClientItem *)(unsigned long)0);
      // print connected count
      console_print_connected_count();
     
      // this causes seg fault ??
      //delete cli;
    }
     
    size_t send_to(int idx, const String &str)
    {
      return ClientList.send(str, idx);
    }
     
    size_t send_to_all(const String &str)
    {
      return ClientList.send2All(str);
    }
    
    

    Bingo ? Sounds good?

    Again, sorry my C++ knowledge is very limited...

    HTH

    Troubleshooting

  • Other Controller get disconnected when sending any command to the Eth. Gateway (v2.0)
    soifS soif

    Thank you for poiting me to this part of the code. It immediately showed something interesting :

    Your highlighted code is for ESP8266 but i'm using W5100 (the recommended one)...
    If I read correctly the code just following for the W5100, I see that :

    // W5100/ENC module does not have hasClient-method. We can only serve one client at the time.
    
    • Would it mean there is absolutely no way to get multiple clients connected with the W5100?
    • Not codable?
    • only workaround it to buy a ESP8266 Wifi (wifi sucks) module ?

    Sorry my C++ knowledge is very limited...

    Troubleshooting
  • Login

  • Don't have an account? Register

  • Login or register to search.
  • First post
    Last post
0
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular