Autorange Analog frontend |
For a deeper Hardware description please take a look at the ESP8266 Analog Extension Board
What we will need:
- ESP8266 nEXT EVO Board
- ESP8266 nEXT EVO - Analog Extension Board - AN1
- For programming and uploading the driver and the software we will continue to use the LuaUploader as before.
ADC Frontend description
Selection of the input voltage divider is done using an analog switch driven by PCF8574 PORT P0 and P1 bits:
0 - 1:20 Divider
1 - 1:10 Divider
2 - 1:5 Divider
3 - Full Voltage Range
As the ADC Input is programmed to be used in the 0-2V range that will give us the followings available ranges:
0 -> 0 - 40V
1 -> 0 - 20V
2 -> 0 - 10V
3 -> 0 - 2V
In the case of using the MCP3421 ADC at 12 Bit resolution, we will have the following corresponding LSB values:
- 1:20 Divider - 0.02V
- 1:10 Divider - 0.01V
- 1:5 Divider - 0.005V
- Full Range - 0.001V
Software implementation
1. Init I2C bus/interface
Standard I2C Bus Initialisation function:
function init_I2C()
i2c.setup(bus, sda, scl, i2c.SLOW)
end
2. Set PCF8574 PORT Register Function
function setPort( port, stat)
i2c.start(id)
i2c.address(id, dev_addr ,i2c.TRANSMITTER)
i2c.write(id,stat)
i2c.stop(id)
end
3. Set Port function
Just a nicer way to write data to PCF8574 Register. Remember that we need to write a "ZERO" to the corresponding bit. We are sinking not sourcing !!
function setPortdata(p)
pp = 255-p
setPort(0x20,pp)
end
4. Set Voltage Divider function
Select the desired Voltage divider ratio based on the choosen ratio value and calibrated LSB data.
--calibration data
x20 = 0.020056
x10 = 0.01014
x5 = 0.005014
xfl = 0.0010075
xrt = x20 --by default start with highest VDIV!
function SetVDivider(rtio)
if (rtio==0) then xrt=x20 end
if (rtio==1) then xrt=x10 end
if (rtio==2) then xrt=x5 end
if (rtio==3) then xrt=xfl end
print("XRT = "..xrt)
setPortdata(rtio) -- select desired voltage divider
return xrt
end
-- Set/Change Voltage Divider ratio:
SetVDivider(0) -- 1:20 Divider
SetVDivider(1) -- 1:10 Divider
SetVDivider(2) -- 1:5 Divider
SetVDivider(3) -- 1:1 Full Voltage in!!
5. MAIN Program
-- Main Program
id = 0
sda=2 --GPIO4
scl=1 --GPIO5
dev_addr = 0x20
--calibration data
x20 = 0.020056
x10 = 0.01014
x5 = 0.005014
xfl = 0.0010075
xrt = x20 --by default start with highest VDIV!
--init I2C Bus
init_I2C()
--Init Volatage divider
setPortdata(0) -- --by default start with highest VDIV!
SetVDivider(0) -- 1:20 Divider
----MCP3421 ADC
require('mcp3421')
sda=2 --GPIO4
scl=1 --GPIO5
mcp3421:init(sda, scl)
mcp3421:write_ADC_config(0x68, 0x10)
tmr.alarm( 0, 1000, 1, function()
adc_val = mcp3421:read_ADC_data(0x68)
print("\nADC Value : "..adc_val.." \n Voltage : " ..adc_val*xrt)
return adc_val
end)
No comments:
Post a Comment