-1

hi i wrote a code(i modified it actually, please forgive me, im in a mess please help me if you can) for my esp8266 to serial communicate with at tiny 85 ,it will monitor switch state and publish accordingly. now i want to write a code where it wont publish but whenever the serial is available i want it to directly take it and digital write in void callback.

//ItKindaWorks - Creative Commons 2016
//github.com/ItKindaWorks
//
//Requires PubSubClient found here: https://github.com/knolleary/pubsubclient
//
//ESP8266 Simple MQTT light controller


#include <PubSubClient.h>
#include <ESP8266WiFi.h>

int LED3 = 12;
int LED4 = 14;
int LED2 = 13;
int LED1 = 15;

bool switch1;
bool switch2;
bool switch3;
bool switch4;
char data ;
// the number of the pushbutton pin

//EDIT THESE LINES TO MATCH YOUR SETUP

#define MQTT_SERVER "192.168.0.223"
const char* ssid = "TACHYON_HOME";
const char* password = "qwertyui";

//LED on ESP8266 GPIO2

char* lightTopic = "/test/light1";
char* lightTopic1 = "/test/light2";
char* lightTopic2 = "/test/light3";
char* lightTopic3 = "/test/light4";


WiFiClient wifiClient;
void callback(char* topic, byte* payload, unsigned int length);
PubSubClient client(MQTT_SERVER, 1883, callback, wifiClient);

void setup() {
  //initialize the light as an output and set to LOW (off)
  Serial.begin(9600);
  pinMode(LED3 , OUTPUT);
  pinMode(LED4 , OUTPUT);
  pinMode(LED1 , OUTPUT);
  pinMode(LED2 , OUTPUT);
 
    delay(100);

    // We start by connecting to a WiFi network

    Serial.println();
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);

    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }

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



void loop(){
  //reconnect if connection is lost
  if (!client.connected() && WiFi.status() == 3) {reconnect();}

  //maintain MQTT connection
  client.loop();

  //MUST delay to allow ESP8266 WIFI functions to run
  delay(10);
   if (Serial.available()>0) /* If data available at serial port, enter if loop */
  {
    data = Serial.read(); /* Read data present at serial port */
    /* Print string with \r\n */
    Serial.print(data); /* Print data received */
    if (data == 'q') {
      client.publish(lightTopic,"1");
   
    }
else  if (data == 'w') {
      client.publish(lightTopic,"0");
    }
 else  if (data == 'e') {
      client.publish(lightTopic1,"1");
    }
    else if (data == 'r') {
      client.publish(lightTopic1,"0");
   
    }
     else if (data == 't') {
      client.publish(lightTopic2,"1");
   
    }
     else if  (data == 'y') {
      client.publish(lightTopic2,"0");
   
    }
     else if (data == 'u') {
      client.publish(lightTopic3,"1");
   
    }
     else if  (data == 'i') {
      client.publish(lightTopic3,"0");
   
    }
   
       
     
  }
}


void callback(char* topic, byte* payload, unsigned int length)
{
  //convert topic to string to make it easier to work with
  String topicStr = topic;

  //Print out some debugging info
  Serial.println("Callback update.");
  Serial.print("Topic: ");
  Serial.println(topicStr);

 

 if(topicStr.equals(lightTopic)){

   if(payload[0] == '1'){
      digitalWrite(LED1 , HIGH);
    }

    else if (payload[0] == '0'){
      digitalWrite(LED1 , LOW);
    }
 }
 if(topicStr.equals(lightTopic1)){

   if(payload[0] == '1'){
      digitalWrite(LED2 , HIGH);
    }

    else if (payload[0] == '0'){
      digitalWrite(LED2 , LOW);
    }
 }
 if(topicStr.equals(lightTopic2)){

   if(payload[0] == '1'){
      digitalWrite(LED3 , HIGH);
    }

    else if (payload[0] == '0'){
      digitalWrite(LED3 , LOW);
    }
 }
  if(topicStr.equals(lightTopic3)){

   if(payload[0] == '1'){
      digitalWrite(LED4 , HIGH);
    }

    else if (payload[0] == '0'){
      digitalWrite(LED4 , LOW);
    }
  }
 
}






void reconnect() {

  //attempt to connect to the wifi if connection is lost
  if(WiFi.status() != WL_CONNECTED){
    //debug printing
    Serial.print("Connecting to ");
    Serial.println(ssid);

    //loop while we wait for connection
    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
    }

    //print out some more debug once connected
    Serial.println("");
    Serial.println("WiFi connected"); 
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
  }

  //make sure we are connected to WIFI before attemping to reconnect to MQTT
  if(WiFi.status() == WL_CONNECTED){
  // Loop until we're reconnected to the MQTT server
    while (!client.connected()) {
      Serial.print("Attempting MQTT connection...");

      // Generate client name based on MAC address and last 8 bits of microsecond counter
      String clientName;
      clientName += "esp8266-";
      uint8_t mac[6];
      WiFi.macAddress(mac);
      clientName += macToStr(mac);

      //if connected, subscribe to the topic(s) we want to be notified about
      if (client.connect((char*) clientName.c_str())) {
        Serial.print("\tMTQQ Connected");
        client.subscribe(lightTopic);
        client.subscribe(lightTopic1);
        client.subscribe(lightTopic2);
        client.subscribe(lightTopic3);
   
       
      }

      //otherwise print failed for debugging
      else{Serial.println("\tFailed."); abort();}
    }
  }
}

//generate unique name from MAC addr
String macToStr(const uint8_t* mac){

  String result;

  for (int i = 0; i < 6; ++i) {
    result += String(mac[i], 16);

    if (i < 5){
      result += ':';
    }
  }

  return result;
}


//////////////////i want to write some thing like///////////////////////////////////////
////////////////////////////////
if(topicStr.equals(lightTopic1)||Serial.available()>0){

   if(payload[0] == '1'|| data =q){
      digitalWrite(LED2 , HIGH);
    }

    else if (payload[0] == '0'|| data = w){
      digitalWrite(LED2 , LOW);
    }
/////////////////////////////////////////
  • so, what is your question? – jsotola Jun 27 at 7:06
  • how to do that i tried it but it isnt working its only taking data from mqtt but not from the switch state – Dharani Sharma Jun 27 at 8:07
  • Please, be more specific about what you want to achieve. And show your code! You wrote “I wrote a code for my esp8266”, yet the code you are showing is visibly not something you wrote. You also wrote you want “a code where it wont publish”: if it won't publish, then what interactions should it have with the MQTT server? Should it do MQTT at all? If not, why are you showing a sketch that is al about MQTT? – Edgar Bonet Jun 27 at 10:17
  • sorry i modified this code correction i want it to monitor the switches and turn off devices with mqtt and without mqtt too. i want it to control relays even when the network is off. – Dharani Sharma Jun 27 at 11:21
  • your post still says that you wrote the code – jsotola Jun 27 at 13:50
1

So you want your program to react to both MQTT and serial messages. You wrote this snippet:

if (topicStr.equals(lightTopic1) || Serial.available() > 0) {
    if (payload[0] == '1' || data = q) {
        digitalWrite(LED2, HIGH);
    }
    else if (payload[0] == '0' || data = w) {
        digitalWrite(LED2 , LOW);
    }
    // ...
}

Other than a couple of syntactic problems (you mean data == 'q', not data = q), the logic is not appropriate. This is because:

  • The test payload[0] == '1' only makes sense in the context of parsing an MQTT message, otherwise payload cannot be meaningfully defined.
  • For the same reason, the test data == 'q' only makes sense in the context of parsing a serial command.

Since MQTT and serial use completely different commands, you will have to handle them independently. You can keep the MQTT callback as is, and implement the parser for the serial commands. Maybe something like:

if (Serial.available()) {
    char command = Serial.read();
    Serial.print(command);  // echo to the serial port
    switch (command) {
        case 'q':
            digitalWrite(LED1, HIGH);
            break;
        case 'w':
            digitalWrite(LED1, LOW);
            break;
        // ...
    }
}

Alternatively, use an if ... else if ... chain if you are not comfortable with the switch syntax.

I personally would rather store the topic names, LED pins and serial commands in an array of structs, and loop through the array in both the MQTT callback and the serial parser. But I assume that may be too advanced for your current programming level, so maybe just stick with the simple, albeit verbose solution.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.