# Sensing & Perception - Lab 1 & 2 Arduino final codes repository ## Arduino Weight Sensor Scale with Servo Pointer This repository contains two Arduino sketches designed to estimate mass using different types of force/weight sensors and display the result both digitally (via the serial monitor) and analogically (using a servo motor as a pointer). ## Repository Contents * **`Interpolation_Gauge_Strain_Load_Cells_Estimation.ino`**: Arduino sketch for estimating mass using a strain gauge load cell. It assumes the input signal (voltage) has been amplified, adjusted, and scaled to a range of [0-5]V. * **`Interpolation_FlexiForce_Estimation.ino`**: Arduino sketch for estimating mass using a FlexiForce A201 sensor. It also assumes the input signal (voltage) is within the range of [0-5]V. ## Overview Both sketches implement a similar approach to estimate mass: 1. **Analog Input Reading:** They read the analog voltage from a specified sensor pin (A0). 2. **Voltage Conversion:** The raw analog reading (0-1023) is converted to a voltage value (0-5V). 3. **Mass Estimation via Linear Interpolation:** They use a pre-defined `calibrationData` array to map the measured voltage to an estimated mass in grams using linear interpolation. This allows for non-linear sensor responses to be approximated. 4. **Digital Output:** The raw sensor value, voltage, and estimated mass are printed to the Arduino Serial Monitor. 5. **Analog Output via Servo:** The estimated mass is then mapped to an angle (0-180 degrees) to control a servo motor, which acts as a pointer on a scale. ## Hardware Requirements * Arduino board * Force/Weight sensor (Strain Gauge Load Cell or FlexiForce A201, depending on the sketch) * Signal conditioning circuitry for the sensor (amplifier, offset adjustment, scaling) to provide a 0-5V output range corresponding to the sensor's measurement range. * Servo motor * Connecting wires ## Software Requirements * Arduino IDE (Tested : Version 2.1.4) installed. ## Setup 1. **Connect the Sensor:** Connect the output of your sensor's signal conditioning circuit to the Arduino's analog input pin A0. 2. **Connect the Servo Motor:** Connect the control pin of the servo motor to digital pin 9 on the Arduino. Connect the servo's power and ground pins appropriately (typically to the Arduino's 5V and GND, or an external power supply if needed). 3. **Calibration:** * **The sensor needs calibration.** This involves applying known weights to the sensor and recording the corresponding voltage readings from the Arduino (via the Serial Monitor, or via an external multimeter). * **Edit the `calibrationData` array** in the chosen sketch with your collected voltage and mass pairs. **Ensure the data is sorted in ascending order of voltage.** The comments in the code provide guidance on the format. * Test the full range of your sensor to get accurate estimations. Masses outside the tested range might not yield reliable results. 4. **Upload the Sketch:** Open the desired `.ino` file in the Arduino IDE, select your Arduino board and port, and upload the sketch to your Arduino. 5. **Open Serial Monitor:** Open the Serial Monitor in the Arduino IDE (Tools > Serial Monitor) to see the digital output of the estimated mass and servo angle. ## Usage Once the sketch is uploaded and the hardware is connected, placing weight on the sensor will: * Display the raw sensor reading, voltage, and estimated mass in grams on the Serial Monitor. * Move the servo motor's arm to an angle proportional to the estimated mass, acting as a pointer on a scale. ## Code Explanation ### `Interpolation_Gauge_Strain_Load_Cells_Estimation.ino` and `Interpolation_FlexiForce_Estimation.ino` Both sketches share a similar structure and functionality, with the main difference being the `calibrationData` tailored to the specific sensor characteristics, since the input nature and range is the same (a voltage of range 0 to 5V). * **`#include `**: Includes the Servo library for controlling the servo motor. * **`Servo myServo;`**: Creates a `Servo` object. * **`const int sensorPin = A0;`**: Defines the analog input pin for the sensor. * **`const int servoPin = 9;`**: Defines the digital pin for the servo motor. * **`double calibrationData[][2]`**: A 2D array storing the calibration points. Each inner array contains a voltage value (in Volts) and the corresponding mass (in grams). **This array must contain your calibration data in ascending order of voltage.** * **`const int calibrationDataSize`**: Calculates the number of calibration points in the `calibrationData` array. * **`double getVoltage(int rawValue)`**: Converts the raw analog reading (0-1023) to a voltage (0-5V). * **`double getMass(double voltage)`**: This function performs linear interpolation to estimate the mass based on the measured voltage and the `calibrationData`. * It handles cases where the input voltage is outside the calibrated range by returning the mass at the closest calibration point. * It iterates through the `calibrationData` to find the voltage interval where the current voltage falls and then performs linear interpolation to estimate the corresponding mass. * It returns `-1` if there's an issue (which should not occur if the `calibrationData` is sorted correctly). * **`int massToAngle(double mass)`**: This function maps the estimated mass (currently assumed to be within a 0-500g range, but you should adjust this based on your calibration) to a servo angle between 0 and 180 degrees. **You will likely need to adjust the `map()` function's input range (0 and 500) to match the actual minimum and maximum mass values in your `calibrationData` once you have data for your full measurement range. However, nothing prevents from limiting the output while still having the calibration points.** * **`void setup()`**: Initializes serial communication and attaches the servo object to the servo pin. * **`void loop()`**: * Reads the raw analog value from the sensor. * Converts the raw value to voltage using `getVoltage()`. * Estimates the mass using `getMass()`. * Prints the raw value, voltage, and estimated mass to the Serial Monitor. * If a valid mass is estimated, it converts the mass to a servo angle using `massToAngle()`, constrains the angle within the servo's limits (0-180), and writes the angle to the servo motor. * Prints the calculated servo angle to the Serial Monitor. * Includes a small delay. ## Notes * **Calibration is critical for accurate mass estimation.** Spend time to collect good calibration data that covers the expected range of your measurements. * The linear interpolation provides an approximation of the sensor's response. For highly non-linear sensors, more calibration points will generally lead to better accuracy. * The `massToAngle()` function currently maps a 0-500g range to the servo's 0-180-degree range. **You will need to adjust the input range of the `map()` function in `massToAngle()` to reflect the actual minimum and maximum mass values you have in your `calibrationData` to utilize the full range of your sensor and the servo.** For example, if your calibration data spans 0g to 800g, you should change `map(mass, 0, 500, 0, 180)` to `map(mass, 0, 800, 0, 180)`. * Consider adding error handling or visual indicators (e.g., servo moving beyond a certain range) for masses outside the calibrated range. ## Author Charles STELANDRE ## Version V0.1 ## Date 2025/05/11