Low Power Argon Design with TINY85


#21

True… but since the intent of the B-Series in this project is be in an un-powered state 99.x % of the time, what about just powering via Vbus (recommended input voltage range is between 4.35V to 5.5V DC) ?

In that scenario, the ATTiny would switch a Regulator instead of the the EN Pin.
image

That leaves the door open for many different possibilities in battery chemistry and pack arrangements.

But it still boils down to designing/finding a replacement for the TPL5110 and 5111 with a sleep interval longer than 2 hours…the rest seems fairly easy.


#22

The “Absolute maximum ratings” just tells you that you (probably) don’t have to power VCC, but you should pay attention to the recommended voltages:

This doesn’t begin to explain why powering this pin from a Li+ connection is acceptable since they tend to be in the range of 3.2-4.2V during operation, but as usual the documentation is inconsistent or leaves out useful design information or commentary.


#23

That’s a thought, I could use 3 Energizer L91 in series to give me 4.5V but only 3.5Ah…


#24

Waking in manual mode to increase a counter and go back under every two hours, is unlikely to cost a lot of power. I bet all the 2 hour wake-sleep cycles power consumption over say 3 years combined, would not amount to many ms of establishing a 2G connection and keeping it going. Could be worth a check for the simpler TPL5111 setup.


#25

I tried that…retained memory doesn’t survive a Power Loss (EN Pin).
That would work if ya have an easy way to store the count externally.
You are correct, the power consumed during a quick wake in manual mode is extremely tiny.


#26

The EN pin is the best alternative for getting the lowest power consumption on the Boron at this time.

Instead of using a Tiny85, I use a NL17SZ74 flip-flop and a MCP79410 real-time clock.

With that, powering this circuitry gets the sleep current down to 75 uA. However, that is still higher than it should be, because there’s a weak 100K pull-up on the EN line, and you have to counteract that all of the time when powered down by EN.

Since there is no regulator or PMIC on the B Series SoM at all, you have complete control over the power supply design you can do whatever you want. I have a sample that uses a high side load switch coming off the LiPo battery. Since I don’t need the actual EN line semantics on the B Series SoM it’s driven directly off the NL17SZ74 and there’s no need for the pull-up and N-MOSFET. I haven’t tested this design yet, however.


#27

Generally not recommended, but any experience with increasing a weak pull-up value to 300k or 1M on a reset or enable line?


#28

The problem is that the pull-up is on the Boron itself. They’re so small (0201) they’re such a pain to rework I didn’t even check to see if it’s under the shield in the bottom or not.

As for the design itself, 100K is about as high as you can go reliably.


#29

Thank you so much for your contribution to the thread @rickkas7 :+1:t3:

Do you have any insight into the best way of powering the B-series using Li-SOCl2 batteries rather than LiPo… does it really need to handle 2A currents?

Also, any update on NB-IoT in the UK with Voda?


#30

So I’ve setup Particle Workbench and been messing around with Manual Mode, I was wondering if someone could take a look at my code and help optimise it please…

I did try playing around with ‘waitFor’ and ‘waitUntil’ instead of using ‘Delay’ but it seemed to block the code. I tried using System_Thread Enabled to see if that fixed anything, after reading the github DeviceOS Issues but no luck.

Description
When the “Switched Input” goes High, the Tiny85 powers on the Argon using the EN Pin and sets the DigitalOutput (Pin 3) High.

Once the Argon is enabled, it reads the state of the DigitalInput (Pin D8) connected to Pin 3 of the Tiny85.

If Pin D8 is High and the Argon hasn’t published an alarm, the Argon connects to the Particle Cloud and publishes an “Alarm” message, disconnects from the Particle Cloud, and sets the ‘alarm_sent’ True.

If Pin D8 goes Low after the alarm message has been published, it then reconnects to the Particle Cloud and publishes an “OK Clear” message, disconnects from the Particle Cloud, and sets the ‘alarm_cleared’ True.

If Pin D8 is Low and the “OK Clear” message has been published, it sets the DigitalOutput (Pin D6) High, which is connected to the DigitalInput (Pin 0) of the Tiny85, powering off the Argon.

Else if, Pin D8 is Low and an alarm message hasn’t been published to the Particle Cloud, set Pin D6 High to power off the Argon.

Argon Code

SYSTEM_MODE(MANUAL);

const int Tiny85_DigitalOut = D8; 
const int Argon_PWR_OFF = D6;  

bool alarm_sent = false;            
bool alarm_cleared = false;        

// setup() runs once, when the device is first turned on.
void setup() {
pinMode(Tiny85_DigitalOut, INPUT);                                       
digitalWrite(Tiny85_DigitalOut, LOW);
pinMode(Argon_PWR_OFF, OUTPUT);
digitalWrite(Argon_PWR_OFF, LOW);
}

// loop() runs over and over again, as quickly as it can execute.
void loop(){

delay(5000);

int Tiny85_Alarm = digitalRead(Tiny85_DigitalOut); 

if (Tiny85_Alarm == HIGH && alarm_sent == false) {                   
  Particle.connect();                                             
}                                                                   

if (Particle.connected()) {
    Particle.process();
    Particle.publish("ALARM", PRIVATE);
    Particle.disconnect();
    alarm_sent = !false;
  }

if (Tiny85_Alarm == LOW && alarm_sent == !false) {
    Particle.connect();
    delay(10000);
    Particle.process();
    Particle.publish("OK Clear", PRIVATE);
    delay(5000);
    Particle.disconnect();
    alarm_cleared = !false;
}

if (Tiny85_Alarm == LOW && alarm_cleared == !false) {
    digitalWrite(Argon_PWR_OFF, HIGH);
}

else {
  if (Tiny85_Alarm == LOW && alarm_sent == false) {
    digitalWrite(Argon_PWR_OFF, HIGH);
    }
  }
}

#31

One thing I would do with this is convert it to a Finite State Machine (FSM). That way you avoid using delay() or wait…() functions.


#32

Thanks @picsil I’ll look into Finite State Machines tomorrow, hopefully it won’t be too difficult to implement.


#33

It shouldn’t be. Search on this forum and you’ll find lots of great examples. Essentially you divide your application into a few finite “known” states. For example, idle, connecting, updating, error. Whatever makes sense to your application.The application only executes the code for the particular state it is currently in. Code in the state routines determine when to switch states, and to what state to switch to.

Code examples on this board will likely be more helpful than my description. :slight_smile:


#34

On a related note, your post got me to thinking about the possibility of using an ATtiny85 alongside the Boron my product. It actually costs as much or less than the external watchdog timer I’m using now and could perform that function and more.


#35

@Alph, below is the basis of the Manual Code I’ve used for Borons in the past . For projects when I use the TPL5111, the System.sleep call is replaced with pulling the TPL’s “Done” Pin Low (in your case, the ATTiny). The Basic concept is the Boron makes (1) trip through Loop() each time it’s awake and then goes to sleep or is shutdown via EN Pin. The emphasis is to preserve Battery Life when something goes wrong.

SYSTEM_MODE(MANUAL);
SYSTEM_THREAD(ENABLED);

int sleepTime =         1 * 60    ;     // (# Minutes * 60 seconds)
int connectionFail =    5 * 60000 ;     // (# Minutes * 60,000 ms ) During the Connection Process, Boron will "Give-Up" after this amount of time and Sleep if un-successful.

inline void softDelay(uint32_t t) {
  for (uint32_t ms = millis(); millis() - ms < t; Particle.process());  //  safer than a delay()
}

void setup()  {
}

void loop()   {
  softDelay(2000);
  
  if ( !Particle.connected() ) {
    Cellular.on();
    softDelay(2000);
    Particle.connect();
    softDelay(2000);   
  }

  //  Limit the time spent for the Connection attempt to preserve Battery
  if (waitFor(Particle.connected, connectionFail)) {    // Will continue once connected, or bail-out after "connectionFail" time-limit
    softDelay(5000);
    Particle.publish("DeBug", "Boron Awake", PRIVATE, NO_ACK);
    softDelay(5000);
  }

  // Either the Publish was performed, or the Boron could not connect.  Either way, go to Sleep.
  goToSleep();  

} // End LOOP()

void goToSleep() {
  // Step through the process safely to ensure the lowest Modem Power.    
  Particle.disconnect();
  softDelay(2000);
  Cellular.off();
  softDelay(3000);  
  System.sleep( {}, {}, (sleepTime) );  //
  softDelay(5000);
  // System.reset();
}

Obviously you cant test this exact code on an Argon (Cellular.on/.off) , but I thought I’d share since you mentioned the Boron is your eventual target device.


#36

Hi, I’m leaving this link here in case it helps. If you get confused, post your questions and I’ll try to help!
I do 95% of my projects with FSMs these days, and I find them very very convenient.
Cheers
Gustavo.


#37

You don’t need the transistor to control the EN pin.
Just toggle the AVR pin between Input (so the pin can float high) and Output LOW.

In the next few weeks ill be working on a firmware for the ATTINY45.
For my project I want the TINY to handle RTC, Particle EN and communicate with I2C.

Check out my Github here:


#38

Thanks @jack4566

I was under the impression though, leaving the pin floating High would consume more power by the Tiny85?

I’ve read a few articles on low power arduinos, and they all say; set all the pins low even if not used.

P.s. I’m away on holiday and not had chance to reply to everyone else properly yet! When I get back I’ll start messing around again. Just like to say a big thank you to everyone who’s contributed to the topic so far :+1:t2:


#39

Your talking about ~200nA per pin when floating vs grounded. Your transistors will have more than that in quiescent current.
Plus the pin isn’t actually floating the boron/Argon will pull it high.