Optimising power consumption

Hi,

I've built a marble game. The aim of the game is to roll a marble from start to finish through an obstacle course as fast as possible.
The start and finish contain an infrared led + receiver.
As soon as the marble leaves the starting position, the time starts and is displayed in a 4-digit seven segment display. (3 segments for seconds, 1 for deciseconds).
The time stops as soon as the marble is at the finish.

This is powered by a rechargeable 9-volt battery.
At the moment, the game lasts about 3 hours on 1 battery charge. I would like to extend this to as long as possible (a whole day would be great).
I don't know if this is even possible, but since I don't have an electronics background, I wouldn't be surprised if I created a battery drain without even knowing it.

This is how it's connected.
White led: ir emitter 5v 220Ω
Purple led: ir receiver 5v 10KΩ
sevseg: 5v 330Ω

Please post you code. Make sure you format the code using Ctrl-T and then paste it with code tags to the forum so it is easily readable

The display consumes most of the power, and if you want that on all the time, there is not much you can do to save battery life, other than to choose a better battery power source (2x18650 would work).

You might do better if instead of feeding the 9 volts directly, where it will be wasted down to 5 volts, you instead use a buck regulator.

That regulator will produce 5 volts efficiently, which 5 volts can be put on a pin as the voltage input.

It varies for board to board or more accurately I can't say exactly which pin would be the one.

Not all day but maybe much longer run time.

Yes. There still might be a place for the buck regulator. I power small projects with 2S lipo batteries (nominal 7.4 volts) and a regulator.

a7

How long does a typical run take?

I wonder if you can shut down the start detector once a run starts, and then only power up the finish detector when the run is expected to finish. Then power this one off and restart the cycle. With this approach in mind you might also put the Arduino to sleep.

Also, depending on the physical setup, you might power the detectors intermittently just for a short moment at a time, perhaps 50% of the time. 20%? 10%? This depends on the size and speed of the marble so you don’t miss a hit.

And of course, make sure you use multiplexing and do not power all display segments simultaneously.

Back to Post #2

I was going to go through and do some back of the envelope math on how much current the LEDs, display and Nano used, relate that to a typical 9V rechargeable with ~600mAh capacity, but then I noticed something odd in the wiring diagram.

The supposed IR transmitters and receivers are only wired to power. There's no signal pin anywhere. So exactly what purpose are they serving? None that I can see, except to consume power.

Considering that, there's no point in mentioning anything else that jumps out at me about that circuit and makes me go "I wouldn't do that if I was worried about battery life".

  • This component connection diagram makes very little sense. :woozy_face:

  • Draw your complete schematic for us to see.

  • Always show us good images of your actual wiring.

  • A P cannel MOSFET HIGH side switch can power off LEDs when not needed.

  • An LCD would be a much better choice for a lower power display.

As pointed out, won't work the way you show it in your wiring diagram. Please post a link, I'm assuming they are IR phototransistors?

You can reduce power by connecting the emitters to 2x Arduino pins and switching them on for a brief moment while the Arduino reads the phototransistor pins (assuming there are any).

You also need some way for the Arduino to shut down and save power while the game is not being played. You could attach an accelerometer to detect movement of the game, and if there is no movement for a few minutes, shut down into power saving mode.

1 Like

We can speculate forever until we see the code.

I rest my case

Here is the code.

#include "SevSeg.h"
SevSeg sevseg;

bool playing = true;
bool gameCompleted = false;
int mils = 0;
int wasmils = 0;
int seconds = 0;
int idleSeconds = 0;
bool idle = false;

int startSensor = A0;
int finishSensor = A1;
int startDetectionBaseline = 0;
int finishDetectionBaseline = 0;
int detectionLimit = 40;

int startDetectionValue = 0;
int finishDetectionValue = 0;

bool atStart = false;
bool atFinish = false;

void setup() {

  byte numDigits = 4;
  byte digitPins[] = {2, 3, 4, 5};
  byte segmentPins[] = {6, 7, 8, 9, 10, 11, 12, 13};
  bool resistorsOnSegments = 1; 
  sevseg.begin(COMMON_CATHODE, numDigits, digitPins, segmentPins, resistorsOnSegments);
  sevseg.setBrightness(90);

  startDetectionBaseline = analogRead(startSensor);
  finishDetectionBaseline = analogRead(finishSensor);

}

void loop() {

  startDetectionValue = analogRead(startSensor);
  finishDetectionValue = analogRead(finishSensor);

  // No marble detected at startposition
  atStart = false;
  if(startDetectionValue > (startDetectionBaseline + detectionLimit) || startDetectionValue < (startDetectionBaseline - detectionLimit)) {
    // marble detected at start position
    atStart = true;
  }
  
  // No marble detected at finish
  atFinish = false;
  if(finishDetectionValue > (finishDetectionBaseline + detectionLimit) || finishDetectionValue < (finishDetectionBaseline - detectionLimit)) {
    // marble detected at finish
    atFinish = true;
  }

  
  if (atStart && !atFinish) {
    //marble at starting position
    seconds = 0; 
    playing = false;
    gameCompleted = false;
    idle = false;
  }


  if (!atStart && !atFinish && !gameCompleted) {
    //marble in game
    playing = true;
  }

  if (!atStart && atFinish) {
    //marble at finish
    playing = false;
    gameCompleted = true;
    idle = false;
  }

  if (atStart && atFinish) {
    //marble at start and finish?
    playing = false;
    gameCompleted = false;
    seconds = 0;
  }

  if (playing || idle) {
    gameCompleted = false;
    mils = millis();

    if ( mils - wasmils >= 100 ) { 
      seconds ++;
      wasmils = mils;
    }                                                  

    if ( seconds == 600 ) {
      seconds = 0;
      idle = true;
    }
  }

  if (!idle) {
    sevseg.setNumber(seconds,1);
  } else {
    sevseg.setNumber(00,1);
  }

  sevseg.refreshDisplay();

  if (gameCompleted && !atFinish && atStart) {
    seconds = 0; 
    gameCompleted = false;
    playing = false;
    idle = false;
  }

}

It doesn't have to be on all the time.
When idle it now shows "00".
I gues when I only show a dot this should save some power...

I assumed the arduino had some sort of regulator function to tranform the 9v input to a 5v output.

A run takes about 30 seconds.

Only powering the IR / detection periodical is a good option.
Completely shutting it down could be an option, maybe in combination with an accelerometer

I have no idea... am I doing this?

You are absolutely right... I made a mistake in the drawing.
I just updated the drawing.

You are right, without the wires to A0 and A1 this wouldn't at all

Done (except for the wires comming from the 9v battery)

Sorry, no good image available

When Idle I could shut off the finish detection there is no extra swich needed.
I could use some analog pins as digital pins for powering the IR led en sensor.

It had to be build in into a 20mm wooden slat, I didn't look for lcd's that small.

That is a good option. The arduino nano has a couple of free ports to connect a accelerometer

Yes. But it makes the difference by burning the excess as heat.

If you use a buck regulator, the difference does not get wasted.

So instead of running for four hours and slightly warming up the room, it might run for six.

a7