Thursday, June 20, 2024

0000 0000 1110 1001

The third impossible thing (first)

I have an idea to move the candle project from a AA NiMH rechargeable battery to a supercapacitor. There are issues!

In previous incarnations of this dream/nightmare  (one and two) I failed due to not being able to drive the candle for more than a few hours overnight - and charging was an issue. The QX5252 outputs 1.3V and the supercap I'm experimenting with is rated 3.8V.

So I've set myself three impossible things to solve for this project to be supercap based:

a) "Boost" the voltage output of the QX5252 to match the supercap
b) Figure out a way to extend the overnight life of the candle
c) Work out some way of making the PFS154 (missing an ADC) pretend it's got an ADC and can therefore react to voltage changes (ideally via interrupts)

Working backwards on these issues (why not?) I have been torturing a PFS154 on the breadboard, trying out a weird internal comparator feeding an interrupt signal to turn on...why an LED of course!

Enjoy the journey - next in line is the second impossible thing - extending the life of the supercap for overnight light.

Late Mail! Due to an online suggestion via the comments section underneath the video below, here is the updated code which is working well! Thank you to @ivolol


/*
    "Alice laughed: "There's no use trying," she said; "one can't believe
    impossible things." "I daresay you haven't had much practice," said the Queen.
    "When I was younger, I always did it for half an hour a day. Why, sometimes
    I've believed as many as six impossible things before breakfast."
                                                                    Lewis Carroll

    This particular impossible thing is a PFS154 sleeping "stopsys()" and being
    woken up by the comparator which is using PA3 as the negative input and the
    internal reference voltage as the positive input.

    Also impossible?
    F_CPU = 10000 (that's Hz!)

  PFS154 pinout
                      +-\/-+
                VDD  1|    |8  GND
             PA7/X1  2|    |7  PA0/AD10/CO/INT0/PG0PWM
             PA6/X2  3|    |6  PA4/AD9/CIN+/CIN1-/INT1/PG1PWM
   PA5/PRSTB/PG2PWM  4|    |5  PA3/AD8/CIN0-/TM2PWM/PG2PWM
                      +----+

  Mon 03 Jun 2024 22:05:27 AEST

  https://www.youtube.com/c/onecircuit-as
  https://onecircuit.blogspot.com/

*/

#include "../device.h"
#include "../easy-pdk/calibrate.h"
#include "../auto_sysclock.h"
#include "../delay.h"
#include <stdbool.h>

bool sunshine = false; // is the sun shining?

// interrupt triggered when the sun goes away, voltage of small
// capacitor is drained
void Interrupt(void) {

  __disgint();                // disable global interrupts
  INTEN = 0;                  // disable all interrupts
  INTRQ = 0;
  sunshine = false;
  __engint();   // enable global interrupts
}

// compares the cap voltage with the internal voltage
bool checksolar(void)
{
  uint8_t compresult = 0; // initially a byte
  compresult = GPCC & 0b01000000; // mask the result output
  compresult = compresult >> 6;   // shift it to the least significant bit
  sunshine = (bool)compresult;    // cast result as a boolean

  return sunshine;
}

// this is where the candle code will go - for now, turn on LED
void candlingon() {
  PAC = 0b00010000;
  PA = 0b00010000;
}

// here is where the uC goes to sleep
void sleepnow() {

  __disgint();  // disable global interrupts

  PA = 0b00000000; // turn off LED

  MISC |= MISC_FAST_WAKEUP_ENABLE;  // fast wakeup

  INTEN = 0b00010000;  // enable comparator interrupt
  INTRQ = 0b00010000; 

  __engint();   // enable global interrupts
  __stopsys();  // go to sleep
}

void main() {

  // PA4 is output, all GPIOs low
  PAC = 0b00010000;
  PA = 0b00000000;


  // page 66 datasheet
  GPCC = 0b10000000;
  // bit 7 enable comparator
  // bit 6 plus input < minus input
  // bit 5 result output NOT sampled by TM2_CLK
  // bit 4 polarity is NOT inversed
  // bit 3-1 000 : PA3 selected as -ve input
  // bit 0 internal voltage set as +ve input

  GPCS = 0b10000110;
  // bit 7 output to PA0 disabled
  // bit 6 reserved
  // bit 5 high range selected
  // bit 4 low range selected
  // bit 3-0 Selection the internal reference voltage level of comparator 
  // 0000 (lowest) ~ 1111 (highest) as a fraction of vdd

  _delay_ms(20);  // small settle time delay


  while (1) {

    _delay_ms(200);  // small loop delay
    sunshine = (bool)checksolar(); // check the sunshine

    if (!sunshine) {
      candlingon();  // it's dark, start candling action
    }
    else
    {
      sleepnow();    // it's light, go to sleep
    }
  }
}

// Startup code - Setup/calibrate system clock
unsigned char _sdcc_external_startup(void) {

  AUTO_INIT_SYSCLOCK();
  AUTO_CALIBRATE_SYSCLOCK(TARGET_VDD_MV);

  return 0;
}



No comments:

Post a Comment