Esp32 pwm not fully switching off

I am using the ESP32 to dim LED's connected to a Meanwell PSU here.

The ESP32 is set up with a webserver and a slider.

I am making use of a transistor circuit to give a 10V PWM Output which inverts the output.

I am making use of the map() function to invert this again from 0 (off) to 255 (fully on).

Each time the slider reaches 0 it is suppose to switch off, but on the the scope I can see a small output causing the LED's to not fully switch off.

The sliderVal also outputs 1 when printed to console.

Any suggestions?

// Send a GET request to <ESP_IP>/slider?value=<inputMessage>
  server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
    String inputMessage;
    // GET input1 value on <ESP_IP>/slider?value=<inputMessage>
    if (request->hasParam(PARAM_INPUT)) {
      inputMessage = request->getParam(PARAM_INPUT)->value();
      sliderValue = inputMessage;
      
      int sliderVal = map((sliderValue.toInt()), 0, 255, 255, 0);
     ledcWrite(ledChannel, (sliderVal));
     Serial.print("SliderVal: ");
     Serial.println(sliderVal);
    }
    else {
      inputMessage = "No message sent";
    }
    Serial.println(inputMessage);
    request->send(200, "text/plain", "OK");
  });

None of the code presented shows the setup of the LEDC API; timer configuration and channel configuration. Would you agree that if there is an issue with the timer configuration then the configuration error would be garbage in to the applying of a PWM value?

ESP32 LEDC API.

Hi, setup code below:

const int output = 23;

String sliderValue = "0";

// setting PWM properties
const int freq = 100;
const int ledChannel = 0;
const int resolution = 8;

void setup(){
  // Serial port for debugging purposes
  Serial.begin(115200);
  
  // configure LED PWM functionalitites
  ledcSetup(ledChannel, freq, resolution);
  
  // attach the channel to the GPIO to be controlled
  ledcAttachPin(output, ledChannel);
  
  ledcWrite(ledChannel, sliderValue.toInt());

  // Connect to Wi-Fi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }

  // Print ESP Local IP Address
  Serial.println(WiFi.localIP());

  // Route for root / web page
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html, processor);
  });

  // Send a GET request to <ESP_IP>/slider?value=<inputMessage>
  server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
    String inputMessage;
    // GET input1 value on <ESP_IP>/slider?value=<inputMessage>
    if (request->hasParam(PARAM_INPUT)) {
      inputMessage = request->getParam(PARAM_INPUT)->value();
      sliderValue = inputMessage;
      
      int sliderVal = map((sliderValue.toInt()), 0, 255, 255, 0);

      ledcWrite(ledChannel, (sliderVal));
    }
    else {
      inputMessage = "No message sent";
    }
    Serial.println(inputMessage);
    request->send(200, "text/plain", "OK");
  });
  
  // Start server
  server.begin();
}

Why so low?

You should read the documentation from the link in post number 1.

I can not confirm your findings that the pwm output does not go to 0. Here is a test sketch which uses an interrupt on pin 21 to read the pwm pulse count output of pin 23.

Jumper pin 21 to pin 23 for this test.

I would verify that your mapping works at you intend. Perhaps use constrain.

const int output = 23;
const int input  = 21;

volatile uint32_t count;
uint32_t copyCount;
uint32_t lastRead;
uint32_t switchCount;

// setting PWM properties
String sliderValue = "0";
const int freq = 100;
const int ledChannel = 0;
const int resolution = 8;

//interrupt counter
void IRAM_ATTR isr() {
  count++;
}

void setup() {
  // Serial port for debugging purposes
  Serial.begin(115200);
  pinMode(input, INPUT_PULLDOWN);
  attachInterrupt(input, isr, RISING);

  // configure LED PWM functionalitites
  ledcSetup(ledChannel, freq, resolution);

  // attach the channel to the GPIO to be controlled
  ledcAttachPin(output, ledChannel);

  ledcWrite(ledChannel, sliderValue.toInt());
}


void loop() {
  ledcWrite(ledChannel, sliderValue.toInt());

  if (millis() - lastRead >= 1000) //read interrupt count every second
  {
    lastRead  += 1000;
    // disable interrupts,make copy of count,reenable interrupts
    noInterrupts();
    copyCount = count;
    count = 0;
    interrupts();
    Serial.println(copyCount);
    switchCount++;
  }
  
  if (switchCount == 5)
    sliderValue = "1";

  if (switchCount == 10)
  {
    sliderValue = "0";
    switchCount = 0;
  }
}

Output:

0
0
0
0
0
100
100
100
100
100
0
0
0
0
0
100
100
100
100
100

Me neither. It goes down to 0 fine for me.
Any chance of the cause of this behavior being on the client side? Perhaps the slider code doesn't allow the used variable to go down to 0?

Slider does not go down to 0. Solved it by using an if statement. Not ideal but it works.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.