This website is still under construction.


Content:

LEDs

Hardware Behavior

LED Brightness

There are two ways to control brightness of LED.

RGB LED

When we know how to change brightness of single LED, let's do it with 3. To be more specific - Red, Green and Blue LEDs. To be even more specific - single RGB LED because RGB LEDs are 3 LEDs in 1 chasing with shared ground.
LED's RGB works same as HTML/CSS color codes. #ffffff is white, #000000 is black, #ff0000 is red...
To select right color, you can try w3schools.com's HTML Color Picker or RGB Color Table.

Software Code

#define PIN_RED 0 #define PIN_GREEN 1 #define PIN_BLUE 2 void setup() { pinMode(PIN_RED, OUTPUT); pinMode(PIN_GREEN, OUTPUT); pinMode(PIN_BLUE, OUTPUT); }
First we need to define our pins.

Own Pulses

To truly understand pulses, let's first write our own. So we can start with a "simple" function.
void performPulse(int pin, float active, int totalMicroseconds) { }
This function has to arguments. First is target (digital) pin, second ranges from 0.0 to 1.0 and last must me greater then 0 and is in μs (microseconds).
digitalWrite(pin, HIGH); int activeMicroseconds = (int)(active * totalMicroseconds); delayMicroseconds(activeMicroseconds); digitalWrite(pin, LOW); delayMicroseconds(totalMicroseconds - activeMicroseconds); We simply calculate activeMicroseconds by multiplying totalMicroseconds by active and flooring the result (by converting to int).
During this time, the pin will be HIGH and rest of time (totalMicroseconds - activeMicroseconds) it will be LOW (and it will leave function in the LOW state).
float Red = 1.0f; float Green = 0.3f; float Blue = 0.1f; #define frequency 60 #define period 1/frequency void loop() { performPulse(PIN_RED, Red, period); performPulse(PIN_GREEN, Green, period); performPulse(PIN_BLUE, Blue, period); }
Before lighting up the RGB LED, we need to define it's values. For our purpose, leaving them static is enough (but you can create some for() loops).
Second thing to define are frequency (blinks per second), period (duration of one pulse) and periodOneColor (duration of one color of pulse).

Whole code
#define PIN_RED 0 #define PIN_GREEN 1 #define PIN_BLUE 2 void setup() { pinMode(PIN_RED, OUTPUT); pinMode(PIN_GREEN, OUTPUT); pinMode(PIN_BLUE, OUTPUT); } // pin = target pin // active = 0.0 to 1.0, "percentage" of active time // totalMicroseconds = >0, 1 000 000 μs = 1s void performPulse(int pin, float active, int totalMicroseconds) { digitalWrite(pin, HIGH); int activeMicroseconds = (int)(active * totalMicroseconds); delayMicroseconds(activeMicroseconds); digitalWrite(pin, LOW); delayMicroseconds(totalMicroseconds - activeMicroseconds); } // Static color definition float Red = 1.0f; float Green = 0.3f; float Blue = 0.1f; // Timing of our pulses const int frequency = 30; const int period = 1 / frequency; const int periodOneColor = period / 3; void loop() { performPulse(PIN_RED, Red, periodOneColor); performPulse(PIN_GREEN, Green, periodOneColor); performPulse(PIN_BLUE, Blue, periodOneColor); }

Arduino's PWM

Second way to make pulses (and mostly better) is Arduino's Pulse-width Modulation. It adds "simple" function analogWrite() which takes 2 parameters - pin (PWN only) and value (0-255).
Problem is with pins which you can find in description of the function and I will quote some.
On most Arduino boards, this function works on pins 3, 5, 6, 9, 10, and 11. On the Arduino Mega, it works on pins 2 - 13 and 44 - 46.
The frequency of the PWM signal on most pins is approximately 490 Hz. On the Uno and similar boards, pins 5 and 6 have a frequency of approximately 980 Hz. Pins 3 and 11 on the Leonardo also run at 980 Hz.
While keeping this in mind, we need to change our pins.
Above you can see pins 3, 5, 6, 9, 10 and 11. It is total of 6 but Micro has 7 PWM Outputs so I looked at my Leonardo (I currently do not have Micro but Leonarho has same microcontroller (ATmega32u4) ) and discovered the 7th pin to be pin 13 (all PMW pins have ~ as prefix). #define PIN_RED 9 #define PIN_GREEN 10 #define PIN_BLUE 11 void setup() { pinMode(PIN_RED, OUTPUT); pinMode(PIN_GREEN, OUTPUT); pinMode(PIN_BLUE, OUTPUT); }
We can remove our own function (performPule()) and both frequency and period variables.
There is also no need for loop() function because we can place analogWrite() into setup (we must move our colors above it).

Whole code
#define PIN_RED 9 #define PIN_GREEN 10 #define PIN_BLUE 11 // Static color definition byte Red = 255; byte Green = 256; byte Blue = 64; void setup() { pinMode(PIN_RED, OUTPUT); pinMode(PIN_GREEN, OUTPUT); pinMode(PIN_BLUE, OUTPUT); // Set colors on output analogWrite(PIN_RED, Red); analogWrite(PIN_GREEN, Green); analogWrite(PIN_BLUE, Blue); } void loop() { delay(1000);// To reduce power usage }
Yes, there is no need for storing the color once we set it but I see no problem with it (and may be used later).

Two LEDs

Because Fursuit has two eyes and we want to change both eyes independently which means to use two LEDs.
#define PIN_LED_0_RED 3 #define PIN_LED_0_GREEN 5 #define PIN_LED_0_BLUE 6 #define PIN_LED_1_RED 9 #define PIN_LED_1_GREEN 10 #define PIN_LED_1_BLUE 11 // Static color definition byte Led_0_Red = 255; byte Led_0_Green = 128; byte Led_0_Blue = 64; byte Led_1_Red = 255; byte Led_1_Green = 128; byte Led_1_Blue = 64; void setup() { { pinMode(PIN_LED_0_RED, OUTPUT); pinMode(PIN_LED_0_GREEN, OUTPUT); pinMode(PIN_LED_0_BLUE, OUTPUT); // Set colors on output analogWrite(PIN_LED_0_RED, Led_0_Red); analogWrite(PIN_LED_0_GREEN, Led_0_Green); analogWrite(PIN_LED_0_BLUE, Led_0_Blue); } { pinMode(PIN_LED_1_RED, OUTPUT); pinMode(PIN_LED_1_GREEN, OUTPUT); pinMode(PIN_LED_1_BLUE, OUTPUT); // Set colors on output analogWrite(PIN_LED_1_RED, Led_1_Red); analogWrite(PIN_LED_1_GREEN, Led_1_Green); analogWrite(PIN_LED_1_BLUE, Led_1_Blue); } } void loop() { delay(1000);// To reduce power usage }
It is just duplicating the code.

Communication

#if defined(__AVR_ATmega32U4__) #define Communication Serial1 #define CommunicationEvent serialEvent1 #else #define Communication Serial #define CommunicationEvent serialEvent #endif
Communication.begin(115200);
void CommunicationEvent() { }
As usual, we add code for detection of Serial, start it in setup and create event on data receive.
void CommunicationEvent() { if(Communication.available() < 3 * 2) return; { Led_0_Red = Communication.read(); Led_0_Green = Communication.read(); Led_0_Blue = Communication.read(); analogWrite(PIN_LED_0_RED, Led_0_Red); analogWrite(PIN_LED_0_GREEN, Led_0_Green); analogWrite(PIN_LED_0_BLUE, Led_0_Blue); } { Led_1_Red = Communication.read(); Led_1_Green = Communication.read(); Led_1_Blue = Communication.read(); analogWrite(PIN_LED_1_RED, Led_1_Red); analogWrite(PIN_LED_1_GREEN, Led_1_Green); analogWrite(PIN_LED_1_BLUE, Led_1_Blue); } }
The code for communication is straightforward. Just read values from Serial and set them on pins.

Whole code:
#if defined(__AVR_ATmega32U4__) #define Communication Serial1 #define CommunicationEvent serialEvent1 #else #define Communication Serial #define CommunicationEvent serialEvent #endif #define PIN_LED_0_RED 3 #define PIN_LED_0_GREEN 5 #define PIN_LED_0_BLUE 6 #define PIN_LED_1_RED 9 #define PIN_LED_1_GREEN 10 #define PIN_LED_1_BLUE 11 // Static color definition byte Led_0_Red = 255; byte Led_0_Green = 128; byte Led_0_Blue = 64; byte Led_1_Red = 255; byte Led_1_Green = 128; byte Led_1_Blue = 64; void setup() { { pinMode(PIN_LED_0_RED, OUTPUT); pinMode(PIN_LED_0_GREEN, OUTPUT); pinMode(PIN_LED_0_BLUE, OUTPUT); // Set colors on output analogWrite(PIN_LED_0_RED, Led_0_Red); analogWrite(PIN_LED_0_GREEN, Led_0_Green); analogWrite(PIN_LED_0_BLUE, Led_0_Blue); } { pinMode(PIN_LED_1_RED, OUTPUT); pinMode(PIN_LED_1_GREEN, OUTPUT); pinMode(PIN_LED_1_BLUE, OUTPUT); // Set colors on output analogWrite(PIN_LED_1_RED, Led_1_Red); analogWrite(PIN_LED_1_GREEN, Led_1_Green); analogWrite(PIN_LED_1_BLUE, Led_1_Blue); } } void CommunicationEvent() { if(Communication.available() < 3 * 2) return; { Led_0_Red = Communication.read(); Led_0_Green = Communication.read(); Led_0_Blue = Communication.read(); analogWrite(PIN_LED_0_RED, Led_0_Red); analogWrite(PIN_LED_0_GREEN, Led_0_Green); analogWrite(PIN_LED_0_BLUE, Led_0_Blue); } { Led_1_Red = Communication.read(); Led_1_Green = Communication.read(); Led_1_Blue = Communication.read(); analogWrite(PIN_LED_1_RED, Led_1_Red); analogWrite(PIN_LED_1_GREEN, Led_1_Green); analogWrite(PIN_LED_1_BLUE, Led_1_Blue); } } void loop() { delay(1000);// To reduce power usage }

Servos

Servos are small motors with gears designed for Radio-Controlled Models.

Protocol

The protocol is designed to be "easy to implement" and (mainly) to set rotation instead of telling it how much to rotate in which direction (so it may not receive all data and still keep precision).
It is from 1 to 2 ms pulse every 20 ms. It means 1ms pulse is one edge of rotation, 2ms is the other. It also means that we can use 10 servos at a time.
Timeline of servo pulse
On image above you can see the pulse and its "timeframe". As you may guess, the bold bottom line is our time and we are operating in 20ms frames.
At start of the frame we set our servo pin to HIGH and keep it that way for at least 1ms. Then anywhere in the gray time (including 1ms and 2ms) we can drop it to LOW.
To control 2 servos, we delay 2nd frame by 2ms which means independently on 1st servo, our 2nd servo will be set to HIGH after 1st servo was set to HIGH "exactly" by 2ms.

I was testing my servos which I have at home (after playing with RC models) and it does not depend on exact timing - it just calculates delay of the pulse, rotate its motor and looking for another pulse.

Implementation

I already described it in Protocol so it may be easy.

One Servo

#define PIN_DATA 0 void setup() { pinMode(PIN_DATA, OUTPUT); }
As always, we start with our pin.
void pulseServo(int pin, float angle) { }
We will also need (use) function which will take pin of our servo and its requested rotation (0.0 to 1.0).
int pulseTime = 1000 + angle * 1000; int pulseWait = 2000 - pulseTime; digitalWrite(pin, HIGH); delayMicroseconds(pulseTime); digitalWrite(pin, LOW); delayMicroseconds(pulseWait);
The code itself is simple - we calculate our time (in microseconds) with minimum 1000 and maximum 2000.

void loop() { pulseServo(PIN_DATA, 0.0f); delay(18); }
The code to keep servo on specific value is easy. Let's try something "harder".
float servo_angle = 0.0f; void loop() { servo_angle += 0.06f; if(servo_angle >= 2) servo_angle -= 2; if(servo_angle <= 1) pulseServo(PIN_DATA, servo_angle); else pulseServo(PIN_DATA, 2 - servo_angle); delay(18); }
This code will rotate servo to one edge (servo_angle: 0.0 - 1.0), then to the other (servo_angle: 1.0 - 2.0) and back again in a loop.
You can change the servo_angle += 0.06f; but this is maximum value for my servo (bigger value has problem reaching servo's limits).

Whole code:
#define PIN_DATA 0 void setup() { pinMode(PIN_DATA, OUTPUT); } void pulseServo(int pin, float angle) { //calculating timing of pulse in μs int pulseTime = 1000 + angle * 1000; int pulseWait = 2000 - pulseTime; digitalWrite(pin, HIGH); delayMicroseconds(pulseTime); digitalWrite(pin, LOW); delayMicroseconds(pulseWait); } float servo_angle = 0.0f; void loop() { // step each "tick" (20ms) servo_angle += 0.06f; if(servo_angle >= 2) servo_angle -= 2; // deciding our current rotation if(servo_angle <= 1) pulseServo(PIN_DATA, servo_angle); else pulseServo(PIN_DATA, 2 - servo_angle); // rest 9 servos time (space) delay(18); }
Servo Limits
We are currently limiting our servo by its own limits which are 1.0 ms and 2.0 ms.
Sometimes we might want to limit them from 1.0 ms to 1.5ms or from 1.3 ms to 1.7 ms to get different angle of movement.
#define SERVO_MIN 1000 #define SERVO_MAX 2000 #define SERVO_RANGE (SERVO_MAX-SERVO_MIN)
int pulseTime = SERVO_MIN + angle * SERVO_RANGE;
Do not forget the bracers in SERVO_RANGE because otherwise it will be int pulseTime = angle * SERVO_MAX because it first multiplies angle with SERVO_MAX.

To change limits, modify SERVO_MIN and SERVO_MAX but keep them in range (min 1000, max 2000) and SERVO_MIN < SERVO_MAX.

Whole code:
#define PIN_DATA 0 void setup() { pinMode(PIN_DATA, OUTPUT); } #define SERVO_MIN 1000 #define SERVO_MAX 2000 #define SERVO_RANGE (SERVO_MAX-SERVO_MIN) void pulseServo(int pin, float angle) { //calculating timing of pulse in μs int pulseTime = SERVO_MIN + angle * SERVO_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(pin, HIGH); delayMicroseconds(pulseTime); digitalWrite(pin, LOW); delayMicroseconds(pulseWait); } float servo_angle = 0.0f; void loop() { // step each "tick" (20ms) servo_angle += 0.06f; if(servo_angle >= 2) servo_angle -= 2; // deciding our current rotation if(servo_angle <= 1) pulseServo(PIN_DATA, servo_angle); else pulseServo(PIN_DATA, 2 - servo_angle); // rest 9 servos time (space) delay(18); }

Speed Limitation

Another thing which we can limit is speed but it is problematic because only takes target rotation and no speed.
That means we need to rewrite some code.
float angle = 0.0; void pulseServo() { //calculating timing of pulse in μs int pulseTime = SERVO_MIN + angle * SERVO_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_DATA, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_DATA, LOW); delayMicroseconds(pulseWait); }
First we want to change some code...
void loop() { pulseServo();
...and call it at begining of the loop. Now we only need to change angle to move servo.
float target_angle = 0.0; float angle_step = 0.06; void recalculateServo() { if(angle != target_angle) { if(angle < target_angle) angle = max(target_angle, angle + angle_step); else // angle > target_step angle = min(target_angle, angle - angle_step); } }
To move servo my small steps (causing it to change speed), we need to a function which will increase our current angle (pulse width).
void loop() { pulseServo(); recalculateServo(); }
We will also call the function in the loop().
Also, we can remove servo_angle because we don't need / use it anymore.

Communication

#if defined(__AVR_ATmega32U4__) #define Communication Serial1 #define CommunicationEvent serialEvent1 #else #define Communication Serial #define CommunicationEvent serialEvent #endif
void setup() { Communication.begin(115200); }
We first need to define our Serial as it can be found in Communication Protocol.
#define PIN_DATA 2
Do not forget to change your PIN_DATA (I changed mine to 2). Pins 0 (RX) and 1 (TX) are used for Serial communication.

void CommunicationEvent() { }
We use event triggered on receiving data on Serial.
void CommunicationEvent() { if(Communication.available() < 2) return; // byte 0 - rotation angle target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed angle_step = Communication.read() / 255.0f; }
Yes, higher values are not usable so let's fix it.
// byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) angle_step = 1.0f; else angle_step = speed / 255.0f / 10.0f
Maximum step size is 0.1 (1.0 / 10) or full (1.0) for 255.

Nine Servos

We can use 10 servos but the Fursuit is (currently) designed to use only 9 which gives us 2ms "free time".
In the "free time" we can just delay(2) (which we will) or calculate it more preciously to get better 20ms in total which is not needed at all because we don't need that precision.

First, we need to add all 9 servos (0-8) which is renaming all of servo variables.
#define PIN_SERVO_0 2 #define PIN_SERVO_1 3 #define PIN_SERVO_2 4 #define PIN_SERVO_3 5 #define PIN_SERVO_4 6 #define PIN_SERVO_5 7 #define PIN_SERVO_6 8 #define PIN_SERVO_7 9 #define PIN_SERVO_8 10 pinMode(PIN_SERVO_0, OUTPUT); pinMode(PIN_SERVO_1, OUTPUT); pinMode(PIN_SERVO_2, OUTPUT); pinMode(PIN_SERVO_3, OUTPUT); pinMode(PIN_SERVO_4, OUTPUT); pinMode(PIN_SERVO_5, OUTPUT); pinMode(PIN_SERVO_6, OUTPUT); pinMode(PIN_SERVO_7, OUTPUT); pinMode(PIN_SERVO_8, OUTPUT);
#define SERVO_0_MIN 1000 #define SERVO_0_MAX 2000 #define SERVO_0_RANGE (SERVO_0_MAX-SERVO_0_MIN) #define SERVO_1_MIN 1000 #define SERVO_1_MAX 2000 #define SERVO_1_RANGE (SERVO_1_MAX-SERVO_1_MIN) #define SERVO_2_MIN 1000 #define SERVO_2_MAX 2000 #define SERVO_2_RANGE (SERVO_2_MAX-SERVO_2_MIN) #define SERVO_3_MIN 1000 #define SERVO_3_MAX 2000 #define SERVO_3_RANGE (SERVO_3_MAX-SERVO_3_MIN) #define SERVO_4_MIN 1000 #define SERVO_4_MAX 2000 #define SERVO_4_RANGE (SERVO_4_MAX-SERVO_4_MIN) #define SERVO_5_MIN 1000 #define SERVO_5_MAX 2000 #define SERVO_5_RANGE (SERVO_5_MAX-SERVO_5_MIN) #define SERVO_6_MIN 1000 #define SERVO_6_MAX 2000 #define SERVO_6_RANGE (SERVO_6_MAX-SERVO_6_MIN) #define SERVO_7_MIN 1000 #define SERVO_7_MAX 2000 #define SERVO_7_RANGE (SERVO_7_MAX-SERVO_7_MIN) #define SERVO_8_MIN 1000 #define SERVO_8_MAX 2000 #define SERVO_8_RANGE (SERVO_8_MAX-SERVO_8_MIN) float servo_0_angle = 0.0; float servo_0_target_angle = 0.0; float servo_0_angle_step = 0.06; float servo_1_angle = 0.0; float servo_1_target_angle = 0.0; float servo_1_angle_step = 0.06; float servo_2_angle = 0.0; float servo_2_target_angle = 0.0; float servo_2_angle_step = 0.06; float servo_3_angle = 0.0; float servo_3_target_angle = 0.0; float servo_3_angle_step = 0.06; float servo_4_angle = 0.0; float servo_4_target_angle = 0.0; float servo_4_angle_step = 0.06; float servo_5_angle = 0.0; float servo_5_target_angle = 0.0; float servo_5_angle_step = 0.06; float servo_6_angle = 0.0; float servo_6_target_angle = 0.0; float servo_6_angle_step = 0.06; float servo_7_angle = 0.0; float servo_7_target_angle = 0.0; float servo_7_angle_step = 0.06; float servo_8_angle = 0.0; float servo_8_target_angle = 0.0; float servo_8_angle_step = 0.06;
void recalculateServo() { if(servo_0_angle != servo_0_target_angle) { if(servo_0_angle < servo_0_target_angle) servo_0_angle = max(servo_0_target_angle, servo_0_angle + servo_0_angle_step); else // servo_0_angle > servo_0_target_step servo_0_angle = min(servo_0_target_angle, servo_0_angle - servo_0_angle_step); } if(servo_1_angle != servo_1_target_angle) { if(servo_1_angle < servo_1_target_angle) servo_1_angle = max(servo_1_target_angle, servo_1_angle + servo_1_angle_step); else // servo_1_angle > servo_1_target_step servo_1_angle = min(servo_1_target_angle, servo_1_angle - servo_1_angle_step); } if(servo_2_angle != servo_2_target_angle) { if(servo_2_angle < servo_2_target_angle) servo_2_angle = max(servo_2_target_angle, servo_2_angle + servo_2_angle_step); else // servo_2_angle > servo_2_target_step servo_2_angle = min(servo_2_target_angle, servo_2_angle - servo_2_angle_step); } if(servo_3_angle != servo_3_target_angle) { if(servo_3_angle < servo_3_target_angle) servo_3_angle = max(servo_3_target_angle, servo_3_angle + servo_3_angle_step); else // servo_3_angle > servo_3_target_step servo_3_angle = min(servo_3_target_angle, servo_3_angle - servo_3_angle_step); } if(servo_4_angle != servo_4_target_angle) { if(servo_4_angle < servo_4_target_angle) servo_4_angle = max(servo_4_target_angle, servo_4_angle + servo_4_angle_step); else // servo_4_angle > servo_4_target_step servo_4_angle = min(servo_4_target_angle, servo_4_angle - servo_4_angle_step); } if(servo_5_angle != servo_5_target_angle) { if(servo_5_angle < servo_5_target_angle) servo_5_angle = max(servo_5_target_angle, servo_5_angle + servo_5_angle_step); else // servo_5_angle > servo_5_target_step servo_5_angle = min(servo_5_target_angle, servo_5_angle - servo_5_angle_step); } if(servo_6_angle != servo_6_target_angle) { if(servo_6_angle < servo_6_target_angle) servo_6_angle = max(servo_6_target_angle, servo_6_angle + servo_6_angle_step); else // servo_6_angle > servo_6_target_step servo_6_angle = min(servo_6_target_angle, servo_6_angle - servo_6_angle_step); } if(servo_7_angle != servo_7_target_angle) { if(servo_7_angle < servo_7_target_angle) servo_7_angle = max(servo_7_target_angle, servo_7_angle + servo_7_angle_step); else // servo_7_angle > servo_7_target_step servo_7_angle = min(servo_7_target_angle, servo_7_angle - servo_7_angle_step); } if(servo_8_angle != servo_8_target_angle) { if(servo_8_angle < servo_8_target_angle) servo_8_angle = max(servo_8_target_angle, servo_8_angle + servo_8_angle_step); else // servo_8_angle > servo_8_target_step servo_8_angle = min(servo_8_target_angle, servo_8_angle - servo_8_angle_step); } } void pulseServo() { { //calculating timing of pulse in μs int pulseTime = SERVO_0_MIN + servo_0_angle * SERVO_0_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_0, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_0, LOW); delayMicroseconds(pulseWait); } { //calculating timing of pulse in μs int pulseTime = SERVO_1_MIN + servo_1_angle * SERVO_1_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_1, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_1, LOW); delayMicroseconds(pulseWait); } { //calculating timing of pulse in μs int pulseTime = SERVO_2_MIN + servo_2_angle * SERVO_2_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_2, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_2, LOW); delayMicroseconds(pulseWait); } { //calculating timing of pulse in μs int pulseTime = SERVO_3_MIN + servo_3_angle * SERVO_3_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_3, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_3, LOW); delayMicroseconds(pulseWait); } { //calculating timing of pulse in μs int pulseTime = SERVO_4_MIN + servo_4_angle * SERVO_4_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_4, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_4, LOW); delayMicroseconds(pulseWait); } { //calculating timing of pulse in μs int pulseTime = SERVO_5_MIN + servo_5_angle * SERVO_5_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_5, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_5, LOW); delayMicroseconds(pulseWait); } { //calculating timing of pulse in μs int pulseTime = SERVO_6_MIN + servo_6_angle * SERVO_6_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_6, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_6, LOW); delayMicroseconds(pulseWait); } { //calculating timing of pulse in μs int pulseTime = SERVO_7_MIN + servo_7_angle * SERVO_7_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_7, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_7, LOW); delayMicroseconds(pulseWait); } { //calculating timing of pulse in μs int pulseTime = SERVO_8_MIN + servo_8_angle * SERVO_8_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_8, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_8, LOW); delayMicroseconds(pulseWait); } }
void CommunicationEvent() { if(Communication.available() < 2 * 9) return; { // byte 0 - rotation angle servo_0_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_0_angle_step = 1.0f; else servo_0_angle_step = speed / 255.0f / 10.0f; } { // byte 0 - rotation angle servo_1_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_1_angle_step = 1.0f; else servo_1_angle_step = speed / 255.0f / 10.0f; } { // byte 0 - rotation angle servo_2_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_2_angle_step = 1.0f; else servo_2_angle_step = speed / 255.0f / 10.0f; } { // byte 0 - rotation angle servo_3_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_3_angle_step = 1.0f; else servo_3_angle_step = speed / 255.0f / 10.0f; } { // byte 0 - rotation angle servo_4_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_4_angle_step = 1.0f; else servo_4_angle_step = speed / 255.0f / 10.0f; } { // byte 0 - rotation angle servo_5_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_5_angle_step = 1.0f; else servo_5_angle_step = speed / 255.0f / 10.0f; } { // byte 0 - rotation angle servo_6_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_6_angle_step = 1.0f; else servo_6_angle_step = speed / 255.0f / 10.0f; } { // byte 0 - rotation angle servo_7_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_7_angle_step = 1.0f; else servo_7_angle_step = speed / 255.0f / 10.0f; } { // byte 0 - rotation angle servo_8_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_8_angle_step = 1.0f; else servo_8_angle_step = speed / 255.0f / 10.0f; } }
As you can see, it is a lot of code do change / add.

Whole code:
#if defined(__AVR_ATmega32U4__) #define Communication Serial1 #define CommunicationEvent serialEvent1 #else #define Communication Serial #define CommunicationEvent serialEvent #endif #define PIN_SERVO_0 2 #define PIN_SERVO_1 3 #define PIN_SERVO_2 4 #define PIN_SERVO_3 5 #define PIN_SERVO_4 6 #define PIN_SERVO_5 7 #define PIN_SERVO_6 8 #define PIN_SERVO_7 9 #define PIN_SERVO_8 10 void setup() { pinMode(PIN_SERVO_0, OUTPUT); pinMode(PIN_SERVO_1, OUTPUT); pinMode(PIN_SERVO_2, OUTPUT); pinMode(PIN_SERVO_3, OUTPUT); pinMode(PIN_SERVO_4, OUTPUT); pinMode(PIN_SERVO_5, OUTPUT); pinMode(PIN_SERVO_6, OUTPUT); pinMode(PIN_SERVO_7, OUTPUT); pinMode(PIN_SERVO_8, OUTPUT); Communication.begin(115200); } #define SERVO_0_MIN 1000 #define SERVO_0_MAX 2000 #define SERVO_0_RANGE (SERVO_0_MAX-SERVO_0_MIN) #define SERVO_1_MIN 1000 #define SERVO_1_MAX 2000 #define SERVO_1_RANGE (SERVO_1_MAX-SERVO_1_MIN) #define SERVO_2_MIN 1000 #define SERVO_2_MAX 2000 #define SERVO_2_RANGE (SERVO_2_MAX-SERVO_2_MIN) #define SERVO_3_MIN 1000 #define SERVO_3_MAX 2000 #define SERVO_3_RANGE (SERVO_3_MAX-SERVO_3_MIN) #define SERVO_4_MIN 1000 #define SERVO_4_MAX 2000 #define SERVO_4_RANGE (SERVO_4_MAX-SERVO_4_MIN) #define SERVO_5_MIN 1000 #define SERVO_5_MAX 2000 #define SERVO_5_RANGE (SERVO_5_MAX-SERVO_5_MIN) #define SERVO_6_MIN 1000 #define SERVO_6_MAX 2000 #define SERVO_6_RANGE (SERVO_6_MAX-SERVO_6_MIN) #define SERVO_7_MIN 1000 #define SERVO_7_MAX 2000 #define SERVO_7_RANGE (SERVO_7_MAX-SERVO_7_MIN) #define SERVO_8_MIN 1000 #define SERVO_8_MAX 2000 #define SERVO_8_RANGE (SERVO_8_MAX-SERVO_8_MIN) float servo_0_angle = 0.0; float servo_0_target_angle = 0.0; float servo_0_angle_step = 0.06; float servo_1_angle = 0.0; float servo_1_target_angle = 0.0; float servo_1_angle_step = 0.06; float servo_2_angle = 0.0; float servo_2_target_angle = 0.0; float servo_2_angle_step = 0.06; float servo_3_angle = 0.0; float servo_3_target_angle = 0.0; float servo_3_angle_step = 0.06; float servo_4_angle = 0.0; float servo_4_target_angle = 0.0; float servo_4_angle_step = 0.06; float servo_5_angle = 0.0; float servo_5_target_angle = 0.0; float servo_5_angle_step = 0.06; float servo_6_angle = 0.0; float servo_6_target_angle = 0.0; float servo_6_angle_step = 0.06; float servo_7_angle = 0.0; float servo_7_target_angle = 0.0; float servo_7_angle_step = 0.06; float servo_8_angle = 0.0; float servo_8_target_angle = 0.0; float servo_8_angle_step = 0.06; void recalculateServo() { if(servo_0_angle != servo_0_target_angle) { if(servo_0_angle < servo_0_target_angle) servo_0_angle = max(servo_0_target_angle, servo_0_angle + servo_0_angle_step); else // servo_0_angle > servo_0_target_step servo_0_angle = min(servo_0_target_angle, servo_0_angle - servo_0_angle_step); } if(servo_1_angle != servo_1_target_angle) { if(servo_1_angle < servo_1_target_angle) servo_1_angle = max(servo_1_target_angle, servo_1_angle + servo_1_angle_step); else // servo_1_angle > servo_1_target_step servo_1_angle = min(servo_1_target_angle, servo_1_angle - servo_1_angle_step); } if(servo_2_angle != servo_2_target_angle) { if(servo_2_angle < servo_2_target_angle) servo_2_angle = max(servo_2_target_angle, servo_2_angle + servo_2_angle_step); else // servo_2_angle > servo_2_target_step servo_2_angle = min(servo_2_target_angle, servo_2_angle - servo_2_angle_step); } if(servo_3_angle != servo_3_target_angle) { if(servo_3_angle < servo_3_target_angle) servo_3_angle = max(servo_3_target_angle, servo_3_angle + servo_3_angle_step); else // servo_3_angle > servo_3_target_step servo_3_angle = min(servo_3_target_angle, servo_3_angle - servo_3_angle_step); } if(servo_4_angle != servo_4_target_angle) { if(servo_4_angle < servo_4_target_angle) servo_4_angle = max(servo_4_target_angle, servo_4_angle + servo_4_angle_step); else // servo_4_angle > servo_4_target_step servo_4_angle = min(servo_4_target_angle, servo_4_angle - servo_4_angle_step); } if(servo_5_angle != servo_5_target_angle) { if(servo_5_angle < servo_5_target_angle) servo_5_angle = max(servo_5_target_angle, servo_5_angle + servo_5_angle_step); else // servo_5_angle > servo_5_target_step servo_5_angle = min(servo_5_target_angle, servo_5_angle - servo_5_angle_step); } if(servo_6_angle != servo_6_target_angle) { if(servo_6_angle < servo_6_target_angle) servo_6_angle = max(servo_6_target_angle, servo_6_angle + servo_6_angle_step); else // servo_6_angle > servo_6_target_step servo_6_angle = min(servo_6_target_angle, servo_6_angle - servo_6_angle_step); } if(servo_7_angle != servo_7_target_angle) { if(servo_7_angle < servo_7_target_angle) servo_7_angle = max(servo_7_target_angle, servo_7_angle + servo_7_angle_step); else // servo_7_angle > servo_7_target_step servo_7_angle = min(servo_7_target_angle, servo_7_angle - servo_7_angle_step); } if(servo_8_angle != servo_8_target_angle) { if(servo_8_angle < servo_8_target_angle) servo_8_angle = max(servo_8_target_angle, servo_8_angle + servo_8_angle_step); else // servo_8_angle > servo_8_target_step servo_8_angle = min(servo_8_target_angle, servo_8_angle - servo_8_angle_step); } } void pulseServo() { { //calculating timing of pulse in μs int pulseTime = SERVO_0_MIN + servo_0_angle * SERVO_0_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_0, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_0, LOW); delayMicroseconds(pulseWait); } { //calculating timing of pulse in μs int pulseTime = SERVO_1_MIN + servo_1_angle * SERVO_1_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_1, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_1, LOW); delayMicroseconds(pulseWait); } { //calculating timing of pulse in μs int pulseTime = SERVO_2_MIN + servo_2_angle * SERVO_2_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_2, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_2, LOW); delayMicroseconds(pulseWait); } { //calculating timing of pulse in μs int pulseTime = SERVO_3_MIN + servo_3_angle * SERVO_3_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_3, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_3, LOW); delayMicroseconds(pulseWait); } { //calculating timing of pulse in μs int pulseTime = SERVO_4_MIN + servo_4_angle * SERVO_4_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_4, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_4, LOW); delayMicroseconds(pulseWait); } { //calculating timing of pulse in μs int pulseTime = SERVO_5_MIN + servo_5_angle * SERVO_5_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_5, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_5, LOW); delayMicroseconds(pulseWait); } { //calculating timing of pulse in μs int pulseTime = SERVO_6_MIN + servo_6_angle * SERVO_6_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_6, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_6, LOW); delayMicroseconds(pulseWait); } { //calculating timing of pulse in μs int pulseTime = SERVO_7_MIN + servo_7_angle * SERVO_7_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_7, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_7, LOW); delayMicroseconds(pulseWait); } { //calculating timing of pulse in μs int pulseTime = SERVO_8_MIN + servo_8_angle * SERVO_8_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_8, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_8, LOW); delayMicroseconds(pulseWait); } } void CommunicationEvent() { if(Communication.available() < 2 * 9) return; { // byte 0 - rotation angle servo_0_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_0_angle_step = 1.0f; else servo_0_angle_step = speed / 255.0f / 10.0f; } { // byte 0 - rotation angle servo_1_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_1_angle_step = 1.0f; else servo_1_angle_step = speed / 255.0f / 10.0f; } { // byte 0 - rotation angle servo_2_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_2_angle_step = 1.0f; else servo_2_angle_step = speed / 255.0f / 10.0f; } { // byte 0 - rotation angle servo_3_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_3_angle_step = 1.0f; else servo_3_angle_step = speed / 255.0f / 10.0f; } { // byte 0 - rotation angle servo_4_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_4_angle_step = 1.0f; else servo_4_angle_step = speed / 255.0f / 10.0f; } { // byte 0 - rotation angle servo_5_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_5_angle_step = 1.0f; else servo_5_angle_step = speed / 255.0f / 10.0f; } { // byte 0 - rotation angle servo_6_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_6_angle_step = 1.0f; else servo_6_angle_step = speed / 255.0f / 10.0f; } { // byte 0 - rotation angle servo_7_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_7_angle_step = 1.0f; else servo_7_angle_step = speed / 255.0f / 10.0f; } { // byte 0 - rotation angle servo_8_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_8_angle_step = 1.0f; else servo_8_angle_step = speed / 255.0f / 10.0f; } } void loop() { pulseServo(); recalculateServo(); }

Complete Code

To be able to send both LED info and Servo info we have two choices - send all info in one packet or have two different packets.
We will use only one packet to communicate both LEDs and Servos. The packet will start with 6 bytes for LEDs (2 RGB LEDs), followed by 9 bytes for Servos.

As base code, we use Servo because adding LEDs will be easier then the other way.
if(Communication.available() < 2 * 9 + 3 * 2)
Only change we will make after merging the codes is changing this line to match packet length.

Whole code:
#if defined(__AVR_ATmega32U4__) #define Communication Serial1 #define CommunicationEvent serialEvent1 #else #define Communication Serial #define CommunicationEvent serialEvent #endif #define PIN_SERVO_0 2 #define PIN_SERVO_1 3 #define PIN_SERVO_2 4 #define PIN_SERVO_3 5 #define PIN_SERVO_4 6 #define PIN_SERVO_5 7 #define PIN_SERVO_6 8 #define PIN_SERVO_7 9 #define PIN_SERVO_8 10 #define PIN_LED_0_RED 3 #define PIN_LED_0_GREEN 5 #define PIN_LED_0_BLUE 6 #define PIN_LED_1_RED 9 #define PIN_LED_1_GREEN 10 #define PIN_LED_1_BLUE 11 // Static color definition byte Led_0_Red = 255; byte Led_0_Green = 128; byte Led_0_Blue = 64; byte Led_1_Red = 255; byte Led_1_Green = 128; byte Led_1_Blue = 64; void setup() { // Servos pinMode(PIN_SERVO_0, OUTPUT); pinMode(PIN_SERVO_1, OUTPUT); pinMode(PIN_SERVO_2, OUTPUT); pinMode(PIN_SERVO_3, OUTPUT); pinMode(PIN_SERVO_4, OUTPUT); pinMode(PIN_SERVO_5, OUTPUT); pinMode(PIN_SERVO_6, OUTPUT); pinMode(PIN_SERVO_7, OUTPUT); pinMode(PIN_SERVO_8, OUTPUT); // LEDs { pinMode(PIN_LED_0_RED, OUTPUT); pinMode(PIN_LED_0_GREEN, OUTPUT); pinMode(PIN_LED_0_BLUE, OUTPUT); // Set colors on output analogWrite(PIN_LED_0_RED, Led_0_Red); analogWrite(PIN_LED_0_GREEN, Led_0_Green); analogWrite(PIN_LED_0_BLUE, Led_0_Blue); } { pinMode(PIN_LED_1_RED, OUTPUT); pinMode(PIN_LED_1_GREEN, OUTPUT); pinMode(PIN_LED_1_BLUE, OUTPUT); // Set colors on output analogWrite(PIN_LED_1_RED, Led_1_Red); analogWrite(PIN_LED_1_GREEN, Led_1_Green); analogWrite(PIN_LED_1_BLUE, Led_1_Blue); } // Serial Communication.begin(115200); } #define SERVO_0_MIN 1000 #define SERVO_0_MAX 2000 #define SERVO_0_RANGE (SERVO_0_MAX-SERVO_0_MIN) #define SERVO_1_MIN 1000 #define SERVO_1_MAX 2000 #define SERVO_1_RANGE (SERVO_1_MAX-SERVO_1_MIN) #define SERVO_2_MIN 1000 #define SERVO_2_MAX 2000 #define SERVO_2_RANGE (SERVO_2_MAX-SERVO_2_MIN) #define SERVO_3_MIN 1000 #define SERVO_3_MAX 2000 #define SERVO_3_RANGE (SERVO_3_MAX-SERVO_3_MIN) #define SERVO_4_MIN 1000 #define SERVO_4_MAX 2000 #define SERVO_4_RANGE (SERVO_4_MAX-SERVO_4_MIN) #define SERVO_5_MIN 1000 #define SERVO_5_MAX 2000 #define SERVO_5_RANGE (SERVO_5_MAX-SERVO_5_MIN) #define SERVO_6_MIN 1000 #define SERVO_6_MAX 2000 #define SERVO_6_RANGE (SERVO_6_MAX-SERVO_6_MIN) #define SERVO_7_MIN 1000 #define SERVO_7_MAX 2000 #define SERVO_7_RANGE (SERVO_7_MAX-SERVO_7_MIN) #define SERVO_8_MIN 1000 #define SERVO_8_MAX 2000 #define SERVO_8_RANGE (SERVO_8_MAX-SERVO_8_MIN) float servo_0_angle = 0.0; float servo_0_target_angle = 0.0; float servo_0_angle_step = 0.06; float servo_1_angle = 0.0; float servo_1_target_angle = 0.0; float servo_1_angle_step = 0.06; float servo_2_angle = 0.0; float servo_2_target_angle = 0.0; float servo_2_angle_step = 0.06; float servo_3_angle = 0.0; float servo_3_target_angle = 0.0; float servo_3_angle_step = 0.06; float servo_4_angle = 0.0; float servo_4_target_angle = 0.0; float servo_4_angle_step = 0.06; float servo_5_angle = 0.0; float servo_5_target_angle = 0.0; float servo_5_angle_step = 0.06; float servo_6_angle = 0.0; float servo_6_target_angle = 0.0; float servo_6_angle_step = 0.06; float servo_7_angle = 0.0; float servo_7_target_angle = 0.0; float servo_7_angle_step = 0.06; float servo_8_angle = 0.0; float servo_8_target_angle = 0.0; float servo_8_angle_step = 0.06; void recalculateServo() { if(servo_0_angle != servo_0_target_angle) { if(servo_0_angle < servo_0_target_angle) servo_0_angle = max(servo_0_target_angle, servo_0_angle + servo_0_angle_step); else // servo_0_angle > servo_0_target_step servo_0_angle = min(servo_0_target_angle, servo_0_angle - servo_0_angle_step); } if(servo_1_angle != servo_1_target_angle) { if(servo_1_angle < servo_1_target_angle) servo_1_angle = max(servo_1_target_angle, servo_1_angle + servo_1_angle_step); else // servo_1_angle > servo_1_target_step servo_1_angle = min(servo_1_target_angle, servo_1_angle - servo_1_angle_step); } if(servo_2_angle != servo_2_target_angle) { if(servo_2_angle < servo_2_target_angle) servo_2_angle = max(servo_2_target_angle, servo_2_angle + servo_2_angle_step); else // servo_2_angle > servo_2_target_step servo_2_angle = min(servo_2_target_angle, servo_2_angle - servo_2_angle_step); } if(servo_3_angle != servo_3_target_angle) { if(servo_3_angle < servo_3_target_angle) servo_3_angle = max(servo_3_target_angle, servo_3_angle + servo_3_angle_step); else // servo_3_angle > servo_3_target_step servo_3_angle = min(servo_3_target_angle, servo_3_angle - servo_3_angle_step); } if(servo_4_angle != servo_4_target_angle) { if(servo_4_angle < servo_4_target_angle) servo_4_angle = max(servo_4_target_angle, servo_4_angle + servo_4_angle_step); else // servo_4_angle > servo_4_target_step servo_4_angle = min(servo_4_target_angle, servo_4_angle - servo_4_angle_step); } if(servo_5_angle != servo_5_target_angle) { if(servo_5_angle < servo_5_target_angle) servo_5_angle = max(servo_5_target_angle, servo_5_angle + servo_5_angle_step); else // servo_5_angle > servo_5_target_step servo_5_angle = min(servo_5_target_angle, servo_5_angle - servo_5_angle_step); } if(servo_6_angle != servo_6_target_angle) { if(servo_6_angle < servo_6_target_angle) servo_6_angle = max(servo_6_target_angle, servo_6_angle + servo_6_angle_step); else // servo_6_angle > servo_6_target_step servo_6_angle = min(servo_6_target_angle, servo_6_angle - servo_6_angle_step); } if(servo_7_angle != servo_7_target_angle) { if(servo_7_angle < servo_7_target_angle) servo_7_angle = max(servo_7_target_angle, servo_7_angle + servo_7_angle_step); else // servo_7_angle > servo_7_target_step servo_7_angle = min(servo_7_target_angle, servo_7_angle - servo_7_angle_step); } if(servo_8_angle != servo_8_target_angle) { if(servo_8_angle < servo_8_target_angle) servo_8_angle = max(servo_8_target_angle, servo_8_angle + servo_8_angle_step); else // servo_8_angle > servo_8_target_step servo_8_angle = min(servo_8_target_angle, servo_8_angle - servo_8_angle_step); } } void pulseServo() { { //calculating timing of pulse in μs int pulseTime = SERVO_0_MIN + servo_0_angle * SERVO_0_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_0, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_0, LOW); delayMicroseconds(pulseWait); } { //calculating timing of pulse in μs int pulseTime = SERVO_1_MIN + servo_1_angle * SERVO_1_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_1, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_1, LOW); delayMicroseconds(pulseWait); } { //calculating timing of pulse in μs int pulseTime = SERVO_2_MIN + servo_2_angle * SERVO_2_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_2, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_2, LOW); delayMicroseconds(pulseWait); } { //calculating timing of pulse in μs int pulseTime = SERVO_3_MIN + servo_3_angle * SERVO_3_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_3, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_3, LOW); delayMicroseconds(pulseWait); } { //calculating timing of pulse in μs int pulseTime = SERVO_4_MIN + servo_4_angle * SERVO_4_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_4, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_4, LOW); delayMicroseconds(pulseWait); } { //calculating timing of pulse in μs int pulseTime = SERVO_5_MIN + servo_5_angle * SERVO_5_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_5, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_5, LOW); delayMicroseconds(pulseWait); } { //calculating timing of pulse in μs int pulseTime = SERVO_6_MIN + servo_6_angle * SERVO_6_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_6, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_6, LOW); delayMicroseconds(pulseWait); } { //calculating timing of pulse in μs int pulseTime = SERVO_7_MIN + servo_7_angle * SERVO_7_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_7, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_7, LOW); delayMicroseconds(pulseWait); } { //calculating timing of pulse in μs int pulseTime = SERVO_8_MIN + servo_8_angle * SERVO_8_RANGE; int pulseWait = 2000 - pulseTime; digitalWrite(PIN_SERVO_8, HIGH); delayMicroseconds(pulseTime); digitalWrite(PIN_SERVO_8, LOW); delayMicroseconds(pulseWait); } } void CommunicationEvent() { if(Communication.available() < 2 * 9 + 3 * 2) return; // LEDs { { Led_0_Red = Communication.read(); Led_0_Green = Communication.read(); Led_0_Blue = Communication.read(); analogWrite(PIN_LED_0_RED, Led_0_Red); analogWrite(PIN_LED_0_GREEN, Led_0_Green); analogWrite(PIN_LED_0_BLUE, Led_0_Blue); } { Led_1_Red = Communication.read(); Led_1_Green = Communication.read(); Led_1_Blue = Communication.read(); analogWrite(PIN_LED_1_RED, Led_1_Red); analogWrite(PIN_LED_1_GREEN, Led_1_Green); analogWrite(PIN_LED_1_BLUE, Led_1_Blue); } } // Servos { { // byte 0 - rotation angle servo_0_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_0_angle_step = 1.0f; else servo_0_angle_step = speed / 255.0f / 10.0f; } { // byte 0 - rotation angle servo_1_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_1_angle_step = 1.0f; else servo_1_angle_step = speed / 255.0f / 10.0f; } { // byte 0 - rotation angle servo_2_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_2_angle_step = 1.0f; else servo_2_angle_step = speed / 255.0f / 10.0f; } { // byte 0 - rotation angle servo_3_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_3_angle_step = 1.0f; else servo_3_angle_step = speed / 255.0f / 10.0f; } { // byte 0 - rotation angle servo_4_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_4_angle_step = 1.0f; else servo_4_angle_step = speed / 255.0f / 10.0f; } { // byte 0 - rotation angle servo_5_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_5_angle_step = 1.0f; else servo_5_angle_step = speed / 255.0f / 10.0f; } { // byte 0 - rotation angle servo_6_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_6_angle_step = 1.0f; else servo_6_angle_step = speed / 255.0f / 10.0f; } { // byte 0 - rotation angle servo_7_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_7_angle_step = 1.0f; else servo_7_angle_step = speed / 255.0f / 10.0f; } { // byte 0 - rotation angle servo_8_target_angle = Communication.read() / 255.0f; // byte 1 - rotation speed int speed = Communication.read(); if(speed == 255) servo_8_angle_step = 1.0f; else servo_8_angle_step = speed / 255.0f / 10.0f; } } } void loop() { pulseServo(); recalculateServo(); }