I am very inexperience in regards to coding (I'm learning...very slowly) so please forgive my ignorance. I'm trying to run a single servo with an ATTiny85 using the SoftwareServo library for a solar panel solar tracker system.
The sketch compiles and it seems to upload to the ATTiny (using an UNO as ISP) but the servo is completely unresponsive. I have verified that the servo works.
Here's the code:
#include <SoftwareServo.h>
SoftwareServo tracker; // create servo object to control a servo
int eastLDRPin = 3; //Assign analogue pins
int westLDRPin = 4;
int eastLDR = 0; //Create variables for the east and west sensor values
int westLDR = 0;
int error = 0;
int calibration = 204; //Calibration offset to set error to zero when both sensors receive an equal amount of light
int trackerPos = 90; //Create a variable to store the servo position
void setup()
{
tracker.attach(0); // attaches the servo on pin 11 to the servo object
}
void loop()
{
eastLDR = calibration + analogRead(eastLDRPin); //Read the value of each of the east and west sensors
westLDR = analogRead(westLDRPin);
if(eastLDR<350 && westLDR<350) //Check if both sensors detect very little light, night time
{
while(trackerPos<=160) //Move the tracker all the way back to face east for sunrise
{
trackerPos++;
tracker.write(trackerPos);
delay(100);
}
}
error = eastLDR - westLDR; //Determine the difference between the two sensors.
if(error>15) //If the error is positive and greater than 15 then move the tracker in the east direction
{
if(trackerPos<=160) //Check that the tracker is not at the end of its limit in the east direction
{
trackerPos++;
tracker.write(trackerPos); //Move the tracker to the east
}
}
else if(error<-15) //If the error is negative and less than -15 then move the tracker in the west direction
{
if(trackerPos>20) //Check that the tracker is not at the end of its limit in the west direction
{
trackerPos--;
tracker.write(trackerPos); //Move the tracker to the west
}
}
delay(100);
}
I connected everything as shown/described in this super jankey photo/diagram (haha):
static void refresh(); // must be called at least every 50ms or so to keep servo alive. you can call more often, it won't happen more than once every 20ms
See the example.
And you need to get rid of any delay() calls. Like the .h files says, refresh needs to called at least every 50msec.
#include <SoftwareServo.h>
SoftwareServo tracker; // create servo object to control a servo
int eastLDRPin = 3; //Assign analogue pins
int westLDRPin = 4;
int eastLDR = 0; //Create variables for the east and west sensor values
int westLDR = 0;
int error = 0;
int calibration = 204; //Calibration offset to set error to zero when both sensors receive an equal amount of light
int trackerPos = 90; //Create a variable to store the servo position
void setup()
{
tracker.attach(0); // attaches the servo on pin 11 to the servo object
}
void loop()
{
// added non blocking timing so that the samples are taken at 10Hz
// but the refresh call is done every time through loop()
static unsigned long timer = 0;
unsigned long interval = 100;
if (millis() - timer >= interval)
{
timer = millis();
eastLDR = calibration + analogRead(eastLDRPin); //Read the value of each of the east and west sensors
westLDR = analogRead(westLDRPin);
if (eastLDR < 350 && westLDR < 350) //Check if both sensors detect very little light, night time
{
while (trackerPos <= 160) //Move the tracker all the way back to face east for sunrise
{
trackerPos++;
tracker.write(trackerPos);
}
}
error = eastLDR - westLDR; //Determine the difference between the two sensors.
if (error > 15) //If the error is positive and greater than 15 then move the tracker in the east direction
{
if (trackerPos <= 160) //Check that the tracker is not at the end of its limit in the east direction
{
trackerPos++;
tracker.write(trackerPos); //Move the tracker to the east
}
}
else if (error < -15) //If the error is negative and less than -15 then move the tracker in the west direction
{
if (trackerPos > 20) //Check that the tracker is not at the end of its limit in the west direction
{
trackerPos--;
tracker.write(trackerPos); //Move the tracker to the west
}
}
}
SoftwareServo::refresh(); //****** added in the refresh function ********
}
Not sure how much help these photos will be since they're so awful but here they are;
It's impossible to see from the orientation of the photo below but the white wire runs to one terminal on each of the LDR's and the yellow and orange wires connected to the green breadboard are each going to the other terminals of their respective LDR's:
Connetions to servo wires There is a wire connected to physical pin #4 that run to the 5V on an Arduino and a wire on connected to physical pin #8 that is connected to the same Arduino's GRND:
groundFungus:
I modified your code to get rid of delay()s and inserted the refresh call. Here are some tutorials on how to use millis() (and micros()) for timing.
SoftwareServo tracker; // create servo object to control a servo
int eastLDRPin = 3; //Assign analogue pins
int westLDRPin = 4;
int eastLDR = 0; //Create variables for the east and west sensor values
int westLDR = 0;
int error = 0;
int calibration = 204; //Calibration offset to set error to zero when both sensors receive an equal amount of light
int trackerPos = 90; //Create a variable to store the servo position
void setup()
{
tracker.attach(0); // attaches the servo on pin 11 to the servo object
}
void loop()
{
// added non blocking timing so that the samples are taken at 10Hz
// but the refresh call is done every time through loop()
static unsigned long timer = 0;
unsigned long interval = 100;
if (millis() - timer >= interval)
{
timer = millis();
eastLDR = calibration + analogRead(eastLDRPin); //Read the value of each of the east and west sensors
westLDR = analogRead(westLDRPin);
if (eastLDR < 350 && westLDR < 350) //Check if both sensors detect very little light, night time
{
while (trackerPos <= 160) //Move the tracker all the way back to face east for sunrise
{
trackerPos++;
tracker.write(trackerPos);
}
}
error = eastLDR - westLDR; //Determine the difference between the two sensors.
if (error > 15) //If the error is positive and greater than 15 then move the tracker in the east direction
{
if (trackerPos <= 160) //Check that the tracker is not at the end of its limit in the east direction
{
trackerPos++;
tracker.write(trackerPos); //Move the tracker to the east
}
}
else if (error < -15) //If the error is negative and less than -15 then move the tracker in the west direction
{
if (trackerPos > 20) //Check that the tracker is not at the end of its limit in the west direction
{
trackerPos--;
tracker.write(trackerPos); //Move the tracker to the west
}
}
}
SoftwareServo::refresh(); //****** added in the refresh function ********
}
groundFungus, you're awesome-the servo's moving!
...not as it should, however. Here's a link to a video of what happens when it gets plugged in:
A 4xAA battery pack works great with a servo. Sharing power with the Arduino, or expecting the 5V Arduino output to power a servo always leads to problems, including destruction of the Arduino, in the long run.