Announcement

Collapse
No announcement yet.

Arduino Mega 2560 MQTT client

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Arduino Mega 2560 MQTT client

    I've put together some "Alpha code" for anyone interested in utilising an Arduino MEGA 2560 as a digital I/O unit that integrates nicely with this plugin. I put this together to see how reliably an arduino mega would work with MQTT. There are LOT of wireless projects with limited numbers of PINS, I wanted at least 20 input and 20 outputs (per node) for my home automation system. Just at my own front door I have 13 inputs and 8 outputs for various devices.

    This code was based on Jonathan Oxers LightswitchMQTT controller, I removed the temp sensors & OLED as I have no need for them

    1) Unit powers up and sends the status of all inputs so your H/A can sync to the state.
    2) Outputs when activated send back a positive acknowledgement so NodeRed switches can be guaranteed to work (status set by input)

    There are definately a few bugs in it, nothing that will cause it to fail, just debug output on the serial isnt correct, that I need to work on. OTHERWISE it works like a CHAMP !

    If anyone wants to help clean it up or otherwise, do a pull of it on GitHub. I did it for fun and learnt along the way....

    https://github.com/petez69/MQTT-Arduino-MEGA-I-O

    HS 2.2.0.11

    #2
    Wow!!! You read my mind!
    I'm playng with arduino mega, ethernet shield and MCS mqtt plugin :-)
    I'm not a programmer so I'll can learn so much!
    Thanks

    EDIT:
    Great great great job Pete!

    I can suggest to add the user and password mqtt connectionserver (I use it), should be:

    Code:
    const char* mqtt_username = "xxxxxxxxx";
    const char* mqtt_password = "xxxxxxxxx";
    Could be great to have the possibility to select in and out pin.
    In my case for example I'm using pin 14 with connected a switch (input pin) and pin 15 as output.
    When input change, the output change.

    Here my code:

    Code:
    #include <SPI.h>
    #include <Ethernet.h>
    #include <PubSubClient.h>
    const char* mqtt_username = "mqttxxxx";
    const char* mqtt_password = "mqttxxx";
    
    int attesaDebounce = 50;
    
    /////SALA
    int interruttore_SALA = 14;
    int luce_SALA = 15;
    bool stato_luce_SALA;
    bool stato_interruttore_SALA;
    bool lettura_interruttore_SALA;
    unsigned long ultimoTempoDebounce_SALA = 0;
    bool ultimaLettura_interruttore_SALA = LOW;
    
    //---------------------------------------------------------------------------
    
    
    
    byte mac[]    = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEE };
    
    // Unique static IP address of this Arduino
    IPAddress ip(192, 168, 178, 238);
    
    // IP Address of MQTT broker
    byte server[] = { 192, 168, 178, 20 };
    
    // Handle and convert incoming MQTT messages ----------------------------------------
    
    void callback(char* topic, byte* payload, unsigned int length) {
      // handle message arrived
      String content = "";
      char character;
      for (int num = 0; num < length; num++) {
        character = payload[num];
        content.concat(character);
      }
      Serial.println(topic);
      Serial.println(content); 
    
      // Set specific virtual switches on basis of specific incoming messages ----------------------------
    
      if (content == "board1/cmnd/luce_SALA/ON") {
        stato_luce_SALA = HIGH;
      }
    
      if (content == "board1/cmnd/luce_SALA/OFF") {
        stato_luce_SALA = LOW;
      }
    }
    
    // Initiate instances -----------------------------------
    
    EthernetClient ethClient;
    PubSubClient client(server, 1883, callback, ethClient);
    
    //-------------------------------------------------------
    
    void setup() {
    
      /////SALA
      //stato_luce_SALA = EEPROM.read(1);  //togli commento se vuoi ricordare ultimo stato prima del riavvio
      stato_luce_SALA = LOW;
      pinMode(luce_SALA, OUTPUT);
      pinMode(interruttore_SALA, INPUT_PULLUP);
      digitalWrite(luce_SALA, stato_luce_SALA);
      lettura_interruttore_SALA = digitalRead(interruttore_SALA);
      stato_interruttore_SALA = digitalRead(interruttore_SALA);
    
      // setup serial and ethernet communications -------------------------------
    
      // Setup serial connection
      Serial.begin(9600);
    
      // Setup ethernet connection to MQTT broker
      Ethernet.begin(mac);
      if (client.connect("arduino-ip-238", mqtt_username, mqtt_password)) {                
        //if (client.connect((char*) clientName.c_str(), mqtt_username, mqtt_password)) {
        client.publish("board1", "hello world - here arduino ip 239");
        Serial.println("connected");
        client.subscribe("board1");                    // subscribe to topic 
      }
    }
    
    //----------------------------------------------
    
    void loop() {
    
      /////SALA
      lettura_interruttore_SALA = digitalRead(interruttore_SALA);
      if (lettura_interruttore_SALA != ultimaLettura_interruttore_SALA) {
        ultimoTempoDebounce_SALA = millis();
    
      }
    
      if ((millis() - ultimoTempoDebounce_SALA) > attesaDebounce) {
        if (lettura_interruttore_SALA != stato_interruttore_SALA) {
          stato_luce_SALA = !stato_luce_SALA;
          digitalWrite(luce_SALA, stato_luce_SALA);
          if (stato_luce_SALA == 1) {
            client.publish("board1/stat/luce_SALA", "ON");
          } else {
            client.publish("board1/stat/luce_SALA", "OFF");
          }
          //EEPROM.write(1, stato_luce_SALA);
        }
        stato_interruttore_SALA = lettura_interruttore_SALA;
      }
    
      ultimaLettura_interruttore_SALA = lettura_interruttore_SALA;
    
    
      //------------------------------------------------
    
      client.loop();
    }
    I'm working for a strip led in living-room (sala).
    published topic and payload are correctly recognized by mqtt plugin (if I change the output pin status I can see on homeseer).
    The problem is when I try to change the status from homeseer... (I'm not a programmer so for me is hard to arrive to the target)

    Again, thanks a lot for sharing your sketch!




    Last edited by khriss75; September 14, 2018, 11:20 AM.

    Comment


      #3
      Looks like a good adaption. Does it provide a serial backdoor for user settings for broker IP etc or does the user need to compile from source? What is the purpose/recovery action of the watchdog logic? No mention of LWT. LWT is nice to have for system-wide management.

      Comment


        #4
        Michael

        Totally agree with your sentiments, there is a LOT missing I know..I jsut wanted to get an alpha version running to see how well the device operates with a large number of inputs and outputs simultaneously, basically that no messages are lost. I'm staring at Tasmota code to see how he implemented the web structure and dynamically changes the pin attributes.

        Anyway, I've got a lot to learn but I'm keen on pursuing this...thanks for the questions, it only motivates me to learn....

        OH I do have 1 question, does HS have the ability to change status on input like NodeRed. Where the switch will send an MQTT message on activation however wont change status until an external message tells it to ?

        Cheers..Peter
        HS 2.2.0.11

        Comment


          #5
          I'm not understanding the question. HS Status is based upon DeviceValue of a device. If HS receives a MQTT message and the payload is different than the DeviceValue then the DeviceValue will be updated and Status will change accordingly. If you want another input to control the Status of the device then the association will be the external message and not the input message.

          Comment


            #6
            Micheal

            Sadly I'm not as articulate at times as needed.....however I've just answered my own question....

            From an end user experience if the ardiuno device is offline then the HS device cannot be turned on....because there is a cmnd associated with the status.

            HS 2.2.0.11

            Comment


              #7
              Michael

              Thanks for the LWT pointer, I've got it in the code now....getting connected and disconnected messages :-)

              Have also set it up on a network disconnect and reconnect (not only power cycles), it sends the status of all input pins to ensure consistency. Kinda neat...

              Thankyou, lots of code clean up to be done but its pretty functional now.....everything needs to be configured in the arduino IDE and compiled. The idea was to build all the functionality I needed and then consolidate and see how Tasmota has done it via the web interface

              Cheers..Pete
              HS 2.2.0.11

              Comment


                #8
                A few more changes...

                1) LWT is implemented
                2) CHanged the configuration, to turn a relay on you send 1 in the payload and a 0 to turn the output off
                3) You can reboot the arduino by cmnd/panelID/reboot 0
                4) WHen rebooting the tele/20 payload is "rebooting"

                There is some sort of bug (either my code is bloated or there is a buffer overflow in the Arduino MQTT library). Turning 8 outputs on and off in quick succession causes the arduino to reboot. Lots of messaging, there are 8 commands being received and 8 status commands being sent immediately....I've got it toggling 5 outputs and its fine....the quick succession in turning 8 relays on and off would not be a normal HA configuration, jsut testing to know how it works

                Pete
                HS 2.2.0.11

                Comment


                  #9
                  Hi Pete,
                  what do you think about a version like the Greig's arduino plugin API version?
                  Should be possible to elaborate a personal sketch with personal in and out. To send mqtt a function like SendToMQTT(topic,payload); to receive/check (stat) FromMQTT(topic,payload)...

                  Comment


                    #10
                    Hi Khriss

                    I think its a good idea.....I'm going to experiment a little to see why the Mega reboots, running out of RAM or similar, i dont know...I know on Greigs plugin when i sent similar relay commands via UDP all is good so not sure if its a MQTT issue. No matter, its an interesting experiment and I will continue. I'm busily deploying SONOFF (tasmota) and ESP12 (ESPeasy) devices around the house to get temp and light sensing..

                    Keeping the MQTT plugin VERY busy :-)
                    HS 2.2.0.11

                    Comment

                    Working...
                    X