tuanpmt / espduino

ESP8266 network client (mqtt, restful) for Arduino
http://tuanpm.net/post/espduino
MIT License
382 stars 122 forks source link

mqtt issues/debug #16

Open prussiap opened 9 years ago

prussiap commented 9 years ago

Hi, I tried to post in the forums to no avail, also I'm not entirely sure something is broken but here goes. I apologize if this is in the wrong place.

I have espduino flashed on esp01, and arduino nano rev3. I've gotten that combination to work perfectly with restful action, and thingspeak updating. I have also managed to get mqtt to work on the esp01 without an arduino and i've gotten mqtt to work with local clients using cloudmqtt broker.

The problem is i have not managed to get mqtt working with espduino. The debug pins show I connected fine, I use the same script on the readme but when I subscribe I don't see any updated topics.

To confirm the only changes i made are:

!mqtt.begin("DVES_duino", "admin", "Isb_C4OGD4c3", 12

client: I think DVES_duino is client username: "admin" password/key (not md5'd?): Isb_C4OGD4c3"

And I changed this: mqtt.connect("yourserver.com", 1883, false); Server, port, false stands for ssl or not ? not sure for that one bug guessed.

Anyway I could have gotten things wrong for sure so wanted to double check and get feedback. Also how can i trigger callbacks or actions on subscribed topic on the arduino from mqtt?

I would really like a way to trigger an action based on something from mqtt parsed. So say a door opened at the entrance triggers a light to turn on an espduino in another room ?

Could somebody elucidate that possibility and thoughts on making that more useable :)..

Any help is much appreciated and thank you for the fantastic esp/duino library. Definitely makes a lot of things possible.

bclouser commented 9 years ago

I too am having some initial trouble getting this to work, and would appreciate a reply to the above post. I am initially trying to use the public "test.mosquitto.org" to confirm that I can send and receive messages, but so far no dice. Any support, or more example code would be appreciated. And indeed, thank you for this library.

eschlenz commented 9 years ago

Guys,

I have some sample code that has worked for me. My project is pretty specific in that it monitors topics that some of my Jenkins build servers post messages to. The pertinent code you need is in there though. And I'm pressed for time at the moment, otherwise I would trim it back to just what you guys would need. I thought I would share what I have now in the meantime in the hopes that it helps.

Don't forget to change the SSID and PASS #defines. And for good measure, the email address in the initESP8266() function.

Hopefully this is enough to get you guys past your road blocks. If not, reply here or directly to me and I will find time to refine the code to just what you guys would need.

FYI, I'm not the author of this library. I've noticed that the author hasn't replied yet to most of the questions. So if I can be of further help. just let me know.

#include <SoftwareSerial.h>
#include <espduino.h>
#include <mqtt.h>
#include <elapsedMillis.h>
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>
#include <avr/power.h>

// SSID of WiFi network
#define SSID ""
// Password of WiFi network
#define PASS ""
// Reset pin
#define ESP_RST         4

#define MQTT_SERVER     "test.mosquitto.org"
#define MQTT_PORT       1883

#define SERVER_1_NAME     "Test Server 1"
#define SERVER_1_LED_NAME "Server 1"
#define SERVER_1_TOPIC    "/SomeTopicRoot/Topic1"

#define SERVER_2_NAME     "Test Server 2"
#define SERVER_2_LED_NAME "Server 2"
#define SERVER_2_TOPIC    "/SomeTopicRoot/Topic2"

#define JENKINS_SUCCESS "SUCCESS"

#define DEBUG_RX 5
#define DEBUG_TX 6
#define DEBUG_BAUD 19200

#define ESP8266_BAUD 19200

#define WIFI_GIVE_UP 30000 // ms

#define LED_PIN            13
#define SCROLL_SPEED 100 // ms

// Struct to describe a Jenkins instance
typedef struct JENKINS_SERVER
{
    const String name;
    const String ledName;
    const String topic;

};

const JENKINS_SERVER SERVERS[] =
{
    {
        SERVER_1_NAME,
        SERVER_1_LED_NAME,
        SERVER_1_TOPIC
    },
    {
        SERVER_2_NAME,
        SERVER_2_LED_NAME,
        SERVER_2_TOPIC
    }

};

// Debug interface
SoftwareSerial debug(DEBUG_RX, DEBUG_TX);
ESP esp(&Serial1, &debug, ESP_RST);
MQTT mqtt(&esp);
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(8, 8, LED_PIN,
                            NEO_MATRIX_TOP     + NEO_MATRIX_RIGHT +
                            NEO_MATRIX_COLUMNS + NEO_MATRIX_PROGRESSIVE,
                            NEO_GRB            + NEO_KHZ800);

elapsedMillis timeElapsed;
unsigned int timeOfWiFiConnect;
unsigned int lastScrollUpdate;
boolean wifiConnected = false;
boolean mqttClientConnected = false;
unsigned int mqttAckIndex = 0;
unsigned int mqttAcking = false;

// Value that will be pushed to the shift register for the LEDs
boolean connecting = false;
boolean statuses[2];
int statusIndex;
int x = matrix.width();

void setup()
{
    timeOfWiFiConnect = 0;
    wifiConnected = false;
    mqttClientConnected = false;
    mqttAckIndex = 0;
    mqttAcking = false;

    // Initial setup for Arduino and attached hardware.
    debug.begin(DEBUG_BAUD);
    debug.println(F("Setup started"));

    initLEDMatrix();

    // Configure the ESP8266, the MQTT client and the WiFi connection.
    initESP8266();

    debug.println(F("Setup finished"));
}

void initESP8266()
{
    debug.println(F("initESP8266"));
    Serial1.begin(19200);

    debug.println(F("Enabling ESP8266"));
    esp.enable();
    delay(500);

    resetESP8266();

    debug.println(F("Waiting for ESP8266 to become ready..."));
    while(!esp.ready());
    debug.println(F("ESP8266 is ready"));

    debug.println(F("Asking MQTT client to begin..."));
    // NOTE: Replace with your email address.
    if(!mqtt.begin("youremail@gmail.com", "", "", 120, 1))
    {
        debug.println(F("MQTT client begin FAILED."));
        resetArduino();
        while(1);
    }

    // Set up Last Will and Testament (probably not required)
    debug.println(F("Setting last will and testament"));
    mqtt.lwt("/lwt", "offline", 0, 0);

    // Set MQTT callbacks.
    debug.println(F("Attaching MQTT callbacks"));
    mqtt.connectedCb.attach(&mqttConnected);
    mqtt.disconnectedCb.attach(&mqttDisconnected);
    mqtt.publishedCb.attach(&mqttPublished);
    mqtt.dataCb.attach(&mqttData);

    // Set the callback for when the WiFi is connected.
    debug.println(F("Attaching WiFi connection callback"));
    esp.wifiCb.attach(&wifiCb);

    // Connect to WiFi and wait for callback.
    debug.println(F("WiFi connecting..."));
    timeOfWiFiConnect = timeElapsed;
    esp.wifiConnect(SSID, PASS);
}

void initLEDMatrix()
{
    matrix.begin();
    matrix.setTextWrap(false);
    matrix.setBrightness(40);
    matrix.fillScreen(0);
    matrix.show();
}

void wifiCb(void* response)
{
    debug.println(F("WiFi callback received"));
    unsigned int status;
    RESPONSE res(response);

    if(res.getArgc() == 1)
    {
        res.popArgs((uint8_t*)&status, 4);
        if(status == STATION_GOT_IP)
        {
            debug.println(F("WiFi connected!"));
            debug.println(F("MQTT client connecting..."));
            mqtt.connect(MQTT_SERVER, MQTT_PORT, false);
            wifiConnected = true;
        }
        else
        {
            debug.println(F("WiFi connection FAILED"));
            wifiConnected = false;
            mqtt.disconnect();
        }
    }
}

void loop()
{
    esp.process();
    int notConnected = 0;
    unsigned int elapsed =  timeElapsed - timeOfWiFiConnect;

    if (wifiConnected)
    {
        notConnected = 0;
        scrollLEDs();
    }
    else
    {
        notConnected++;
        if ((notConnected % 100) == 0)
        {
            debug.print(F("WiFi still not connected: "));
            debug.print(elapsed);
            debug.println(F(" ms"));
            connectingLEDs();
            notConnected = 0;
        }
    }

    if (!wifiConnected && (elapsed > WIFI_GIVE_UP))
    {
        elapsed = 0;
        resetArduino();
        return;
    }

    int serverCount = sizeof(SERVERS) / sizeof(JENKINS_SERVER);
    if (mqttClientConnected && !mqttAcking && (mqttAckIndex < serverCount))
    {
        ackNextSubscribe();
    }
}

void connectingLEDs()
{
    matrix.fillScreen(matrix.Color(255, 255, 0));
    matrix.show();
}

void connectedLEDs()
{
    matrix.fillScreen(matrix.Color(0, 255, 0));
    matrix.show();
}

void scrollLEDs()
{
    unsigned int elapsed = timeElapsed - lastScrollUpdate;
    if (elapsed >= SCROLL_SPEED)
    {
        lastScrollUpdate = timeElapsed;
        String name = SERVERS[statusIndex].ledName;
        boolean success = statuses[statusIndex];

        if (success)
        {
            matrix.setTextColor(matrix.Color(0, 255, 0));
        }
        else
        {
            matrix.setTextColor(matrix.Color(255, 0, 0));
        }

        matrix.fillScreen(0);
        matrix.setCursor(x, 0);
        matrix.print(name);
        if(--x < -40)
        {
            x = matrix.width();
            int serverCount = sizeof(SERVERS) / sizeof(JENKINS_SERVER);
            statusIndex++;
            if (statusIndex >= serverCount)
            {
                statusIndex = 0;
            }
        }
        matrix.show();
    }
}

void ackNextSubscribe()
{
    mqttAcking = true;
    String topicStr = SERVERS[mqttAckIndex].topic;
    topicStr += "/1";

    int length = topicStr.length() + 1;
    char topic[length];
    SERVERS[mqttAckIndex].topic.toCharArray(topic, length);

    debug.print(F("Subscribing to: "));
    debug.println(topicStr);

    mqtt.subscribe(topic);
}

void mqttConnected(void* response)
{
    debug.println(F("Connected!"));
    mqttClientConnected = true;
    connectedLEDs();
}

void mqttDisconnected(void* response)
{
    debug.println(F("Disconnected."));
    resetArduino();
}

void mqttData(void* response)
{
    debug.println(F("Data received"));

    if (mqttAcking)
    {
        mqttAcking = false;
        mqttAckIndex++;
    }

    RESPONSE res(response);

    debug.print(F("Received: topic="));
    String topic = res.popString();
    debug.println(topic);

    debug.print(F("data="));
    String data = res.popString();
    debug.println(data);

    int serverCount = sizeof(SERVERS) / sizeof(JENKINS_SERVER);
    for (int i = 0; i < serverCount; i++)
    {
        if (SERVERS[i].topic.indexOf(topic) != -1)
        {
            if (data.indexOf(JENKINS_SUCCESS) != -1)
            {
                debug.print(SERVERS[i].name);
                debug.println(F(" Jenkins SUCCESS."));
                statuses[i] = true;
            }
            else
            {
                debug.print(SERVERS[i].name);
                debug.println(F(" Jenkins FAILED."));
                statuses[i] = false;
            }
        }
    }

}

void mqttPublished(void* response)
{
    debug.println(F("Published"));
}

void resetESP8266()
{
    debug.println(F("Resetting ESP8266..."));
    debug.flush();

    esp.reset();
    delay(5000);  //ESP8266 takes a while to restart
}

void resetArduino()
{
    debug.println(F("Resetting Arduino..."));
    delay(1000);
    setup();
}
bclouser commented 9 years ago

I got it working. I am not really sure what i did. My best guess is that I increased the serial buffer size from 64 to 256. I tried switching it back to 64 (to prove this to be the culprit) and it still worked :( ... but it seems to be inconsistent.

I appreciate the code you sent @eschlenz. An intriguing idea! Now all i want to do now is hook up our jenkin's builds at work to an LED marquee!

ibrahimisim commented 8 years ago

Hello,

When I upload software to esp8266 I get an error that is below. Please help me !!!.

pi@raspberrypi /usr/share/arduino/libraries/espduino $ sudo esp8266/tools/esptool.py -p /dev/ttyUSB0 write_flash 0x00000 esp8266/release/0x00000.bin 0x40000 esp8266/release/0x40000.bin Could not find platform dependent libraries Consider setting $PYTHONHOME to [:] Traceback (most recent call last): File "esp8266/tools/esptool.py", line 22, in import serial ImportError: No module named serial

bclouser commented 8 years ago

Looks like you dont have the Python serial module installed on your computer.

If you have pip installed, it should be as easy as "pip install pyserial"

-ben On Oct 15, 2015 2:55 PM, "ibrahimisim" notifications@github.com wrote:

Hello,

When I upload software to esp8266 I get an error that is below. Please help me !!!.

pi@raspberrypi /usr/share/arduino/libraries/espduino $ sudo esp8266/tools/esptool.py -p /dev/ttyUSB0 write_flash 0x00000 esp8266/release/0x00000.bin 0x40000 esp8266/release/0x40000.bin Could not find platform dependent libraries Consider setting $PYTHONHOME to [:] Traceback (most recent call last): File "esp8266/tools/esptool.py", line 22, in import serial ImportError: No module named serial

— Reply to this email directly or view it on GitHub https://github.com/tuanpmt/espduino/issues/16#issuecomment-148487822.

ibrahimisim commented 8 years ago

pi@raspberrypi /usr/share/arduino/libraries/espduino/esp8266/tools $ sudo apt-get install python-serial Reading package lists... Done Building dependency tree Reading state information... Done python-serial is already the newest version. 0 upgraded, 0 newly installed, 0 to remove and 34 not upgraded.

bclouser commented 8 years ago

What are we to do with the reset pin. I would think we should tie it to vcc but that seems to make the chip unstable