Maker Pro
Configurable Logic Block

Smart Light : Touch to Glow

MB
June 23, 2025 by Mohamed Bedair
 
Share
banner

This project demonstrates a low-latency capacitive touch detection system using the Configurable Logic Block (CLB) and the Capacitive Voltage Divider (CVD) method on the PIC16F13145 microcontroller. The touch input is processed using hardware logic for ultra-fast and deterministic response, ideal for low-power and real-time embedded applications.

🔗 Key Features

  • Capacitive touch detection using only 2 MSBs (ADC9, ADC8)
  • Hardware-based noise filtering using majority vote
  • Digital hysteresis logic for debouncing
  • LED indicator mapped via CLB output
  • CVD method for robust touch sensing

🔧 How It Works

CVD ADC Reading

The CVD method samples the capacitive pad via the ADC in a charge/discharge cycle

CLB Input

The 10-bit ADC result is sent to the CLB as a 10-bit bus. Only ADC9 and ADC8 are used to detect if the value is below 256 (touch condition).

CLB Pipeline

  • Digital filtering: Applies a 3-sample majority filter on ADC9 and ADC8.
  • Thresholding: Interprets ADC < 256 as touch and ADC > 512 as release.
  • Hysteresis: Holds state to prevent flicker.
  • Majority Vote Filter: Ensures consistent detection before triggering.
  • Output Register: Drives GPIO-connected LED on touch detection.

💻 Software Structure

Main Application (CPU Code):

  • Periodic ADC conversion triggered by a timer interrupt (every 100 ms)
  • Result sent to CLB using CLB1_SWIN_Write16()
  • UART prints ADC value for debugging
void ADC_Callback(void)
{
    volatile adc_result_t adcVal = 0;
    
    /* Read the result from the ADC */
    adcVal = ADC_ConversionResultGet();
    
    /* Send the ADC value to the CLB for further processing */
    CLB1_SWIN_Write16(adcVal);
    
    /* Print the ADC value over UART for debugging */
    printf("ADC Value: %d \r\n", adcVal);
}


void Tmr_100ms_Callback(void)
{
    /* Trigger new ADC conversion */
    ADC_ConversionStart();
}

CLB Verilog Logic

CLB Block Diagram

module CapTouch_Pipeline (
     CLK,             // CLB global clock
     ADC9, ADC8,      // Most significant ADC bits
     TOUCH            // Final touch detection output
);

  input CLK;
  input ADC9, ADC8;
  output TOUCH;

  // === Stage 1: Digital Filters on ADC Bits ===
  reg [2:0] adc9_hist;
  wire adc9_filtered;

  always @(posedge CLK) begin
    adc9_hist <= {adc9_hist[1:0], ADC9};
  end

  assign adc9_filtered = (adc9_hist[0] + adc9_hist[1] + adc9_hist[2]) >= 2;

  reg [2:0] adc8_hist;
  wire adc8_filtered;

  always @(posedge CLK) begin
    adc8_hist <= {adc8_hist[1:0], ADC8};
  end

  assign adc8_filtered = (adc8_hist[0] + adc8_hist[1] + adc8_hist[2]) >= 2;

  // === Stage 2: Hysteresis Logic ===
  reg touch_state;
  always @(posedge CLK) begin
    if (~adc9_filtered & ~adc8_filtered)            // ADC < 256 → Touch
      touch_state <= 1'b1;
    else if (~adc9_filtered & adc8_filtered)        // ADC ≥ 256 → No touch
      touch_state <= 1'b0;
    // Note: ADC9 == 1 (≥ 512) is already handled here
  end

  // === Stage 3: Majority Filter for Stability ===
  reg [4:0] hist;
  always @(posedge CLK) begin
    hist <= {hist[3:0], touch_state};
  end

  wire [2:0] sum = hist[0] + hist[1] + hist[2] + hist[3] + hist[4];
  wire majority = (sum >= 3);

  // === Stage 4: Output Register ===
  reg touch_out;
  always @(posedge CLK) begin
    touch_out <= majority;
  end

  assign TOUCH = touch_out;

endmodule

🚀 Why This Matters

This project shows how Microchip’s CLB can handle real-time touch processing tasks with minimal CPU usage, making it suitable for ultra-low-power and latency-sensitive applications like wearables, capacitive buttons, and industrial panels.

Related Content

Categories

Comments


You May Also Like