Monday, June 5, 2017

Arduino core for ESP32, output PWM to GPIO using ledcWrite()


For ESP-32 Wifi/Bluetooth module with Arduino core for ESP32, to output PWM to GPIO, we can call ledcWrite(), something like Arduino analogWrite() function.

It's a example to output PWM to GPIO 21, 22 and 23, to control color/brightness of RGB LED.
/*
 Arduino core for ESP32 example: output PWM to GPIO using ledcWrite()
 Modify from the example code:
 /ESP32/examples/AnalogOut/LEDCSoftwareFade
*/

// use first 3 channels of 16 channels (started from zero)
#define LEDC_CHANNEL_0_R  0
#define LEDC_CHANNEL_1_G  1
#define LEDC_CHANNEL_2_B  2

// use 13 bit precission for LEDC timer
#define LEDC_TIMER_13_BIT  13

// use 5000 Hz as a LEDC base frequency
#define LEDC_BASE_FREQ     5000

// LED PINs
#define LED_PIN_R   21
#define LED_PIN_G   22
#define LED_PIN_B   23

// Arduino like analogWrite
// value has to be between 0 and valueMax
void ledcAnalogWrite(uint8_t channel, uint32_t value, uint32_t valueMax = 255) {
  // calculate duty
  uint32_t duty = (LEDC_BASE_FREQ / valueMax) * min(value, valueMax);

  // write duty to LEDC
  ledcWrite(channel, duty);
}

void setup() {
  // Setup timer and attach timer to a led pins
  ledcSetup(LEDC_CHANNEL_0_R, LEDC_BASE_FREQ, LEDC_TIMER_13_BIT);
  ledcAttachPin(LED_PIN_R, LEDC_CHANNEL_0_R);
  ledcSetup(LEDC_CHANNEL_1_G, LEDC_BASE_FREQ, LEDC_TIMER_13_BIT);
  ledcAttachPin(LED_PIN_G, LEDC_CHANNEL_1_G);
  ledcSetup(LEDC_CHANNEL_2_B, LEDC_BASE_FREQ, LEDC_TIMER_13_BIT);
  ledcAttachPin(LED_PIN_B, LEDC_CHANNEL_2_B);
}

void loop() {
  ledcAnalogWrite(LEDC_CHANNEL_0_R, 0);
  ledcAnalogWrite(LEDC_CHANNEL_1_G, 0);
  ledcAnalogWrite(LEDC_CHANNEL_2_B, 0);
  delay(1000);

  for(int i = 0; i < 255; i++){
    ledcAnalogWrite(LEDC_CHANNEL_0_R, i);
    delay(10);
  }
  for(int i = 255; i > 0; i--){
    ledcAnalogWrite(LEDC_CHANNEL_0_R, i);
    delay(10);
  }

  for(int i = 0; i < 255; i++){
    ledcAnalogWrite(LEDC_CHANNEL_1_G, i);
    delay(10);
  }
  for(int i = 255; i > 0; i--){
    ledcAnalogWrite(LEDC_CHANNEL_1_G, i);
    delay(10);
  }

  for(int i = 0; i < 255; i++){
    ledcAnalogWrite(LEDC_CHANNEL_2_B, i);
    delay(10);
  }
  for(int i = 255; i > 0; i--){
    ledcAnalogWrite(LEDC_CHANNEL_2_B, i);
    delay(10);
  }

  for(int i = 0; i < 255; i++){
    ledcAnalogWrite(LEDC_CHANNEL_0_R, i);
    ledcAnalogWrite(LEDC_CHANNEL_1_G, i);
    ledcAnalogWrite(LEDC_CHANNEL_2_B, i);
    delay(10);
  }
  for(int i = 255; i > 0; i--){
    ledcAnalogWrite(LEDC_CHANNEL_0_R, i);
    ledcAnalogWrite(LEDC_CHANNEL_1_G, i);
    ledcAnalogWrite(LEDC_CHANNEL_2_B, i);
    delay(10);
  }
}


Connection:
Reference:
Example at /ESP32/examples/AnalogOut/LEDCSoftwareFade
or here.

Next:
ESP32/Arduino core for ESP32 example, simple Web control RGB LED

Thursday, June 1, 2017

NodeMCU/ESP8266 Arduino Core example, simple http server to output PWM

Last post show a dummy example of NodeMCU/ESP8266 Arduino Core to output PWM to control color/brightness of RGB LED.

It's another example to setup a simple HTTP-like server, to receive request from client, output PWM, to control color/brightness of RGB LED.


NodeMCU_WiFiWebServer_RGB.ino
/*
 *  This sketch run on NodeMCU (ESP8266),
 *  demonstrates how to set up a simple HTTP-like server.
 *  The server will set a GPIO pins depending on the request,
 *  to control the brightness of RGB LED connected to:
 *    D0 : BLUE
 *    D1 : GREEN
 *    D2 : RED
 *    
 *    http://server_ip/rgb/rrggbb/
 *    where rr is the value set RED
 *    where gg is the value set GREEN
 *    where bb is the value set BLUE
 *    then terminate with '/'
 *  server_ip is the IP address of the NodeMCU, will be 
 *  printed to Serial when the module is connected.
 */

#include <ESP8266WiFi.h>

const char* ssid = "Xtation";
const char* password = "password";

int ledB = D0;
int ledG = D1;
int ledR = D2;

// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(80);

void setup() {
  Serial.begin(115200);
  delay(10);

  // prepare GPIOs for RGB LED
  pinMode(D0, OUTPUT);
  pinMode(D1, OUTPUT);
  pinMode(D2, OUTPUT);
  analogWriteRange(99); //PWM: 0~99
  
  // Connect to 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");
  
  // Start the server
  server.begin();
  Serial.println("Server started");

  // Print the IP address
  Serial.println(WiFi.localIP());
}

void loop() {
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
  
  // Wait until the client sends some data
  Serial.println("new client");
  while(!client.available()){
    delay(1);
  }
  
  // Read the first line of the request
  String req = client.readStringUntil('\r');
  Serial.println(req);
  client.flush();
  
  // Match the request
  int valR, valG, valB;
  String subStringR, subStringG, subStringB;
  int index = req.indexOf("/rgb/");
  if(index != -1){
    if(req.charAt(index+11)=='/'){
      subStringR = req.substring(index+5, index+7);
      subStringG = req.substring(index+7, index+9);
      subStringB = req.substring(index+9, index+11);
      Serial.println("R: " + subStringR);
      Serial.println("G: " + subStringG);
      Serial.println("B: " + subStringB);

      valR = subStringR.toInt();
      valG = subStringG.toInt();
      valB = subStringB.toInt();
      Serial.println("valR: " + String(valR));
      Serial.println("valG: " + String(valG));
      Serial.println("valB: " + String(valB));
      
    }
    else{
      Serial.println("Not terminated with /");
      client.stop();
      return;
    }
  }
  else {
    Serial.println("No /rgb/ found");
    client.stop();
    return;
  }

  // Set GPIOs according to the request
  // No check valid of the requested setting
  analogWrite(ledR, valR);
  analogWrite(ledG, valG);
  analogWrite(ledB, valB);
  
  client.flush();

  // Prepare the response
  String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIOs of RGB is now ";
  s += String(valR) +":" + String(valG) + ":" + String(valB);
  s += "</html>\n";

  // Send the response to the client
  client.print(s);
  delay(1);
  Serial.println("Client disonnected");

  // The client will actually be disconnected 
  // when the function returns and 'client' object is detroyed
}


Connection same as in last post:



Compare with ESP32 version: ESP32/Arduino core for ESP32 example, simple Web control RGB LED

NodeMCU/ESP8266 Arduino Core analog output PWM

Example of NodeMCU with ESP8266 Arduino Core to output PWM by calling analogWrite(), to control brightness of RGB LED.



NodeMCU_PWM.inf
int ledB = D0;
int ledG = D1;
int ledR = D2;

void setup() {
  pinMode(D0, OUTPUT);
  pinMode(D1, OUTPUT);
  pinMode(D2, OUTPUT);
  //Set PWM frequency 500, default is 1000
  //Set range 0~100, default is 0~1023
  analogWriteFreq(500);
  analogWriteRange(100);
}

// the loop function runs over and over again forever
void loop() {
  analogWrite(ledR, 0);
  analogWrite(ledG, 0);
  analogWrite(ledB, 0);
  delay(500);
  analogWrite(ledR, 100);
  analogWrite(ledG, 100);
  analogWrite(ledB, 100);
  delay(500);
  analogWrite(ledR, 0);
  analogWrite(ledG, 0);
  analogWrite(ledB, 0);
  delay(500);

  int i;
  for(i=0; i<100; i++){
    analogWrite(ledR, i);
    delay(10);
  }
  analogWrite(ledR, 0);
  
  for(i=0; i<100; i++){
    analogWrite(ledG, i);
    delay(10);
  }
  analogWrite(ledG, 0);
  
  for(i=0; i<100; i++){
    analogWrite(ledB, i);
    delay(10);
  }
  analogWrite(ledB, 0);

  for(i=0; i<100; i++8){
    analogWrite(ledR, i);
    analogWrite(ledG, i);
    analogWrite(ledB, i);
    delay(10);
  }

  for(i=100; i>0; i--){
    analogWrite(ledR, i);
    analogWrite(ledG, i);
    analogWrite(ledB, i);
    delay(10);
  }

}

Reference:
analogWrite(pin, value) enables software PWM on the given pin. PWM may be used on pins 0 to 16. Call analogWrite(pin, 0) to disable PWM on the pin. value may be in range from 0 to PWMRANGE, which is equal to 1023 by default. PWM range may be changed by calling analogWriteRange(new_range).

PWM frequency is 1kHz by default. Call analogWriteFreq(new_frequency) to change the frequency.

Next:
simple http server to output PWM, to control color/brightness of RGB LED.