How to detect water level with 12F1822 CPS module?

Started by Mustafa_cmbz, Apr 06, 2024, 03:06 PM

Previous topic - Next topic

Mustafa_cmbz

Hello.

I want to detect the presence of liquids using the CPS module in the internal structure of 12F1822. But I am stuck in the software part of Proton. Can you help me?

I would like you to share a few sample codes to understand the logic.




top204

What software have you created for it, and what is it not doing correctly?

With that information, we can then try to help solve the problem.

Mustafa_cmbz

Device = 12F1822
Declare Xtal=16
Config1 FOSC_INTOSC, WDTE_OFF, PWRTE_ON, MCLRE_OFF, CP_ON, CPD_ON, BOREN_OFF, CLKOUTEN_OFF, IESO_OFF, FCMEN_OFF
Config2 WRT_OFF, PLLEN_OFF, STVREN_OFF, BORV_19, LVP_OFF

Osc_16MHz()

'*********************************
'**** CPS MODÜL AYARLARI *********

CPSCON1=%00000000    ' İLK DÖRT BİT ETKİSİZ SONRAKİ 4 BİT KANAL SEÇİMİ 0000= A0 GİRİŞİ KAPASİTİF SEÇİM
CPSCON0.7=1          ' CPSON enb - disable
CPSCON0.6=1          ' CPSRM
 
CPSCON0.3=1          ' CPSRNG
CPSCON0.2=1          ' CPSRNG
CPSCON0.1=1          ' CPSOUT
CPSCON0.0=1          ' T0XCS 

'********************************
'***** TİMER AYARLARI ***********

T1CON.0      = 1  ' TMR1ON ENB-DİSABLE
T1GCON.7     = 1  ' Timer1 Gate Kontrol Blok ON/OFF
T1GCON.0     = 1  ' Timer1 Taban Timer0 Counter.
T1GCON.1     = 0  ' Timer1 Taban Timer0 Counter.
OPTION_REG.5 = 0  ' T0XCS 1 ise bu bit 0 olmalı. TMR0CS
OPTION_REG.3 = 0  ' PSA Timer0  PreScaller Aktif.   
OPTION_REG.0 = 0  ' PS Timer0 PreScaller değeri.   
OPTION_REG.1 = 0  ' PS Timer0 PreScaller değeri.   
OPTION_REG.2 = 0  ' PS Timer0 PreScaller değeri.   

INTCON.6     = 1  ' PEIE    Çevresel İnterrupt modülleri Aktif. 
INTCON.2     = 0  ' TMR0IF  False İnterrupt.
INTCON.5     = 0  ' TMR0IE  TMR0 İnterrupt ON/OFF
INTCON.7     = 0  ' GIE     Global İnterrupt Anahtar.


ANSELA=%0000001    ' 1 NOLU ANALOG GİRİŞ AKTİF
 

TRISA=%000000:PORTA=%000000
Declare All_Digital= true


Symbol TOUCH = PORTA.0
Input  TOUCH
Symbol BTN   = PORTA.1
Symbol LED   = PORTA.2

Dim GlobalCapTouchVal  As Word
Dim CalibrationVal     As Word




On_Interrupt GoTo KESME
GoTo BASLA


'***************************************************

 BASLA:
 
 


 GoTo BASLA

'***************************************************

    Proc Osc_16MHz()   
    OSCCON = $7A                    ' 16MHz_HF
    OSCTUNE = $00
    BORCON = $00
    EndProc

'***************************************************
 Disable
 KESME:
 Context Save

 High LED
 DelayMS 50
 Low LED
 DelayMS 50


 
 GlobalCapTouchVal =  (TMR1H << 8) + TMR1L
 TMR1H = 0  : TMR1L = 0
 
 

 Context Restore
 Return





I made a configuration like this... But I couldn't create a data logic that I could process. I couldn't fully understand the structure.

SeanG_65


Yasin

#4
Hi @Mustafa_cmbz. I have never used MCU's Capacitive touch feature. I guess you are using it for the first time. But you drew the pcb without doing any preliminary research. Check out the application notes I shared. As far as I know, only capacitive change can be detected after the mcu starts working. So with this method, if there is touch when the PCB is not powered, you cannot understand this after the MCU is working. Because there will be no capacitive change of the touched surface.

(Mcu nun Kapasitif dokunma özelliğini hiç kullanmadım. Galiba sende ilk defa kullanıyorsun. Fakat hiçbir ön araştırma yapmadan pcb çizmişsin. Paylaştığım uygulama notlarını incele. Bildiğim kadarıyla mcu çalışmaya başladıktan sonra sadece kapasitif değişim algılanabilir. Yani bu yöntemle, pcb de enerji yokken dokunma varsa, mcu çalıştıktan sonra bunu anlayamazsın. Çünkü dokunulan yüzeyin kapasitif değişimi olmayacak.)

https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ApplicationNotes/ApplicationNotes/01102a.pdf
https://ww1.microchip.com/downloads/en/Appnotes/Capacitive-Touch-Sensor-Design-Guide-DS00002934-B.pdf

top204

I found a japanese site that has a piece about capacitive sensing that was better than any microchip app note, here:

PIC12F1822 Capacitive Sensing Module

It will need translating with your browser, but it did have an interesting piece of firmware on the site, so I converted it to Positron8, and tidied the code up to make it more readable. I cannot test the capacitance operation on it because I do not have a PIC18F1822 device, but I have run the program in Isis and it does seem to operate and at the correct speed and sets up all the peripherals correctly etc... Give it a try and see if you can adapt it to your application.

The converted Positron8 code listing is below:

'
'   /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\     \/\\\                                                 /\\\          /\\\
'   \/\\\\\\\\\\\/        /\\\\\     /\\\\\\\\\\     /\\\\\\\\   /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'     \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\     \/\\\         \/\\\        /\\\\\\\\\\
'      \/\\\     \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\     \/\\\ /\\   /\\\/////\\\
'       \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\   \//\\\\\\\\/\\
'        \///        \///     \/////     \//////////    \//////////      \/////        \/////     \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' Capacitive sensing experiment.
' LEDs light up with approaching CPS electrode.
'
' Adapted for the Positron8 BASIC Compiler by Les Johnson.
'
' Microcontroller pin connections:
'
'              |-----\/-----|
'    VDD  -----| 1        8 |----- VSS
'              |            |
'    LED  -----| 2        7 |----- NC
'              |            |
'    CPS3 -----| 3        6 |----- LED
'              |            |
'    MCLR -----| 4        5 |----- CPS2
'              |____________|
'
    Device = 12F1822                                            ' Tell the compiler what device to compile for
    Declare Xtal = 4                                            ' Tell the compiler what frequency the device is operating at (in MHz)

$define Chan0_LED_Pin PORTA.1                                   ' CPS channel 0 LED connection port
$define Chan1_LED_Pin PORTA.5                                   ' CPS channel 1 LED connection port

$define cChan0_In 2                                             ' CPS channel 0 Pad connection CPS terminal number
$define cChan1_In 3                                             ' CPS channel 1 Pad connection CPS terminal number

$define cLED_On 1
$define cLED_Off 0
'
' Create global variables here
'
    Dim bChan_In[2] As Byte = cChan0_In, cChan1_In              ' CPS channel numbers
    Dim wAverage[2] As Word                                     ' Normal average count
    Dim wSwOn[2]    As Word = 180, 180                          ' On threshold count
    Dim wSwOff[2]   As Word = 90, 90                            ' Off threshold count

'------------------------------------------------------------------------------------
' The main program starts here
'
Main:
    Setup()                                                     ' Setup the program and peripherals

    Do                                                          ' Create a loop
        CPS_Check(0)                                            ' Processing CPS channel 0
        CPS_Check(1)                                            ' Processing CPS channel 1
    Loop                                                        ' Do it forever

'------------------------------------------------------------------------------------
' Setup the program and peripherals
' Input     : None
' Output    : None
' Notes     : None
'
Proc Setup()
    OSCCON = %01101010                                          ' Setup for internal clock at 4MHz

    Input PORTA                                                 ' Make all pins of PORTA inputs
    PinLow Chan0_LED_Pin                                        ' Extinguish the Chan0_LED pin
    PinLow Chan1_LED_Pin                                        ' Extinguish the Chan1_LED pin
    ANSELA = %00010100                                          ' Pins RA2 and RA4 are for CPS, others are digital
    WPUA = %00001001                                            ' \ Pins RA0 and RA3 have weak pull-ups on
    OPTION_REGbits_NOT_WPUEN = 0                                ' /
'
' Timer0 settings
' Overflows At 8.2mS and becomes the time base for CPS counting
'
    OPTION_REGbits_TMR0CS = 0                                   ' Counter with internal clock
    OPTION_REGbits_PSA = 0                                      ' Use prescaler
    OPTION_REGbits_PS0 = 0                                      ' \
    OPTION_REGbits_PS1 = 0                                      ' | PS 1:32
    OPTION_REGbits_PS2 = 1                                      ' /
'
' Timer1 settings
' Count CPS in single toggle mode of Gate function
'
    T1CON = %11000001                                           ' CAPOSC, PS 1:1, OSC disabled, synchronous, Timer1 On
    T1GCON = %11110001                                          ' Gate enabled, positive polarity, toggle, single, T0 input
'
' CPS settings
'
    CPSCON0 = %10001000                                         ' CPS enabled, built-in reference voltage, Medium range
    wAverage[0] = CPS_Count(0)                                  ' \ Initial setting of normal time average count
    wAverage[1] = CPS_Count(1)                                  ' /
EndProc

'------------------------------------------------------------------------------------
' Measure the count of the specified CPS channel and compare it with the average count
' Input     : pChan holds the CPS channel (0 or 1)
' Output    : None
' Notes     : If smaller than On threshold then turn on the LED
'           : If larger than the Off threshold then turn off the LED and update the average value
'
Proc CPS_Check(pChan As Byte)
    Dim wRaw As Word

    wRaw = CPS_Count(pChan)                                     ' Measure the channel count
    If wRaw < (wAverage[pChan] - wSwOn[pChan]) Then             ' If smaller than the On threshold
        LED_Out(cLED_On, pChan)                                 ' LED On

    ElseIf wRaw > (wAverage[pChan] - wSwOff[pChan]) Then        ' If greater than the Off threshold
        LED_Out(cLED_Off, pChan)                                ' LED Off
        wAverage[pChan] = wAverage[pChan] + ((wRaw - wAverage[pChan]) / 16)   ' Update average value
    EndIf
EndProc

'------------------------------------------------------------------------------------
' Measure the count of the specified CPS channel
' Input     : pChan holds the CPS channel (0 or 1)
' Output    : None
' Notes     : None
'
Proc CPS_Count(pChan As Byte), Word
    Dim wTMR1 As TMR1L.Word

    CPSCON1 = bChan_In[pChan]                                   ' CPS channel specification
    TMR0 = $FE                                                  ' Start Timer0
    wTMR1 = 0                                                   ' Clear Timer1
    T1GCONbits_T1GGO_DONE = 1                                   ' Start a measurement
    Repeat: Until T1GCONbits_T1GGO_DONE = 0                     ' Wait for the measurement to finish
    Result = wTMR1                                              ' Read Timer1
EndProc

'------------------------------------------------------------------------------------
' Turn On/Off the LED of the specified CPS channel
' Input     : pChan holds the CPS channel (0 or 1)
'           : pOnOff holds if the LED is to be turned on or off
' Output    : None
' Notes     : None
'
Proc LED_Out(pOnOff As Bit, pChan As Byte)
    If pChan = 0 Then
        Chan0_LED_Pin = pOnOff
    Else If pChan = 1 Then
        Chan1_LED_Pin = pOnOff
    EndIf
EndProc

'------------------------------------------------------------------------------------
' Setup the config fuses for an internal oscillator on a PIC12F1822 device
' OSC pins are general purpose I/O lines
'
    Config1 FOSC_INTOSC,_           ' INTOSC oscillator: I/O function on CLKIN pin
            WDTE_OFF,_              ' WDT disabled
            PWRTE_OFF,_             ' PWRT disabled
            MCLRE_OFF,_             ' MCLR/VPP pin function is digital input
            CP_OFF,_                ' Program memory code protection is disabled
            CPD_OFF,_               ' Data memory code protection is disabled
            BOREN_ON,_              ' Brown-out Reset enabled
            CLKOUTEN_OFF,_          ' CLKOUT function is disabled
            IESO_OFF,_              ' Internal/External Switchover mode is disabled
            FCMEN_OFF               ' Fail-Safe Clock Monitor is disabled

    Config2 WRT_OFF,_               ' Write protection off
            PLLEN_OFF,_             ' 4x PLL disabled
            STVREN_ON,_             ' Stack Overflow or Underflow will cause a Reset
            BORV_19,_               ' Brown-out Reset Voltage (VBOR) set to 1.9V
            LVP_OFF                 ' High-voltage on MCLR/VPP must be used for programming


Mustafa_cmbz

#6
Quote from: Yasin on Apr 14, 2024, 02:49 PMHi @Mustafa_cmbz. I have never used MCU's Capacitive touch feature. I guess you are using it for the first time. But you drew the pcb without doing any preliminary research. Check out the application notes I shared. As far as I know, only capacitive change can be detected after the mcu starts working. So with this method, if there is touch when the PCB is not powered, you cannot understand this after the MCU is working. Because there will be no capacitive change of the touched surface.

(Mcu nun Kapasitif dokunma özelliğini hiç kullanmadım. Galiba sende ilk defa kullanıyorsun. Fakat hiçbir ön araştırma yapmadan pcb çizmişsin. Paylaştığım uygulama notlarını incele. Bildiğim kadarıyla mcu çalışmaya başladıktan sonra sadece kapasitif değişim algılanabilir. Yani bu yöntemle, pcb de enerji yokken dokunma varsa, mcu çalıştıktan sonra bunu anlayamazsın. Çünkü dokunulan yüzeyin kapasitif değişimi olmayacak.)

https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ApplicationNotes/ApplicationNotes/01102a.pdf
https://ww1.microchip.com/downloads/en/Appnotes/Capacitive-Touch-Sensor-Design-Guide-DS00002934-B.pdf








I did a lot of research on PCB design and found a document with pictures like this in structure. I shaped my design based on it. But I don't know about the size, maybe there will be a problem. I will test it and see...

*********

pcb tasarım konusunda epey araştırdım ve yapı olarak bu şekilde resimlere sahip bir döküman buldum.tasarımımı bunun üzerine şekillendirdim.Fakat boyut olarak bilemiyorum belki sorun olacaktır.Onu test edip göreceğim...


@top204 Thank you very much, I will try it as soon as possible and get back to you...

Yasin

I didn't understand it from the photo above at first glance. What I said for PCB design is invalid. We are waiting for the test result.

ken_k

Quote from: Mustafa_cmbz on Apr 06, 2024, 03:06 PMHello.

I want to detect the presence of liquids using the CPS module in the internal structure of 12F1822.


Hi
My guess is the detection of liquids may somewhat depend on the liquid you are trying to detect. As the device is a capacitance detector the dielectric constant of the liquid may be of some significance.
I see water is 80, carbon tetrachloride 2.6, gasoline 2.2, transformer oil 2.4 and air is one. The device may be selective due to the type of liquid.

I wonder if there is a test instrument that reads out the dielectric constant and gives a list of possible substances.

Ken_K

david

I know it's not the same challenge but wouldn't a little Lidar module be an easier option?
I could open a beer and try it out on a mixed fluid but it should read the same regardless of dielectric constant - up to about 1m depth too!   I could really enjoy this work....

Mustafa_cmbz

@top204 hello again.

I rearranged the code you gave to have a single channel. As you said, it works in the Proteus simulation, but it does not work in real. I think it may be related to the PCB. I will test it with the other PCB and try it.






It doesn't work in reality. I started to wonder if there might be a problem with my PCB dimensions. Or should I make changes to the cps register, oscillator, etc.

trastikata

Hello,

Proteus sim is with 2.5nF cap, what is the capacitance of your plate sensor in reality? Try to measure it dry and in liquid ... I suppose it would be an order of magnitude less than what is used in the sim.

Yasin

To test the MCu code in real life, use a button with a 2.5nF capacitor and test it. If it gives the same result as the simulation, you draw a solution according to the situation.

Craig

a Lidar like the VL53L0X doesn't work well on water, especially if the surface is rippling, then there is the problem of moisture buildup on the sensor due to condensation.   

Bravo

Hi Mustafa,
How about this super cheap & easy solution. Use a touch switch module which costs about NZ $ 1.60 for 10 from AliExpress & draws micro Amps when not wet. You have to connect a 3 core cable to it & then cover it with epoxy.
The module is a TTP223 Touch Switch Sensor.
Here is the link: 
https://www.aliexpress.com/item/4000558561521.html?spm=a2g0o.order_list.order_list_main.20.21ef18021bS1o7

I am using this for boat bilge level sensors & for water levels when heavy rain happens here & builds up in front of the garage. The sensor trigger a controller which operates a bilge pump to pump the water away.
Retired RF Tech

top204

#15
That's a good idea Bravo if capacitance is the method required.

I have also used these little devices instead of buttons and they work well and are extremely inexpensive. I've also used the CTMU peripheral on some devices and it has worked well as a touch sensor, but they have to take samples every now and then, so if the atmosphere is constantly damp, the cpacitance is always going to be high, and will there be enough difference to trigger it? Even mobile phones and tablet screens sometimes fail if the atmosphere is too damp, but they have gotten better over time with very fast processors and multiple samples and constellation algorithms etc.

I have used some of the early capacitance detectors that fit on the side of a casing and measure the fluid liquid from there, but I have also use ultra-sonic and optical and Hall sensor with magnet methods. If it is always water, why not use the tried and tested method of resistance up a PCB.


Mustafa_cmbz

Quote from: Bravo on Apr 17, 2024, 08:02 AMHi Mustafa,
How about this super cheap & easy solution. Use a touch switch module which costs about NZ $ 1.60 for 10 from AliExpress & draws micro Amps when not wet. You have to connect a 3 core cable to it & then cover it with epoxy.
The module is a TTP223 Touch Switch Sensor.
Here is the link: 
https://www.aliexpress.com/item/4000558561521.html?spm=a2g0o.order_list.order_list_main.20.21ef18021bS1o7

I am using this for boat bilge level sensors & for water levels when heavy rain happens here & builds up in front of the garage. The sensor trigger a controller which operates a bilge pump to pump the water away.

We cannot use such touch button chips for this purpose due to their auto calibration functions.
The reason is this. When you buy and use this sensor, yes, it detects water, but if the power is cut off while there is water in the tank and the sensor is making contact and it is turned on again, it does the calibration accordingly at the start, since there is water, and does not see the water in the tank...

Mustafa_cmbz

Quote from: top204 on Apr 17, 2024, 09:51 AMThat's a good idea Bravo if capacitance is the method required.

I have also used these little devices instead of buttons and they work well and are extremely inexpensive. I've also used the CTMU peripheral on some devices and it has worked well as a touch sensor, but they have to take samples every now and then, so if the atmosphere is constantly damp, the cpacitance is always going to be high, and will there be enough difference to trigger it? Even mobile phones and tablet screens sometimes fail if the atmosphere is too damp, but they have gotten better over time with very fast processors and multiple samples and constellation algorithms etc.

I have used some of the early capacitance detectors that fit on the side of a casing and measure the fluid liquid from there, but I have also use ultra-sonic and optical and Hall sensor with magnet methods. If it is always water, why not use the tried and tested method of resistance up a PCB.



 

What I want to do is to detect the level of water in a plastic or glass container without touching it. I want to make exactly the same sensor as in the picture. I will write the results at the weekend. It seems like there is a problem with my PCB.