Lesson 84: Using sq() Function
Learn how sq() quickly squares values for distance, error, and energy-style calculations in Arduino.
Progress indicator
Lesson 84 of 84
Learning Objectives
- Understand what sq() does mathematically and how squaring amplifies larger values.
- Learn sq() syntax and where it fits naturally in Arduino control logic.
- Use sq() for error-strength calculations and non-linear emphasis of deviations.
- Compare sq() with pow(x, 2) in terms of purpose, readability, and performance expectations.
- Avoid common sq() mistakes such as overflow, wrong data types, and missing output scaling.
Concept Explanation
What is sq()
sq() returns the square of a value. Squaring means multiplying a value by itself: x * x.
Because negatives become positive after squaring, sq() is useful when you care about error magnitude rather than direction.
sq() Syntax
Basic syntax: sq(x)
sq(3)returns9.sq(-4)returns16.sq(error)emphasizes larger error magnitudes.
Use a clear variable name (for example errorSquared) so intent is obvious.
How sq() Works
- Take input value x.
- Multiply x by itself.
- Return the squared result.
Small values stay relatively small, but large values grow quickly. This makes sq() good for making big errors visually or numerically more important.
Square Calculation Concept
Squaring makes bigger values grow much faster. This is useful when you want large errors to stand out more strongly than small errors.
Example: error 2 gives 4, but error 10 gives 100. The larger error now dominates control output.
sq() vs pow(x, 2) (Comparison)
sq(x)is specialized and simple for x squared.pow(x, 2)is more general but heavier functionally.- Use
sq()when you only need square operation repeatedly.
Use pow() when exponent must change dynamically. Use sq() when square is fixed and you want clearer intent.
When to Use sq()
- Error energy style calculations.
- Distance-like formulas (with multi-axis terms).
- When emphasizing larger differences in control logic.
- Penalty functions where large deviation should react more strongly.
Example Code
This example squares sensor error and uses it to drive LED intensity.
const int LED_PIN = 2;
int setPoint = 500;
int sensorValue = 430;
void setup() {
pinMode(LED_PIN, OUTPUT);
Serial.begin(115200);
}
void loop() {
// Simulate changing sensor value.
sensorValue = sensorValue + 35;
if (sensorValue > 620) {
sensorValue = 380;
}
int error = sensorValue - setPoint;
long errorSquared = sq(error);
// Convert squared error into a PWM-like indicator.
int pwmValue = (int)(errorSquared / 20);
pwmValue = constrain(pwmValue, 0, 255);
analogWrite(LED_PIN, pwmValue);
Serial.print("sensor: ");
Serial.print(sensorValue);
Serial.print(" | error: ");
Serial.print(error);
Serial.print(" | sq(error): ");
Serial.print(errorSquared);
Serial.print(" | pwm: ");
Serial.println(pwmValue);
delay(700);
}Example Code Explanation
- sensorValue changes in a loop to simulate measurement drift around setPoint.
error = sensorValue - setPointcomputes signed deviation.errorSquared = sq(error)converts deviation into magnitude-emphasized value.- Squared value is scaled down (
/20) to fit PWM-friendly range. constrain()ensures final pwmValue always stays between 0 and 255.analogWrite()applies error-strength indicator to LED brightness.- Serial logs expose each stage: input, error, squared error, and output.
What Happens Inside
- Input error is computed from measurement minus setpoint.
- sq() performs multiply-by-self operation.
- Result is converted into output scale for control signal.
- Hardware PWM is updated based on squared magnitude.
- Runtime serial logs provide direct trace of how squaring affects output intensity.
Common Mistakes with sq()
- Using variable type too small and causing overflow on squared result.
- Forgetting that sq() amplifies large values quickly.
- Not scaling/clamping squared result before writing to output hardware.
- Using sq() when plain absolute value (
abs()) is actually the correct metric. - Assuming sq() preserves sign information (it does not).
Best Practices for sq()
- Use larger numeric type (
longor wider) for squared intermediate values. - Constrain outputs after scaling squared values.
- Use sq() for fixed square logic; use pow() only when exponent must vary.
- Log intermediate values during tuning so curve strength is transparent.
- Document why squaring is chosen over linear error logic for future maintenance.
Try it now
Open the simulator workspace and observe how sq(error) amplifies deviations into output intensity.