Lesson 86: Using cos() Function
Learn how cos() works with radians to build wave motion, periodic signals, and angle-based control logic.
Progress indicator
Lesson 86 of 86
Learning Objectives
- Understand what cos() calculates and why it naturally creates smooth periodic signals.
- Learn cos() syntax and correct angle input usage in radians.
- Understand radians vs degrees and apply correct conversion formulas.
- Use cos() output safely for PWM/animation by normalizing and scaling ranges.
- Avoid common mistakes like wrong units, missing normalization, and unstable timing steps.
- Read cosine-based LED behavior as a predictable waveform instead of random brightness changes.
Concept Explanation
What is cos()
cos() computes cosine of an angle. Cosine is a trigonometric function that produces smooth repeating values in the range -1 to 1.
This periodic behavior makes cos() useful for wave-based motion, brightness breathing effects, and cyclic control logic.
Think of cosine like a virtual wave generator inside your code. As your angle moves forward, cosine gives a value that rises and falls smoothly. That smooth rise/fall is exactly what we want for natural LED fades and repeated motion curves.
cos() Syntax
Basic syntax: cos(angleInRadians)
cos(0)returns 1cos(PI / 2)returns near 0cos(PI)returns -1
Full cosine cycle completes when angle moves from 0 to 2 * PI.
How cos() Works
- Take angle input (in radians).
- Compute cosine from trigonometric math routine.
- Return a floating-point value between -1 and 1.
As angle changes gradually, output also changes smoothly. That is why cosine is ideal for natural-looking transitions.
Important idea: cosine does not increase forever. It repeats in cycles. One full cycle is from 0 to 2 * PI, then the pattern repeats.
Radians vs Degrees
cos() expects radians, not degrees. Convert degrees with: radians = degrees * PI / 180.0.
- 0 degrees = 0 rad
- 90 degrees = PI/2 rad
- 180 degrees = PI rad
If you pass degree numbers directly, your output shape and timing will look wrong. Most beginner cosine bugs come from unit mismatch.
cos() Return Value
Return range is from -1.0 to 1.0. For hardware outputs like PWM (0..255), normalize the value first.
Example normalization: (cosValue + 1.0) * 0.5 gives 0.0..1.0.
Then scale to output domain: normalized * 255.0 for PWM.
Without normalization, negative values can produce invalid LED output. Converting ranges correctly is the key bridge from math to hardware control.
When to Use cos()
- Wave-style LED brightness animation.
- Periodic control movement and timing patterns.
- Angle-based geometry or motion formulas.
- Smooth cyclic modulation instead of abrupt step-based changes.
Real-life ESP32 example: use cos() to create a breathing status LED that fades in and out smoothly, instead of blinking ON/OFF sharply.
Example Code
This example uses cos() to generate a smooth PWM wave for LED fading.
const int LED_PIN = 2;
float angleRad = 0.0;
void setup() {
pinMode(LED_PIN, OUTPUT);
Serial.begin(115200);
}
void loop() {
// Increase angle in radians.
angleRad = angleRad + 0.25;
if (angleRad > 6.283185) { // 2 * PI
angleRad = 0.0;
}
float wave = cos(angleRad); // range: -1.0 to 1.0
float normalized = (wave + 1.0) * 0.5; // range: 0.0 to 1.0
int pwmValue = (int)(normalized * 255.0);
pwmValue = constrain(pwmValue, 0, 255);
analogWrite(LED_PIN, pwmValue);
Serial.print("angle(rad): ");
Serial.print(angleRad, 2);
Serial.print(" | cos: ");
Serial.print(wave, 3);
Serial.print(" | pwm: ");
Serial.println(pwmValue);
delay(120);
}Example Code Explanation
- angleRad is increased in fixed radian step for consistent waveform progression.
- After crossing
2*PI, angle resets to keep the cycle repeating. cos(angleRad)generates smooth periodic value in -1..1 domain.- Output is normalized into 0..1 so negative cosine values become usable for PWM.
- Normalized value is scaled to 0..255 and constrained for hardware safety.
- analogWrite() sets LED brightness from the cosine-derived pwmValue.
- Serial logs show angle, trig output, and pwm for debugging and tuning.
- The LED appears brightest when cosine is near
1, medium around0, and dimmest near-1after normalization and scaling. delay(120)controls update speed; smaller delay gives smoother motion but uses more update cycles.
What Happens Inside
- CPU reads current
angleRadfrom memory. - CPU performs floating-point addition to increment the angle.
- Range guard checks if angle crossed
2 * PI; if yes, angle resets to 0. - Math library computes cosine for that angle and returns a float in -1..1.
- Program remaps that float into 0..1 using normalization math.
- Program scales to 0..255 and converts to integer PWM value.
- Safety clamp via
constrain()prevents out-of-range output. - PWM register is updated through
analogWrite(), changing LED duty cycle. - Serial monitor prints live values so you can debug waveform behavior.
- Loop repeats forever, creating a continuous breathing LED pattern.
Common Mistakes with cos()
- Passing degree values directly without converting to radians.
- Using cos() output directly for PWM without normalization.
- Forgetting to wrap/reset angle, causing floating drift over very long runs.
- Using too large angle step, producing jerky output instead of smooth waves.
- Ignoring update interval, causing flicker or unstable visual behavior.
Best Practices for cos()
- Keep angle in radians and document conversion when needed.
- Normalize trig output before mapping to hardware ranges.
- Use consistent step size and delay for stable wave animations.
- Tune step and delay together to match desired smoothness and speed.
- Print debug values during setup/tuning, then reduce logs for runtime performance.
Try it now
Open the simulator workspace and observe how cosine values map into smooth LED brightness changes.