Showing posts with label LUA. Show all posts
Showing posts with label LUA. Show all posts

Saturday, November 5, 2016

WIFI Dev Board for Home Automation - Part 2



This is Part 2 of the Wifi Dev Board for Home Automation series. For general presentation and hardware description please take a look also at Part 1 of the series


MPRSx8 Board is available also on Tindie store: https://www.tindie.com/stores/nEXT_EVO1/







What we will need:



Software implementation:

As this time we will talk about the Software side we will design a very simple driver for our board that will include also a interactive Web command interface for the MPRSx8 Home Automation Dev Board Relays.

To keep things simple, we will just add in our Web Interface 8 ON/OFF Buttons and one general OFF one, from where we can turn ON/OFF all the Relays switches. 


1. Main Program
cls                       ' clear interface
let address = 56  'PCF8574 I2C Address

i2c.setup(4,5)      'choose your I2C bus pins

i2c.begin(address)
ss = 0 xor 255      'XOR - Bit masking for the desired I/O pins
i2c.write(ss)
i2c.end()
button "x1", [5]    ' Button for Relay 1
button "x2", [6]
button "x3", [7]
button "x4", [8]
button "x5", [1]
button "x6", [2]
button "x7", [3]
button "x8", [4]    ' Button for Relay 8
button "OFF", [9] ' General OFF for all the Relays
wait


2. General OFF for all the Relays subroutine
[9]
i2c.begin(address)
ss = 0 xor 255 'XOR - Bit masking for the desired I/O pins
i2c.write(ss)
i2c.end()
wait


3. Subroutines for each Button
[1]
i2c.begin(address)
ss = ss xor 1   'XOR - Bit masking for the desired I/O pins
i2c.write(ss)
i2c.end()
wait

[2]
i2c.begin(address)
ss = ss xor 2
i2c.write(ss)
i2c.end()
wait

[3]
i2c.begin(address)
ss = ss xor 4
i2c.write(ss)
i2c.end()
wait

[4]
i2c.begin(address)
ss = ss xor 8
i2c.write(ss)
i2c.end()
wait

[5]
i2c.begin(address)
ss = ss xor 16
i2c.write(ss)
i2c.end()
wait

[6]
i2c.begin(address)
ss = ss xor 32
i2c.write(ss)
i2c.end()
wait

[7]
i2c.begin(address)
ss = ss xor 64
i2c.write(ss)
i2c.end()
wait

[8]
i2c.begin(address)
ss = ss xor 128
i2c.write(ss)
i2c.end()
wait


In the Web editor interface Save your program as "test_MPRSx8_1.bas" and Run it.



If all OK the result should look as below:




If you want your program to start automatically at reboot/power ON then just Save it as "default.bas" and also from Settings Tab enable the "Run default.bas at startup".



Be aware that at start-up/reboot, it is a delay before your program will start automatically.




WIFI MAINS 8x Relay Board for Home Automation and more


Available also on Tindie store: https://www.tindie.com/stores/nEXT_EVO1/








Features:
  • Compact, standard size: 16x5 cm! (half Eurocard height)
  • Universal AC MAINS input (240VAC/50Hz (EU) or 110V/60Hz (US)
  • Proper MOV and high quality ceramic FUSE MAINS input protection.
  • 8 x MAINS rated 15A Relays
  • 8 x independent swithing Power Channels 
  • Power Channels can be software configured for mutually exclusive usage
  • Recommended load upto 10A each channel
  • LED signaling Panel for each Power Channel Status 
  • Integrated switchmode MAINS PSU
  • Separate high efficient switchmode PSU for command & control circuit
  • Can work also from a external +12V power supply just not install the MAINS PSU
  • Safe operation design
  • I2C / nEXT Bus compatible - you can add your own extension modules - light sensors, gas, motion, etc
  • Can be stacked upto 8 boards ( 1 Master and 7 slaves) for a total of 64 Power Channels!!
  • Compatible with any I2C compatible MCU: Arduino, ARM, PIC, ATMEGA, ESP8266, ESP32, etc
  • ESP8266 friendly design: can add your ESP8266 module directly onboard for a full WIFI MAINS Power switchboard solution
  • Full access to ESP8266 pins thru 2 headers gives you even more flexibility in developing your projects!
  • Full programming header  (Tx, Rx, GPIO0 and Reset)

Command and control side - pinout details




 Schematics:


MAINS input power supply



3.3V power supply for the command and control section



Relays driver


In Part 2 we will continue with the software side, how to connect, program and use the MPRSx8 Relay board.






Creative Commons License All schematics, boards, software and articles released by ESP8266-Projects.com are licensed under a Creative Commons Attribution-NonCommercial 4.0 International License








Thursday, August 11, 2016

ESP8266 - Internal ADC 2 - the easy way example



This is just a very quick example on how to add a Voltage Divider to the ESP8266 Internal ADC input to increase the ADC input range.

For more theory behind, please take a look at the previous related article: ESP8266 - Internal ADC


Today project:

      Measure a voltage input range from 0-5V with the ESP8266 internal ADC


What do we need:

  • 2 Resistors for the voltage divider, R1=105.6k, R2=24.08k. I am using here precision resistors and the values are measured values with a proper calibrated bench meter.
  • a good, trustable, calibrated ok Multimeter.
  • some wires to connect all together.


I will not insist on connections, take a deeper look at the previous article about


Voltage divider schematic and Vout (ADC input voltage) formula




How do we do it :


1. Measure your Max desired input voltage
    In my case, Max Input Voltage (Vmax) = 5.1919 (measured)



 
2. Measure Resistors values:
    R1 = 105.6k
    R2 = 24.08k


 
3. Check if Full Scale Value at the voltage divider output is inside the ADC defined domain:
  • Calculated : Vout = (R2/(R1+R2))*Vin = 0.964072733 V
  • Measured = 0.96038V
     Good enough for the precision we are looking for. ESP8266 ADC is 10bit only and not exactly the most accurate in town



4. Calculate Voltage Divider Ratio:
  • Vdivider Ratio= Max Input Voltage/Fullscale value =  5.405976676



5.  Read ADC value : 
       adcr = adc.read(0)
      print("    ReadADC     : "..adcr)
     Average result for adcr = 1017

THIS IS IMPORTANT !! It tell us that we are inside the ADC domain as adcr < 1024 !

IF adcr > 1023 then you need to adjust your voltage divider resistors to fit inside ADC domain!



6. Calculate LSB  in 2 ways to cross check that we have the right value:
  • LSB = Input Voltage read by multimeter/ADC readed Value = 
                   =  5.1919 / 1017 =  0.005105113 V
      OR
  • LSB = (ADC Input  pin read Voltage by multimeter/ADC readed Value/)*Vdivider Ratio = 
                  = (0.96038/1017)*5.405976676 = 0.005105113 V
       It looks that we have the right LSB Value for our exercise!

     If you want to know also the ADC LSB, then
       LSB = ADC Input  pin read Voltage by multimeter/ADC readed Value  =   
                =  0.96038/1017 = 0.000944346 V

    Guess what's happening if you multiply ADC LSB with Vdivider ratio :)




7. Software Implementation for the ADC read function:

 function readADC()
      ad = 0
      LSB = 0.005105113 --calibrate based on your voltage divider AND Vref!
      adcr = adc.read(0)
      ad= adcr*LSB       
      print("    ReadADC     : "..adcr)
      print("    Read Voltage     : "..ad)
      return ad
end

and some results in the terminal window:

> SENT: readADC()
readADC()
    ReadADC     : 1017
    Read Voltage     : 5.191899921
>






Saturday, July 30, 2016

AC PWM Dimmer with Light Sensor



//YOUTUBE VIDEO HERE//

You can see this article as a continuation of the previous BH1750FVI - I2C Light Sensor Driver one.

    The main goal of the project is to create a AC Mains Light dimmer that can automatically control the level of light and keep in in the desired set interval without any external intervention.

   Why would you be intrested in such a setup? Well, if you have any interest in hydroponics, photography, or anywhere where you need some sort of constant flood light lamps with precise light intensitity level setup then might be a good idea to take a look :)


What we will need:

 

     Connection with the ESP8266 nEXT EVO Board is very easy, as MPU6050 GY-521 Module connector is fully compatible with the nEXT Bus connector. Depending on how to you choose you socket type, you can install it on TOP or Bottom of the ESP8266 nEXT EVO Board :



BH1750FVI Module directly connected to the ESP8266 nEXT EVO Board


And the whole project setup, with MPDVv4 AC Dimmer connected on ESP8266 GPIO13 (pin 7):

 
MPDM v4 + nEXT EVO + BH1750FVI



Closer look, MPDMv4 connected at ESP8266 GPIO13 (Pin7) for PWM control



Software implementation

You will need also the code from the previous BH1750FVI article. Please take also a look there for more details.




1. Ligth level auto-adjust function

 function set_light()
    read_input(dev_addr)
    ll = light - hst    --lower level
    lh = light + hst    --upper level
    if (lux < ll) then
       p=0
       i = i - step
       if (i<0) then i = 0
       end
       pwm.setduty(7, i)    
    end
    if (lux >lh) then
       p=0
       i = i + step
       if (i>880) then i = 880
       end
       pwm.setduty(7, i)    
    end
    --print("Auto Level Adjust : "..i)
    --print(ll)
    --print(lh)
    if (ll< lux and lux < lh) then
      if (p<1) then p=1
      end
      if (p<2) then
         print(string.format("\nLight Level: %0.2f lux",lux))
         print("Auto Level Adjust : "..i)
         p=2
      end
    end
end



Main Program
 
--PWM testing for MPDMv4 AC Dimmer Board
 

pwm.setup(7, 500, 850)    --MPDMv4 control pin
i=10                                  --initial Light Level

pwm.setduty(7, i)             --set initial ligfht level

light = 250                       --light level
hst = 40                            --histeresis coef for desired light interval
step = 1                            --light step
p=0         
 

--read light intensity value every 50 and autoadjust Light Dimmer Driver accordingly
tmr.alarm( 1, 50, 1, function()
  set_light()
end)



Wednesday, July 27, 2016

Mailbag - BH1750FVI - I2C Light Sensor Driver




//YOUTUBE VIDEO WILL FOLLOW HERE //

   In the process of choosing of some Light Sensors for one of the new projects that will involve the nEXT EVO Board and also the MPDMv4 Mains Dimmer  somebody suggested to give a try also to the ROHM BH1750FVI Sensor.

Just received some BH1750FVI modules in my mail yesterday and must say that it's a pretty impressive little board for only about 2.5USD, even less in a pack of 10!

This is how are looking the received modules:

BH1750FVI Module - TOP

   As you can see on the picture above, on the tiny board, you have the BH1750FVI Sensor, a LDO regulator some filtering caps and pull-up resistors and that's it!



 
BH1750FVI Module - Bottom
     The bottom side is bringing us more good news, the Module interface connector is fully compatible with the nEXT EVO  Bus!



BH1750FVI Overview

  BH1750FVI is an digital Ambient Light Sensor IC for I2C bus interface. This IC is the mostly used to obtain the ambient light data for adjusting LCD and Keypad backlight power of Mobile phone. 
 This is great as we are looking forward to use it for Automatic light adjustment using the MPDMv4 AC Dimmer board :)





Features

  • I2C bus Interface ( f / s Mode Support )
  • Spectral responsibility is approximately human eye response
  • Illuminance to Digital Converter
  • Wide range and High resolution. ( 1 - 65535 lx )
  • Low Current by power down function
  • 50Hz / 60Hz Light noise reject-function
  • 1.8V Logic input interface
  • Native 3.3V Device
  • No need any external parts
  • Light source dependency is little. ( ex. Incandescent Lamp. Fluorescent Lamp. Halogen Lamp. White LED. Sun Light )
  • It is possible to select 2 type of I2C slave-address.
  • Adjustable measurement result for influence of optical window ( It is possible to detect min. 0.11 lx, max. 100000 lx by using this function. )
  • Small measurement variation (+/- 20%)
  • The influence of infrared is very small.


Internal Diagram
BH1750FVI - Internal Diagram

  • PD - Photo diode with approximately human eye response.
  • AMP - Integration-OPAMP for converting from PD current to Voltage.
  • ADC - AD converter for obtainment Digital 16bit data.
  • Logic + I2C Interface :
                 - Ambient Light Calculation and I2C BUS Interface. It is including below register.
                 - Data Register - This is for registration of Ambient Light Data. Initial Value is
                       "0000_0000_0000_0000".
                 - Measurement Time Register - This is for registration of measurement time. Initial Value
                          is  "0100_0101".
  • OSC - Internal Oscillator ( typ. 320kHz ). It is CLK for internal logic.

For more details please take a look at the BH1750FVI Datasheet.



What we will need:

    Connection with the ESP8266 nEXT EVO Board is very easy, as MPU6050 GY-521 Module connector is fully compatible with the nEXT Bus connector. Depending on how to you choose you socket type, you can install it on TOP or Bottom of the ESP8266 nEXT EVO Board :


BH1750FVI Module directly connected to the ESP8266 nEXT EVO Board







BH1750FVI Driver implementation


1. Init I2C bus/interface


 Standard I2C Bus Initialisation function:

function init_I2C()
    i2c.setup(bus, sda, scl, i2c.SLOW)
end



2. WRITE Function - Set BH1750FVI Register config

      From BH1750FVI Datasheet :
   

  • No active state : pwr_down 0x00 
  • Wating for measurment command : pwr_on=0x01 
  • Reset data register value - not accepted in POWER_DOWN mode : reset=0x07

    Continuous modes, no pwr down:
  •  Start measurement at 1lx resolution. Measurement time is approx 120ms:
            hi_res_m1=0x10 
  • Start measurement at 0.5lx resolution. Measurement time is approx 120ms. 
           hi_res_m2=0x11
  • Start measurement at 4lx resolution. Measurement time is approx 16ms.
           lo_res_m1=0x13


    Device is automatically set to Power Down after measurement:
  • Start measurement at 1lx resolution. Measurement time is approx 120ms.
          hi_res_m3=0x20
  • Start measurement at 0.5lx resolution. Measurement time is approx 120ms.
           hi_res_m4=0x21
  • Start measurement at 1lx resolution. Measurement time is approx 120ms.
          lo_res_m2=0x23
 

function setcfg(cfg) 
    i2c.start(id)
    i2c.address(id, dev_addr ,i2c.TRANSMITTER)
    i2c.write(id,cfg)
    i2c.stop(id)
end


3. READ Sensor Input Function


Measurement Procedure

function read_input(dev_addr)
      i2c.start(id)
      i2c.address(id, dev_addr,i2c.RECEIVER)
      c = i2c.read(id,2)
      i2c.stop(id)
      --print("RAW H: "..string.byte(c,1))
      --print("RAW L: "..string.byte(c,2))
      rawl = (bit.lshift(string.byte(c, 1), 8) + string.byte(c, 2))
      lux = rawl/1.2
      print(string.format("\nLight Level: %0.2f lux",lux))
      --print(string.format("             %d raw",rawl))
      return rawl
end


4. MAIN PROGRAM


id = 0                    --I2C Bus ID
sda=2                     --GPIO4
scl=1                      --GPIO5
dev_addr = 0x23   --BH1750FVI I2C Address
i2c_init()                          --init I2C Bus
setcfg(hi_res_m1)            --SET config register
read_input(dev_addr)     --Read sensor data and compute LUX Light level value





Thursday, June 30, 2016

P1 - PCF8575 - Remote 16-bit I/O expander for ESP8266 I2C-bus



AVAILABLE also on TINDIE Store : https://www.tindie.com/stores/nEXT_EVO1/


Today we will continue with the most requested typer os posts the "Driver Implementation Series": Part 1 of the PCF8575 16-bit I/O Port Expander - Output.






    In the situation when you need more I/O pins that available on your MCU the simplest solution is to use a "port expander". In the previous articles, nEXT EVO Extension Board AN1 (for I/O output) and 4x4 Matrix Keyboard input example for ESP8266 (for I/O input), we spoken already about a 8 bit I/O port expander based on the PCF8574 IC from NXP.

    But what to do if you need for your project even more I/O lines?

    You have 2 solution:

    1. Use more that one PCF8574, configure each with it's own unique I2C address.

    2. For higher density number of I/O pins os just a compact 16 I/O lines interface, use the bigger brother of the PCF8574, the PCF8575.

    As the option (1) I think is obvious for everybody and means just replication of the PCF8574 as many times you need it (and have free available I2C addresses for each), today we will explore a bit the 16bit version, the PCF8575.


  PCF8575 General Description

    The PCF8575 is a silicon CMOS circuit, and provides general purpose remote I/O expansion for most microcontroller families via the two-line bidirectional bus (I²C-bus).

    The device consists of a 16-bit quasi-bidirectional port and an I²C-bus interface (PCF8574 has 8-bit one).
     The PCF8575 has a low current consumption and includes latched outputs with high current drive capability for directly driving LEDs.
      It also possesses an interrupt line (INT) which can be connected to the interrupt logic of the microcontroller. By sending an interrupt signal on this line, the remote I/O can inform the microcontroller if there is incoming data on its ports without having to communicate via the I²C-bus.
And here you can see the advantage over using 2xPCF8574. For each of the 16 I/O lines you can use just one INT line to your MCU. In case of the PCF8574 usage you need 2 INT lines. So, less overhead on number of the I/O lines.

     Every data transmission from the PCF8575 must consist of an even number of bytes, the first byte will be referred to as P07 to P00 and the second byte as P17 to P10. The third will be referred to as P07 to P00 and so on.


PCF8575 - Block Diagram


    Features

  • Operating supply voltage 2.5 to 5.5 V
  • Low standby current consumption of 10 µA maximum
  • I²C-bus to parallel port expander
  • 400 kbits/s FAST I²C-bus
  • Open-drain interrupt output
  • 16-bit remote I/O port for the I²C-bus
  • Compatible with most microcontrollers
  • Latched outputs with high current drive capability for directly driving LEDs
  • Address by 3 hardware address pins for use of up to 8 devices
  • SSOP24 package.

     As been very similar with his small brother, the PCF8575, described already, I will not insist too much on the IC itself, for a deeper look please take a look also at the Datasheet.


 What we will need:


  • ESP8266 nEXT EVO Board
  • PCA9685 Extension Board as below or similar
  • For programming and uploading the driver and the software we will continue to use the LuaUploader as before.  
    Connection with the ESP8266 nEXT EVO Board is very easy, as PCF8575 Extension Board connector is fully compatible with the nEXT connector. Depending on how to you choose you socket type, you can install it on TOP or Bottom of the ESP8266 nEXT EVO Board :

PCF8575 - nEXT EVO 16bit Expander Board - TOP

 On the bottom side you can see also available the jumpers for I2C address selection in case that you need more than one I/O Expander board connected in the same time:

PCF8575 - nEXT EVO 16bit Expander Board - Bottom



Driver implementation
 
 
As PCF8575 is a I2C device, building a driver for it will follow the same path as for any other  I2C compatible device:
   
 
1 . I2C Bus initialisation function
function  init_i2c(sda, scl)
          i2c.setup(id, sda, scl, i2c.SLOW)
     end

2 . PCF8575 Write register function (for data Output)

     To write, the master (microcontroller) first addresses the slave device. By setting the last bit of the byte containing the slave address to logic 0 the write mode is entered.

     The PCF8575 acknowledges and the master sends the first data byte for P07 to P00. After the first data byte is acknowledged by the PCF8575, the second data byte P17 to P10 is sent by the master. Once again the PCF8575 acknowledges the receipt of the data after which this 16-bit data is presented on the port lines.


    The number of data bytes that can be sent successively is not limited. After every two bytes the previous data is overwritten.
    The first data byte in every pair refers to Port 0 (P07 to P00), whereas the second data byte in every pair refers to Port 1 (P17 to P10):




function setPort( port, PL, PH) 
    i2c.start(id)
    i2c.address(id, io_addr,i2c.TRANSMITTER)
    i2c.write(id,PL)
    i2c.write(id,PH)
    i2c.stop(id)
end


3 . PCF8575 Set Port (for data Output)

function setPortdata(pl, ph)
    ppl = 255-pl
    pph = 255-ph
    setPort(0x20,ppl, pph)
end

4 . Main program
 id = 0                    --I2C bus ID
sda=2                    --GPIO4
scl=1                     --GPIO5
io_addr = 0x20     --PCF8575 I2C Address


--init I2C nEXT BUS
i2c_init()

 -- Direct port bit set examples
setPortdata(0,0)   -- All OFF  

setPortdata(1,0)     -- P0 - ON
setPortdata(2,0)     -- P1 - ON
setPortdata(4,0)     -- P2 - ON
setPortdata(8,0)     -- P3 - ON
setPortdata(16,0)    -- P4 - ON
setPortdata(32,0)    -- P5 - ON
setPortdata(64,0)    -- P6 - ON
setPortdata(128,0)   -- P7 - ON

setPortdata(0,1)     -- P8  - ON
setPortdata(0,2)     -- P9  - ON
setPortdata(0,4)     -- P10 - ON
setPortdata(0,8)     -- P11 - ON
setPortdata(0,16)    -- P12 - ON
setPortdata(0,32)    -- P13 - ON
setPortdata(0,64)    -- P14 - ON
setPortdata(0,128)   -- P15 - ON


Next time we will explore the PCF8575 16 bit I/O Port Expander Inpout capabilities.




Wednesday, June 29, 2016

PCA9685-16Channel 12-bit PWM I²C-bus LED controller Driver


    !! UPDATE !! UPDATE !!
   Available on Tindie Store here 




   PCA9685 General Description

   If you are looking for a very simple to use 16 Channel LED controller or just for a nice 16 Channel, high resolution PWM driver then this one is for you!

   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.



PCA9685 - Block Diagram

   

Features

  • 16 LED drivers. Each output programmable at:
    • Off
    • On
    • Programmable LED brightness
    • Programmable LED turn-on time to help reduce EMI
     
  • 1 MHz Fast-mode Plus compatible I²C-bus interface with 30 mA high drive capability on SDA output for driving high capacitive buses 
  • 4096-step (12-bit) linear programmable brightness per LED output varying from fully off (default) to maximum brightness 
  • LED output frequency (all LEDs) typically varies from 24 Hz to 1526 Hz (Default of 1Eh in PRE_SCALE register results in a 200 Hz refresh rate with oscillator clock of 25 MHz)
  • Sixteen totem pole outputs (sink 25 mA and source 10 mA at 5 V) with software programmable open-drain LED outputs selection (default at totem pole). No input function.
  • Output state change programmable on the Acknowledge or the STOP Command to update outputs byte-by-byte or all at the same time (default to ‘Change on STOP’)
  • Active LOW Output Enable (OE) input pin. LEDn outputs programmable to logic 1, logic 0 (default at power-up) or ‘high-impedance’ when OE is HIGH.
  • 6 hardware address pins allow 62 PCA9685 devices to be connected to the same I²C-bus
  • Toggling OE allows for hardware LED blinking
  • 4 software programmable I²C-bus addresses (one LED All Call address and three LED Sub Call addresses) allow groups of devices to be addressed at the same time in any combination (for example, one register used for ‘All Call’ so that all the PCA9685s on the I²C-bus can be addressed at the same time and the second register used for three different addresses so that 1⁄3 of all devices on the bus can be addressed at the same time in a group). Software enable and disable for these I²C-bus address.
  • Software Reset feature (SWRST General Call) allows the device to be reset through the I²C-bus
  • 25 MHz typical internal oscillator requires no external components
  • External 50 MHz (max.) clock input
  • Internal power-on reset
  • Noise filter on SDA/SCL inputs
  • Edge rate control on outputs
  • No output glitches on power-up
  • Supports hot insertion
  • Low standby current
  • Operating power supply voltage range of 2.3 V to 5.5 V
  • 5.5 V tolerant inputs
  • -40 °C to +85 °C operation
  • ESD protection exceeds 2000 V HBM per JESD22-A114, 200 V MM per JESD22-A115 and 1000 V CDM per JESD22-C101
  • Latch-up testing is done to JEDEC Standard JESD78 which exceeds 100 mA
  • Packages offered: TSSOP28, HVQFN28


 For more details please take a look at the PCA9685 Datasheet



What we will need:

  • ESP8266 nEXT EVO Board
  • PCA9685 Extension Board as below or similar
  • For programming and uploading the driver and the software we will continue to use the LuaUploader as before.  
    Connection with the ESP8266 nEXT EVO Board is very easy, as PCA9685 Extension Board connector is fully compatible with the nEXT connector. Depending on how to you choose you socket type, you can install it on TOP or Bottom of the ESP8266 nEXT EVO Board :

PCA9685 16 Channel PWM Extension Board


Driver implementation
 
 
As
PCA9685 has a I2C compatible compatible interface, building a driver for it it's a pretty straigh forward process following the standard path for a I2C compatible device:
 
 
1 . I2C Bus initialisation function
function  init_i2c(sda, scl)
          i2c.setup(id, sda, scl, i2c.SLOW)
     end


2 . PCA9685 Read register function
function read_reg(reg)
          i2c.start(id)
          i2c.address(id, dev_addr ,i2c.TRANSMITTER)
          i2c.write(id,reg)
          i2c.stop(id)
          i2c.start(0x0)
          i2c.address(0x0, dev_addr,i2c.RECEIVER)
          c = i2c.read(0x0,1)
          i2c.stop(0x0)
          rval = string.byte(c, 1)
          --print(rval)
          return rval
end

3 . PCA9685 Write register function
function write_reg(reg, data)
          i2c.start(id)
          i2c.address(id, dev_addr ,i2c.TRANSMITTER)
          i2c.write(id,reg)
          i2c.write(id,data)
          i2c.stop(id)
end


4 . Write 12bit values function
function write_12_bit(a)
         ah=bit.rshift(a,8)
         al=bit.band(a,0xff)
         --print(a,ah,al)
         return ah, al
end  

5 . PCA9685 initialisation function

-- LED_ON and LED_OFF are 12bit values (0-4095)
-- ledN is 0-15

function init_pca()
    write_reg(mode1, rst)           --reset device

    if (read_reg(mode1)==0x01) then --check status
        status = true
        print("PCA9685 Init OK")
    else
        status = false
        print("PCA9685 Init Failure!")
    end
    --print(status)

    write_reg(mode1, 0xA0) --10100000 - set for auto-increment


   -- choose here the desired output mode!

    --Direct LED connection
    write_reg(mode2, 0x10) --set to output mode INVRT = 1 OUTDRV = 0

    --External N-type driver
    --write_reg(mode2, 0x04)   -- set to output mode INVRT = 0 OUTDRV = 1

    --External P-type driver
    --write_reg(mode2, 0x14) --set to output mode INVRT = 1 OUTDRV = 1
   
    return status
end


6 . Write LEDn function
 function write_LED(ledN, LED_ON, LED_OFF)
          i2c.start(id)
          i2c.address(id, dev_addr ,i2c.TRANSMITTER)
          i2c.write(id,led0+4*ledN)
          write_12_bit(LED_ON)
          i2c.write(id,al)
          i2c.write(id,ah)
          write_12_bit(LED_OFF)
          i2c.write(id,al)
          i2c.write(id,ah)
          i2c.stop(id)
end


7 . Set LEDn ON function  

function setLED_ON(ledN)
        write_LED(ledN,0x1000,0)
end


8 . Set LEDn OFF function

function setLED_OFF(ledN)
        write_LED(ledN,0,0x1000)
end


9 . Set LEDn Dimmer function

function LED_Dimmer(ledN, dimm)
   if (dimm==0) then setLED_OFF(ledN)
   else if (dimm==100) then setLED_ON(ledN)
        else write_LED(ledN, dim, 0)
   end
   end
end


 10 . Main Program
dev_addr=0x40  --I2C Address for the PCA9685

mode1=0x00     --location for Mode1 register address
mode2=0x01     --location for Mode2 reigster address
led0=0x06      --location for start of LED0 registers
rst=0x01       --reset device

id = 0
sda=2 --GPIO4
scl=1 --GPIO5

--init I2C Bus
init_i2c(sda, scl)


--init PCA9685
init_pca()
 
--running tests
--set LED_0 ON/OFF
setLED_ON(0)
setLED_OFF(0)

--Dim LED_0 at different levels
write_LED(0,0,4095)
write_LED(0,0,2048)
write_LED(0,0,1024)
write_LED(0,0,512)
write_LED(0,0,256)
write_LED(0,0,128)
write_LED(0,0,64)
write_LED(0,0,32)
write_LED(0,0,16)
write_LED(0,0,8)
write_LED(0,0,4)

 --test Dimmer
dim=2
tmr.alarm( 1, 200, 1, function()
      if (dim>=4096) then dim=2 end
      write_LED(0,0,dim)
      dim=dim+200
      print(dim)
end)


tmr.stop(1)










Wednesday, April 20, 2016

MPDMv4 - AC MAINS Dimmer - software example

UPDATE !! Fixed broken Tindie Link from below, now should be OK UPDATE !!


--------------------------------------------------- DISCLAIMER --------------------------------------------------
WARNING!! You will play with LIVE MAINS!! Deadly zone!! 
      If you don't have any experience and are not qualified for working with MAINS power I will not encourage you to play arround!. The author take no responsibility for any injury or death resulting, directly or indirectly, from your inability to appreciate the hazards of household mains voltages.
   The circuit diagrams are as accurately as possible, but are offered with no guarantees whatsoever. 
    There is no guarantee that this design meets any Rules which may be in force in your country so please check before your local rules/regulations.
----------------------------------------------------------------------------------------------------------------------------
 
                                                             Creative Commons License

MPDMv4 by ESP8266-Projects.com is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.  

 ---------------------------------------------------------------------------------------------------------------------------

    For any new orders/requests please feel free to use as usual: tech at esp8266-projects.com. 
   
    MPDMv4 Boards are also available on Tindie: AC MAINS Dimmer - MPDMv4









As been a Voltage controled AC MAINS Dimmer you can control it with:
  • PWM signal
  • DAC output Voltage
  • or if you don't want any kind of MCU involved, just user a 10k Potentiometer in a voltage divider as part of a simple VCNT input circuit!

In this example we will use a MCP4728 4 channels/12 Bit DAC as a VCNT (voltage control) command source for our MPDMv4 Dimmer Board.



What we will need:


Software implementation

 1. MCP4728 DAC Driver

1.1 I2C Bus Initialisation
    init = function (self, sda, scl)
          self.id = 0
          i2c.setup(self.id, sda, scl, i2c.SLOW)
    end,

1.2 Set DAC Voltage output on the selected Channel

    dac = function(self, ch_reg,voltage)
          volt=(voltage*4096)/vcal
          msb = bit.rshift(volt, 8)  
          lsb = volt-bit.lshift(msb,8)   
          i2c.start(id)
          i2c.address(id, dac_addr ,i2c.TRANSMITTER)
          i2c.write(id,ch_reg)
          i2c.write(id,msb)
          i2c.write(id,lsb)
          i2c.stop(id)
    end,




1.3 Set DAC Register 

   set_reg_dac = function(self, reg)
          i2c.start(id)
          i2c.address(id, dac_addr ,i2c.TRANSMITTER)
          i2c.write(id,ch_reg)
          i2c.stop(id)
     end

2. MAIN Program
id=0
sda=2
scl=1
dac_addr=0x60
ch_reg=0x58      -- DAC CH A - Ext REF -
vcal=3.2325      -- external voltage reference = Vcc

require('mcp4728')             --call MCP4728 Driver module
mcp4728:init(sda, scl)       --Init I2C BUS
mcp4728:dac(ch_reg,2.8)  --Set VCMD Voltage (0-2.8V)

    2.1 Dimming stage example based on timer :


vcmd=0
tmr.alarm( 0, 1000, 1, function()
    print("Set VCMD value : "..vcmd)
    mcp4728:dac(ch_reg,vcmd)
    vcmd=vcmd+0.10
    if (vcmd>=2.81) then vcmd=0 end
end)

tmr.stop(0)   --stop the timer when you want to finnish cycling thru dimmer stages.