2020/11/22 17:48:19
Ghufran
Hello All!



I am fairly new to programming in C, and have been mainly learning from online forums and videos. I have a PIC16LF15325 that I am programming with XC8 compiler and MCC to setup the header and C files. I have a pin configured as GPIO that is controlling the LED status. I am wanting the PIC to go into constant sleep mode unless an input from the ADC reaches a certain threshold voltage that would then wake the PIC from sleep and indicate that it is awake by turning the LED on, and indicate that it is back to sleep by turning the LED off. So far, I know that it goes into sleep mode because I am measuring the current to be much lower than when it is awake, so I know that the system clock is turned off. But the LED would not turn on once I adjust the ADC input to go over the threshold value that I have specified in the code.







[/code]
#include "mcc_generated_files/mcc.h"

/*
Main application
*/
void main(void)
{
// initialize the device
SYSTEM_Initialize();
int result;
while (1)
{
// Enable the Global Interrupts
INTERRUPT_GlobalInterruptEnable();

// Enable the Peripheral Interrupts
INTERRUPT_PeripheralInterruptEnable();
PIR1bits.ADIF = 0;
SLEEP();
__delay_us(20); // wait for acquisition time. *check acquisition time for ADC in data sheet
ADCON0bits.GOnDONE = 1; // start the conversion
result = (ADRESH<<8) +ADRESL; // combine the 10 bits of the conversion with 8bits stored in the ADRESH
if(PIR1bits.ADIF == 1)
if (result >60) // (ADIF =1) ADIF will be automatically set at the end of each ADC conversion
PORTCbits.RC0 =1; //turn led on
else
PORTCbits.RC0 =0; //turn it off

}


}
[/code]


Any help or guidance would be much appreciated!
2020/11/23 08:55:34
katela

#include "mcc_generated_files/mcc.h"

/*
Main application
*/
void main(void)
{
// initialize the device
SYSTEM_Initialize();
int result;
while (1)
{
// Enable the Global Interrupts
INTERRUPT_GlobalInterruptEnable();

// Enable the Peripheral Interrupts
INTERRUPT_PeripheralInterruptEnable();
PIR1bits.ADIF = 0;
SLEEP();
__delay_us(20); // wait for acquisition time. *check acquisition time for ADC in data sheet
ADCON0bits.GOnDONE = 1; // start the conversion
result = (ADRESH<<8) +ADRESL; // combine the 10 bits of the conversion with 8bits stored in the ADRESH
if(PIR1bits.ADIF == 1)
if (result >60) // (ADIF =1) ADIF will be automatically set at the end of each ADC conversion
PORTCbits.RC0 =1; //turn led on
else
PORTCbits.RC0 =0; //turn it off

}
}

 
Note: Don't start with a closing code tag: [/code].  Only at the end.
2020/11/23 09:55:57
Mysil
Hi,
Code shown in message #1 seem like a mixup with some MCC generated code,
so there are a lot of details that are not shown.
 
There is no need to enable Global  interrupts in order to wake up from sleep when ADC conversion is complete.
Device Interrupt from the ADC module must be Enabled in order to wake up.
 
Do Not go to sleep before the acquisitiion delay,
there is no way for __delay_us(20); to wake the processor from Sleep mode,
so it will sleep until some other event wake up the processor, or it is Reset.
 
Go to SLEEP()  after the Start Conversion bit have been Set:
    ADIF = 0;        /* Make sure ADC Interrupt flag from previous conversion have been cleared. */
    ADIE = 1;        /* Make sure that ADC interrupt is enabled. */
    __delay_us(20); // wait for acquisition time.
    ADCON0bits.GOnDONE = 1; // start the conversion
    SLEEP();

 
You cannot perform calculations, or test results while the processor is in Sleep mode.
The device have to wake up after ADC conversion is done,
to test result and light the LED.
 
If you want some time to sleep between measurements,
then it is possible to arrange another sleep with Watchdog timer,
or another timer clocked from LPRC, to wake the device.
 
    Mysil
2020/11/23 10:29:20
crosland
If you want to wake from sleep from an ADC result you need a PIC with the ADC2 peripheral which can interrupt on threshold comparison.
2020/11/23 11:45:47
mpgmike
...or you could use the Comparator Interrupt and set the DAC to your threshold.
2020/11/23 13:10:43
PStechPaul
I made similar suggestions in my response to a duplicate post: https://www.microchip.com/forums/m1158593.aspx#1158652
 
The OP should rename the duplicate posts to something like "Ignore-Duplicate" to keep discussion in one thread.
2020/11/23 13:11:31
davea
what is the MAX delay you can tolerate (from wake voltage to actual sleep exit) 
will define the best way to to get it done
using WDT .5ua 
using CMP and DAC  2ua+
ADC2 peripheral 
 
2020/11/23 13:34:17
dan1138
@Ghufran,

What your code fragment seems to be trying to do is to wake the controller after the ADC has made a conversion of a specific value. The ADC in the PIC16F15325 does not work this way.

It seems possible to use the comparator in the PIC16F15325 to wake from sleep bit it's complicated.

Setting a specific threshold for the comparator tip point use the DAC and connect it to the comparator positive input.

Connect the comparator negative input to your analog signal source.

The comparator module is clocked from the same source as TIMER1 so select a source for TIMER1 that will run during sleep.

The attached MCC generated project uses the LFINTOSC as the TIMER1 clock source and enabled the timer to count.

This project uses AN1(RA1) as the analog signal input.

I have no way to test this but it may work for you.

Things to watch out for:

Verify that TIMER1 actually runs in sleep mode before trying to debug the action of the comparator.

Verify the comparator and DAC can set the voltage trip point you need before trying to debug sleep mode behavior.

Verify the ADC does a correct conversion before trying to debug sleep mode behavior.

The comparator uses the negative input for the analog signal. This means the when the analog input voltage is lower that the voltage set by the DAC the comparator output will be high. When the analog input voltage transitions from below to above the voltage set by the DAC the comparator output will switch from high to low.


Attached Image(s)

2020/11/25 09:29:55
Ghufran
I can not thank you enough! It worked!!! I’m so happy right now.
2020/11/25 09:32:43
Ghufran
I’m sorry for the duplicate posts, I thought that my posts weren’t getting approved due to some issue with my phrasing of the question so I made several with different titles. I appreciate all the responses and help from all of you, I was stuck with this problem for a long time. I finally rearranged my code the way the user “Mysil” suggested and that solved the problem! :) thanks again.
© 2021 APG vNext Commercial Version 4.5

Use My Existing Forum Account