IRremoteESP8266 icon indicating copy to clipboard operation
IRremoteESP8266 copied to clipboard

Can't use the method in example of "CommonAcControl"

Open qifan2019 opened this issue 1 year ago • 6 comments

Version/revision of the library used

I used the 2.8.2 version and the chip was esp-01s

Describe the bug

I wrote the "CommonAcControl.ino" in chips which was example code. set the "kIrLed" =0 or 3(RX), linking the GPIOs to the irsend module's "in" pin, it can work

properly, sending ir signal intermittently.

But when I wrote my code also used the GPIO0 or GPIO3 as "kreLed", the problem came.

The GPIOs would keep high potential,of course, the irsend module would keep lighting. But the "ac.sendAc()" is not work at all. I was so puzzled.

I have tried not performing any serial I/O or using “Serial.begin(115200, SERIAL_8N1, SERIAL_TX_ONLY)”.

Those are useless

Example code used

My code:

#include <Arduino.h>
#include <IRremoteESP8266.h>
#include <IRac.h>
#include <IRutils.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <string>
#include <WiFiManager.h>
#include <EEPROM.h>


// wifiname
const char *ssid = "qifan";
// wifipassword
const char *password = "123456789";

const char *mqttServer = "120.76.140.89";
const char *topic = "smartAcControl/esp8266";
const char *username = "esp8266";
const char *userpassword = "123456789";
const int mqtt_port = 1883;
////////////////////////////////////////

const uint16_t kIrLed = 0; // The ESP GPIO pin to use that controls the IR LED.
bool flag = true;
// if ac matched
bool res;
char *acControl = "acControl";
char *setProtocol = "setProtocol";
char *matchProtocol = "matchProtocol";
char *power = "power";
char *temperature = "temperature";
char *mode = "mode";

/////////////////initwifi
IRac ac(kIrLed);
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
// Create a A/C object using GPIO to sending messages with.

////////////////////////////

void setup()
{
    // digitalWrite(kSendSinal,LOW);
    Serial.begin(115200);
    delay(200);
    // set wifi workmode
    WiFi.mode(WIFI_STA);
    // set gpio0‘s to output
    //  2 eeprom units
    EEPROM.begin(2);
    WiFiManager wm;
    // open captive portal redeirct
    wm.setCaptivePortalEnable(true);
    
    res = wm.autoConnect("smartControl", "123456789");

    if (!res)
    {
        Serial.println("Failed to connect");
        // ESP.restart();
    }
    else
    {
        // if you get here you have connected to the WiFi
        Serial.println("connected...yeey :)");
    }
    // set serve & port of mqtt
    mqttClient.setServer(mqttServer, mqtt_port);
    mqttClient.setCallback(receiveCallback);
    connectMQTTServer();
    // init();
    ////revicer
}
// send sign to user by led of esp

void loop()
{
    // succeed in connecting server
    if (mqttClient.connected())
    { //  keep client heartbeat
        mqttClient.loop();
        // only send led sign one time
    }
    else
    { // try connct server
        connectMQTTServer();
    }
    /// revicer
    delay(10000);
    ac.sendAc();
}

void initAc()
{
    // Set up what we want to send.
    // See state_t, opmode_t, fanspeed_t, swingv_t, & swingh_t in IRsend.h for
    // all the various options.
    // needs test
    int protocolNum = EEPROM.read(0);
    int modelNum = EEPROM.read(1);
    Serial.print("protocolNum:");
    Serial.println(protocolNum);
    Serial.print("modelNum:");
    Serial.println(modelNum);
    decode_type_t protocol = (decode_type_t)protocolNum;
    ac.next.protocol = protocol;                   // Set a protocol to use.
    ac.next.model = modelNum;                      // Some A/Cs have different models. Try just the first.
    ac.next.mode = stdAc::opmode_t::kCool;         // Run in cool mode initially.
    ac.next.celsius = true;                        // Use Celsius for temp units. False = Fahrenheit
    ac.next.degrees = 23;                          // 25 degrees.
    ac.next.fanspeed = stdAc::fanspeed_t::kMedium; // Start the fan at medium.
    ac.next.swingv = stdAc::swingv_t::kOff;        // Don't swing the fan up or down.
    ac.next.swingh = stdAc::swingh_t::kOff;        // Don't swing the fan left or right.
    ac.next.light = false;                         // Turn off any LED/Lights/Display that we can.
    ac.next.beep = false;                          // Turn off any beep from the A/C if we can.
    ac.next.econo = false;                         // Turn off any economy modes if we can.
    ac.next.filter = false;                        // Turn off any Ion/Mold/Health filters if we can.
    ac.next.turbo = false;                         // Don't use any turbo/powerful/etc modes.
    ac.next.quiet = false;                         // Don't use any quiet/silent/etc modes.
    ac.next.sleep = -1;                            // Don't set any sleep time or modes.
    ac.next.clean = false;                         // Turn off any Cleaning options if we can.
    ac.next.clock = -1;                            // Don't set any current time if we can avoid it.
    ac.next.power = false;                         // Initially start with the unit off.
}

void matchAcProtocol(int protocolNo, int modelNo)
{
    decode_type_t protocol = (decode_type_t)protocolNo;
    if (ac.isProtocolSupported(protocol))
    {
        Serial.println("Protocol " + String(protocol) + " / " +
                       typeToString(protocol) + " is supported.");
        ac.next.protocol = protocol;
        ac.next.model = (int)modelNo;
        // Change the protocol used.

        ac.next.power = true; // We want to turn on the A/C unit.
        Serial.println("try to matching.....");
        // publishMessage("protocolMatch", protocolNo, j);
        ac.sendAc();
    }
}

void connectWifi()
{

    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED)
    {
        Serial.print("Connecting to WiFi");
    }
    Serial.println("");
    Serial.println("WiFi Connected!");
    Serial.println("");
}

void connectMQTTServer()
{
    String clientId = "connect_all_esp8266_mqtt_led_client" + WiFi.macAddress();

    if (mqttClient.connect(clientId.c_str(), username, userpassword))
    {
        Serial.println("MQTT Connected.");
        subscribeTopic();
        publishMessage("1", "2", "3");
    }
    else
    {
        Serial.print("MQTT Server Connect Failed. Client State:");
        Serial.println(mqttClient.state());
        delay(500);
    }
}
void subscribeTopic()
{
    // topicString
    String topicString = "smartAcControl/uniapp";

    char subTopic[topicString.length() + 1];
    strcpy(subTopic, topicString.c_str());

    if (mqttClient.subscribe(subTopic))
    {
        Serial.println("Subscrib Topic:");
        Serial.println(subTopic);
    }
    else
    {
        Serial.print("Subscribe Fail...");
    }
}

void publishMessage(String type, String operation, String parameter)
{
    StaticJsonDocument<256> doc;
    char message[128];
    doc["type"] = type;
    doc["operation"] = operation;
    doc["parameter"] = parameter;
    serializeJson(doc, message);
    mqttClient.publish(topic, message);
    Serial.print("published");
}

//// receive and decode mqtt message
void receiveCallback(char *topic, byte *payload, unsigned int length)
{
    Serial.print("Message Received [");
    Serial.print(topic);
    Serial.print(",");
    Serial.print("] ");
    StaticJsonDocument<200> doc;

    //
    char message[length];
    for (int i = 0; i < length; i++)
    {
        message[i] = (char)payload[i];
        Serial.print(message[i]);
    }
    Serial.println();
    DeserializationError error = deserializeJson(doc, payload);
    // Test if parsing succeeds.
    if (error)
    {
        Serial.print(F("deserializeJson() failed: "));
        Serial.println(error.f_str());
        return;
    }

    const char *type = doc["type"];
    const char *operation = doc["operation"];
    const char *parameter = doc["parameter"];
    Serial.print("type:");
    Serial.println(type);
    Serial.print("operation:");
    Serial.println(operation);
    Serial.print("parameter:");
    Serial.println(parameter);
    // if equal return 0;
    if (!strcmp(type, acControl))
    {
        // control ac
        // if want to turn ac on or off
        if (!strcmp(operation, power))
        {
            turnOnOrOffAc(atoi(parameter));
        }
        // if want to switch ac's temperature
        else if (!strcmp(operation, temperature))
        {
            temperatureControl(atoi(parameter));
        }
        // if want to switch ac mode
        else if (!strcmp(operation, mode))
        {
        }
        else
        {
        }
    }
    // done
    else if (!strcmp(type, setProtocol))
    {
        // store protocol & model
        EEPROM.write(0, (atoi(operation)));
        EEPROM.commit();
        EEPROM.write(1, (atoi(parameter)));
        EEPROM.commit();
        initAc();
    }
    else if (!strcmp(type, matchProtocol))
    {
        matchAcProtocol(atoi(operation), atoi(parameter));
    }
    // set settings  systemsettings
    else
    {
    }
}

// control  ac-matched

void turnOnOrOffAc(int powerflag)
{
    Serial.print("powerflag:");
    Serial.println(powerflag);
    ac.next.power = powerflag == 1 ? true : false;
    ac.sendAc(); // Have the IRac class create and send a
    Serial.println("Sending a message to turn ON the A/C unit.");
}

void temperatureControl(int temp)
{
    ac.next.degrees = temp;
    ac.sendAc();
}

Expected behaviour

What steps did you do and what should it have done? A clear and concise description of what you expected to happen.

I tried to test every function, but didn't find the reason

I guess the problem is about the function “loop” ,but i don’t know why and how to solve it

I have followed the steps in the Troubleshooting Guide & read the FAQ

_Yes

Has this library/code previously worked as expected for you?

No.

Other useful information

qifan2019 avatar Jul 18 '22 10:07 qifan2019

I have tried not performing any serial I/O or using “Serial.begin(115200, SERIAL_8N1, SERIAL_TX_ONLY)”.

I am confused. Your code is littered with Serial commands. e.g.

    Serial.println("Sending a message to turn ON the A/C unit.");

Have you tried simplifying your code down to determin where the problem might be?

Have you tried it on a more capable board than the ESP-01 to debug your code? e.g. a WEMOS D1-mini or a NodeMCU board? i.e. One with more GPIOs so you can debug a bit better. What's the debug output on the serial?

Are you sure you're parsing your MQTT values correctly? Are you setting the parameters with the values you think you are? i.e. integers not strings etc.

crankyoldgit avatar Jul 19 '22 15:07 crankyoldgit

See also: https://github.com/crankyoldgit/IRremoteESP8266/wiki/Troubleshooting-Guide#reporting-an-issue

crankyoldgit avatar Jul 19 '22 15:07 crankyoldgit

I have tried not performing any serial I/O or using “Serial.begin(115200, SERIAL_8N1, SERIAL_TX_ONLY)”.

I am confused. Your code is littered with Serial commands. e.g.

    Serial.println("Sending a message to turn ON the A/C unit.");

Have you tried simplifying your code down to determin where the problem might be?

Have you tried it on a more capable board than the ESP-01 to debug your code? e.g. a WEMOS D1-mini or a NodeMCU board? i.e. One with more GPIOs so you can debug a bit better. What's the debug output on the serial?

Are you sure you're parsing your MQTT values correctly? Are you setting the parameters with the values you think you are? i.e. integers not strings etc.

Thank you very much for your reply.

There are some supplemental Information

1、I had deleted all the “Serial” commands,but it didn‘t solve problem. The code I gave is the version that didn't delete “Serial” commands

2、I have bought NodeMCU board based esp-12F,it is on delivery.

3、I have tried to delete or add code to debug, it is so interesting ,if i add codes:

 for (int i = 1; i < kLastDecodeType; i++) {
    decode_type_t protocol = (decode_type_t)i;
    // If the protocol is supported by the IRac class ...
    if (ac.isProtocolSupported(protocol)) {
      Serial.println("Protocol " + String(protocol) + " / " +
                     typeToString(protocol) + " is supported.");
      ac.next.protocol = protocol;  // Change the protocol used.
      ac.next.power = true;  // We want to turn on the A/C unit.
      Serial.println("Sending a message to turn ON the A/C unit.");
      ac.sendAc();  // Have the IRac class create and send a message.
      delay(5000);  // Wait 5 seconds.
      ac.next.power = false;  // Now we want to turn the A/C off.
      Serial.println("Send a message to turn OFF the A/C unit.");
      ac.sendAc();  // Send the message.
      delay(1000);  // Wait 1 second.
    }
  }

in my program,the GPIOs would work normally

4、I determine that I parsing my MQTT values correctly,bacause the output on the serial is normally

5、So far I think the problem is with the function loop, but I don't know why and how to fix it

qifan2019 avatar Jul 20 '22 08:07 qifan2019

4、I determine that I parsing my MQTT values correctly,bacause the output on the serial is normally

Um, you do know that:

String str = "2";
Serial.println(str);  // An arduino string
Serial.println("2");  // A c-style string.
Serial.println('2');  // An ascii uint8_t/byte.
Serial.println(2);  // An integer
int i = 2;
Serial.println(i);  // An integer.

all produce exactly the same output, right?! Yet they are all different types. e.g. '2' == 0x32 == 50 and '2' != 2 != "2"

Serial.println() will convert types to give you a result most people want.

I suggest you put in some appropriate debugging code to indicate you're parsing the numbers from MQTT correctly.

You need to test and debug all of your assumptions. eg.

if (my_parsed_protocol_number == EXPECTED_PROTOCOL_NUMBER) {  // e.g. 42 or something
  // Success. I got the correct protocol number I expected.
  Serial.println("DEBUG: Yay, I got the value of 42!");
}

or simplify your code to remove the parsing from MQTT, hardwire it, and slowly re-add bits back to see where it fails.

But, we are now heading into this teritory.

3、I have tried to delete or add code to debug, it is so interesting ,if i add codes:

To me, this really indicates you've got a problem parsing the values to put into the ac.next structure.

crankyoldgit avatar Jul 20 '22 08:07 crankyoldgit

How's this going?

crankyoldgit avatar Aug 16 '22 02:08 crankyoldgit

Thank you for your support, I was looking for a job in the past few months, so I forgot about it, I will continue to troubleshoot the problem afterwards

qifan2019 avatar Nov 09 '22 03:11 qifan2019