Categories

Follow

PCA9685 LED controller and ESP8266 example

In this example we connect a PCA9685 LED controller to an ESP8266

The PCA9685 is an I²C-bus controlled 16-channel LED controller optimized for Red/Green/Blue/Amber (RGBA) color backlighting applications. Each LED output has its own 12-bit resolution (4096 steps) fixed frequency individual PWM controller that operates at a programmable frequency from a typical of 24 Hz to 1526 Hz with a duty cycle that is adjustable from 0 % to 100 % to allow the LED to be set to a specific brightness value. All outputs are set to the same PWM frequency.

Each LED output can be off or on (no PWM control), or set at its individual PWM controller value. The LED output driver is programmed to be either open-drain with a 25 mA current sink capability at 5 V or totem pole with a 25 mA sink, 10 mA source capability at 5 V. The PCA9685 operates with a supply voltage range of 2.3 V to 5.5 V and the inputs and outputs are 5.5 V tolerant. LEDs can be directly connected to the LED output (up to 25 mA, 5.5 V) or controlled with external drivers and a minimum amount of discrete components for larger current or higher voltage LEDs.

 

Parts List

 

Name Link
ESP8266 D1 mini – Mini NodeMcu 4M bytes Lua WIFI Internet of Things development board based ESP8266 by WeMos
PCA9685 module 1pc PCA9685 16-Channel 12-bit PWM Servo motor Driver I2C Module For Arduino
Connecting cable Free shipping Dupont line 120pcs 20cm male to male + male to female and female to female jumper wire

 

Layout

This example only shows one led connected, my test board had all 16 connected – ideally the PCA9685 board should be externally powered

esp8266 and PCA9685

esp8266 and PCA9685

 

Code

You will need to add the Adafruit PWM Servo driver library – https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library/archive/master.zip

This is the default code, I commented out a couple of lines so this would compile for the ESP32

 

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
 
// called this way, it uses the default address 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
 
void setup() {
  Serial.begin(9600);
  Serial.println("16 channel PWM test!");
  pwm.begin();
  pwm.setPWMFreq(1600);  // This is the maximum PWM frequency
 
  // save I2C bitrate
  //uint8_t twbrbackup = TWBR;
  // must be changed after calling Wire.begin() (inside pwm.begin())
  //TWBR = 12; // upgrade to 400KHz!
 
}
 
void loop() {
  // Drive each PWM in a 'wave'
  for (uint16_t i=0; i<4096; i += 8) 
  {
    for (uint8_t pwmnum=0; pwmnum < 16; pwmnum++) 
    {
      pwm.setPWM(pwmnum, 0, (i + (4096/16)*pwmnum) % 4096 );
    }
  }
}

 

TMP102 digital sensor and ESP8266 example

In this article we look at the TMP102 digital sensor and we will connect it up to an ESP8266

The TMP102 device is a digital temperature sensor ideal for NTC/PTC thermistor replacement where high accuracy is required. The device offers an accuracy of ±0.5°C without requiring calibration or external component signal conditioning. Device temperature sensors are highly linear and do not require complex calculations or lookup tables to derive the temperature. The on-chip 12-bit ADC offers resolutions down to 0.0625°C.

The TMP102 device features SMBus™, two-wire and I2C interface compatibility, and allows up to four devices on one bus. The device also features an SMBus alert function. The device is specified to operate over supply voltages from 1.4 to 3.6 V with the maximum quiescent current of 10 µA over the full operating range.

The TMP102 device is ideal for extended temperature measurement in a variety of communication, computer, consumer, environmental, industrial, and instrumentation applications. The device is specified for operation over a temperature range of –40°C to 125°C.

 

Layout/Schematic

 

 

 

Parts List

Name Link
ESP8266 D1 mini – Mini NodeMcu 4M bytes Lua WIFI Internet of Things development board based ESP8266 by WeMos
TMP102 breakout TMP102 Digital Temperature Sensor Breakout Board Module 12-bit 1.4V To 3.6VDC Sensor Module Temperature Module
connecting wire Free shipping Dupont line 120pcs 20cm male to male + male to female and female to female jumper wire

Code

This is from the Arduino site with a few tweaks

#include "Wire.h"
#define TMP102_I2C_ADDRESS 72 /* This is the I2C address for our chip. This value is correct if you tie the ADD0 pin to ground. See the datasheet for some other values. */
 
 
void setup() 
{
  Wire.begin(); // start the I2C library
  Serial.begin(115200); //Start serial communication at 115200 baud
}
 
 
void loop() 
{
  getTemp102();
  delay(5000); //wait 5 seconds before printing our next set of readings. 
}
 
void getTemp102()
{
  byte firstbyte, secondbyte; //these are the bytes we read from the TMP102 temperature registers
  int val; /* an int is capable of storing two bytes, this is where we "chuck" the two bytes together. */ 
  float convertedtemp; /* We then need to multiply our two bytes by a scaling factor, mentioned in the datasheet. */ 
  float correctedtemp; 
 
  /* Reset the register pointer (by default it is ready to read temperatures)
You can alter it to a writeable register and alter some of the configuration - 
the sensor is capable of alerting you if the temperature is above or below a specified threshold. */
 
  Wire.beginTransmission(TMP102_I2C_ADDRESS); //Say hi to the sensor. 
  Wire.write(0x00);
  Wire.endTransmission();
  Wire.requestFrom(TMP102_I2C_ADDRESS, 2);
  Wire.endTransmission();
 
 
  firstbyte      = (Wire.read()); 
  /*read the TMP102 datasheet - here we read one byte from
   each of the temperature registers on the TMP102*/
  secondbyte     = (Wire.read()); 
  /*The first byte contains the most significant bits, and 
   the second the less significant */
    val = firstbyte;
    if ((firstbyte & 0x80) > 0) 
    {
      val |= 0x0F00;
    } 
    val <<= 4; 
 /* MSB */
    val |= (secondbyte >> 4);    
/* LSB is ORed into the second 4 bits of our byte.
Bitwise maths is a bit funky, but there's a good tutorial on the playground*/
    convertedtemp = val*0.0625;
    correctedtemp = convertedtemp - 5; 
    /* See the above note on overreading */
 
 
  Serial.print("firstbyte is ");
  Serial.print("\t");
  Serial.println(firstbyte, BIN);
  Serial.print("secondbyte is ");
  Serial.print("\t");
  Serial.println(secondbyte, BIN);
  Serial.print("Concatenated byte is ");
  Serial.print("\t");
  Serial.println(val, BIN);
  Serial.print("Converted temp is ");
  Serial.print("\t");
  Serial.println(val*0.0625);
  Serial.print("Corrected temp is ");
  Serial.print("\t");
  Serial.println(correctedtemp);
  Serial.println();
}

 

Output

Open the serial monitor window and you should see something like this

firstbyte is 10110
secondbyte is 1100000
Concatenated byte is 101100110
Converted temp is 22.37
Corrected temp is 17.37

firstbyte is 10110
secondbyte is 1100000
Concatenated byte is 101100110
Converted temp is 22.37
Corrected temp is 17.37

firstbyte is 10110
secondbyte is 1000000
Concatenated byte is 101100100
Converted temp is 22.25
Corrected temp is 17.25

 

Link

http://www.ti.com/lit/gpn/tmp102

Si1145 sensor and ESP8266 example

Another sensor reaches the desk, this time it is a Si1145 sensor, we will connect it to an ESP8266 and test it out

The Si1145/46/47 is a low-power, reflectance-based, infrared proximity, ultraviolet (UV) index, and ambient light sensor with I2C digital interface and programmableevent interrupt output. This touchless sensor IC includes an analog-to-digital converter, integrated high-sensitivity visible and infrared photodiodes, digital signal processor, and one, two, or three integrated infrared LED drivers with fifteen selectable drive levels. The Si1145/46/47 offers excellent performance under a wide dynamic range and a variety of light sources including direct sunlight. The Si1145/46/47 can also work under dark glass covers.

The photodiode response and associated digital conversion circuitry provide excellent immunity to artificial light flicker noise and natural light flutter noise. With two or more LEDs, the Si1146/47 is capable of supporting multiple-axis proximity motion detection. The Si1145/46/47 devices are provided in a 10-lead 2×2 mm QFN package and are capable of operation from 1.71 to 3.6 V over the –40 to +85 °C temperature range.

 

Parts List

name Link
ESP8266
Si1145 breakout SI1145 UV IR Visible Sensor I2C GY1145 Light Breakout Board Module
connecting wire Free shipping Dupont line 120pcs 20cm male to male + male to female and female to female jumper wire

 

Layout/Schematic

 

 

 

Code

This example requires the Adafruit Si1145 library, you can add this via the library manager or download from https://github.com/adafruit/Adafruit_SI1145_Library

#include <Wire.h>
#include "Adafruit_SI1145.h"
 
Adafruit_SI1145 uv = Adafruit_SI1145();
 
void setup() {
  Serial.begin(9600);
 
  Serial.println("Adafruit SI1145 test");
 
  if (! uv.begin()) {
    Serial.println("Didn't find Si1145");
    while (1);
  }
 
  Serial.println("OK!");
}
 
void loop() {
  Serial.println("===================");
  Serial.print("Vis: "); Serial.println(uv.readVisible());
  Serial.print("IR: "); Serial.println(uv.readIR());
 
  // Uncomment if you have an IR LED attached to LED pin!
  //Serial.print("Prox: "); Serial.println(uv.readProx());
 
  float UVindex = uv.readUV();
  // the index is multiplied by 100 so to get the
  // integer index, divide by 100!
  UVindex /= 100.0;  
  Serial.print("UV: ");  Serial.println(UVindex);
 
  delay(1000);
}

 

Output

Open the serial monitor window and you will see something like this

 

Link

https://www.silabs.com/documents/public/data-sheets/Si1145-46-47.pdf

PCF8575 I/O expander and ESP8266 examples

This 16-bit I/O expander for the two-line bidirectional bus (I2C) is designed for 2.5-V to 5.5-V VCC operation.

The PCF8575 device provides general-purpose remote I/O expansion for most microcontroller families by way of the I2C interface [serial clock (SCL), serial data (SDA)].

The device features a 16-bit quasi-bidirectional input/output (I/O) port (P07–P00, P17–P10), including latched outputs with high-current drive capability for directly driving LEDs. Each quasi-bidirectional I/O can be used as an input or output without the use of a data-direction control signal. At power on, the I/Os are high. In this mode, only a current source to VCC is active.

Features

  • I2C to Parallel-Port Expander
  • Open-Drain Interrupt Output
  • Low Standby-Current Consumption of 10 µA Max
  • Compatible With Most Microcontrollers
  • 400-kHz Fast I2C Bus
  • Address by Three Hardware Address Pins for Use of up to Eight Devices
  • Latched Outputs With High-Current Drive Capability for Directly Driving LEDs

 

Connection

This example shows only one LED, I had a special LED test board with 6 LEDs fitted to it

esp8266 and PCF8575

esp8266 and PCF8575

 

Parts List

Part Link
ESP8266 D1 mini – Mini NodeMcu 4M bytes Lua WIFI Internet of Things development board based ESP8266 by WeMos
Connecting wire Free shipping Dupont line 120pcs 20cm male to male + male to female and female to female jumper wire
PCF8575 PCF8575 IIC I2C I/O Extension Shield Module 16 bit SMBus I/O

 

Code examples

Output – switch LED on and off

#include <Wire.h>
 
// Set I2C address
int address = 0x20;
 
void setup()
{ 
  Wire.begin();
  // Set all ports as output
  pf575_write(word(B11111111,B11111111));
} 
 
void loop()
{
  // Set port P0 on
  pf575_write(word(B00000000,B00000001));
  delay(1000);
  // Set port P0 off
  pf575_write(word(B00000000,B00000000));
  delay(1000);
} 
 
// Function for writing two Bytes to the I2C expander device
void pf575_write(uint16_t data) 
{
  Wire.beginTransmission(address);
  Wire.write(lowByte(data));
  Wire.write(highByte(data));
  Wire.endTransmission();
}

 

Output – switch LEDs on and off

#include <Wire.h>
 
byte address = 0x20;   // address of PCF8575
 
void setup()
{
   Wire.begin();       // join i2c bus as master
}
 
 
void loop()
{
  unsigned char x;
  unsigned char y;
 
  for (x=0, y=255; (x+y)==255; x++, y--)
  {
      Wire.beginTransmission(address);   // send the address and the write cmnd
      Wire.write(x);                      // pack the first byte
      Wire.write(y);                      // pack the second byte
      Wire.endTransmission();            // send the data
      delay(150);     
   }
}