Last Updated or created 2023-03-14
- Sends a “connected” to Mosquitto
- Mqtt controls Display
- Rotary values are displayed, a push on the rotary sends the value to Mosquitto
Code :
Notes: There is a problem with 4 line LCD using LiquidCrystal_I2C
Lines 3 and 4 will be shifted 4 characters to the right.
Workaround is: lcd.setCursor(-4, 2); // Go to column 0, row 3
#include <ESP8266WiFi.h> #include <PubSubClient.h> #include <WiFiClient.h> #include "SoftwareSerial.h" #include <Ethernet.h> #include <Arduino.h> #include <RotaryEncoder.h> #define wifi_ssid "MYSSID" #define wifi_password "MYSSIDPASS" #define mqtt_server "MQTTSERVER" #define mqtt_port 1883 WiFiClient espClient; EthernetClient ethClient; PubSubClient mqtt(espClient); #include <Wire.h> // Include Wire library (required for I2C devices) #include <LiquidCrystal_I2C.h> // Include LiquidCrystal_I2C library LiquidCrystal_I2C lcd(0x27, 16, 4); // Configure LiquidCrystal_I2C library with 0x27 address, 16 columns and 4 rows volatile bool flag = false; #define PIN_IN1 D7 #define PIN_IN2 D6 #define push D5 int temp = 0; RotaryEncoder *encoder = nullptr; #if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_NANO_EVERY) // This interrupt routine will be called on any change of one of the input signals void checkPosition() { encoder->tick(); // just call tick() to check the state. } #elif defined(ESP8266) /** * @brief The interrupt service routine will be called on any change of one of the input signals. */ IRAM_ATTR void checkPosition() { encoder->tick(); // just call tick() to check the state. } #endif void scrollText(int row, String message, int delayTime, int lcdColumns) { for (int i=0; i < lcdColumns; i++) { message = " " + message; } message = message + " "; for (int pos = 0; pos < message.length(); pos++) { lcd.setCursor(0, row); lcd.print(message.substring(pos, pos + lcdColumns)); delay(delayTime); } } void setup_wifi() { delay(10); WiFi.mode(WIFI_STA); WiFi.begin(wifi_ssid, wifi_password); while (WiFi.status() != WL_CONNECTED) { delay(500); } } void setup() { setup_wifi(); mqtt.setServer(mqtt_server, mqtt_port); mqtt.setCallback(callback); Serial.begin(115200); Serial.println("initializing..."); WiFiClient espClient; PubSubClient mqtt(espClient); mqtt.setClient(espClient); mqtt.setServer(mqtt_server, 1883); mqtt.setCallback(callback); mqtt.subscribe("escape/display1/#"); lcd.init(); // Initialize I2C LCD module lcd.backlight(); // Turn backlight ON lcd.setCursor(0, 0); // Go to column 0, row 0 lcd.print("Init"); lcd.setCursor(0, 1); // Go to column 0, row 1 lcd.print("Display #1"); encoder = new RotaryEncoder(PIN_IN1, PIN_IN2, RotaryEncoder::LatchMode::TWO03); // register interrupt routine attachInterrupt(digitalPinToInterrupt(PIN_IN1), checkPosition, CHANGE); attachInterrupt(digitalPinToInterrupt(PIN_IN2), checkPosition, CHANGE); pinMode(push, INPUT_PULLUP); } void reconnect() { // Loop until we're reconnected while (!mqtt.connected()) { // Create a random client ID String clientId = "ESP8266Client-"; clientId += String(random(0xffff), HEX); // Attempt to connect if (mqtt.connect(clientId.c_str())) { // Once connected, publish an announcement... mqtt.publish("escape", "display1 connected"); // ... and resubscribe mqtt.subscribe("escape/display1/#"); } else { // Wait 5 seconds before retrying delay(5000); } } } void callback(char* topic, byte* payload, unsigned int length) { payload[length]= '\0'; char * charPointer = (char *)payload; String s=""; s =charPointer; s = s + " "; String topicStr = topic; if (topicStr == "escape/display1/clear"){ lcd.clear(); } if (topicStr == "escape/display1/1in"){ lcd.setCursor(0, 0); // Go to column 0, row 1 lcd.print(s.substring(0, 16)); } if (topicStr == "escape/display1/2in"){ lcd.setCursor(0, 1); // Go to column 0, row 2 lcd.print(s.substring(0, 16)); } if (topicStr == "escape/display1/3in"){ lcd.setCursor(-4, 2); // Go to column 0, row 3 lcd.print(s.substring(0, 16)); } if (topicStr == "escape/display1/4in"){ lcd.setCursor(-4, 3); // Go to column 0, row 4 lcd.print(s.substring(0, 16)); } } void loop() { if (!mqtt.connected()) { reconnect(); } mqtt.loop(); static int pos = 0; encoder->tick(); // just call tick() to check the state. int newPos = encoder->getPosition() / 2; if (pos != newPos) { String nr=""; Serial.print("pos:"); Serial.print(newPos); Serial.print(" dir:"); Serial.println((int)(encoder->getDirection())); pos = newPos; // hier nog iets mee doen // zonder setPos moet je eerst lang clockwise voordat weer gaat tellen // met setPos blijft 0 // if (pos < 0){ // pos = 0; // encoder->setPosition(0); // } nr = pos + " "; lcd.setCursor(10, 3); // Go to column 10, row 3 lcd.print(pos); lcd.print(" "); } temp = digitalRead(push); if (temp == LOW) { char msg_out[20]; sprintf(msg_out, "%d",pos); mqtt.publish("escape/display1/rotary", msg_out); } }