Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
Sorry I haven't been on here in forever. Having a baby along with other hobbies and projects have kinda pushed the tank to the back burner. Plus my t5 fell in the tank a few months ago causing a slow crash. So I'm about to tear it down and start fresh. But, to answer the question, yes the servo is still running. You can definitely tell that it's wearing out because its no longer a smooth sweep all the time, there are some dead spots for sure. But it's been running 24/7 for the past 977 days straight with no real issues, assuming a sweep takes 15 seconds that's over 5.5 million sweeps, which I'd say is pretty great. I honestly didn't think the servo would last a year.Any updates on how well the servo's are performing? I search the web and found some Heavy Duty/waterproof; would they work?
What board did you use?Congratulations!!!
I did some research and found another board that can be used for this purpose and build my own. So far they been running close to a year but depending on pump speed they can be a little noisy. One of the servos bottom shaft is faulty (not the same as listed here). I’m in the process of replacing them but this time I’m going to place them with gear down.
Nope. Just Amazon availabilityAny details on why you have selected this specific servo? What makes this one special over others?
Thanks!
I ordered the below servo - the waterproof sold me. Will it work?
ANNIMOS 20KG RC Servo Digital High Torque Full Metal Gear Waterproof,180° Control Angle
I also have a bracket I bought online that is purpose built for DIY sea sweeps and takes the Futaba servo's - https://neo3plus.com/en/accessoires/203-osmolateur-digiosmo.html
I'm actually in Australia, but just bought in online.Is this sold by anyone in the US?
/* Need to do the following
* Need to store setpoint[1] & setpoint[2] and sweep_array[sweep_delay] values in EEPROM in case of power outage
* and read them back on boot
*/
#include <Servo.h>
//#include <EEPROM.h>
// define pins to be used
#define ENC_SW_PIN 2
#define SERVO_PIN 3
#define ENC_DATA_PIN 4
#define ENC_CLK_PIN 5
#define LEFT_LED 6
#define RIGHT_LED 7
#define LED_1 8
#define LED_2 9
#define LED_3 10
#define LED_4 11
#define SW_ROT1 22
#define SW_ROT2 24
#define SW_ROT3 26
#define SW_ROT4 28
//define variables
#define INCREMENT 1
#define SWEEP_INCREMENT 10
#define SERVO_INTERVAL 5 //ms between servo steps
#define MIN_ANGLE 5
#define MAX_ANGLE 175
#define MIN_SWEEP 50
#define MAX_SWEEP 500
byte sweep_delay;
byte enc_clk, enc_clk_old;
byte enc_switch, enc_switch_old;
byte pointer; // pointer to setpoint[pointer]
int angle = (MIN_ANGLE + MAX_ANGLE) / 2;
int setpoint[2] = {angle, angle + 10}; //startup angles
int sweep_array[1] = {sweep_delay};
unsigned long timeforservo;
Servo servo;
void setup() {
pinMode (ENC_CLK_PIN,INPUT_PULLUP);
pinMode (ENC_DATA_PIN,INPUT_PULLUP);
pinMode (ENC_SW_PIN,INPUT_PULLUP);
pinMode (LEFT_LED, OUTPUT);
pinMode (RIGHT_LED, OUTPUT);
pinMode (SW_ROT1,INPUT_PULLUP);
pinMode (SW_ROT2,INPUT_PULLUP);
pinMode (SW_ROT3,INPUT_PULLUP);
pinMode (SW_ROT4,INPUT_PULLUP);
pinMode (LED_1,OUTPUT);
pinMode (LED_2,OUTPUT);
pinMode (LED_3,OUTPUT);
pinMode (LED_4,OUTPUT);
servo.attach(SERVO_PIN);
Serial.begin (9600);
enc_clk_old = digitalRead(ENC_CLK_PIN);
enc_switch_old = digitalRead(ENC_SW_PIN);
sweep_array[sweep_delay] = 50;
}
void loop() {
digitalRead (SW_ROT1);
digitalRead (SW_ROT2);
digitalRead (SW_ROT3);
digitalRead (SW_ROT4);
// THIS IS USED TO SET MIN AND MAX IN SETUP MODE
if (digitalRead (SW_ROT1) == 0) {
// Serial.println ("Setup Mode selected");
digitalRead (SW_ROT1);
digitalWrite (LED_1, HIGH);
digitalWrite (LED_2, LOW);
digitalWrite (LED_3, LOW);
digitalWrite (LED_4, LOW);
enc_switch = digitalRead(ENC_SW_PIN);
if((enc_switch == 0) && (enc_switch_old == 1)) { // 1->0 transition detected
pointer = (pointer + 1) % 2; // change servo setpoint
Serial.print("SETPOINT is ");
Serial.print(angle);
Serial.print(", Min Angle is currently ");
Serial.print(setpoint[0]);
Serial.print(", Max Angle is currently ");
Serial.println(setpoint[1]);
delay(50);
if (angle < setpoint[pointer]) {
digitalWrite (LEFT_LED, HIGH);
digitalWrite (RIGHT_LED, LOW);
} else {
digitalWrite (LEFT_LED, LOW);
digitalWrite (RIGHT_LED, HIGH);
}
}
enc_switch_old = enc_switch;
// READ ROTARY AND MODIFY SERVO SETPOINT MIN, MAX
enc_clk = digitalRead(ENC_CLK_PIN);
if((enc_clk == 1) && (enc_clk_old == 0)) { // 0->1 transition
if(digitalRead(ENC_DATA_PIN) == 1) {
setpoint[pointer] = setpoint[pointer] + INCREMENT;
} else {
setpoint[pointer] = setpoint[pointer] - INCREMENT;
}
if((setpoint[pointer] > MAX_ANGLE) && (angle > setpoint [0])) setpoint[pointer] = MAX_ANGLE;
if(setpoint[pointer] < MIN_ANGLE) setpoint[pointer] = MIN_ANGLE;
Serial.println(angle);
delay(10);
}
enc_clk_old = enc_clk;
// ROTATE SERVO
if (millis() > timeforservo) {
timeforservo = millis() + SERVO_INTERVAL;
if (angle < setpoint[pointer]) {
angle++;
}
if (angle > setpoint[pointer]) {
angle--;
}
servo.write(angle);
}
}
// THIS IS USED TO MOVE SERVO MANUALLY
if (digitalRead (SW_ROT2) ==0) {
digitalRead (SW_ROT2);
digitalWrite (LED_1, LOW);
digitalWrite (LED_2, HIGH);
digitalWrite (LED_3, LOW);
digitalWrite (LED_4, LOW);
// READ ROTARY AND MODIFY SERVO SETPOINT MIN, MAX
enc_clk = digitalRead(ENC_CLK_PIN);
if((enc_clk == 1) && (enc_clk_old == 0)) { // 0->1 transition
if(digitalRead(ENC_DATA_PIN) == 1) {
setpoint[pointer] = setpoint[pointer] + INCREMENT;
digitalWrite (LEFT_LED, LOW);
digitalWrite (RIGHT_LED, HIGH);
}
else {
setpoint[pointer] = setpoint[pointer] - INCREMENT;
digitalWrite (LEFT_LED, HIGH);
digitalWrite (RIGHT_LED, LOW);
}
if(setpoint[pointer] > MAX_ANGLE) setpoint[pointer] = MAX_ANGLE;
if(setpoint[pointer] < MIN_ANGLE) setpoint[pointer] = MIN_ANGLE;
Serial.println(setpoint[pointer]);
delay(10);
}
enc_clk_old = enc_clk;
// ROTATE SERVO
if (millis() > timeforservo) {
timeforservo = millis() + SERVO_INTERVAL;
if (angle < setpoint[pointer]) angle++;
if (angle > setpoint[pointer]) angle--;
servo.write(angle);
}
}
// THIS IS USED TO SWEEP FROM LEFT TO RIGHT AND BACK
if (digitalRead (SW_ROT3) == 0) {
// THIS CODE BELOW IS USED TO SWEEP
digitalWrite (LED_1, LOW);
digitalWrite (LED_2, LOW);
digitalWrite (LED_3, HIGH);
digitalWrite (LED_4, LOW);
Serial.println ("Sweep Mode selected");
Serial.print ("Encoder Switch pin is ");
Serial.println (digitalRead (ENC_SW_PIN));
Serial.print ("Sweep Speed is ");
Serial.println (sweep_array[sweep_delay]);
if (digitalRead (ENC_SW_PIN) == HIGH) {
for (angle = setpoint[0]; angle <= setpoint[1]; angle += 1) { // goes from MIN_ANGLE to MAX_ANGLE in increments of 1 degree
// for (angle = MIN_ANGLE; angle <= MAX_ANGLE; angle += 1) { // goes from MIN_ANGLE to MAX_ANGLE in increments of 1 degree
// LED's configured for left sweep
digitalWrite (LEFT_LED, HIGH);
digitalWrite (RIGHT_LED, LOW);
servo.write(angle); // tell servo to go to position 'angle'
delay(sweep_array[sweep_delay]); // waits for servo delay
digitalRead (SW_ROT3);
digitalRead (ENC_SW_PIN); // Reads encoder switch pin looking for press
while (digitalRead (ENC_SW_PIN) == LOW) {
// LED's both on to indicate speed configuration
digitalWrite (LEFT_LED, HIGH);
digitalWrite (RIGHT_LED, HIGH);
enc_clk = digitalRead(ENC_CLK_PIN);
if((enc_clk == 1) && (enc_clk_old == 0)) { // 0->1 transition
if(digitalRead(ENC_DATA_PIN) == 1) sweep_array[sweep_delay] = sweep_array[sweep_delay] + SWEEP_INCREMENT;
else sweep_array[sweep_delay] = sweep_array[sweep_delay] - SWEEP_INCREMENT;
if(sweep_array[sweep_delay] > MAX_SWEEP) sweep_array[sweep_delay] = MAX_SWEEP;
if(sweep_array[sweep_delay] < MIN_SWEEP) sweep_array[sweep_delay] = MIN_SWEEP;
Serial.print ("Sweep Delay is ");
Serial.println(sweep_array[sweep_delay]);
delay(10);
}
enc_clk_old = enc_clk;
}
}
Serial.println ("Finished MIN to MAX angle sweep");
for (angle = setpoint[1]; angle >= setpoint[0]; angle -= 1) { // goes from 180 degrees to 0 degrees
// for (angle = MAX_ANGLE; angle >= MIN_ANGLE; angle -= 1) { // goes from 180 degrees to 0 degrees
// LED's configured for right sweep
digitalWrite (LEFT_LED, LOW);
digitalWrite (RIGHT_LED, HIGH);
servo.write(angle); // tell servo to go to position in variable 'point of sale'
delay(sweep_array[sweep_delay]); // waits 15ms for the servo to reach the position
digitalRead (ENC_SW_PIN);
while (digitalRead (ENC_SW_PIN) == LOW) {
// LED's both on to indicate speed configuration
digitalWrite (LEFT_LED, HIGH);
digitalWrite (RIGHT_LED, HIGH);
enc_clk = digitalRead(ENC_CLK_PIN);
if((enc_clk == 1) && (enc_clk_old == 0)) { // 0->1 transition
if(digitalRead(ENC_DATA_PIN) == 1) sweep_array[sweep_delay] = sweep_array[sweep_delay] + SWEEP_INCREMENT;
else sweep_array[sweep_delay] = sweep_array[sweep_delay] - SWEEP_INCREMENT;
if(sweep_array[sweep_delay] > MAX_SWEEP) sweep_array[sweep_delay] = MAX_SWEEP;
if(sweep_array[sweep_delay] < MIN_SWEEP) sweep_array[sweep_delay] = MIN_SWEEP;
Serial.print ("Sweep Delay is ");
Serial.println(sweep_array[sweep_delay]);
delay(10);
}
enc_clk_old = enc_clk;
}
}
}
}
// THIS IS RESERVED - MAYBE FOR RANDOM SWEEP SPEED - CURRENTLY BLINKS LEDS
if (digitalRead (SW_ROT4) == LOW){
Serial.println ("Mode 4 selected");
digitalWrite (LED_1, LOW);
digitalWrite (LED_2, LOW);
digitalWrite (LED_3, LOW);
digitalWrite (LED_4, HIGH);
digitalWrite (LEFT_LED, LOW);
digitalWrite (RIGHT_LED, HIGH);
delay (100);
digitalWrite (LEFT_LED, HIGH);
digitalWrite (RIGHT_LED, LOW);
delay (100);
digitalRead (SW_ROT4);
}
}
Aquatic Life made these few years ago at a very affordable price.
I just recently bought one, I have yet to put it on my tank.
I also do have the OG SeaSwirls on the bigger tank.
Not quite the same - the aquatic life one doesn't move an existing powerhead. I already have the Tunze 6105's in the tank (near a corner). I want to make it swirl.
Plus who doesn't like a bit of DIY.
For me the hardware is almost as much of a challange (enjoyment) as the tank itself.