Part IV: Software Programming

Posted on: November 20, 2018, by :

Introduction

For ESP8266 programming part, we use Arduino IDE version 1.6.11, but other version should be fine to use. First, download its BSP and required libraries by following this tutorial : https://tutorial.cytron.io/2016/03/17/getting-started-for-espresso-lite-v2-0/ . You can skip the first part and start with sub-chapter Getting Started Espresso Lite v2.0 with Arduino IDE. Next, install peripheral libraries :

  1. INA219 by https://github.com/adafruit/Adafruit_INA219
  2. MCP4017 by https://github.com/SparkysWidgets/SW_MCP4017-Library
  3. I2C Liquid LCD by https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library

Flow Chart

Copy the following source code to your IDE, please take note line 31 to 33:

/*Library header*/
#include "unosupply_b.h"

/*Peripheral define*/
#define CURL        15
#define PWR_LED     2
#define MUXA        12
#define MUXB        13

/*Others*/
#define VBAT        0
#define VOUT        1
#define VTEMP       2
#define R_9V        1995
#define R_12V       875
#define R_15V       480
#define R_17V       200
#define R_20V       100

/*Internal Functions*/
void unosupply_lcdp();
double adc_switch_read(int sw);

/*Peripheral Handler*/
Adafruit_INA219   ina219;
MCP4716           MCP4716(0x60);
LiquidCrystal_I2C lcd(0x27,16,2);
MCP4017           i2cDP(MCP4017ADDRESS, 128, 5000);

/*Wifi Capablity*/
char auth[] = "<put your authentication code here>";
char ssid[] = "<put your wifi ssid here>";
char pass[] = "<put your wifi password here>";

/*Variables*/
  double current_mA         = 0;
  uint16_t setVoltage       = 0;
  uint16_t setCurrent       = 0;
  uint16_t setCurrentValue  = 0;
  double ReadVout           = 0;  
  double ReadBout           = 0;
  int    vflag              = 0;
  
  
/*Function to overwrite output voltage value*/
BLYNK_WRITE(V0)
{
  setVoltage = param.asInt();
  /*calculate value to set potentiometer and dac*/
  if(setVoltage >= 0 && setVoltage <= 350){
    if(vflag != 0){
      i2cDP.setResistance(R_9V);
    }
    vflag = 0;
    MCP4716.setVout(setVoltage);
  }
  else if(setVoltage <= 500){
    if(vflag != 1){
      i2cDP.setResistance(R_12V);
    }
    vflag = 1;
    MCP4716.setVout(setVoltage);
  }
  else if(setVoltage <= 600){
    if(vflag != 2){
      i2cDP.setResistance(R_15V);
    }
    vflag = 2;
    MCP4716.setVout(setVoltage);
  }
  else if(setVoltage <= 770){
    if(vflag != 3){
      i2cDP.setResistance(R_17V);
    }
    vflag = 3;
    MCP4716.setVout(setVoltage);
  }
  else if(setVoltage > 770){
    if(vflag != 4){
      i2cDP.setResistance(R_20V);
    }
    vflag = 4;
    MCP4716.setVout(setVoltage);
  }
}

/*Function to read current value and publish to app*/
BLYNK_READ(V1) 
{
  char buffer_a[15];
  unosupply_lcdp();
  dtostrf(current_mA,4,3,buffer_a);
  Blynk.virtualWrite(1, buffer_a);
}

/*Function to read voltage value and publish to app*/
BLYNK_READ(V2) 
{
  char buffer_v[15];
  /*use analogRead to Vout*/
  ReadVout = adc_switch_read(VOUT);
  dtostrf(ReadVout,4,2,buffer_v);
  unosupply_lcdp();
  Blynk.virtualWrite(2, buffer_v);
}

/*Function to set current limit*/
BLYNK_WRITE(V3)
{
  setCurrent = param.asInt();
  analogWrite(CURL, setCurrent);
}

/*Function to read battery voltage value and publish to app*/
BLYNK_READ(V4) 
{
  char buffer_b[15];
  ReadBout = adc_switch_read(VBAT);
  dtostrf(ReadBout,4,2,buffer_b);
  unosupply_lcdp();
  Blynk.virtualWrite(4, buffer_b);
}
/*Function to read current limit value and publish to app*/
BLYNK_READ(V5)
{
  String buffer_c;
  setCurrentValue = setCurrent + 15;
  buffer_c = String(setCurrentValue);
  Blynk.virtualWrite(5, buffer_c);
}

/*Function to update LCD screen*/
void unosupply_lcdp() { 
  current_mA = ina219.getCurrent_mA();
  lcd.clear();
  lcd.setCursor(2,0);
  lcd.print("VOUT: ");lcd.print(ReadVout);lcd.print("V");
  lcd.setCursor(2,1);
  lcd.print("IOUT: ");lcd.print(current_mA);lcd.print("mA");
}

/*Function to swicth probe channel*/
double adc_switch_read(int sw) {
    double value_adc    = 0;
    double value_cald;
    
    if (sw == VBAT){
         digitalWrite(MUXA,LOW);
         digitalWrite(MUXB,LOW);
    }
    else if (sw == VOUT) {
         digitalWrite(MUXA,HIGH);
         digitalWrite(MUXB,LOW);
    }
    else if (sw == VTEMP) {
         digitalWrite(MUXA,LOW);
         digitalWrite(MUXB,HIGH);
    }
    else {
         digitalWrite(MUXA,LOW);
         digitalWrite(MUXB,LOW);
    }

    value_adc = analogRead(A0);

    if (sw == VBAT) {
      value_cald =(((value_adc/1024) * 3.38)/0.186);
    }
    else if(sw == VOUT) {
      value_cald = (((value_adc/1024) * 3.38)/0.094);
    }
    else {
      value_cald = (((value_adc/1024) * 3.38)/0.186);
    }

    return value_cald;

}

/*Init Seqeunce*/
void unosupply_init() {
    //Initialize I2C Master
    Wire.begin();                   
    Wire.setClock(100000);          
    //Initialize Current Sensor w/ 32V/1A MAX
    ina219.begin();               
    ina219.setCalibration_32V_1A();
    //Initialize LCD
    lcd.init();
    lcd.backlight();
    lcd.setCursor(4,0);
    lcd.print("Unosupply");
    lcd.setCursor(1,1);
    lcd.print("Connection Idle");
    //Initialize Potentiometer w/ backend 9V
    MCP4716.setGain(1);
    MCP4716.setVref(2);
    i2cDP.setResistance(R_9V); 
    //Initialize DAC w/ frontend 0v
    MCP4716.setVout(0);      
    //Initialize Current Limit w/ 0.1A
    pinMode(CURL, OUTPUT);
    analogWrite(CURL, 100);
    //Init adc switch ports,10(a,s1),9(b,s2)
    pinMode(MUXA, OUTPUT);
    pinMode(MUXB, OUTPUT);
    pinMode(A0, INPUT);
    //Initialization done
    pinMode(PWR_LED, OUTPUT);
    analogWrite(PWR_LED,HIGH);
}

/*Setup Seqeunce*/
void setup() {
  unosupply_init();
  //unosupply_lcdp();
  Blynk.begin(auth, ssid, pass);
}

/*Start the Blynk*/
void loop() {
  Blynk.run();
}

Blynk APP

For Mobile apps, we use Blynk for user-friendly plug and play features. You can get the Blynk Apps from Google Play Store.

After install the apps, create an account and you will receive an authentication token for your account. Copy the token paste to line 31 of source code above, compile the source code and upload to ESP8266. This token will make sure your ESP8266 will connect to your Blynk project only. Then, create a new project and start placing the components: 

You can refer to components arrangement below, properties are free to edit by clicking the component:

 

Leave a Reply

Your email address will not be published. Required fields are marked *