sinricpro / esp8266-esp32-sdk

Library for https://sinric.pro - simple way to connect your device to Alexa, Google Home, SmartThings and cloud
https://sinric.pro
228 stars 121 forks source link

Node MCU ESP-32s Fan Integration with L298N PWM #278

Closed killerman1135 closed 2 years ago

killerman1135 commented 2 years ago

Hello I am trying to get this fan coding to work and I have searched through all the closed tickets looking for information but could not get it working. Here is the code that I am working on.

#define ENABLE_DEBUG

#ifdef ENABLE_DEBUG
#define DEBUG_ESP_PORT Serial
#define NODEBUG_WEBSOCKETS
#define NDEBUG
#endif

#include <Arduino.h>
#ifdef ESP8266
#include <ESP8266WiFi.h>
#endif
#ifdef ESP32
#include <WiFi.h>
#endif

#include "SinricPro.h"
#include "SinricProFanUS.h"
#include <analogWrite.h>

#define WIFI_SSID         "************"
#define WIFI_PASS         "**********"
#define APP_KEY           "xxxxxxxxxxx"      // Should look like "de0bxxxx-1x3x-4x3x-ax2x-5dabxxxxxxxx"
#define APP_SECRET        "xxxxxx"   // Should look like "5f36xxxx-x3x7-4x3x-xexe-e86724a9xxxx-4c4axxxx-3x3x-x5xe-x9x3-333d65xxxxxx"
#define FAN_ID            "xxx"    // Should look like "5dc1564130xxxxxxxxxxxxxx"
#define BAUD_RATE         115200                // Change baudrate to your need
#define Fan_speed         19
#define Fan_power         18

// we use a struct to store all states and values for our fan
// fanSpeed (1..3)
struct {
  bool powerState = false;
  int fanSpeed = 1;
} device_state;

bool onPowerState(const String &deviceId, bool &state) {
  Serial.printf("Fan turned %s\r\n", state ? "on" : "off");
  device_state.powerState = state;
  digitalWrite(Fan_power, onPowerState ? LOW : HIGH);
  return true; // request handled properly
}

// Fan rangeValue is from 1..3

bool onRangeValue(const String &deviceId, int &value) {
  int analogValue = map(value, 0, 3, 0, 1023); // map the value from 0..3 to 0..1023
  analogWrite(Fan_speed, analogValue);     // write the anlog value to a pin
  return true;
}

// Fan rangeValueDelta is from -3..+3
bool onAdjustRangeValue(const String &deviceId, int& rangeValueDelta) {
  device_state.fanSpeed += rangeValueDelta;
  Serial.printf("Fan speed changed about %i to %d\r\n", rangeValueDelta, device_state.fanSpeed);

  rangeValueDelta = device_state.fanSpeed; // return absolute fan speed
  return true;
}

void setupWiFi() {
  Serial.printf("\r\n[Wifi]: Connecting");
  WiFi.begin(WIFI_SSID, WIFI_PASS);

  while (WiFi.status() != WL_CONNECTED) {
    Serial.printf(".");
    delay(250);
  }
  Serial.printf("connected!\r\n[WiFi]: IP-Address is %s\r\n", WiFi.localIP().toString().c_str());
}

void setupSinricPro() {
  SinricProFanUS &myFan = SinricPro[FAN_ID];

  // set callback function to device
  myFan.onPowerState(onPowerState);
  myFan.onRangeValue(onRangeValue);
  myFan.onAdjustRangeValue(onAdjustRangeValue);

  // setup SinricPro
  SinricPro.onConnected([]() {
    Serial.printf("Connected to SinricPro\r\n");
  });
  SinricPro.onDisconnected([]() {
    Serial.printf("Disconnected from SinricPro\r\n");
  });
  SinricPro.begin(APP_KEY, APP_SECRET);
}

// main setup function
void setup() {
  Serial.begin(BAUD_RATE); Serial.printf("\r\n\r\n");
  setupWiFi();
  setupSinricPro();
  pinMode(Fan_speed, OUTPUT);
  pinMode(Fan_power, OUTPUT);

}

void loop() {
  SinricPro.handle();
}
kakopappa commented 2 years ago

Hi @killerman1135

code LGTM.

Have you tried the code without Sinric Pro integration?

int enA = 19; 
int enB = 18; 

void setup() {
    pinMode(enA, OUTPUT);
    pinMode(enB, OUTPUT); 
}

void loop() {
    // Accelerate from zero to maximum speed
    for (int i = 0; i < 256; i++) {
        analogWrite(enA, i);
        analogWrite(enB, i);
        delay(20);
    }

    // Decelerate from maximum speed to zero
    for (int i = 255; i >= 0; --i) {
        analogWrite(enA, i);
        analogWrite(enB, i);
        delay(20);
    }

    delay(1000);
}

Can you be more specific about the problem?

sivar2311 commented 2 years ago

If the basic control (as mentioned by kakopappa) works I suggest the following:

Implement a function that controls the pins depending on the settings in the device_state:

void updateFan() {
  bool power = device_state.powerState;
  bool speed = device_state.fanSpeed;

  int analogSpeed = map(speed, 0, 3, 0, 1023);

  digitalWrite(Fan_power, power ? LOW : HIGH);
  analogWrite(Fan_speed, power ? analogSpeed : 0);
}

Then you just have to update the device_state struct in the callbacks and call the updateFan() function like this:

bool onPowerState(const String &deviceId, bool &state) {
  Serial.printf("Fan turned %s\r\n", state ? "on" : "off");
  device_state.powerState = state;
  updateFan();
  return true; // request handled properly
}

bool onRangeValue(const String &deviceId, int &value) {
  Serial.printf("Fan speed set to %d\r\n", value);
  device_state.fanSpeed = value;
  updateFan();
  return true;
}

// Fan rangeValueDelta is from -3..+3
bool onAdjustRangeValue(const String &deviceId, int& rangeValueDelta) {
  device_state.fanSpeed += rangeValueDelta;
  Serial.printf("Fan speed changed about %i to %d\r\n", rangeValueDelta, device_state.fanSpeed);
  rangeValueDelta = device_state.fanSpeed; // return absolute fan speed
  updateFan();
  return true;
}
killerman1135 commented 2 years ago

This is as far as I could get to make both pins turn on and off from Sinric control panel but neither of the pins change their voltage when checked with a multimeter. im reading 1.12V constant on both and then 0 when toggled off on the control panel.

define ENABLE_DEBUG

ifdef ENABLE_DEBUG

define DEBUG_ESP_PORT Serial

define NODEBUG_WEBSOCKETS

define NDEBUG

endif

include

ifdef ESP8266

include

endif

ifdef ESP32

include

endif

include "SinricPro.h"

include "SinricProFanUS.h"

include

define WIFI_SSID "xxx"

define WIFI_PASS "xxxx"

define APP_KEY "xxxxxx" // Should look like "de0bxxxx-1x3x-4x3x-ax2x-5dabxxxxxxxx"

define APP_SECRET "xxxx" // Should look like "5f36xxxx-x3x7-4x3x-xexe-e86724a9xxxx-4c4axxxx-3x3x-x5xe-x9x3-333d65xxxxxx"

define FAN_ID "xxx" // Should look like "5dc1564130xxxxxxxxxxxxxx"

define BAUD_RATE 115200 // Change baudrate to your need

const int Fan_speed = 16; const int Fan_power = 18; const int Fan_Ch = 0; const int Fan_Res = 8; const int Fan_Freq = 5000;

// we use a struct to store all states and values for our fan // fanSpeed (1..3) struct { bool powerState = false; int fanSpeed = 1; } device_state;

void updateFan() { bool power = device_state.powerState; bool speed = device_state.fanSpeed; int analogSpeed = map(speed, 0, 3, 0, 255); digitalWrite(Fan_power, power ? LOW : HIGH); ledcWrite(Fan_Ch, power ? analogSpeed : 0); }

bool onPowerState(const String &deviceId, bool &state) { Serial.printf("Fan turned %s\r\n", state ? "on" : "off"); device_state.powerState = state; updateFan(); return true; // request handled properly }

bool onRangeValue(const String &deviceId, int &value) { Serial.printf("Fan speed set to %d\r\n", value); device_state.fanSpeed = value; updateFan(); return true; }

// Fan rangeValueDelta is from -3..+3 bool onAdjustRangeValue(const String &deviceId, int& rangeValueDelta) { device_state.fanSpeed += rangeValueDelta; Serial.printf("Fan speed changed about %i to %d\r\n", rangeValueDelta, device_state.fanSpeed); rangeValueDelta = device_state.fanSpeed; // return absolute fan speed updateFan(); return true; }

void setupWiFi() { Serial.printf("\r\n[Wifi]: Connecting"); WiFi.begin(WIFI_SSID, WIFI_PASS);

while (WiFi.status() != WL_CONNECTED) { Serial.printf("."); delay(250); } Serial.printf("connected!\r\n[WiFi]: IP-Address is %s\r\n", WiFi.localIP().toString().c_str()); }

void setupSinricPro() { SinricProFanUS &myFan = SinricPro[FAN_ID];

// set callback function to device myFan.onPowerState(onPowerState); myFan.onRangeValue(onRangeValue); myFan.onAdjustRangeValue(onAdjustRangeValue);

// setup SinricPro SinricPro.onConnected([]() { Serial.printf("Connected to SinricPro\r\n"); }); SinricPro.onDisconnected([]() { Serial.printf("Disconnected from SinricPro\r\n"); }); SinricPro.begin(APP_KEY, APP_SECRET); }

// main setup function void setup() { Serial.begin(BAUD_RATE); Serial.printf("\r\n\r\n"); setupWiFi(); setupSinricPro();
ledcSetup(Fan_Ch, Fan_Freq, Fan_Res); ledcAttachPin(Fan_speed, Fan_Ch); ledcAttachPin(Fan_power, 0); pinMode(Fan_speed, OUTPUT); pinMode(Fan_power, OUTPUT);

}

void loop() { SinricPro.handle(); }

sivar2311 commented 2 years ago

It seems that the digital write command was not working with any example sketch so I substituted the ledcWrite

Do you mean digitalWrite() or analogWrite()? Because ledcWrite is the esp32's version for analogWrite(). But the hint with the ledcWrite() points to an ESP32.

could you review the code to see if it will work?

src/main.cpp:19:10: fatal error: analogWrite.h: No such file or directory
 #include <analogWrite.h>
          ^~~~~~~~~~~~~~~
compilation terminated.

Delete line 19: #include <analogWrite.h> There is no analogWrite.h in the espressif32-arduino framework.

src/main.cpp:30: warning: "Fan_speed" redefined
 #define Fan_speed 5

src/main.cpp:27: note: this is the location of the previous definition
 #define Fan_speed 19

You have 2x #define Fan_speed

Change lines 27-28 This makes it clear that these are GPIOs.:

#define Fan_speed_gpio 19
#define Fan_power_gpio 18

The espressif-arduino framework supports the analogWrite() function without problems. The error was probably in the mapping from 0 to 1023. The values must be between 0 and 255. So lets switch back to the analogWrite() function.

Delete lines 30-33:

#define Fan_speed 5
#define Fan_Ch 0
#define Fan_Res 8
#define Fan_Freq 5000

Change lines 46-47:

    digitalWrite(Fan_power_gpio, power ? LOW : HIGH);
    analogWrite(Fan_speed_gpio, power ? analogSpeed : 0);

Delete lines 108-112:

    ledcAttachPin(Fan_speed, 0);
    ledcAttachPin(Fan_power, 0);

    pinMode(Fan_speed, OUTPUT);
    pinMode(Fan_power, OUTPUT);

This leaves us with the following errors (which might be a cause of posting the code without using code-blocks)

src/main.cpp: In function 'void setupSinricPro()':
src/main.cpp:94:44: error: expected '}' before ';' token
 Serial.printf("Connected to SinricPro\r\n");
                                            ^
src/main.cpp:93:24: note: to match this '{'
 SinricPro.onConnected( {
                        ^
src/main.cpp:94:44: error: expected ')' before ';' token
 Serial.printf("Connected to SinricPro\r\n");
                                            ^
                                            )
src/main.cpp:93:22: note: to match this '('
 SinricPro.onConnected( {
                      ^
src/main.cpp: At global scope:
src/main.cpp:95:2: error: expected unqualified-id before ')' token
 });
  ^
src/main.cpp:96:1: error: 'SinricPro' does not name a type
 SinricPro.onDisconnected( {
 ^~~~~~~~~
src/main.cpp:98:2: error: expected unqualified-id before ')' token
 });
  ^
src/main.cpp:99:1: error: 'SinricPro' does not name a type
 SinricPro.begin(APP_KEY, APP_SECRET);
 ^~~~~~~~~
src/main.cpp:100:1: error: expected declaration before '}' token
 }
 ^

To fix this, change lines 93-98:

  SinricPro.onConnected( []() {
    Serial.printf("Connected to SinricPro\r\n");
  });
  SinricPro.onDisconnected( []() {
    Serial.printf("Disconnected from SinricPro\r\n");
  });

With these changes, the code now compiles without problems. Assuming your wiring matches the code (you did not specify your circuit and the components used) - everything should work. I hope this helps you.

I kindly ask you

killerman1135 commented 2 years ago

Yes I am using a ESP-32s Expressif. I am also trying to turn on 1 pin to enable the motor controller and 1 pin to provide the pwm to control the motors speed I read that pin 19 is not an analog pin so I changed to pin 16. I tried to get Analogwrite to work by adding this #include . since it is a ESP32 should I use the ledcwrite in place of analogWrite?

sivar2311 commented 2 years ago

Yes I am using a ESP-32s Expressif.

ESP-32s is unclear. It could be the ESP32-S2 (single core without Bluetooth) or the ESP32-S3 (dual core with Bluetooth LE 5.0). Maybe you can name your used developer module?

I tried to get Analogwrite to work by adding this #include . since it is a ESP32 should I use the ledcwrite in place of analogWrite?

There is no file analogWrite.h. But the analogWrite() function is included in the espressif32-arduino framework and implemented in the file esp32-hal-led.c. (You don`t have to include this file, this is done automatically by the Arduino framework). You can use this function directly without any extra includes.

killerman1135 commented 2 years ago

Maybe you can name your used developer module? HiLetgo ESP-WROOM-32 ESP32 ESP-32S Development Board 2.4GHz Dual-Mode WiFi + Bluetooth Dual Cores Microcontroller Processor Integrated with Antenna RF AMP Filter AP STA for Arduino IDE.

kakopappa commented 2 years ago

Hi @killerman1135

are you using a library for analogWrite.h ? perhaps you have installed https://github.com/erropix/ESP32_AnalogWrite

if you are going to use ledcWrite, make sure to call ledcSetup, ledcAttachPin as well.

#define LED1 21
/* setting PWM properties */
const int freq = 5000;
const byte ledChannel = 0;
const byte resolution = 8;

void setup(){
  ledcSetup(ledChannel, freq, resolution);
  ledcAttachPin(LED1, ledChannel);
}
void loop(){
  for(int duty = 0; duty <= 255; duty++){   
    ledcWrite(ledChannel, duty);
    delay(15);
  }
  for(int duty = 255; duty >=0; duty--){   
    ledcWrite(ledChannel, duty);
    delay(15);
  }  
}
sivar2311 commented 2 years ago

So this is an Ai-Thinker NodeMCU-32S. As far as i can see this is using the "standard" ESP32 WROOM module. (Unfortunately, AI-Thinker's specifications are also somewhat confusing.)

Using GPIO 13,or GPIOs 16 to 33 shound be no problem^1.

sivar2311 commented 2 years ago

@kakopappa There is no need for ledc since the espressif32-Arduino framework supports analogWrite(). Unless you absolutely need it and want to initialize the channels and PWM frequencies specifically.

Simple solution: analogWrite() Advanced (but more complicated) solution: ledcWrite()

killerman1135 commented 2 years ago

okay so I have changed my coding back to analogwrite but I am not getting output on pin 18 to enable the L298N motor controller. and I am getting a voltage(1.20V) on pin 16 that i can control with Sinric turnon fan and turn off fan but selecting any of the speeds doesnt change the voltage output on the pin 16.

(Edit by sivar2311: code-blocks)

#define ENABLE_DEBUG
#ifdef ENABLE_DEBUG
#define DEBUG_ESP_PORT Serial
#define NODEBUG_WEBSOCKETS
#define NDEBUG
#endif

#include <Arduino.h>
#ifdef ESP8266
#include <ESP8266WiFi.h>
#endif
#ifdef ESP32
#include <WiFi.h>
#endif

#include "SinricPro.h"
#include "SinricProFanUS.h"
#include <analogWrite.h>

#define WIFI_SSID         "kevin2.4"
#define WIFI_PASS         "prettyflyforawifi"
#define APP_KEY           "x"      
#define APP_SECRET        "x" 
#define FAN_ID            "x"    
#define BAUD_RATE         115200 

#define Fan_speed_gpio 16
#define Fan_power_gpio 18

// we use a struct to store all states and values for our fan
// fanSpeed (1..3)
struct {
  bool powerState = false;
  int fanSpeed = 1;
} device_state;

void updateFan() {
  bool power = device_state.powerState;
  bool speed = device_state.fanSpeed;
  int analogSpeed = map(speed, 0, 3, 0, 255);
  digitalWrite(Fan_power_gpio, power ? LOW : HIGH);
  analogWrite(Fan_speed_gpio, power ? analogSpeed : 0);
}

bool onPowerState(const String &deviceId, bool &state) {
  Serial.printf("Fan turned %s\r\n", state ? "on" : "off");
  device_state.powerState = state;
  updateFan();
  return true; // request handled properly
}

bool onRangeValue(const String &deviceId, int &value) {
  Serial.printf("Fan speed set to %d\r\n", value);
  device_state.fanSpeed = value;
  updateFan();
  return true;
}

// Fan rangeValueDelta is from -3..+3
bool onAdjustRangeValue(const String &deviceId, int& rangeValueDelta) {
  device_state.fanSpeed += rangeValueDelta;
  Serial.printf("Fan speed changed about %i to %d\r\n", rangeValueDelta, device_state.fanSpeed);
  rangeValueDelta = device_state.fanSpeed; // return absolute fan speed
  updateFan();
  return true;
}

void setupWiFi() {
  Serial.printf("\r\n[Wifi]: Connecting");
  WiFi.begin(WIFI_SSID, WIFI_PASS);

  while (WiFi.status() != WL_CONNECTED) {
    Serial.printf(".");
    delay(250);
  }
  Serial.printf("connected!\r\n[WiFi]: IP-Address is %s\r\n", WiFi.localIP().toString().c_str());
}

void setupSinricPro() {
  SinricProFanUS &myFan = SinricPro[FAN_ID];

  // set callback function to device
  myFan.onPowerState(onPowerState);
  myFan.onRangeValue(onRangeValue);
  myFan.onAdjustRangeValue(onAdjustRangeValue);

  // setup SinricPro
  SinricPro.onConnected( []() {
    Serial.printf("Connected to SinricPro\r\n");
  });
  SinricPro.onDisconnected( []() {
    Serial.printf("Disconnected from SinricPro\r\n");
  });
  SinricPro.begin(APP_KEY, APP_SECRET);
}

// main setup function
void setup() {
  Serial.begin(BAUD_RATE); Serial.printf("\r\n\r\n");
  setupWiFi();
  setupSinricPro();

}

void loop() {
  SinricPro.handle();
}
sivar2311 commented 2 years ago

@killerman1135 There is also an example for the L298N Motor Driver at randomnerdtutorials. This example shows you how to set up and use ledcWrite(). But I am sure this can also be done easier by using analogWrite()

If GPIO16 is not working for you, simply try another gpio.

sivar2311 commented 2 years ago

... voltage(1.20V) ... ... but selecting any of the speeds doesnt change the voltage output on the pin 16.

The voltage is always 3.3V on these pins! What you measure is the average voltage (generated by PWM^1).

killerman1135 commented 2 years ago

So shouldn't the average voltage change from speed 1 to 2 to 3 when selecting fan speeds?

... voltage(1.20V) ...

... but selecting any of the speeds doesnt change the voltage output on the pin 16.

The voltage is always 3.3V on these pins!

What you measure is the average voltage (generated by PWM^1).

sivar2311 commented 2 years ago

What I meant to say: Forget about the voltage. The L298N is controlled via PWM.

Have a look at the example from randomnerdtutorials.

killerman1135 commented 2 years ago

@sivar2311 @kakopappa Thank you soo much for the assistance I will review the provided resources and come back with more questions!

sivar2311 commented 2 years ago

Just another note: In your code you have digitalWrite(Fan_power_gpio, power ? LOW : HIGH); which mean if the device is turned ON, the pin is set to LOW if the device is turned OFF, the pin is set to HIGH

Screenshot from randomnerdtutorials: image

sivar2311 commented 2 years ago

I have connected my oscilloscope to GPIOs 16, 18 and 22. (Unfortunately my oscilloscope has only 2 channels). The duty cycle was set to 50%, e.g. anlogWrite(gpio, 128). GPIOs 18 and 22 produced a clear PWM signal (yellow) GPIO 16 produced a strange signal (blue) with a peak-to-peak voltage of about 132mV. This wave is also generated when there is no analogWrite to GPIO16! Conclusion: GPIO 16 is not usable for PWM output

2022-06-17 12_29_03_59

killerman1135 commented 2 years ago

hello I was able to get it to power on with the on and off function of sinric but am unable to change the fan speed please help.

#define DEBUG_ESP_PORT Serial
#define NODEBUG_WEBSOCKETS
#define NDEBUG
#include <Arduino.h>
#include <WiFi.h>
#include "SinricPro.h"
#include "SinricProFanUS.h"

#define WIFI_SSID         "xx"
#define WIFI_PASS         "x"
#define APP_KEY           "x"      // Should look like "de0bxxxx-1x3x-4x3x-ax2x-5dabxxxxxxxx"
#define APP_SECRET        "x"   // Should look like "5f36xxxx-x3x7-4x3x-xexe-e86724a9xxxx-4c4axxxx-3x3x-x5xe-x9x3-333d65xxxxxx"
#define FAN_ID            "x"    // Should look like "5dc1564130xxxxxxxxxxxxxx"
#define BAUD_RATE         115200                // Change baudrate to your need

#define ENA         27
#define IN2         14
//#define ENB         NA

//#define IN4         NA
//#define IN1         NA
//#define IN3         NA
// Setting PWM properties
const int PWM1_Freq = 30000;
const int PWM1_Ch = 0;
const int PWM1_Res = 8;

// we use a struct to store all states and values for our fan
struct {
  bool powerState = false;
  int fanSpeed = 1;
} device_state;

void updateFan() {
  bool power = device_state.powerState;
  bool speed = device_state.fanSpeed;

  int analogSpeed = map(speed, 0, 3, 0, 255);

  digitalWrite(ENA, power ? analogSpeed : 0); //previously this was (ENA, power ? LOW:HIGH) but it wasnt working
  ledcWrite(0, power ? analogSpeed : 0);
  Serial.println("power");
  Serial.println(power);
  Serial.println("speed");
  Serial.println(speed);
  Serial.println("analogSpeed");
  Serial.println(analogSpeed);

  }

bool onPowerState(const String &deviceId, bool &state) {
  Serial.printf("Fan turned %s\r\n", state ? "on" : "off");
  device_state.powerState = state;
  updateFan();
  return true; // request handled properly
}

// Fan rangeValue is from 1..3

bool onRangeValue(const String &deviceId, int &value) {
  Serial.printf("Fan speed set to %d\r\n", value);
  device_state.fanSpeed = value;
updateFan();
  return true;
}

// Fan rangeValueDelta is from -3..+3
bool onAdjustRangeValue(const String &deviceId, int& rangeValueDelta) {
  device_state.fanSpeed += rangeValueDelta;
  Serial.printf("Fan speed changed about %i to %d\r\n", rangeValueDelta, device_state.fanSpeed);
  rangeValueDelta = device_state.fanSpeed; // return absolute fan speed
  updateFan();
  return true;
}

void setupWiFi() {
  Serial.printf("\r\n[Wifi]: Connecting");
  WiFi.begin(WIFI_SSID, WIFI_PASS);

  while (WiFi.status() != WL_CONNECTED) {
    Serial.printf(".");
    delay(250);
  }
  Serial.printf("connected!\r\n[WiFi]: IP-Address is %s\r\n", WiFi.localIP().toString().c_str());
}

void setupSinricPro() {
  SinricProFanUS &myFan = SinricPro[FAN_ID];

  // set callback function to device
  myFan.onPowerState(onPowerState);
  myFan.onRangeValue(onRangeValue);
  myFan.onAdjustRangeValue(onAdjustRangeValue);

  // setup SinricPro
  SinricPro.onConnected([]() {
    Serial.printf("Connected to SinricPro\r\n");
  });
  SinricPro.onDisconnected([]() {
    Serial.printf("Disconnected from SinricPro\r\n");
  });
  SinricPro.begin(APP_KEY, APP_SECRET);
}

// main setup function
void setup() {
  Serial.begin(BAUD_RATE); Serial.printf("\r\n\r\n");
  setupWiFi();
  setupSinricPro();
  pinMode(ENA, OUTPUT);
  pinMode(IN2, OUTPUT);
  ledcAttachPin(IN2, PWM1_Ch);
  ledcSetup(PWM1_Ch, PWM1_Freq, PWM1_Res);

}

void loop() {
  SinricPro.handle();
}
sivar2311 commented 2 years ago

The code looks okay at first glance. But that's all that can be determined from the code. Could you already control the fan with a non-SinricPro sketch?

killerman1135 commented 2 years ago

The code looks okay at first glance. But that's all that can be determined from the code.

Could you already control the fan with a non-SinricPro sketch?

I am able to vary the fan speed with non-sinric integration The issue that I have pinpointed is that the fan speed value is set to 1 out of 3 but I'm unable to change it with set speed in the current configuration I am able to turn on the pulse with the on button and turn off the pulse with the offer instead of it being controlled with that fan speed value.

sivar2311 commented 2 years ago

How do you change the speed in your non-sinricpro sketch? Please provide a simple implementation for this so we can adapt it together.

Note: the fan device is limited to 3 fixed speed settings from 1 to 3. So the value is between 1 and 3 and must be mapped to x..255. Since 0 is no speed i suggest a mapping the values 1..3 to 64..255 like this: int analogSpeed = map(speed, 1, 3, 64, 255);

killerman1135 commented 2 years ago

I can change those numbers but the fan speed setting on the webpage doesnt pass the fan speed change to int analogSpeed = map(speed, 1, 3, 64, 255);

sivar2311 commented 2 years ago

https://user-images.githubusercontent.com/2558564/174663144-b486f7ea-6adc-43f6-9736-ceedc47a0739.mp4

Try this updateFan function and watch your serial monitor:

void updateFan() {
  bool powerState = device_state.powerState;
  int fanSpeed = device_state.fanSpeed;
  int analogSpeed = map(fanSpeed, 1, 3, 64, 255);
  Serial.printf("Power: %s, Speed %d, mapped Speed: %d\r\n", powerState ? "On" : "Off", fanSpeed, analogSpeed);
}
sivar2311 commented 2 years ago

Hi @killerman1135 Do you get the same serial output?

killerman1135 commented 2 years ago

Thank you soo much I really appreciate the assistance from @sivar2311 @kakopappa sivar2311 I was able to get everything working perfectly!

#define DEBUG_ESP_PORT Serial
#define NODEBUG_WEBSOCKETS
#define NDEBUG
#include <Arduino.h>
#include <WiFi.h>
#include "SinricPro.h"
#include "SinricProFanUS.h"

#define WIFI_SSID         "x"
#define WIFI_PASS         "x"
#define APP_KEY           "x"      // Should look like "de0bxxxx-1x3x-4x3x-ax2x-5dabxxxxxxxx"
#define APP_SECRET        "x"   // Should look like "5f36xxxx-x3x7-4x3x-xexe-e86724a9xxxx-4c4axxxx-3x3x-x5xe-x9x3-333d65xxxxxx"
#define FAN_ID            "x"    // Should look like "5dc1564130xxxxxxxxxxxxxx"
#define BAUD_RATE         115200                // Change baudrate to your need

#define ENA         27
#define IN2         14
#define IN4         12
//#define ENB         NA

//#define IN4         NA
//#define IN1         NA
//#define IN3         NA
// Setting PWM properties
const int PWM1_Freq = 30000;
const int PWM1_Ch = 0;
const int PWM1_Res = 8;

// we use a struct to store all states and values for our fan
struct {
  bool powerState = false;
  int fanSpeed = 1;
} device_state;
void updateFan() {
  bool powerState = device_state.powerState;
  int fanSpeed = device_state.fanSpeed;
  int analogSpeed = map(fanSpeed, 1, 3, 64, 255);
  Serial.printf("Power: %s, Speed %d, mapped Speed: %d\r\n", powerState ? "On" : "Off", fanSpeed, analogSpeed);
  digitalWrite(ENA, powerState ? LOW : HIGH); 
  ledcWrite(0, powerState ? analogSpeed : 0);
}

bool onPowerState(const String &deviceId, bool &state) {
  Serial.printf("Fan turned %s\r\n", state ? "on" : "off");
  device_state.powerState = state;
  updateFan();
  return true; // request handled properly
}

// Fan rangeValue is from 1..3

bool onRangeValue(const String &deviceId, int &value) {
  Serial.printf("Fan speed set to %d\r\n", value);
  device_state.fanSpeed = value;
  updateFan();
  return true;
}

// Fan rangeValueDelta is from -3..+3
bool onAdjustRangeValue(const String &deviceId, int& rangeValueDelta) {
  device_state.fanSpeed += rangeValueDelta;
  Serial.printf("Fan speed changed about %i to %d\r\n", rangeValueDelta, device_state.fanSpeed);
  rangeValueDelta = device_state.fanSpeed; // return absolute fan speed
  updateFan();
  return true;
}

void setupWiFi() {
  Serial.printf("\r\n[Wifi]: Connecting");
  WiFi.begin(WIFI_SSID, WIFI_PASS);

  while (WiFi.status() != WL_CONNECTED) {
    Serial.printf(".");
    delay(250);
  }
  Serial.printf("connected!\r\n[WiFi]: IP-Address is %s\r\n", WiFi.localIP().toString().c_str());
}

void setupSinricPro() {
  SinricProFanUS &myFan = SinricPro[FAN_ID];

  // set callback function to device
  myFan.onPowerState(onPowerState);
  myFan.onRangeValue(onRangeValue);
  myFan.onAdjustRangeValue(onAdjustRangeValue);

  // setup SinricPro
  SinricPro.onConnected([]() {
    Serial.printf("Connected to SinricPro\r\n");
  });
  SinricPro.onDisconnected([]() {
    Serial.printf("Disconnected from SinricPro\r\n");
  });
  SinricPro.begin(APP_KEY, APP_SECRET);
}

// main setup function
void setup() {
  Serial.begin(BAUD_RATE); Serial.printf("\r\n\r\n");
  setupWiFi();
  setupSinricPro();
  pinMode(ENA, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN4, OUTPUT);
  //pinMode(ENB, OUTPUT);
  //pinMode(IN4, OUTPUT);
  ledcAttachPin(IN2, PWM1_Ch);
  ledcAttachPin(IN4, PWM1_Ch);
  ledcSetup(PWM1_Ch, PWM1_Freq, PWM1_Res);

}

void loop() {
  SinricPro.handle();
}
sivar2311 commented 2 years ago

Hi @killerman1135 What was the exact solution for you?

killerman1135 commented 2 years ago

@sivar2311 The issue was not understanding the purpose of the variable once you provided the last piece to the puzzle everything worked.

Try this updateFan function and watch your serial monitor:

void updateFan() {
  bool powerState = device_state.powerState;
  int fanSpeed = device_state.fanSpeed;
  int analogSpeed = map(fanSpeed, 1, 3, 64, 255);
  Serial.printf("Power: %s, Speed %d, mapped Speed: %d\r\n", powerState ? "On" : "Off", fanSpeed, analogSpeed);
}