Fading Adafruit neopixels - arduino

I would like to create a motion-controlled night light for my corridor. For my project I have
Arduino Uno
PIR sensor
WS2812b RGBW light strip
5V power bank to drive the LEDs
After tinkering with my light strip, I have managed to get the LEDs to turn on and fade to a low Red color followed by a delay and finally fade back to a point where they turn off. As I understand the Neopixel library, maximum light intensity has a value of 255. However, as we're talking about night light, I estimate that a value of less than 20 is more than sufficient to illuminate my corridor. (I should note that I see many suggestions placing a resistor in front of the LED strip and a capacitor on the power supply - will this affect intensity?) As a consequence, the light does not fade/turn off smoothly, but instead go through the lower intensities before turning off - which is not very pleasant to look at... My question is therefore if you know of any way to create a more smooth fade? Below is my code so far. Note that I have had to insert specific lines at the bottom to actually turn off the leds, as setting the intensity to "0" apparently doesn't seem to do the trick - am I missing something here?
Ideally I would like to be able to dictate how long it takes for the LEDs to fade in/out.
Thanks in advance
#include <Adafruit_NeoPixel.h>
#define LED_PIN 6
#define LED_COUNT 30 // How many NeoPixels are attached to the Arduino?
#define High_Intensity 20
#define Low_Intensity 1
// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
//Adafruit_NeoPixel strip = Adafruit_NeoPixel(12, PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRBW + NEO_KHZ800);
// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel. Avoid connecting
// on a live circuit... if you must, connect GND first.
void setup() {
strip.begin();
strip.show(); // initialize all pixels to "off"
}
void loop() {
brighten();
darken();
}
// 0 to 255
void brighten() {
uint16_t i, j;
for (j = Low_Intensity; j < High_Intensity; j++) {
for (i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, j, 0, 0);
}
strip.show();
delay(50);
}
delay(500);
}
// 255 to 0
void darken() {
Serial.begin(9600);
uint16_t i, j;
for (j = High_Intensity; j > 1; j--) {
for (i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, j, 0, 0);
}
strip.show();
delay(100);
Serial.println(j);
}
// Turn leds back off
for(int i=0; i<60; i++) {
strip.setPixelColor(i, 0);
strip.show();}
delay(5000);
}

Regarding the off-topic part (I won't go into detail)
The capacitor between the power leads will protect the Neopixels controller from sudden voltage changes due to the fact that each pixel drives their leds with PWM.
The resistor terminates the communication lines which reduces reflections in the wires.
Both improve performance and reduce risk of damage to the pixels. Hence you should use them. Just make sure you use them on the correct pins. There's plenty of information online on how to properly control Neopixel strings.
(I should note that I see many suggestions placing a resistor in front
of the LED strip and a capacitor on the power supply - will this
affect intensity?)
This will not affect intensity! Intensity is only controlled by the pixels' pwm signal and the supplied current.
Programming-wise:
As I understand the Neopixel library, maximum light intensity has a
value of 255.
Yes brightness is controlled by 3 values, red, green and blue each ranging from 0 (off) to 255 (max brightness). It's the duty cycle of the led's color channel.
This gives you a brightness resolution of 256 values over the entire brightness range. (8 bit).
My question is therefore if you know of any way to create a more
smooth fade?
This causes a problem. If you want to operate in a lower brightness range you only have a very limited number of steps to fade through.
So what if we reduce the current that supplies the leds?
As control and led supply voltage are usually supplied through the same rail there is no way to dim the entire strip while keeping the 8-bit resolution.
To control the fading time alter the delay time between each value update. Keep in mind the limited dynamic and persistence of human vision. Any visible brightness change that happens < 30Hz will cause a noticable step.
Below is my code so far. Note that I have had to insert specific lines
at the bottom to actually turn off the leds, as setting the intensity
to "0" apparently doesn't seem to do the trick - am I missing
something here?
for (j = High_Intensity; j > 1; j--)
In the loop that darkens the strip you run the loop while j > 1. So the last brightness value you set is 2 which obviously isn't 0.
for (j = High_Intensity; j > -1; j--)
should do the trick.

Related

How to Get Data from Rotary Encoder at VERY High Speeds (>4500 RPM)

Equipment:
Arduino ATmega2560
Rotary Encoder: https://www.amazon.ca/gp/product/B08RS6M32J/ref=ppx_yo_dt_b_asin_title_o06_s01?ie=UTF8&psc=1
Manual Curved Treadmill (what it looks like if you've never seen one before): https://www.youtube.com/watch?v=0oil6cmUCog&ab_channel=ResolutionFitness
Background:
I have a manual treadmill and I want to use my Arduino to capture distance and speed data. To do this, my approach was to use a rotary encoder, attach it to a skateboard wheel (older picture is attached, I'm using a bigger wheel now and there's no photo for that right now) such that when I run on the treadmill, the wheel spins proportionately.
In the code below, whenever I run it, the counter variable would accumulate to about 2000 (pulses) every time the wheel makes a full rotation. The wheel diameter = 6cm, therefore, it's circumference = 18.8495559215 cm.
This means for every centimeter I travel, there are about 106 pulses. (2000 pulses/18.8495559215 cm = ~106 pulses/cm).
Here's the code: (I got it from this website and only changed 2 lines of code because my sensor doesn't need to go in reverse; the treadmill only travels in one direction - https://electricdiylab.com/how-to-connect-optical-rotary-encoder-with-arduino/)
volatile long temp, counter = 0; //This variable will increase or decrease depending on the rotation of encoder
void setup() {
Serial.begin (9600);
pinMode(2, INPUT_PULLUP); // internal pullup input pin 2
pinMode(3, INPUT_PULLUP); // internalเป็น pullup input pin 3
//Setting up interrupt
//A rising pulse from encodenren activated ai0(). AttachInterrupt 0 is DigitalPin nr 2 on moust Arduino.
attachInterrupt(0, ai0, RISING);
//B rising pulse from encodenren activated ai1(). AttachInterrupt 1 is DigitalPin nr 3 on moust Arduino.
attachInterrupt(1, ai1, RISING);
}
void loop() {
// Send the value of counter
if( counter != temp && counter % 106 == 0 ){ // Only print something if the wheel travels in increments of 1 cm.
Serial.println (counter);
temp = counter;
}
}
void ai0() {
// ai0 is activated if DigitalPin nr 2 is going from LOW to HIGH
// Check pin 3 to determine the direction
if(digitalRead(3)==LOW) {
counter++;
}else{
counter++; // The original code said counter-- but my treadmill only goes one direction and the this variable starts to decrease when I reach a certain speed (around 5 kmk/h or (3.1 mph) or so). After I changed it to counter++, this issue was resolved however, the arduino serial monitor kept freezing at high speeds.
}
}
void ai1() {
// ai0 is activated if DigitalPin nr 3 is going from LOW to HIGH
// Check with pin 2 to determine the direction
if(digitalRead(2)==LOW) {
counter++; //// The original code said counter-- but my treadmill only goes one direction and the this variable starts to decrease when I reach a certain speed (around 5 kmk/h or (3.1 mph) or so). After I changed it to counter++, this issue was resolved however, the arduino serial monitor kept freezing at high speeds.
}else{
counter++;
}
}
The Problem
*To get the speed is easy, it's just not in this code right now. Accomplished by using t1 and t2 variables and the Millis() function.
When I walk on the treadmill, I typically walk at about 4 or 5 km/h (3.1 mph). This works fine. However, the issue is I want to be able to sprint over 30 km/h (18.6 mph) and have the code be able to support up to 50 km/h (31 mph). Right now, I'm unable to run at speeds over 5 km/h without the serial monitor freezing periodically, or there being inaccurate data.
At these speeds, I would need the sensor to support the wheel moving at over 4500 RPM -> 75 RPS or (75 RPS x 2000 P/R = 150,000 Pulses/Second)
I have absolutely no idea why this issue is happening and how I should approach this to achieve my desired speeds.
Possible reasons why this is happening:
I'm not an expert at Arduino at all and am just starting to understand things like interrupts. I have my pins in 2 and 3. Should I leave this alone or change it?
If you click the Amazon link, you'll see that there is a 3rd Orange "Z" wire which I have absolutely no idea what it does. The few tutorials I could find only involve the two "A" and "B" wires. Maybe incorporating the "Z" wire would point me in the right direction?
My Rotary encoder sensor is using the Arduino's 5V. If you click on the Amazon link, you'd see that it actually supports up to 26V. Should I find an external power source that allows up to 26V and pair it with a relay? Not sure if the extra voltage will help me.
I'm not sure why by default, the sensor counted a full rotation for the wheel to be 2000 pulses. On Amazon, you'll see that it supports the following Pulses/Revolution:
Resolution (pulse/rotation) : 100, 200, 300, 360, 400, 500, 600, 1000, 1024, 1200, 2000, 2500, 3600, 5000 (optional)
How can I change my 2000 P/R to 5000 P/R for example? Would this help?
Summary
I want to use my Arduino and rotary sensor to collect speed and distance data from my manual treadmill. At slow speeds (up to 5 km/h), the code works fine, but at high speeds, the data is highly inaccurate, and the serial monitor freezes every few seconds. I want the Arduino to support speeds up to 50 km/h which is about 4500 RPM. If my solution with the rotary sensor is not feasible, I am 100% open to other ideas as I just want the speed and distance data. I'll purchase any new equipment that's necessary but ideally, I'd like to work with what I have right now.
Thank you for your help!
Well I looked at the datasheet of your encoder and I was also very confused regarding the multiple values of resolution... what I suspect is that maybe there are different E6B2-CWZ6C models with differnt ppr's...
But what was useful was that I found out that your encoder is an incermental rotary encoder (this video explains better the inner workings of your type of encoder) what this means is that you have three wires A black, B white and Z the orange one.
As described on the video when your shaft completes 1 full rotation you will get N quantity of pulses from A and B, but depending on which pulse you get first would determines the rotation, according to the diagram below, if you first get a pulse from A it would mean that the rotation is CW but if you get B first it would then be CCW.
So for example lets say you start with a pulse_count=0 and start turning your shaft CW and you start counting the pulses on A, the count would go 0,1,2... and so on, but how would you know when to stop counting? that's when the Z orange cable comes in place, because it makes a pulse only after a whole rotation has been made so let's say you counted up to 200 and then you get a pulse from Z then you would know that you should restart your count back to the begining.
So to solve your problem and if you are only interested in the measured speed i would sugest to only measure how long does it take from one Z pulse to the next one, which would tell you how long it took for your encoder to complete one rotation, which could then be use to calculate the speed.
If we solve for rpms using this formula we get that RPM=(V60)/(2pir) if V=50km/h=13.88 m/s and r=3cm=0.03m we get that at 50km/h we would get 4418.14 rpm or 4418/60= 73.63 revs per sec what means 73 pulses of Z every second.
What was maybe happening is that for example if A had a resolution of 2000 ppr would imply that for every second you were receiving 73*2000 = 146000 pulses every second and as you configured your baudrate for your serial communication at Serial.begin(9600) you were only capable of reading at most 9600 pulses for each second which is way less than your 146000 pulses in A. However there are different baudrates you can set: 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, or 115200. Just be sure to select the same audrate when using the serial monitor.
For extremely high speeds you have to use bit operators and port registers.
Try this code with the equivalent pins CLK and DT connected to A2 and A1 receptively.
// Rotary Encoder Inputs
#define CLK A2
#define DT A1
int counter = 0;
String currentDir ="";
unsigned char currentPairBit = 0b0; // 8 bits
unsigned char lastPairBit = 0b0; // 8 bits
void setup() {
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
DDRC = 0b00000000; // Set Analog(C) encoder pins as inputs
}
void loop() {
while(true) { // while cycle is faster than loop!
// reads the analog states!
currentPairBit = PINC >> 1 & 0b11; // Gets A2(PC2) and A1(PC1) bits on C (analog input pins) (>> 1 = Jumps pin 0)
if ((lastPairBit & 0b11) != currentPairBit) {
lastPairBit = lastPairBit << 2 | currentPairBit;
// Bit Pairs Cyclic Sequence:
// 1. 2. 3. 4. 5.
// 11 | 01 | 00 | 10 | 11 for CCW
// 11 | 10 | 00 | 01 | 11 for CW
if (lastPairBit == 0b01001011 || lastPairBit == 0b10000111) {
if (lastPairBit == 0b01001011) {
currentDir = "CCW";
counter--;
} else {
currentDir = "CW";
counter++;
}
Serial.print("Direction: ");
Serial.print(currentDir);
Serial.print(" | Counter: ");
Serial.println(counter);
}
}
}
}
Then check the Serial Monitor to see how fast it is. Note that you should avoid the delay() function in your code or any other that interrupts the cycle by too much time. Consider using a second auxiliary Arduino for anything else than counting.
Resulting Serial Output:

Creating an oscillating tone using Arduino, ATTiny85 and a simple buzzer

First a bit of background. I am attempting to make an LED glow and a buzzer produce a tone that sweeps smoothly up and down in frequency, like an air raid siren. I am using an Arduino Uno, connected to an ATTiny85 chip operating at 8hz clock speed. An SPDN contact switch is used to provide input on 4, while 0 and 1 go out to the positive legs of the buzzer and LED respectively. Suitable resistors are being used to limit current, which is 5v from the Arduino board.
Now, my problem. I can produce a constant tone at any frequency I like. I can produce a tone that goes back and forth between two tones like a UK police siren (Dee-Daa-Dee-Daa etc) but I am unable to generate a smooth transition between two tones. The LED works as expected.
What I actually observe is a single tone that does not vary. Once or twice I've managed to produce a tone that varies, but randomly within the given range rather than smoothly.
I am not using the tone() Arduino command and would prefer not to, as it is not best suited for what I am trying to accomplish.
Here is my code:
const float pi2 = 6.28318530717;
const int buzzer = 0;
const int light = 1;
const int button = 4;
// Set up the pins as input and output
void setup() {
pinMode(buzzer, OUTPUT);
pinMode(light, OUTPUT);
pinMode(button, INPUT);
}
bool buzzerState = LOW;
float nextFlip = 0;
// Generates a sine wave for the given uptime, with a period and offset (in milliseconds).
float sineWave(float uptime, float period, float offset, float minimum, float maximum) {
float s = sin(((uptime + offset) * pi2) / period);
// Normalise the result between minimum and maximum
return (s + 1) / 2 * (maximum - minimum) + minimum;
}
// Returns the time between buzzer inversions based on a given system uptime.
float frequency(float uptime) {
return sineWave(uptime, 5000, 0, 1, 10);
}
// Main loop
void loop() {
// Check button state and turn the light on or off
bool buttonDown = digitalRead(button);
digitalWrite(light, buttonDown);
// Check to see if it's time for the next buzzer inversion
float m = micros();
if (!buttonDown || m < nextFlip) return;
// Get the inverse of the current buzzer state
if (buzzerState == HIGH) {
buzzerState = LOW;
} else {
buzzerState = HIGH;
}
// Write the new buzzer state
digitalWrite(buzzer, buzzerState);
// Decide when the next inversion will occur
nextFlip = m + frequency(m);
}
Silly mistake! I finally noticed: I'm reading micros() where I meant to read millis() - in other words, it was oscillating, just a thousand times faster than I intended it to! Multiplying all values up by a factor of 1000 in the sine wave function produced a lovely oscillation.

LED strip not working

we are still having trouble with our LED strip. We fixed the library issue, and are now trying to program the LED's but have run into a few issues.
1) First of all, our LED strip does not consistently light up. We are using a 12v battery and everything is wired correctly, but how the LED's appear is very inconsistent. Not all of them light up, they are all different colors, and are all of varying brightness. We have tried to resolve this by just powering it with the battery, using our arduino as a power supply, and added a 1000uf capacitor to make sure the strip doesnt get a surge of power and short the strip. Our code is this:
/* Arduino Tutorial - How to use an RGB LED Strip
Dev: Michalis Vasilakis // Date 3/6/2016 // Ver 1.0
Info: www.ardumotive.com */
//Library
#include <Adafruit_NeoPixel.h>
//Constants
const int dinPin = 4; // Din pin to Arduino pin 4
const int numOfLeds = 10; // Number of leds
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(numOfLeds, dinPin, NEO_GRB + NEO_KHZ800);
// Color takes RGB values, from 0,0,0 up to 255,255,255
// e.g. White = (255,255,255), Red = (255,0,0);
int red = 255; //Value from 0(led-off) to 255().
int green = 0;
int blue = 0;
void setup() {
pixels.begin(); // Initializes the NeoPixel library
pixels.setBrightness(100); // Value from 0 to 100%
}
void loop() {
// For a set of NeoPixels the first NeoPixel is 0, second is 1, all the way up to the count of pixels minus one.
for(int i=0;i<numOfLeds;i++){
pixels.setPixelColor(i, pixels.Color(red,green,blue));
pixels.show(); // This sends the updated pixel color to the hardware.
delay(10); // Delay for a period of time to change the next led
}
}
We are trying to set all the LED's to red just to test the code, but nothing is working. Has anyone experienced this before or has any idea of what is not working?
99% of the time this happens when you haven't tied the ground of the LED strip to the ground of the Arduino and the ground of the power supply.

Using arduino analog inputs

I am creating my first Arduino program on the UNO r3. I have played with the Arduino Uno before just with petty example programs, etc. I am using two analog inputs to sense distance using 2 laser sensors with 0-5vdc scaling. These two inputs are 0-5vdc and I have ensured common grounding throughout. The two sensors are named left and right and are input to A0 and A1 respectively. I also have a differential POT which uses a 10K ohm POT wiper voltage as an input on A2. The theory of the program is to take the absolute value of the difference in input voltages between the left and right lasers then determine if the result is greater than or equal to the voltage on pin A2 from the POT wiper. Based on the resulting math, turn on or off a relay interposed to pin D13 via a transistor driver circuit.
The PROBLEM: I cannot achieve accurate changes in voltage on the scale (0-1023) on pins A0, A1, or A2. I have utilized the serial monitor to diagnose this problem. Not sure what the problem is, any help would be great. Also, I cannot achieve a 0 value on any of the above analog pins, even the POT wiper!!!
Here's my code:
const int lf_dist = A0; //names A0
const int rt_dist = A1; //names A1
const int differential = A2; //names A2
const int relay = 13; // select the pin for the relay coil
unsigned int left = 0; // variable to store the value coming from the left sensor
unsigned int right = 0; // variable to store the value coming from the right sensor
unsigned int diff = 0; // variable to store the value coming from the differential POT for maximum distance differential
unsigned int offset = 0; // variable that stores the value between the two laser sensors
void setup() {
Serial.begin(9600);
pinMode(A0, INPUT);
pinMode(A1, INPUT);
pinMode(A2, INPUT);
pinMode(relay, OUTPUT); // declare the relay pin as an OUTPUT:
analogReference(DEFAULT);
}
void loop()
{
unsigned int left = 0; // variable to store the value coming from the left sensor
unsigned int right = 0; // variable to store the value coming from the right sensor
unsigned int diff = 0; // variable to store the value coming from the differential POT for maximum distance differential
unsigned int offset = 0; // variable that stores the value between the two laser sensors
left = analogRead(A0); // read the value from the left laser
delay(5);
right = analogRead(A1); // read the value from the right sensor
delay(5);
diff = analogRead(A2); // read the value from the differential POT
delay(5);
offset = abs(left - right);
if(offset >= diff) // does math to check if left and right distances are greater than the value clocked in by the differential POT
{
digitalWrite(relay, LOW); // turns off the relay, opens the stop circuit, and turns on the yellow light
}
else
{
digitalWrite(relay, HIGH); // turns on the relay if all is good, and that keeps the machine running
}
Serial.print("\n left = " );
Serial.print(left);
Serial.print("\n right = " );
Serial.print(right);
Serial.print("\n differential = " );
Serial.print(diff);
delay(1000);
}
afaict, this should really be due to the floating pins surrounding the measuring pins, having erratic values, hence perturbating your measures. You should look at your values using arduinoscope, which will show you the interfering effects of the other floating pins on your measuring pins.
The easy workaround for this is to ground all analogical input pins you're not using, and put as much space as you can between both your inputs, so they don't interfere with each other.
I realize this thread is somewhat old not, but perhaps this will help someone. If you power the Arduino with only 5V, as you say you did with a regulator, you will get very erratic behavior, particularly from the analog pins. This is because you will start to brown out the internal voltage regulators that provide the AREF, 3.3, and 5.0 outputs. I've tested this for a robotics project I'm working on, and right around 6.5 volts, everything begins to go wrong. I suppose if you always provided 5.0 input voltage you could compensate for this effect, but in my case I used a LiPo battery that could range from 8.4 volts down to 6.0 volts, and everything goes crazy at 6.5 volts.
The minimum current that arduino sinks in during the sampling from potentiometer should not disturb the actual open input volts at the wiper.
Initialize the pins in pull up mode to avoid garbage values or 'floating' pins or use your own pull down/up resistors at the pins :)

How to control speed of a Servo motor using arduino Mega

I am working on a project in which I need to change the speed of servo motors. The hardware I am using is an Arduino Mega 2560 board and I am using Servo.h library to control servos. Servo rotates from o to 180 degree. I am using 12 servo motors in the project and have to control them simultaneously. Is there a way?
You can use delay() function in a while or for loop
Example:
Servo s;
s.attach(9);
for(int i=0 ; i<180 ; i++)
{
s.write(i);
delay(10); //10 milisecond
}
If they all are the same degree, try this code below.
At the very top (Not between any "{}"s):
#include <Servo.h>
Servo S1;
Servo S2;
Servo S3;
Servo S4;
Servo S5;
Servo S6;
Servo S7;
Servo S8;
Servo S9;
Servo S10;
Servo S11;
Servo S12;
Put this in Setup:
S1.attach(1);
S2.attach(2);
S3.attach(3);
S4.attach(4);
S5.attach(5);
S6.attach(6);
S7.attach(7);
S8.attach(8);
S9.attach(9);
S10.attach(10);
S11.attach(11);
S12.attach(12);
You need to change the pin numbers.
Just put this anywhere (Not between any "{}"s):
void TurnServos(int toDegree){
servosAt = S1.read;
if(servosAt == toDegree){
}
if(servosAt > toDegree){
while(S1.read > toDegree){
int currentToDegree = S1.read - 1;
S1.write(currentToDegree);
S2.write(currentToDegree);
S3.write(currentToDegree);
S4.write(currentToDegree);
S5.write(currentToDegree);
S6.write(currentToDegree);
S7.write(currentToDegree);
S8.write(currentToDegree);
S9.write(currentToDegree);
S10.write(currentToDegree);
S11.write(currentToDegree);
S12.write(currentToDegree);
delay(10); //Adjust this to make it faster or slower.
}
}
if(servosAt < toDegree){
while(S1.read < toDegree){
int currentToDegree = S1.read + 1;
S1.write(currentToDegree);
S2.write(currentToDegree);
S3.write(currentToDegree);
S4.write(currentToDegree);
S5.write(currentToDegree);
S6.write(currentToDegree);
S7.write(currentToDegree);
S8.write(currentToDegree);
S9.write(currentToDegree);
S10.write(currentToDegree);
S11.write(currentToDegree);
S12.write(currentToDegree);
delay(10); //Adjust this to make it faster or slower.
}
}
}
void ClearServos(){
int startDegree = 90; //Change this number to anything you want.
S1.write(startDegree);
S2.write(startDegree);
S3.write(startDegree);
S4.write(startDegree);
S5.write(startDegree);
S6.write(startDegree);
S7.write(startDegree);
S8.write(startDegree);
S9.write(startDegree);
S10.write(startDegree);
S11.write(startDegree);
S12.write(startDegree);
}
How to use this:
In setup before you do anything with servos but after the part I told you to put in setup, use ClearServos(); to prepare the servos to be used. (This probably isn't necessarily, but I don't know what happens when you use S1.read without changing it and if the servos are at different positions, it will fix problems. It can be avoided if it won't cause problems, but I think you should use it if you can.) All of them will turn to 90 degrees. (90 degrees can be changed with the variable startDegree in void ClearServos.)
To turn them, use TurnServos(90);. 90 is the degree you want it to turn to.
Haven't tested this because I don't have a Mega or 12 servos. Please comment if you notice any errors since this is huge. I spent a lot of time on this so I hope I helped. :)
Maybe you can put some resistors in series to your servo's VCC pin, before your servo motor to decrease the voltage across; thus slowing it. However, this will cause your servo's to be "constant" speed.
An alternative could be to put a transistor in between your servo VCC connection and set PWM on base pin to regulate current (to regulate speed), but that would cost you an extra pin per servo if you're not using a multiplexer in between; and could make your design a little more complicated.
delayMicroseconds(value) closest to 90-null is slowest for 360 servos both pan and carriage on my timelapse rig, shoot move shoot, in time with the mechanical shutter clicker (mini standard servo).
in Servo library WriteMicroseconds(...) function sets servo speed.
for more information please click

Resources