Assistance with Narcoleptic Sleep Code

New Arduino hobbyist here with no prior programming experience. After reading up on the use of the Narcoleptic library and implementing it, I haven't gotten energy savings (based on rough estimates). I expected dramatic results but haven't gotten any to speak of. To briefly describe my project, I am creating a solar powered Arduino Uno controlled chicken coop door that opens in the morning and closes at night. The problem I'm having is that the Arduino eats about 25-30% of my 6000 Mah Lipo battery over night, and my solar panel can't recharge that much in one day of direct sunlight so I turned to Narcoleptic to sleep the board for 8000 ms at a time. I expected this to save a ton of power, but the next morning the board had eaten 25+% again. Can someone look at my code (keeping in mind that I'm at that beginner stage where I'm grabbing code snippets from the web and plugging them in).

#include <Servo.h>
#include <Narcoleptic.h>

Servo servo1;

int photocellPin = 0; // select the input pin for the sensor resistor
int servoPin = 9;
int pos = 0;


void setup() 
{
  // Serial.begin(9600); // open the serial port to send data back to the computer, OFF
  servo1.attach(9); 
}

void loop() 
{
  
// Serial.print("Light = "); // for testing purposes only
// Serial.println(analogRead(photocellPin)); // for testing purposes only
  
  pos = analogRead(photocellPin);
  pos = constrain (pos, 515, 875);
  
  int servoPos = map(pos, 515, 875, 255, 0);
  int servoDegree = map(servoPos, 255, 0, 0, 179);

 // Serial.print("Servo Degree =  "); // for testing purposes only
 // Serial.println(servoDegree); // for testing purposes only
  
  if (pos <600) {
  
  servo1.write(servoDegree); // rotate servo at dark
  delay(17000); // duration of rotation
  }
  
   if (pos >750) {
  
  servo1.write(servoDegree); // rotate servo depending on light level
  delay(17000); // duration of rotation
   }
   
   else {
  servo1.write(90); // stop and hold servo
  
  // Serial.print("Taking a nap "); 
  Narcoleptic.delay(8000); // 8 seconds sleepy delay
  }

  // Serial.print("Servo Degree = "); // for testing purposes only
  // Serial.println(servoDegree); // for testing purposes only
}

I have another problem to solve in the code above which I'll be working on while waiting for feedback.

The library i just downloaded was flimsy, try here;

Sleep.h is the library you really want to use.

What is your servo's idle current? What is your photocell current?
I am using narcoleptic delay with a TFT display and BMP085 baro, the idle current in Narcoleptic.delay(8000) is 204uA.
The servo's idle current could be 20-50mA. Try to "detach" the servo before entering sleep..

servo1.detach(9); // detaches the servo on pin 9

Most probably it will not decrease the servo's idle current, however.. You can switch off the servo fully with a high-side PNP transistor switch during the sleep.

Hi,

Need help in a solar charge controller project

I've constructed a solar charge controller using an induino board using Atmega 328. Here the problem is when the voltage is supplies from and auxiliary source such as laptop USB, the setup runs. But when I use the same battery which i'm sensing for powering the board, the board goes haywire and all LEd's blink.

The code is as follows.

#define voltage_in 0
#define voltage_out 1

#define LED1 12
#define LED2 10
#define charge_enable 11

int x;
int y;

int chon = 5000; // charge on time
int choff = 2000; // charge off time

int CP = 368; // charge point variable
// CP sets the battery charge voltage level. Can vary from 346 - 410.
void setup() {

pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(charge_enable, OUTPUT);

digitalWrite(LED1, LOW);
digitalWrite(LED2, LOW);
digitalWrite(charge_enable, LOW);

}

void loop() {

x = analogRead(voltage_in); // voltage from solar panel
//under CP on ADC indicates not enough voltage to charge battery
y = analogRead(voltage_out); // voltage on battery to be charged
// over or equal to CP on ADC indicates fully charged battery

if (x < CP) digitalWrite(LED1, HIGH);
else digitalWrite(LED1, LOW);
// LED off indicates good input voltage

if (y > CP) digitalWrite(LED2, HIGH);
else if (y <= CP) digitalWrite(LED2, LOW);
// LED on means battery is charged

if ((x > y) & (y < CP) & (x > CP)) { // check input voltage and voltage on battery
// turn on charge cycle if voltage input good AND battery voltage low.

digitalWrite(charge_enable, HIGH); // turn on voltage to battery
chon = (CP - y) * 1000;
delay(chon); // ON wait
digitalWrite(charge_enable, LOW); // turn off charge enable
delay(choff); // OFF wait
} // end if
}

Arduino board.docx (25.9 KB)

Hijacking another persons post is just rude. Post a new thread & learn to use code tags btw pmadithya.

Also you may add hysteresis in your measurement loop to avoid too frequent servo activity. You may use much longer narcoleptic delay for your application - few minutes would be ok for your chicks, I think.. :slight_smile:

JB- I'll give that library a try and see what happens. Thanks.

pito- according to http://www.jameco.com/Jameco/Products/ProdDS/283039.pdf, the servo draws 15ma in a static state. I'll try detaching before sleep, and look into the "high-side PNP transistor" you mentioned.

From what I've read the Arduino Uno can be pretty power hungry so I'm hoping to save by sleeping it as long as possible. I've read that you can sleep for longer durations than 8000 milliseconds (although I haven't tried to yet) which would serve my purposes since I really only need the loop to run twice a day not every 8 seconds.

-RC

JB-

I've looked around and can't find the avr/sleep library. Didn't see the library available for download on Nick Gammons tutorial, and google wasn't coming up with a Sleep library. Ideas? Should I throw the sleep.h source code into a text file and rename it sleep.h then put that in my library directory? I'm new to all this so bear with me...

Thanks, -RC

C:\Users\pjs9486\Documents\arduino-1.0.5\hardware\tools\avr\avr\include<mark>avr\sleep.h exists on my computer.

Thanks Paul

pito-

I looked up that PNP transistor and if I understand it right the idea is to send an 'on' signal using one of the Arduino pins which would trigger the transistor (via the base) to close the circuit and start the current flow to the servo. Then turn the signal off before sleep. Is that what you had in mind?