5
\$\begingroup\$

I'm using a low-power PIC16LF1554 together with an nRF24l01+ 2.4GHz transceiver.

During power-up, the PIC will try to initialise the RF module before the supply has reached the required minimum and will fail unless I insert a delay. Something like this

void main()
{
    // 4x PLL, 8MHz internal oscillator = 32MHz clock
    OSCCON = 0xF0;

    // wait for HFINTOSC to stabilise
    while (OSCSTATbits.HFIOFR == 0);
    while (OSCSTATbits.HFIOFS == 0);

    // configure TRIS, APFCON etc.
    // (removed for clarity)

    // **** necessary delay ****
    __delay_ms(500);

    // initialise RF transceiver
    NRF_Setup();

    // main loop
    while (1)
    {
        // ... whatever ...
    }
}

I don't quite understand why this is so because the RF has a minimum requirement of 1.9V and, according to the datasheet, the PIC requires 2.5V for the HFINTOSC to stabilise, so I thought it should be ok. (The nRF24l01+ is on a separate breakout board, which has other supporting components so maybe that affects things).

So, while this works fine and obviously the delay has no impact on the end application, I still don't like the idea of having to code an arbitrary delay and my gut feeling would be to try something a bit more deterministic. The 500ms is probably overkill and I could empirically find something shorter, but that doesn't feel like a robust approach.

So, is there some easy way to measure what the VDD is as it ramps during power-up, either in code or with external components, in the absence of a known voltage reference? Or perhaps that's not the problem I'm seeing and the delay is necessary for another reason?

EDIT In case it's relevant, these are the CONFIG settings

// CONFIG1
#pragma config FOSC = INTOSC    // Oscillator Selection Bits (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled. SWDTEN bit is ignored.)
#pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = OFF      // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable (Brown-out Reset disabled. SBOREN bit is ignored.)
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)

// CONFIG2
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config STVREN = OFF     // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), 1.9V trip point selected.)
#pragma config LPBOR = OFF      // Low-Power Brown Out Reset (Low-Power BOR is disabled)
#pragma config LVP = OFF        // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
\$\endgroup\$
3
  • \$\begingroup\$ You could capture the powerup with a scope with an appropriate trigger, do this at both the PIC and the nRF24L01 and you'll see if they rise at different rates. \$\endgroup\$
    – David
    Commented Jan 7, 2015 at 8:21
  • 2
    \$\begingroup\$ Are you sure it's the power that's causing the problem, and not a power-on delay (while it pre-configures itself) within the nRF chip itself? Is there a period after power-on where the nRF chip sets up its internal structures, configures the RF hardware, and other similar things, before it is able to accept commands? \$\endgroup\$
    – Majenko
    Commented Jan 7, 2015 at 10:29
  • \$\begingroup\$ @Majenko Well I'm not sure it's the power. There is a 100ms delay required after the nRF powers up, which I already have in my NRF_Setup function. I think I should scope it to see if I can determine what's happening. \$\endgroup\$ Commented Jan 7, 2015 at 11:04

4 Answers 4

2
\$\begingroup\$

You need to clear the PWRTE configuration bit to enable the power-up timer. With this feature, the PIC will wait with executing any code for some time determined by an RC oscillator. For your chip that means a delay of approximately 64ms. More information can be found in AN607 and in section 6.1 of the datasheet of your chip.

You can also try setting the BOREN bits to 10, enabling Brown-out reset, meaning that VDD has to reach a minimum voltage before starting code execution.

\$\endgroup\$
5
\$\begingroup\$

Did you experiment with the delay value, can it be lower?

More complex chips often have a power-up sequence during which they can't be used, like the (in)famous HD44780 LCD controller. I noticed this Tpor value in the nRF24L01+ datasheet (100 ms). I am not really sure what it specifies, but it could be interpreted as the time between the power reaching 1.8V and the chip being ready to handle commands.

enter image description here

Reading a bit further, the diagram on p22 confirms my interpretation.

enter image description here

\$\endgroup\$
1
  • \$\begingroup\$ Yes, I saw that too and I have the 100ms delay in my NRF_Setup function. I'm sure I can use less than the 500ms extra, but I'm thinking now that I should probably do a periodic initialise using a state machine in the main loop. That way, it won't matter how variable the necessary delay is. \$\endgroup\$ Commented Jan 7, 2015 at 9:30
4
\$\begingroup\$

This got a bit long for comments so just three small points.

You could capture the powerup with a scope and an appropriate trigger, do this at both the PIC and the nRF24L01 and you'll see if they rise at different rates. It could well be that extra capacitance or additional regulation make the two slopes different.

With regard to the delay in your code, I do not think it is bad if you can quantify it. You know the reason for the delay is to let the voltage settle, this should be a similar length of time at each startup. Plenty of my code has a similar delay like yours, for example to wait for a graphic LCD to initialise or for external parts to stabilise.

If you were simply inserting a delay to fix an unknown, intermittent problem it would be quite different, but that isn't the case.

However another idea is that on some PICs you can connect the Fixed Voltage Reference (FVR) to the input of the ADC - so long as you have a stable reference elsewhere (or the internal reference) you could use this to threshold an appropriate stable voltage for the RF module. I wrote a short article about this "Measuring PIC Vdd with no external components using the FVR".

From the article:

In order to calculate our unknown Vdd we need a known value to compare it against, which the Fixed Voltage Reference (FVR) module provides. Normally the FVR would supply a stable reference voltage for the ADC, but close inspection of the datasheet shows that it can also be used as an input.

You could also connect the power supply from the RF board (if the scope tests show that it varies) to an ADC channel and monitor it there.

\$\endgroup\$
4
  • \$\begingroup\$ Thanks for the comments - this PIC does have an FVR, but I only have the one supply, so I can't use that technique. I didn't consider scoping it though (d'oh) so will looksee what insight that gives. \$\endgroup\$ Commented Jan 7, 2015 at 8:40
  • 1
    \$\begingroup\$ You only need one supply to use the technique above! \$\endgroup\$
    – David
    Commented Jan 7, 2015 at 20:53
  • \$\begingroup\$ Sorry, I didn't read deeply enough! Will take another look as this seems like a really useful technique. \$\endgroup\$ Commented Jan 8, 2015 at 4:18
  • \$\begingroup\$ It's useful but careful with accuracy, you are limited by the FVR if you use the internal one. \$\endgroup\$
    – David
    Commented Jan 8, 2015 at 8:32
4
\$\begingroup\$

Why don't you consider a MAX6326 - it's a SOT23-3 pin power supplier supervisor chip that will keep the PIC in reset until the power lines have stabilized at above a certain voltage. Here are the types you can get: -

enter image description here

One of these should do the job. BTW you don't need to use it on the reset pin - you can just read the pin on any GPIO line.

\$\endgroup\$
1
  • \$\begingroup\$ Now that is a nice idea - I didn't know such devices existed (still a novice in this area), so very helpful, thanks. \$\endgroup\$ Commented Jan 7, 2015 at 8:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.