Help with code. Willing to pay

Hi,

I've been trying to figure out what's wrong with this code for a few weeks now and it's time I admit defeat. I can't code. If someone was able to help me with this I'd gladly make payment via PayPal.

Essentially it's a ESP8266 what connects to Wifi and MQTT broker. Subscribes to topic and publishes the value on a oled display.

I have no problems editing the user specific information such as wifi and broker credentials.

When I upload this using Arduino and check the serial monitor I see "connecting to SKY11223..." every 10 seconds but it never actually connects.

(SKY11223 is the name of my ssid)

My MQTT broker is already set up and is publishing the values I hope to view on the oled every 30 second.

I'm using a nodemcu dev board but it's basically just an ESP12. I have two displays, one is an SPI and the other is I2C depending which is easier to implement.

I'm serious about getting this working. I've spend a lot of time and money on this only to fail and I'll be more than happy to pay someone if they can help me.

Code is below (unedited original from GitHub)

/*
 
 Quick demo for displaying temperature on oled screen.
 
  - connects to wifi
  - connects to an MQTT server
  - subscribes to topic
  - displays temperature (needs to be in xx.xx format)
  Based on the built-in examples from ESP8266 MQTT lib and the SPI OLED ESP8266 lib from somhi.
*/

// MQTT and wifi libs
#include <ESP8266WiFi.h>
#include <PubSubClient.h> // using v1.65. v2 from the esp8266 arduino library didn't work for me for some reason.

// OLED libs
#include <ESP_SSD1306.h>    // Modification of Adafruit_SSD1306 for ESP8266 compatibility -> https://github.com/somhi/ESP_SSD1306
#include <Adafruit_GFX.h>   // Needs a little change in original Adafruit library (See README.txt file) --> https://github.com/adafruit/Adafruit-GFX-Library
#include <SPI.h>            // For SPI comm (needed for not getting compile error)
#include <Wire.h>           // For I2C comm, but needed for not getting compile error

/*HardWare  ESP8266 SPI pins --> https://raw.githubusercontent.com/nodemcu/nodemcu-devkit-v1.0/master/Documents/NODEMCU_DEVKIT_V1.0_PINMAP.png
Fixed..
D5 (GPIO14) -> D0 pin OLED display (CLK)
D7 (GPIO13) -> D1 pin OLED display (MOSI)
*/

// Pin definitions for OLED spi
#define OLED_CS     15  // D8 (GPIO15) -> CS (Chip select) pin OLED display
#define OLED_DC     2   // D4 (GPIO2)  -> DC (Digital signal) pin OLED display
#define OLED_RESET  16  // D0 (GPIO16) -> RESET pin OLED display

ESP_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS); // FOR SPI


// WIFI setup
const char *ssid =	"xxxxxxxxxx";		// cannot be longer than 32 characters!
const char *pass =	"xxxxxxxxxx";		//

// MQTT broker
IPAddress server(192, 168, 4, 24);


#define BUFFER_SIZE 100

void callback(const MQTT::Publish& pub) {
  Serial.print(pub.topic());
  Serial.print(" => ");
  if (pub.has_stream()) {
    // probably don't need this, just using it because it is part of the example
    uint8_t buf[BUFFER_SIZE];
    int read;
    while (read = pub.payload_stream()->read(buf, BUFFER_SIZE)) {
      Serial.write(buf, read);
    }
    pub.payload_stream()->stop();
    Serial.println("");
  } else
    Serial.println(pub.payload_string());
    display.clearDisplay();
    display.setTextSize(3);
    display.setTextColor(WHITE);
    display.setCursor(20, 10);
    display.println(pub.payload_string());
    display.display();
    delay(2000);
}

WiFiClient wclient;
PubSubClient client(wclient, server);

void setup() {
  // Setup console
  Serial.begin(115200);
  delay(10);
  Serial.println();
  Serial.println();

  // SSD1306 Init
  display.begin(SSD1306_SWITCHCAPVCC);  // Switch OLED
  // Clear the buffer.
  display.clearDisplay();
  // draw a single pixel
  display.drawPixel(10, 10, WHITE);
  // Show the display buffer on the hardware.
  // NOTE: You _must_ call display after making any drawing commands
  // to make them visible on the display hardware!
  display.display();
  delay(2000);
  display.clearDisplay();
}

void loop() {
  if (WiFi.status() != WL_CONNECTED) {
    Serial.print("Connecting to ");
    Serial.print(ssid);
    Serial.println("...");
    WiFi.begin(ssid, pass);

    if (WiFi.waitForConnectResult() != WL_CONNECTED)
      return;
    Serial.println("WiFi connected");
    display.clearDisplay();
    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.setCursor(0, 0);
    display.println("WiFi connected");
    display.display();
    delay(2000);
  }

  if (WiFi.status() == WL_CONNECTED) {
    if (!client.connected()) {
      if (client.connect("esp_temp")) {
        client.set_callback(callback);
        client.subscribe("house/outside/temp/current");  // expecting a decimal, eg 25.54 degrees
        display.setCursor(0, 10);
        display.println("MQTT Broker connected");
        display.display();
        delay(2000);
      }
    }

    if (client.connected())
      client.loop();
  }
}

I had some issues with the pubsubclient.h which prevented it from compiling. I found it would do so if I used this version:

Many thanks

Andrew

Well, if there's a connection problem, what you would normally do is inspect the result from waitForConnectResult to get a clue as to why it's not connecting.

Also, you are kind of spamming the connect - as soon as the connection fails, the loop immediately re-runs and tries to reconnect. Which is a little rude.

   int connectResult =WiFi.waitForConnectResult();
   if (connectResult != WL_CONNECTED) {
      Serial.print("WiFi not connected, error code ");
      Serial.println(connectResult);
      Serial.println("Pausing 5 sec before retry");
      delay(5000);
      return;
  }

Check the documentation to find out what your error code indicates. Then you might have an idea how to proceed.

****************************************************/
#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"

/************************* WiFi Access Point *********************************/

#define WLAN_SSID       "...your SSID..."
#define WLAN_PASS       "...your password..."

/************************* Adafruit.io Setup *********************************/

#define AIO_SERVER      "io.adafruit.com"
#define AIO_SERVERPORT  1883                   // use 8883 for SSL
#define AIO_USERNAME    "...your AIO username (see https://accounts.adafruit.com)..."
#define AIO_KEY         "...your AIO key..."

/************ Global State (you don't need to change this!) ******************/

// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;
// or... use WiFiFlientSecure for SSL
//WiFiClientSecure client;

// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);

/****************************** Feeds ***************************************/

// Setup a feed called 'photocell' for publishing.
// Notice MQTT paths for AIO follow the form: <username>/feeds/<feedname>
Adafruit_MQTT_Publish photocell = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/photocell");

// Setup a feed called 'onoff' for subscribing to changes.
Adafruit_MQTT_Subscribe onoffbutton = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/onoff");

/*************************** Sketch Code ************************************/

// Bug workaround for Arduino 1.6.6, it seems to need a function declaration
// for some reason (only affects ESP8266, likely an arduino-builder bug).
void MQTT_connect();

void setup() {
  Serial.begin(115200);
  delay(10);

  Serial.println(F("Adafruit MQTT demo"));

  // Connect to WiFi access point.
  Serial.println(); Serial.println();
  Serial.print("Connecting to ");
  Serial.println(WLAN_SSID);

  WiFi.begin(WLAN_SSID, WLAN_PASS);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();

  Serial.println("WiFi connected");
  Serial.println("IP address: "); Serial.println(WiFi.localIP());

  // Setup MQTT subscription for onoff feed.
  mqtt.subscribe(&onoffbutton);
}

uint32_t x=0;

void loop() {
  // Ensure the connection to the MQTT server is alive (this will make the first
  // connection and automatically reconnect when disconnected).  See the MQTT_connect
  // function definition further below.
  MQTT_connect();

  // this is our 'wait for incoming subscription packets' busy subloop
  // try to spend your time here

  Adafruit_MQTT_Subscribe *subscription;
  while ((subscription = mqtt.readSubscription(5000))) {
    if (subscription == &onoffbutton) {
      Serial.print(F("Got: "));
      Serial.println((char *)onoffbutton.lastread);
    }
  }

  // Now we can publish stuff!
  Serial.print(F("\nSending photocell val "));
  Serial.print(x);
  Serial.print("...");
  if (! photocell.publish(x++)) {
    Serial.println(F("Failed"));
  } else {
    Serial.println(F("OK!"));
  }

  // ping the server to keep the mqtt connection alive
  // NOT required if you are publishing once every KEEPALIVE seconds
  /*
  if(! mqtt.ping()) {
    mqtt.disconnect();
  }
  */
}

// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect() {
  int8_t ret;

  // Stop if already connected.
  if (mqtt.connected()) {
    return;
  }

  Serial.print("Connecting to MQTT... ");

  uint8_t retries = 3;
  while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
       Serial.println(mqtt.connectErrorString(ret));
       Serial.println("Retrying MQTT connection in 5 seconds...");
       mqtt.disconnect();
       delay(5000);  // wait 5 seconds
       retries--;
       if (retries == 0) {
         // basically die and wait for WDT to reset me
         while (1);
       }
  }
  Serial.println("MQTT Connected!");
}