combining 2 sketches

Hello I've been working on combining 2 sketches for about a year on and off right now I have 2 different esp8266 nodemcu's running one code for each servo, I'm trying to free up a esp8266 and run the code on just one for both servos. I have combined both and get no errors the problem I'm having is no matter what Topic I send to open or close one servo, one will run and then the other one will. I want it to work if I send the twist topic I just want the twist servo to run, If I send the travel topic I just want the travel servo to run.

This is the code I am running on each esp8266 for now

#include <ESP8266WiFi.h>
#include <Servo.h>
#include <PubSubClient.h>
 
/***WiFi Access Point***/
 
#define WLAN_SSID "YOUR SSID HERE"
#define WLAN_PASS "YOUR PW HERE"
 
/*** MQTT Setup***/
 
const char* mqtt_server  = "YOUR SERVER IP HERE";
const char* topic_state = "/blinds/state";
const char* topic_command = "/blinds/command";
WiFiClient espClient;
PubSubClient client (espClient);
 
/***Sketch Code ***/
Servo myservo;
int state = 0;
int prevstate = 0;
int dirc = 0;
int spintime = 0;
int servoPin = D4; //CHANGE TO WHATEVETR PIN YOUR USING
 
void MQTT_connect();
void callback(char* topic, byte* payload, unsigned int length);
 
 
void setup() {
  Serial.begin(115200);
  delay(10);
  Serial.println("Blind Startup Sequence");
  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());
 
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
 
}
void servo_move() {
  Serial.println("State Change. Rotating Servo");
  if ( dirc == 180) {
    client.publish(topic_state,"opened");
  }
  else if (dirc == 0) {
    client.publish(topic_state,"closed");  
}
  myservo.attach(servoPin);
  myservo.write(dirc);
  delay(spintime);
  myservo.detach();
 
  Serial.println("Returning to main loop");
  return;
}
 
void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived: [");
  Serial.print(topic);
  Serial.print(" ]");
  char *blindcommand = (char *) payload; // convert mqtt byte array into char array
  blindcommand[length] ='\0';            // Must delimit with 0
 
  Serial.print(blindcommand);
  if (strcmp(blindcommand,"open") == 0) {
    Serial.println(" 433MHZ OPEN COMMAND RECEIVED");
    dirc = 180; // direction for servo to run
    spintime = 3700; // << CHANGE TO WHATEVER TIME YOU NEED TO OPEN YOUR BLINDS
    state = 1; //sets current state
  }
  else if (strcmp(blindcommand,"close") == 0) {
    Serial.println(" 433MHZ CLOSE COMMAND RECEIVED");
    dirc = 0;
    spintime = 3300; // << CHANGE TO WHATEVER TIME YOU NEED TO CLOSE YOUR BLINDS
    state = 2; //sets current state
  }
  if (state != prevstate) {
    Serial.println("State change!");
    servo_move();
  }
  prevstate = state;
}
 
void MQTT_connect() {
  while (!client.connected()) {  
  Serial.print("Attempting MQTT connection...");
  if (client.connect("ESP8266Client")) {
    Serial.println("MQTT Connected!");
    client.subscribe(topic_command);
  } else {
    Serial.print("failed, rc=");
  Serial.print(client.state());
  Serial.println(" try again in 5 seconds");
  delay(5000); // wait 5 seconds
  }
  }
}
 
 
void loop() {
  if (!client.connected()) {
    MQTT_connect();
  }
  client.loop();
}

And here is the code I have been working on

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

/***WiFi Access Point***/

#define WLAN_SSID "SSID"
#define WLAN_PASS "PASSWORD"

/*** MQTT Setup***/

const char* mqtt_server  = "192.168.1.115";

// Topic to twist the blinds open or close
const char* twist_state = "Home/twist/state";
const char* twist_command = "Home/twist/command";

// Topic to move the blinds across the window
const char* travel_state = "Home/travel/state";
const char* travel_command = "Home/travel/command";

WiFiClient shades2;
PubSubClient client (shades2);

/***Sketch Code ***/

// TWIST SERVO
Servo twist;
int state_twist = 0;
int prevstate_twist = 0;
int dirc_twist = 0;
int spintime_twist = 0;
int servoPin_twist = D1; //CHANGE TO WHATEVETR PIN YOUR USING

// TRAVEL SERVO
Servo travel;
int state_travel = 0;
int prevstate_travel = 0;
int dirc_travel = 0;
int spintime_travel = 0;
int servoPin_travel = D2; //CHANGE TO WHATEVETR PIN YOUR USING

void MQTT_connect();
void callback(char* topic, byte* payload, unsigned int length);

void setup() {
  Serial.begin(115200);
  delay(10);
  Serial.println("Shades2 Startup Sequence");
  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());

  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);

}
void servo_move() {
  Serial.println("State Change. Rotating Servo");
  if ( dirc_twist == 180) {
    client.publish(twist_state, "opened");
  }
  else if (dirc_twist == 0) {
    client.publish(twist_state, "closed");
  }
  twist.attach(servoPin_twist);
  twist.write(dirc_twist);
  delay(spintime_twist);
  twist.detach();

  if ( dirc_travel == 180) {
    client.publish(travel_state, "opened");
  }
  else if (dirc_travel == 0) {
    client.publish(travel_state, "closed");
  }
  travel.attach(servoPin_travel);
  travel.write(dirc_travel);
  delay(spintime_travel);
  travel.detach();

  Serial.println("Returning to main loop");
  return;
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived: [");
  Serial.print(topic);
  Serial.print(" ]");
  char *twistcommand = (char *) payload; // convert mqtt byte array into char array
  twistcommand[length] = '\0';           // Must delimit with 0

  Serial.print(twistcommand);
  if (strcmp(twistcommand, "open") == 0) {
    Serial.println(" 433MHZ OPEN COMMAND RECEIVED");
    dirc_twist = 180; // direction for servo to run
    spintime_twist = 480; // << CHANGE TO WHATEVER TIME YOU NEED TO OPEN YOUR BLINDS
    state_twist = 1; //sets current state
  }
  else if (strcmp(twistcommand, "close") == 0) {
    Serial.println(" 433MHZ CLOSE COMMAND RECEIVED");
    dirc_twist = 0;
    spintime_twist = 480; // << CHANGE TO WHATEVER TIME YOU NEED TO CLOSE YOUR BLINDS
    state_twist = 2; //sets current state
  }
  if (state_twist != prevstate_twist) {
    Serial.println("State change!");
    servo_move();
  }

  prevstate_twist = state_twist;

  //second servo

  char *travelcommand = (char *) payload; // convert mqtt byte array into char array
  travelcommand[length] = '\0';           // Must delimit with 0

  Serial.print(travelcommand);
  if (strcmp(travelcommand, "open") == 0) {
    Serial.println(" 433MHZ OPEN COMMAND RECEIVED");
    dirc_travel = 180; // direction for servo to run
    spintime_travel = 11480; // << CHANGE TO WHATEVER TIME YOU NEED TO OPEN YOUR BLINDS
    state_travel = 1; //sets current state
  }
  else if (strcmp(travelcommand, "close") == 0) {
    Serial.println(" 433MHZ CLOSE COMMAND RECEIVED");
    dirc_travel = 0;
    spintime_travel = 11480; // << CHANGE TO WHATEVER TIME YOU NEED TO CLOSE YOUR BLINDS
    state_travel = 2; //sets current state
  }
  if (state_travel != prevstate_travel) {
    Serial.println("State change!");
    servo_move();
  }
  prevstate_travel = state_travel;
}

void MQTT_connect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (client.connect("Shades2Client")) {
      Serial.println("MQTT Connected!");
      client.subscribe(twist_command);
      client.subscribe(travel_command);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000); // wait 5 seconds
    }
  }

}


void loop() {
  if (!client.connected()) {
    MQTT_connect();
  }
  client.loop();
}

Today I tried changing the void servo_move to void twist and void travel, but got the same results

Thank you

You have lots of Serial.print() statements showing where you are in the program logic, which is great, but none printing the values of what your compares are looking at. That will help debugging a whole lot!

Paul

Hi Paul thanks for the reply, I don't have much experience with arduino I got my first arduino about a year and a half ago and still have a lot to learn, how can I set up to print the values of what I'm comparing

Dee723:
Hi Paul thanks for the reply, I don't have much experience with arduino I got my first arduino about a year and a half ago and still have a lot to learn, how can I set up to print the values of what I'm comparing

For instance, in this code:

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

You can add line to print the values being compared:

while (WiFi.status() != WL_CONNECTED) {

Serial.println("WL_CONNECTED = ", WL_CONNECTED);

delay(500);
Serial.print(".");

etcetera!

Paul
}

Hi Paul, I think I'm going to give up on this. I just can't seem to get my head around it, I'm 60 years old and just starting to learn this, and my brain don't work like it use to :slight_smile: The sketch runs fine with a single sketch so I guess I'll just leave it the way it is.

I got and error when I did the

while (WiFi.status() != WL_CONNECTED) {

Serial.println("WL_CONNECTED = ", WL_CONNECTED);

delay(500);
Serial.print(".");

Error: call of overloaded 'println(const char [16], wl_status_t)' is ambiguous

also tried changing and adding many different things I want to Thank you for your help

also I see you have been a ham since 1955, My wife and I also are, we keep our license but have not been active for many years.

Thank you again Dee

Serial.println("WL_CONNECTED = ", WL_CONNECTED);what did you intend there?

Dee723:
Hi Paul, I think I'm going to give up on this. I just can't seem to get my head around it, I'm 60 years old

Hey, c'mon now. You are 6 years younger than I am.

...R

Robin2:
Hey, c'mon now. You are 6 years younger than I am.

...R

That may be but I got my first arduino a year and a half ago. never even knew about them.

You get one reply every five minutes - can you maybe prioritise your replies?

Robin2:
Hey, c'mon now. You are 6 years younger than I am.
...Ra

And 18 years younger than me!

Paul

Hey Dee, I hear ya. I got my first Arduino when I was 61, about 5 years ago. There is certainly a learning curve to it - and lots of going to bed frustrated too! But keep at it - remember, the computer is a servant, not a master (yet.)

When I bang my head against an unyielding wall for a few days, it's time to take a different approach. Unfortunately though, I have no help for your immediate problem. I have never used an ESP8266 device :(...

But I encourage you to keep up the fight! Maybe walk away for a day or three, but come back and try something you haven't tried already. The answers are in there!

Hi ChrisTenone, The problem is not the ESP8266 i have 12 of them around the house.

About a year ago I started trying to combined 2 sketches together,

Now I have them compiling OK with no errors, but both servos move one after the other no matter what one of the two topics are published.

That is the part I'm giving up on

That is the part I'm giving up on

Why? You've been given good suggestions. What is the value of payload in callback()? What is the value of topic in callback()?

I'm going to guess that, in callback(), you need to pay attention to both values. Currently, you ignore the value of topic (which I'm going to guess is "twist" or "travel") and only pay attention to payload (which I'm going to guess is "open" or "close").

You want to open or close the proper servo, not both of them.

PaulS Thank you, I think I found a few things, I'll keep working at for a while longer.

you need to pay attention to both values. Currently, you ignore the value of topic (which I'm going to guess is "twist" or "travel") and only pay attention to payload (which I'm going to guess is "open" or "close").

that got me looking at the sketch a bit closer. And learning a bit more

at lease I think I'm getting closer I'll let you all know in a few days, Thank you for not giving up on me :slight_smile:

Dee723:
that got me looking at the sketch a bit closer. And learning a bit more

Many times what appears to be a programming problem is actually a problem of logic - of not thinking carefully about the series of steps that need to happen.

When the developer has a clear idea of what needs to happen then it is usually straightforward to convert that into program code.

...R
Planning and Implementing a Program

OK I have been reading and watching videos and have Questions, on callback

You've been given good suggestions. What is the value of payload in callback()? What is the value of topic in callback()?

I'm going to guess that, in callback(), you need to pay attention to both values. Currently, you ignore the value of topic (which I'm going to guess is "twist" or "travel") and only pay attention to payload (which I'm going to guess is "open" or "close").

You want to open or close the proper servo, not both of them.

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived: [");
  Serial.print(topic);
  Serial.print(" ]");
  char *twistcommand = (char *) payload; // convert mqtt byte array into char array
  twistcommand[length] = '\0';           // Must delimit with 0

  Serial.print(twistcommand);
  if (strcmp(twistcommand, "open") == 0) {
    Serial.println(" 433MHZ OPEN COMMAND RECEIVED");
    dirctwist = 180; // direction for servo to run
    spintimetwist = 480; // << CHANGE TO WHATEVER TIME YOU NEED TO OPEN YOUR BLINDS
    statetwist = 1; //sets current state
  }
  else if (strcmp(twistcommand, "close") == 0) {
    Serial.println(" 433MHZ CLOSE COMMAND RECEIVED");
    dirctwist = 0;
    spintimetwist = 480; // << CHANGE TO WHATEVER TIME YOU NEED TO CLOSE YOUR BLINDS
    statetwist = 2; //sets current state
  }
  if (statetwist != prevstatetwist) {
    Serial.println("State change!");
    servo_twist();
  }

  prevstatetwist = statetwist;

Am I wrong isn't *twistcommand my topic here? maybe I have to change the way I'm asking the if statement, do I need to change the strcmp? and use something else.

I have decided to try and get this one done so that at least I understand it better.

The part that is confusing me the most, is it worked with one servo, because I'm combining 2 of the same sketches does it have to be written differently?

Thank you all for your help

OK everyone I finally got one working but not sure if was the direction you all was suggesting, but all works great. Thanks for all your help and pushing me to Finish it. I ended up combining the one I was using with another one I found with the void callback() I thought might work. Here is what I ended up doing, If you think I can clean it up let me know Thank you again.

The itsatrap I had to add "int itsatrap" at the top of the sketch

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived: [");
  Serial.print(topic);
  Serial.print(" ]");

    char p[length + 1];
    memcpy(p, payload, length);
    p[length] = NULL;
    String message(p);
    String mytopic(topic);
    if (itsatrap == 0 && mytopic == "Home/twist/command" && message.equals("open")){


    Serial.println(" TWISTING OPEN BLINDS");
    dirctwist = 180; // direction for servo to run
    spintimetwist = 480; // << CHANGE TO WHATEVER TIME YOU NEED TO OPEN YOUR BLINDS
    statetwist = 1; //sets current state
  }
    else if (mytopic == "Home/twist/command" && message.equalsIgnoreCase("close")){
    Serial.println(" TWISTING CLOSE BLINDS");
    dirctwist = 0;
    spintimetwist = 480; // << CHANGE TO WHATEVER TIME YOU NEED TO CLOSE YOUR BLINDS
    statetwist = 2; //sets current state
  }
  if (statetwist != prevstatetwist) {

    servo_twist();
  }

  prevstatetwist = statetwist;

  //second servo


  if (itsatrap == 0 && mytopic == "Home/travel/command" && message.equals("open")){

    Serial.println(" TRAVELING OPEN BLINDS");
    dirctravel = 180; // direction for servo to run
    spintimetravel = 11480; // << CHANGE TO WHATEVER TIME YOU NEED TO OPEN YOUR BLINDS
    statetravel = 1; //sets current state
  }
  else if (mytopic == "Home/travel/command" && message.equalsIgnoreCase("close")){

    Serial.println(" TRAVELING CLOSE BLINDS");
    dirctravel = 0;
    spintimetravel = 11480; // << CHANGE TO WHATEVER TIME YOU NEED TO CLOSE YOUR BLINDS
    statetravel = 2; //sets current state
  }
  if (statetravel != prevstatetravel) {

    servo_travel();
  }
  prevstatetravel = statetravel;
  }

Congrats!