Shahariar
Published © CC BY-SA

PSoC4: CapSense based Portable Power Supply

CapSense Touch based HMI device to control power flow of high current DC loads with adjustable voltage control & current limiting feature

BeginnerFull instructions provided6 hours148
PSoC4: CapSense based Portable Power Supply

Things used in this project

Hardware components

PSoC 4 Prototyping Kit
Cypress PSoC 4 Prototyping Kit
×1

Software apps and online services

PSoC Creator
Cypress PSoC Creator

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Schematics

schematic

psoc internal sch

sch

schematic

internal

Code

main.c

C/C++
// Copypaste by Who ? lol, that's me !

#include <project.h>
#include <stdlib.h>
#include <stdio.h>
#include "ssd1306.h"

#define DISPLAY_ADDRESS 0x3C // I2C Oled address 0x3C

//#define R_Lower         10   // 10k Resistor for voltage divider   
//#define R_Upper         100  // 100k Resistor for voltage divider
//#define V_Ref           5    // 5V as ADC reference (0V to 5V range
//#define ADC_Resolution  4096 // 12 bit ADC
//#define Current_Scaling 185  // ACS712 output changes by 185mV/A 

// some variables to measure and calculate ADC results
uint16_t I_Sense = 0;
uint16_t V_Sense = 0;
int Volts = 0;
int Amps = 0;
int Current_Limit = 300;
char Results[10];
uint8 output = 0;
// mcp4131 10k SPI digipot resistance changing commands
uint8_t increment_cmd = 0b00000100;
uint8_t decrement_cmd = 0b00001000;

void refresh_oled(void) 
{
    CyDelay(100); 
    display_clear();
}

void enable_outout (void)
{
    Load_Off_Write(0);
    Load_On_Write(1);
    Output_OnOff_LED_Write(1);
    output = 1;
    CyDelay(75);
    Load_On_Write(0);
    
}


void disable_outout (void)
{
    Load_On_Write(0);
    Load_Off_Write(1);    
    Output_OnOff_LED_Write(0);
    output = 0;
    CyDelay(75);
    Load_Off_Write(0);
    
}

void haptic_feedback (void)
{
    HapticVibe_Write(1);
    CyDelay(40);
    HapticVibe_Write(0);
}
/// beginning of main ///

int main(){
    // this variable will keep track of  
    // latest touch infut from user
    uint16 which_button = 999;
    
    // making sure output is disabled at startup
    disable_outout();
    //Init Global Interrupt
    CyGlobalIntEnable;
    
    
    // Init CapSense for Touch HMI
    CapSense_Start();
    CapSense_InitializeAllBaselines();
 //   CyDelay(50);
    
    // Init ADC for voltage, current, power measurement
    ADC_IV_Sense_Start();
 //   CyDelay(50);
    
    // Init SPI to control 10k MPC4131 digital pot
    SPI_Digipot_Start();
 //   CyDelay(50);
    
    // config 1306 OLED // text settings, font size
       // Init 1306 I2C OLED
    I2COLED_Start();
 //   CyDelay(50);
    display_init(DISPLAY_ADDRESS);
    display_clear();    
    display_update();      
    gfx_setTextSize(3);
    gfx_setTextColor(WHITE);
    gfx_setCursor(0,0);
  
    /// for forever ///
    
        for(;;){

        // if someting is sensed by capsense module
        // (i.e. any touch from user) process it  
        // this is the core HMI function of this device
            
        while ( CapSense_IsBusy() !=0 )
        {}
            CapSense_ProcessAllWidgets();
            
                if( CapSense_IsWidgetActive(CapSense_BUTTON0_WDGT_ID)) 
           
            {
             which_button = 0;
            }
            
            else if( CapSense_IsWidgetActive(CapSense_BUTTON1_WDGT_ID))
            {
             which_button = 1;
            }
            
             else if( CapSense_IsWidgetActive(CapSense_BUTTON2_WDGT_ID))
            {
                which_button = 2;
            }
            
             else if( CapSense_IsWidgetActive(CapSense_BUTTON3_WDGT_ID))
            {
                which_button = 3;
            }
            
             else if( CapSense_IsWidgetActive(CapSense_BUTTON4_WDGT_ID))
            {
                which_button = 4;
            }
            // trigger under overload or short circuit condition
             else if( Amps > Current_Limit)
            {
                which_button = 1;
            }
            else
            {
             which_button = 999;
            }
            
            ////////////////////////////////////////////////
            // Get ADC to measure current & output voltage//
            ////////////////////////////////////////////////
            for(int i=0; i<8; i++)
            {
            ADC_IV_Sense_StartConvert();
            while(ADC_IV_Sense_IsEndConversion(ADC_IV_Sense_RETURN_STATUS))
            {} // blocking while polling/scanning ADC
            
            // Get raw counts from ADC ch 0 an ch 1
            I_Sense =I_Sense + ADC_IV_Sense_GetResult16(0);
            V_Sense =V_Sense + ADC_IV_Sense_GetResult16(1);
            }
            I_Sense = I_Sense/8;// avg of 8 readings
            V_Sense = V_Sense/8;// avg of 8 readings
            // convert into real voltage and current data
            //float Voltage = (V_Sense/4096.0)*5.0*(10+1)/10.0;
            // float Voltage = V_Sense*0.001343;
            // float Amperage  = 1000/(5000/4096*185);
            Volts = (V_Sense*1.343) ; // convert into mV
            Amps  = ((I_Sense-2048)*4.4247) ;   // convert into mA
            // ADC_IV_Sense_StopConvert();
            I_Sense = 0;
            V_Sense = 0;
    
            
            /////////////////////////////////////////////
            /////////////////////////////////////////////
            // HMI Action based on user input on touch //
            /////////////////////////////////////////////
            /////////////////////////////////////////////
            
            if (which_button == 0)
            {
             // adjust digital pot to decrease output voltage
             SPI_Digipot_WriteTxData (increment_cmd);
             
             gfx_setCursor(0,0);
             gfx_print("volt(-)");
             gfx_setCursor(0,32);
             gfx_print(itoa(Volts,Results,10));
             gfx_setCursor(85,32);
             gfx_print("mV"); 
             display_update();          
             haptic_feedback();
             refresh_oled();
             
            }
            
            if (which_button == 1)
            {
               // Disconnect output latch relay to 
               // disable output voltage
               // can be user trigger or overload triggered
               gfx_setCursor(0,0);
               haptic_feedback();
               disable_outout();
            
               // display info on Oled display
               gfx_print("Pwr OFF");
               display_update();
               refresh_oled();
                          
            }
            
            if (which_button == 2)
            {
               gfx_setCursor(0,0);
               haptic_feedback();
               // display info on Oled display
               gfx_print("Current");
               gfx_setCursor(0,32);
               gfx_print(" Limit ");
               display_update();
               refresh_oled(); 
               Current_Limit = Current_Limit+100;
               if (Current_Limit>3000)
               {Current_Limit = 300;}
               gfx_setCursor(0,0);
               gfx_print(itoa(Current_Limit,Results,10));
               gfx_setCursor(85,0);
               gfx_print("mA");
               display_update();
               refresh_oled(); 
            
            }
            
            if (which_button == 3)
            {
               // Connect output latch relay to 
               // enable output voltage 
                haptic_feedback();
                enable_outout();
            // display info on Oled display
               gfx_setCursor(0,0);
               gfx_print("Pwr ON");
               display_update();
               refresh_oled();
            }
            
            if (which_button == 4)
            {
             // adjust digital pot to increase output voltage
               SPI_Digipot_WriteTxData (decrement_cmd);
               
               
             gfx_setCursor(0,0);
             gfx_print("volt(+)");
             gfx_setCursor(0,32);
             gfx_print(itoa(Volts,Results,10));
             gfx_setCursor(85,32);
             gfx_print("mV"); 
             display_update();          
             haptic_feedback();
             refresh_oled();
             
            }
            
            
            // when no touch detected //
            if (which_button ==999)
            {            
            // disable vibration + visual feedback    
            HapticVibe_Write(0);
            
            
            if (!output)
            {Volts = 0; Amps = 0;}
            
            // show output current on display
            gfx_setCursor(0,0);
            gfx_print(itoa(Amps,Results,10));
            gfx_setCursor(85,0);
            gfx_print("mA");
            
            // show output voltage on display
            gfx_setCursor(0,32);
            gfx_print(itoa(Volts,Results,10));
            gfx_setCursor(85,32);
            gfx_print("mV");
           
            display_update();
            refresh_oled();
            
            }
            
        // scan again to check any CapSense input 
        // given bu the user or not    
        CapSense_ScanAllWidgets();
        // CapSense_UpdateEnabledBaselines();    
    }    ///// end of forever /////
} ///// end of main /////
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////

Full Code

C/C++
Unzip and Import Project to PSoC Creator 4.4
No preview (download only).

Credits

Shahariar

Shahariar

71 projects • 261 followers
"What Kills a 'Great life' is a 'Good Life', which is Living a Life Inside While Loop"

Comments