ESP8266 Projects Blog
Home of CBDB / MPDMv4 /SmartMon Development boards (ESP-12/ESP-07).
Guidelines and ESP8266 programming examples using LUA, Eclipse and Arduino IDE, ESP Basic and many more!
As been asked so many times in the latest days about, please find below a quick install guide that might help you to have a smooth and easy installation:
Inside the new "arduino-1.6.4" subfolder create a New Folder called "Portable"
In
this way you can avoid the way Arduino is installing files all
over the place on your system. All your Arduino IDE v 1.6.4 files will be located only
under the new created "arduino-1.6.4" folder. And yes, your drive can be
in this case a Stick/SD Card or external HDD/SSD Drive so you can take your Arduino IDE
and your projects everywhere, just ready for coding!
2. Start the new installed Arduino IDE.
Go to File
Preferences - in Preferences window go to
"additional boards manager URL's" where you need to paste the following link:
Boards - > Boards manager, in the Boards manager
window select "contributed" from the TYPE drop
Select
ESP8266 by ESP8266 community forum and version 1.6.2
Press Install.
Installation process can take a while, so please be patient! A cup of tea/coffee might work here :)
4. Restart IDE
5. Select your board as ADAFRUIT HUZZAH ESP8266 or GenericESP8266 Module. For CBDBv2 EVO use provided config file or GenericESP8266.
6. Select CPU frequency: 80Mhz
7.
Select your Serial port and upload speed. Looks like it's working upto 921600 but quite unstable. Keep the usual 115200 baud for more solid
upload results.
You are ready for your first ESP8266 Program written in Arduino IDE :)
Working last days on the driver for MAX7219 8 digit display module I found that dtostrf() ESP8266 STDLIB function is not working properly for values containing "0"'s after dot, like: 1.0256,1.00256, etc.
With the quick written test code from below and the collaboration of the great guys from Arduino.cc Forum was able to confirm that it is a nasty BUG and is affecting ESP8266 libraries only, on Arduino (AVR) boards results confirmed from different sources as been OK.
TEST CODE:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}
void print_float(int no, float fVal, String sVal )
{
char charVal[12]; //temporarily holds data from vals
String stringVal = ""; //data on buff is copied to this string
dtostrf(fVal, 8, 4, charVal);
//4 is mininum width, 3 is precision; float value is copied onto buff
stringVal = charVal;
int strl = stringVal.length()-1;
Serial.print(no); //just a order number
//the number represented as string for reference
Serial.print(". Expected value :"); Serial.print(sVal);
//display lenght of the obtained string after conversion
Serial.print(" - String Length: ");Serial.print(strl);
//display the value as stored in stringVal
Serial.print(" - Conversion value in stringVal :");
Serial.println(stringVal);
}
void loop() {
print_float(1,1.256,"1.2560"); //No 1
print_float(2,1.0256,"1.0256"); //No 2
print_float(3,1.00256,"1.0026"); //No 3
Serial.println();
delay(5000); // delay in between reads for stability
}
WRONG RESULT - ESP8266 build
1. Expected value :1.2560 - String Length: 5 - Conversion value in stringVal: 1.2560
2. Expected value :1.0256 - String Length: 4 - Conversion value in stringVal: 1.256
3. Expected value :1.0026 - String Length: 3 - Conversion value in stringVal: 1.26
TEST PASSED RESULT - Arduino (AVR) build:
1. Expected value :1.2560 - String Length: 7 - Conversion value in stringVal: 1.2560
2. Expected value :1.0256 - String Length: 7 - Conversion value in stringVal: 1.0256
3. Expected value :1.0026 - String Length: 7 - Conversion value in stringVal: 1.0026
For ESP8266 Arduino IDE package the "dtostrf()" function is hidding in "core_esp8266_noniso.c" and is called by "#include<stdlib_noniso.h>"
{
if(isnan(number)) {
strcpy(s, "nan");
return s;
}
if(isinf(number)) {
strcpy(s, "inf");
return s;
}
if(number > 4294967040.0 || number < -4294967040.0) {
strcpy(s, "ovf");
return s;
}
char* out = s;
// Handle negative numbers
if(number < 0.0) {
*out = '-';
++out;
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
for(uint8_t i = 0; i < prec; ++i)
rounding /= 10.0;
number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long) number;
double remainder = number - (double) int_part;
out += sprintf(out, "%d", int_part);
// Print the decimal point, but only if there are digits beyond
if(prec > 0) {
*out = '.';
++out;
}
while(prec-- > 0) {
remainder *= 10.0;
}
sprintf(out, "%d", (int) remainder);
return s;
}
Going step-by-step thru the code is quite easy to find out that the remainder part is moved into integer, but on the iteration process the leading zeroes are not added into the buffer.
The fix is simple, changing the remainder add section in a way to properly add the "0"'s to the buffer until the remainder part become non-zero:
{
if(isnan(number)) {
strcpy(s, "nan");
return s;
}
if(isinf(number)) {
strcpy(s, "inf");
return s;
}
if(number > 4294967040.0 || number < -4294967040.0) {
strcpy(s, "ovf");
return s;
}
char* out = s;
// Handle negative numbers
if(number < 0.0) {
*out = '-';
++out;
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
for(uint8_t i = 0; i < prec; ++i)
rounding /= 10.0;
number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long) number;
double remainder = number - (double) int_part;
out += sprintf(out, "%d", int_part);
// Print the decimal point, but only if there are digits beyond
if(prec > 0) {
*out = '.';
++out;
}
while(prec-- > 0) {
remainder *= 10.0;
if((int)remainder == 0){
*out = '0';
++out;
}
}
sprintf(out, "%d", (int) remainder);
return s;
}
To fix your own ESP8266 Arduino IDE lib, just replace the old "dtostrf()" function in "core_esp8266_noniso.c" with the code above.
I have posted it also on esp8266.com, maybe somebody will put the fix also in mainstream code.
All the credits for the bugfix will go this time to "Delta_G" from Arduino.cc forum, who was the quickest in posting a solution. They are also other solutions, including mine, but this one it's the most elegant until now.
Had a lot fun fun with them, looks a nice and stable solution so I'm thinking to use them as Display for one of my future projects.
Meanwhile I was also playing with ESP8266 CBDBv2 EVO and Arduino IDE and because it looks like the latest 1.6.4 version it's becoming more stable and usable than previous releases I will give it a try for MAX7219 Driver implementation.
I still consider ESP8266 + NodeMCU LUA interpreter as the best environment for Learning/Drivers Developpment or even small projects, offering you a great flexibility that a Interpreter can give you but it's obviously that for bigger projects you need something else, so let's give Arduino IDE a try.
What we will need:
CBDBv2 EVO Board ( or any other ESP8266 Board with the same capabilities you may like )
USB adapter (take a look on Part 1 for details about the USB Adapter)
For programming and uploading the driver and the software we will use the Arduino IDE.
I will not insist to much on the Arduino IDE install process, it is a quite trivial process. If anybody wants more details about please feel free to ask.
MAX 7219 - 8 digit display driver connections
Wire MAX7219 ESP8266
Green +5Vcc Blue GND GND Yellow DIN 13 White CS 12 Orange CLK 14
MAX7219 Driver Implementation
For details about MAX Timing Diagram, Registers, Initialisation, etc please take a look at the detailed description from the previous MAX7219 article.
1. Init
int INTENSITYMIN = 0; // minimum brightness, valid range [0,15] int INTENSITYMAX = 1; // maximum brightness, valid range [0,15]
int DIN_PIN = 13; // data in pin int CS_PIN = 12; // load (CS) pin int CLK_PIN = 14; // clock pin int dly = 50; // delay in us int adc=0; // read ADC int spr=32; // number of readings int offset=5; // input offset
4. Convert anf Print float value in xxxx.xxx format
void print_LED(float fVal, int w, int p) { int d = 1; int ch = 1; int n = 0; int nr_size = 0; char charVal[11]; //temporarily holds data from vals String stringVal = ""; //data on buff is copied to this string
//dtostrf(fVal, w, p, charVal); //4 is mininum width, 3 is precision; //NOT WORKING FOR Values SMALLER THAT 0.01 !! // stringVal = charVal; // created a new function below for converting properly a pozitive xxxx.xxx float to string
stringVal=ftos(fVal,3);
int strl = stringVal.length()-1; for (int i=0;i<strl+1;i++) { charVal[i]=stringVal[i]; }
Serial.print("Length: ");Serial.println(strl); //display string Serial.println(stringVal); //convert charVal[] to LED Display string for(int i=0;i<strl+1;i++) { if ((charVal[i] == '.') && (d==1)) { stringVal=charVal[i]; n = 0; n = (n * 10) + (charVal[i-1] - 48); setRegistry(strl-i+1, 128+n); d = 0; } else { stringVal=charVal[i]; Serial.print("d: ");Serial.print(d); //display string Serial.print(" - Increment: ");Serial.print(i); //display string Serial.print(" - INT: ");Serial.println(charVal[i]); //display string n=0; n = (n * 10) + (charVal[i] - 48); int pos = i; if (d==0) { pos = i-1; } setRegistry(strl-pos,n); } } }
5. Convert float value to a string String ftos(float fVal, int prec) { int mlt=10; String snr; String dp; int iprt,dprt;
iprt = int(fVal);
// Round fVal for proper prec printing - correctly so that print(1.999, 2) prints as "2.00" double rnd = 0.5; for(uint8_t i = 0; i < prec; ++i) rnd /= 10.0; mlt *= 100; fVal += rnd;
// Check and count "0"'s proper after ZERO (0.00xx) number display dprt = 1000*(fVal-iprt); if (dprt < 10) { dp = "00" + String(dprt); }else if (dprt < 100) { dp = "0" + String(dprt); }else {dp = dprt;}
Another very popular and widely available module, used already in many Projects before, meeting the ESP8266 ecosystem :)
You can buy MAX7219 modules from Banggood, Amazon, Ebay, nameyourfavorite.com, quality and price might hugely vary from one to another so don't choose the cheapest one in town as you might find it as been not a very good deal to the end.
Description
The MAX7219 are compact, serial input/output common-cathode
display drivers that interface microprocessors (µPs) to 7-segment
numeric LED displays of up to 8 digits, bar-graph displays, or 64
individual LEDs. Included on-chip are a BCD code-B decoder, multiplex
scan circuitry, segment and digit drivers, and an 8x8 static RAM that
stores each digit. Only one external resistor is required to set the
segment current for all LEDs.
A convenient 4-wire serial interface connects to all common µPs.
Individual digits may be addressed and updated without rewriting the
entire display. The MAX7219 also allow the user to select code-B
decoding or no-decode for each digit.
The devices include a 150µA low-power shutdown mode, analog and digital
brightness control, a scan-limit register that allows the user to
display from 1 to 8 digits, and a test mode that forces all LEDs on.
Key Features
10MHz Serial Interface
Individual LED Segment Control
Decode/No-Decode Digit Selection
150µA Low-Power Shutdown (Data Retained)
Digital and Analog Brightness Control
Display Blanked on Power-Up
Drive Common-Cathode LED Display
24-Pin DIP and SO Packages
Typical Application Circuit
This is a 5V operation device. If you need to run it by the book at 3.3V Logic Level you will
need to use a level shifter. In practice, as you will see below, you can
try and run it directly, a bit out of spec. As MAX7219 HIGH logic level is at
3.5V...well...looks like it's working quite OK also in this way, in 48
hours of continuous running no freeze or strange behaviour:)
For programming and uploading the driver and the software we will continue to use the LuaUploader as before.
MAX7219 - CBDBv2 EVO Connection
Wire MAX7219 ESP8266
Green +5Vcc
Blue GND GND
Yellow DIN 13
White CS 12
Orange CLK 14
MAX7219 Driver Implementation
Timing Diagram
Initial Power-Up
On initial power-up, all control registers are reset, the display is blanked, and the MAX7219 enter shutdown mode.
Program the display driver prior to display use. Otherwise, it will initially be set to scan one digit, it will not decode data in the data registers, and the intensity register will be set to its minimum value.
Shutdown Mode
When the MAX7219 is in shutdown mode, the scan oscillator is halted, all segment current sources are pulled to ground, and all digit drivers are pulled to V+, thereby blanking the display.
Data in the digit and control registers remains unaltered.
Shutdown can be used to save power or as an alarm to flash the display by successively entering and leaving shutdown mode.
For minimum supply current in shutdown mode, logic inputs should be at ground or V+ (CMOS-logic levels).
Typically, it takes less than 250μs for the MAX7219 to leave shutdown mode.
A nice thing is the fact that the display driver can be programmed while in shutdown mode, and shutdown mode can be overridden by the display-test function.
Serial-Addressing Modes
For the MAX7219, serial data at DIN, sent in 16-bit packets, is shifted into the internal 16-bit shift register with each rising edge of CLK regardless of the state of LOAD. For the MAX7221, CS must be low to clock data in or out. The data is then latched into either the digit or control registers on the rising edge of LOAD/CS.
LOAD/CS must go high concurrently with or after the 16th rising clock edge, but before the next rising clock edge or data will be lost. Data at DIN is propagated through the shift register and appears at DOUT 16.5 clock cycles later.
Data is clocked out on the falling edge of CLK.
Data bits are labeled D0–D15.
D8–D11 contain the register address.
D0–D7 contain the data, and D12–D15 are “don’t care” bits.
The first received is D15, the most significant bit (MSB).
Digit and Control Registers
14 addressable digit and control registers.
The digit registers are realized with an on-chip, 8x8 dual-port SRAM. They are addressed directly so that individual digits can be updated and retain data as long as V+ typically exceeds 2V.
The control registers consist of decode mode, display intensity, scan limit(number of scanned digits), shutdown, and display test (all LEDs on).
Decode-Mode Register
The decode-mode register sets BCD code B (0-9, E, H, L, P, and -) or no-decode operation for each digit.
Each bit in the register corresponds to one digit.
A logic high selects code B decoding while logic low bypasses the decoder.
When the code B decode mode is used, the decoder looks only at the lower nibble of the data in the digit registers (D3–D0), disregarding bits D4–D6. D7, which sets the decimal point (SEG DP), is independent of the decoder and is positive logic (D7 = 1 turns the decimal point on).
When no-decode is selected, data bits D7–D0 correspond to the segment lines of the MAX7219/MAX7221.
Intensity Control and Interdigit Blanking
The MAX7219 allow display brightness to be controlled with an external resistor (RSET) connected between V+ and ISET.
The peak current sourced from the segment drivers is nominally 100 times the current entering ISET.
This resistor can either be fixed or variable to allow brightness adjustment from the front panel.
Its minimum value should be 9.53kΩ, which typically sets the segment current at 40mA.
Display brightness can also be controlled digitally by using the intensity register.
Digital control of display brightness is provided by an internal pulse-width modulator, which is controlled by the lower nibble of the intensity register.
The modulator scales the average segment current in 16 steps from a maximum of 31/32 down to 1/32 of the peak current set by RSET.
The minimum interdigit blanking time is set to 1/32 of a cycle.
Scan-Limit Register
The scan-limit register sets how many digits are displayed, from 1 to 8.
They are displayed in a multiplexed manner with a typical display scan rate of 800Hz with 8 digits displayed.
If fewer digits are displayed, the scan rate is 8fOSC/N, where N is the number of digits scanned.
Since the number of scanned digits affects the display brightness, the scan-limit register should not be used to blank portions of the display (such as leading zero suppression).
Display-Test Register
The display-test register operates in two modes: normal and display test. Display-test mode turns all LEDs on by overriding, but not altering, all controls and digit registers(including the shutdown register).
In display-test mode, 8 digits are scanned and the duty cycle is 31/32
function wrByte(data) i=8 while (i>0) do mask = bit.lshift(0x01,i-1) --print(mask) gpio.write( CLK, 0) -- tick dser = bit.band(data,mask) if (dser > 0) then gpio.write(DIN, 1) -- send 1 --print("1") else gpio.write(DIN, 0) -- send 0 --print("0") end --endif --print(dser) gpio.write( CLK, 1) -- tick i=i-1 end --while end
3. Set Register
function setReg(reg, value) gpio.write(CS, 0)
wrByte(reg) -- specify register tmr.delay(10) wrByte(value) -- send data
gpio.write(CS, 0) --tmr.delay(10) gpio.write(CS, 1) end
4. Convert anf Print integer number in xxxx format
function print_led_int(c) th = string.format("%d",c / 1000) h = string.format("%d",(c-th*1000) / 100) t = string.format("%d", (c-th*1000-h*100) / 10) u = string.format("%d", c-th*1000-h*100-t*10) --print(string.format("%d %d %d %d", th,h,t,u)) setReg(4, th) setReg(3, h) setReg(2, t) setReg(1, u) end
5. Create a Display 'ZERO' init stage
function zero_all() v=1 while (v<9) do setReg(v,0) v=v+1 end end
6. MAX7219 Initialisation
setReg(MAXREG_SCANLIMIT, 0x07) tmr.delay(100) setReg(MAXREG_DECODEMODE, 0xFF) -- full decode mode BCD tmr.delay(100) setReg(MAXREG_SHUTDOWN, 0x01) -- not in shutdown mode tmr.delay(100) setReg(MAXREG_DISPTEST, 0x00) -- no display test tmr.delay(100) setReg(MAXREG_INTENSITY, 0x00) -- set Brightness zero_all() -- set all to ZERO
7. Test Display - 9999 counter
count=0 tmr.alarm(0,1000,1, function() count=count+1; --print(count); print_led_int(count) if (count>9999) then count=0;zero_all() end end)
In this part we will explore the programming side of the ACS712 Current reading function.
If you didn't read yet the previous article about ACS712 Current sensor Board it might be a good idea to start from there as it will be easier to understant how it's working the entire process. You can find there schematics, theory of operation and technical related things.
What we will need:
ACS712 Current Board module (pick your desired choice - 5A, 20A, 30A )
CBDB Board ( or any other ESP8266 Board you may like but who has the same capabilities)
USB adapter (take a look on Part 1 for details about the USB Adapter
ACS712 Software For programming CBDBv2 Board and uploading the drivers and the software we will continue to use the LuaUploader as before. 1. Reading ACS712 with VLSAM DC
In this case, as VLSAM DC Output is already scaled to ADC input of 0-1V the only things that we need to do for proper measurements of the current are:
establish the LSB value for ADC
extablish your own desired VLSAM Offset value. It's desired to not start your currrent range scale exactly at 0V ADC (ADC linearity, etc), for easing the calculations, just set Vdiv to have an output of about 100mV for ZERO Amps. As ASC712/20 gives us 100mV/A that means that we will have 100mA reading for 200mV and so on, just substract your offset.
function readADC_VLSAM() ad = 0 ad=adc.read(0) --calibrate based on your voltage divider AND Vref! print("\nReadADC : " ..ad) ACS712 = ad*LSB print("Current Read: " ..string.format("%g",ACS712-offset) .."mA") return ACS712 end For increasing the precison of the measurement just take a bigger number of readings and obtain a average value. 128 steps looks quite ok, but in case of more noise in the system just use a bigger number and eliminate the most extreme values for the obtained interval.
function readADC_avg_VLSAM() ad1 = 0 i=0 while (i<128) do ad1=ad1+adc.read(0) --calibrate based on your voltage divider AND Vref! tmr.delay(1000) --print(ad1) i=i+1 end ad1 = ad1/128 ACS712 = ad1*LSB print("Current Read: " ..string.format("%g",ACS712-offset) .."mA") return ACS712avg end
2. Direct Reading ACS712 Current Sensor
Another available option is to read directly the ACS Current sensor output.
In this case because the sensor output will swing between 0 and 5V, with ZERO Amps reading at 2.5V, we will use the CBD V2 EVO Board voltage divider or add your own in case of using a different board without such capabilities.
To better understand how it will work in this case, please take a look at the ESP8266 Internal ADC article where was also discussed the voltage divider for ADC input.
-- Select ADC SOURCE ADC_SRC = 5 -- select Voltage Divider / Current Input by default ! gpio.mode(ADC_SRC,gpio.OUTPUT, gpio.PULLUP)
gpio.write(ADC_SRC,1) -- Voltage Measurement - Voltage Divider Source selected
dival = 0.0009605 -- ADC volt/div value - CALIBRATE !! -- USB resdiv = 4.31447 -- Voltage divider Ration - CALIBRATE!! offset = 2.45 --ACS712 measured offset - CALIBRATE !!
function readADC_VDIV() adcV = 0 advr = 0 advr=adc.read(0) print("\nADCV Step : " ..string.format("%g",advr).." steps") adcV=advr*dival*resdiv print("Current : " ..string.format("%g",adcV-offset).." mA") return adcV end For increasing the precison of the measurement just take a bigger number of readings and obtain a average value as before, but this type you need more, like 512 or even 1024. Also some extra filtering on ACS712 output will be great.
Despite the fact that might be easier to use the Voltage divider, because of the high noise from the ASC712 output I will recommend you to use option1 - VLSAM DC . It will give you more accurate values than option2with Voltage divider.
Because of the very cheap ACS712 Current Sensor Board modules available all over the place, I really think that everybody heard about ACS712 sensor from Allegro MicroSystems.
As I was asked if "Can be used as a current sensor module for our ESP8266 Projects without too much hustle?", I ordered few of them and let's explore them for the answer :)
The ACS712 device consists of a precise, low-offset, linear Hall circuit with a copper conduction path located near the surface of the die. That means that it is a isolated path device, a very nice thing if you want to monitor MAINS Current or any other High Voltage path that you want isolated from your device.
IMPORTANT NOTE !! This device is a Hall Effect transducer. It should not be used near significant magnetic fields. If you have a magnetic noisy environment take a look at other solutions like isolation transformers, isolation OpAmps, linear isolation circuit, bus path isolation, etc.
Theory of operation
Applied current flowing through the ACS712 copper conduction path generates a magnetic field which the Hall IC converts into a proportional voltage. Device accuracy is optimized through the close proximity of the magnetic signal to the Hall transducer.
A precise, proportional voltage is provided by the low-offset, chopper-stabilized BiCMOS Hall IC, which is programmed for accuracy after packaging.
The ACS712 outputs an analog signal, VIOUT that varies linearly with the uni- or bi-directional AC or DC primary sampled current, IP (between IP+ e IP-) within the range specified.
It requires a power supply of 5V (VCC) and two capacitors to filter power supply and output. CF is recommended for noise management, with values that depend on the application.
Voltage Level Shifter and dc amplifier module - VLSAM DC(see details below)
Voltage Level Shifter and amplifier module - VLSAM DC
As our main goal is to explore the posibility to use the ACS712 module with ESP8266 devices, from the description above and datasheet we can identify very quick some problems that need to be solved to make ACS712 a "ESP Friendly" device:
ASC712:
5 Vdc power supply device
measure positive and negative 5/20/30Amps, corresponding to the analog output 100mV/A BUT
"ZERO" point, means no test current through the output voltage is VCC / 2 =5v/2=2.5V !
ESP8266:
3V only device
ADC range max: 0-1V
What we will need is to "move" the "ZERO" point as low as we want to GND and in the same time to amplify the received analog signal to obtain a better resolution in the desired measuring range. (don't forget, for our experiment we have DC only voltage here and just one current flow direction)
So, what can be done?
Probably they are some other solutions to this problem, and if you know any of them, please feel free to share in the comments below, but the clasical one is to use a difference amplifier:
This kind of amplifier uses both
inverting and non-inverting inputs of a OPAmp with a
gain of one to produce an
output equal
to the
difference
between the inputs. Actually if you take a closer look it is a special case of
the differential amplifier.
The good thing is that in the same time you can also choose the resistances values in a way to amplify the difference.
If all the resistor values are equal, this amplifier will have a
differential voltage gain of 1. The analysis of this circuit is
essentially the same as that of an inverting amplifier, except that the
noninverting input (+) of the op-amp is at a voltage equal to a fraction
of V2, rather than being connected directly to ground. As would stand to reason, V2 functions as the noninverting input and V1 functions as the inverting input of the final amplifier circuit. Therefore:
Vout = V2 - V1
If we want to provide a differential gain of anything other than 1, we would have to adjust the resistances in both upper and lower voltage dividers, necessitating multiple resistor
changes and balancing between the two dividers for symmetrical
operation.
A limitation of this simple amplifier design is the fact that its
input impedances are rather low compared to that of some other op-amp
configurations, most notably the noninverting (single-ended input)
amplifier. Each input voltage source has to drive current through a
resistance, which constitutes far less impedance than the bare input of
an op-amp alone. It is a solution to this problem, fortunately, quite
simple, all we need to do is “buffer” each input voltage signal through a
voltage follower.
For our case, as we want to "substract" the ACS712 - 2.5Vdc to move the "ZERO" point near GND, we will have:
V1 = 2.5V - can be easy obtained from 5V with a buffered voltage divider
V2 = VIOUT - output voltage from ASC712 Module
Amplification:
IF R1=R2=R3=R4=10K
output for ADC input of 100mV/A
max range: 10A
resolution: 10mA
Changing range R1=R2=10K, R3=R4=100k
output for ADC input of 1V/A
max range: 1A
resolution: 1mA
VLSAM DC Schematic
And the simulation result for a 0-10A, 2.5-3.5 VIOut sweep:
GREEN - Voltage divider output : 2.5Vdc
FUCHSIA - ASC712 VIOut : 2.5 -> 3.5Vdc
RED - ADC input : 0 -> 1Vdc
So far so good, let's move it on a breadboard for a quick test: