HOW TO GET DATA OUT OF LOOP

hi i wrote a code fo 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);
    }
if (data == 'q') {
      callback(lightTopic,"1", 1);

?

PaulRB:

if (data == 'q') {

callback(lightTopic,"1", 1);



?

thank you paul but it will still switch things when its connected to mqtt only. i want it to be able to switch manually whenever there is something wrong with my lan

it will still switch things when its connected to mqtt only.

Why do you say that? Did you try it?

i dont have access to my modules, sorry but if the connection is lost then the while loop will run continuously, please correct me if im wrong. im a total noob ,and ill try it asap.

Before I try to help again, are there any other requirements you have not mentioned? I don’t want to waste time trying my best to help and then you say “oh, but I need X or Y or Z also”.

thanks for your patience paul. no i only want it to be able to switch things on and off from network and also directy from serial com update given by attiny even if it couldnt connect to wifi

OK, try this. It compiles but I can’t test it for you.

//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);

}



void loop() {
  //reconnect if connection is lost
  reconnect();

  //maintain MQTT connection
  if (client.connected()) 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') {
      if (client.connected()) client.publish(lightTopic, "1");
      else callback(lightTopic, (byte*) "1", 1);
    }
    else  if (data == 'w') {
      if (client.connected()) client.publish(lightTopic, "0");
      else callback(lightTopic, (byte*) "0", 1);
    }
    else  if (data == 'e') {
      if (client.connected()) client.publish(lightTopic1, "1");
      else callback(lightTopic1, (byte*) "1", 1);
    }
    else if (data == 'r') {
      if (client.connected()) client.publish(lightTopic1, "0");
      else callback(lightTopic1, (byte*) "0", 1);
    }
    else if (data == 't') {
      if (client.connected()) client.publish(lightTopic2, "1");
      else callback(lightTopic2, (byte*) "1", 1);
    }
    else if  (data == 'y') {
      if (client.connected()) client.publish(lightTopic2, "0");
      else callback(lightTopic2, (byte*) "0", 1);
    }
    else if (data == 'u') {
      if (client.connected()) client.publish(lightTopic3, "1");
      else callback(lightTopic3, (byte*) "1", 1);
    }
    else if  (data == 'i') {
      if (client.connected()) client.publish(lightTopic3, "0");
      else callback(lightTopic3, (byte*) "0", 1);
    }



  }
}


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() {

  static unsigned long lastConnectionCheck = 0;

  if (lastConnectionCheck == 0 || millis() - lastConnectionCheck > 120000) {
    lastConnectionCheck = millis();
    
    //attempt to connect to the wifi if connection is lost
    if (WiFi.status() != WL_CONNECTED) {
      //debug printing
      Serial.print("Connecting to ");
      Serial.println(ssid);
  
      WiFi.begin(ssid, password);
  
      //loop while we wait for connection
      int retries = 0;
      while (WiFi.status() != WL_CONNECTED && retries++ < 50) {
        delay(500);
        Serial.print(".");
      }
  
      if (WiFi.status() == WL_CONNECTED) {
        //print out some more debug once connected
        Serial.println("");
        Serial.println("WiFi connected");
        Serial.println("IP address: ");
        Serial.println(WiFi.localIP());
      }
      else {
        Serial.println("");
        Serial.println("WiFi connection failed.");      
      }
    }
  
    //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
      int retries;
      while (!client.connected() && retries++ < 5) {
        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
      if (!client.connected()) {
        Serial.println("\tMQTT Connection Failed.");
      }
    }
  }
}

//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;
}

If/when it works, I don’t want you to simply accept it. I want you to understand every change I made, so ask any questions you need to.

 else callback(lightTopic, (byte*) "1", 1);

thank you so much paul. im almost about to submit my project, i only didnt get the byte*

I've done your homework for you? Dang, should have seen that coming!

The (byte*) doesn't really do anything. It just stops the C compiler from complaining. The client.publish() function expects a C-string as the payload, but the callback() function expects it to be a pointer to an array of bytes. In reality there is no real difference between those 2 things. So the (byte*) tells the compiler to "cast" or pretend that the C-string is an array of bytes (which it is anyway) and that stops the compiler from complaining.

Note that a C-string is not the same thing as a String, even though they appear to be.

thank you so much paul