> ## Documentation Index
> Fetch the complete documentation index at: https://stem-docs.intellectualpoint.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Sensor validation

> Run the test suite to verify every sensor and actuator on your robot, troubleshoot failures, and confirm your robot is ready for Day 2.

## Time estimate

<Info>
  **Scheduled time:** 11:35 AM – 12:15 PM (40 minutes)
</Info>

Your PiCar-X has an ultrasonic distance sensor, a 3-channel grayscale sensor, three servos, two DC drive motors, a camera, a battery pack, and a speaker. Before you write any code that depends on these, you need to prove every one of them works. The test suite walks you through each component one by one.

***

## Running the test suite

<Steps>
  <Step title="SSH into your robot">
    Open a terminal and connect to your Pi over SSH. Use the hostname and username you set during imaging.

    ```bash theme={null}
    ssh car@picar.local
    ```
  </Step>

  <Step title="Launch the test script">
    Run the test suite with `sudo` (required for hardware access):

    ```bash theme={null}
    sudo python3 ~/camp/day1/test_all_sensors.py
    ```

    The script initializes the PiCar-X hardware and drops you into an interactive menu.
  </Step>

  <Step title="Use the menu">
    You see a menu like this:

    ```
    ============================================================
      PiCar-X  —  Sensor & Actuator Test Menu
    ============================================================
        1.  [ — ]  Ultrasonic Sensor
        2.  [ — ]  Grayscale Sensor
        3.  [ — ]  Servos
        4.  [ — ]  DC Motors
        5.  [ — ]  Camera
        6.  [ — ]  Battery / Speaker

        a.  Run ALL tests
        r.  Show results summary
        q.  Quit
    ============================================================
    ```

    * Type **1–6** to run a single test.
    * Type **a** to run every test in order.
    * Type **r** to print a results summary at any time.
    * Type **q** to quit (the summary prints automatically on exit).

    You can re-run any test as many times as you want. The menu updates with **\[PASS]**, **\[FAIL]**, or **\[SKIP]** after each test.
  </Step>

  <Step title="Confirm each result">
    At the end of every test, the script asks:

    ```
    Did the <test name> test work?  [y]es / [n]o / [s]kip:
    ```

    * Press **y** if the hardware behaved as expected.
    * Press **n** if something was wrong.
    * Press **s** if you want to skip it for now.

    You can always come back and re-run a test to change your answer.
  </Step>
</Steps>

<Tip>
  Press **Ctrl-C** during any test to skip the remaining readings and jump straight to the pass/fail prompt.
</Tip>

***

## Each test in detail

### Test 1 — Ultrasonic distance sensor

<Accordion title="What does this test do?">
  The script reads the HC-SR04 ultrasonic sensor **10 times**, one reading per second. Each reading shows the distance to the nearest object in centimeters, along with a small bar chart.

  ```
  Reading  1/10  |  Distance:   23.45 cm  |  #######################
  Reading  2/10  |  Distance:   12.10 cm  |  ############
  Reading  3/10  |  Distance:     — cm    |  (no echo — nothing in range)
  ```
</Accordion>

**What you should see:** distance values that change as you move your hand closer to and farther from the two round "eyes" on the front of the robot.

**Expected range:** 2–400 cm. A value of **–1.00** (displayed as `—`) means "no echo received" — the sensor didn't detect anything within range. This is normal if nothing is in front of the robot.

**PASS criteria:** values change when you move your hand near the sensor.

<Warning>
  If every single reading is `—` (no echo), the ultrasonic module may not be connected. Power off the robot, check the 4-pin cable between the sensor and the Robot HAT, then re-run the test.
</Warning>

***

### Test 2 — Grayscale sensor

<Accordion title="What does this test do?">
  The script reads all **3 channels** (Left, Center, Right) of the grayscale sensor module 10 times, one reading per second. It also reports the **cliff detection** status and line-following status for each reading.

  ```
     #      Left    Center     Right    Cliff?    Line status
     —      ————    ——————     —————    ——————    ———————————
     1     1024.0   1100.5     980.3        no         0
     2      320.0   1095.2     970.1        no         1
  ```
</Accordion>

**What you should see:**

* **High values** (800–1400) on light surfaces (white paper, light-colored desk).
* **Low values** (100–400) on dark surfaces (black tape, dark paper).

**PASS criteria:** values are responsive to surface changes. Place something dark under one sensor at a time and watch that channel drop. If you calibrated in the previous step, the **Cliff** column should show `no` on a normal surface and `YES` when the sensor is lifted off the table.

<Tip>
  If all three channels read very similar values regardless of surface color, the sensor may be too far from the surface. Make sure the robot is sitting flat on the table with the grayscale module close to the surface.
</Tip>

***

### Test 3 — Servos

<Accordion title="What does this test do?">
  The script sweeps all **3 servos** through their full range of motion (–35° to +35°), one at a time:

  1. **Steering servo** — turns the front wheels left and right.
  2. **Camera pan servo** — rotates the camera horizontally.
  3. **Camera tilt servo** — tilts the camera up and down.

  Each servo sweeps out, sweeps back, and returns to center (0°).
</Accordion>

**What you should see:** smooth, continuous movement on each axis. All three servos return to center when the sweep finishes.

**PASS criteria:** all 3 servos move without grinding, stuttering, or stalling.

<AccordionGroup>
  <Accordion title="Servo movement is jerky or stuttering">
    This almost always means **low battery**. The servos draw significant current during movement. Charge your batteries and try again.
  </Accordion>

  <Accordion title="One or more servos don't move at all">
    Power off the robot and check the servo cable connections on the Robot HAT. Each servo plugs into a specific 3-pin header — make sure none are loose or plugged into the wrong port.
  </Accordion>
</AccordionGroup>

***

### Test 4 — DC motors

<Warning>
  **Prop the car up on a book or box, or clear a large space on the table before running this test.** The wheels will spin and the car will drive forward and backward.
</Warning>

<Accordion title="What does this test do?">
  The script runs both DC drive motors at **30% speed**:

  1. **Forward** for 2 seconds.
  2. **Pause** for half a second.
  3. **Backward** for 2 seconds.
  4. **Stop.**
</Accordion>

**What you should see:** both wheels spin forward together, then both spin backward together.

**PASS criteria:** both wheels spin and the car moves in the correct direction (forward first, then backward).

<AccordionGroup>
  <Accordion title="Car goes backward when it should go forward">
    The motor direction needs to be swapped. Run the calibration script again and use **option 2** (motor direction):

    ```bash theme={null}
    sudo python3 ~/camp/day1/calibrate_picar.py
    ```

    Select option `2`, then follow the prompts to reverse the motor direction.
  </Accordion>

  <Accordion title="Only one wheel spins">
    Check the motor cable connections on the Robot HAT. One of the two motor connectors may be loose.
  </Accordion>

  <Accordion title="Neither wheel spins">
    Make sure the Robot HAT power switch is **on** and batteries are charged. Motors require more current than sensors — a low battery can power the Pi but not the motors.
  </Accordion>
</AccordionGroup>

***

### Test 5 — Camera

<Accordion title="What does this test do?">
  The script captures a single still image and saves it to `~/test_capture.jpg`. It uses `picamera2` if available, falling back to `libcamera-still`. After capturing, it prints the file size so you can verify the image is real.

  ```
  Image saved to /home/car/test_capture.jpg
  File size: 1,245,678 bytes
  [INFO] Looks good — file is large enough to be a real image.
  ```
</Accordion>

**What you should see:** an "Image saved" message with a file size **greater than 1,000 bytes**.

**PASS criteria:** the file is created and is large enough to be a real image (not a 0-byte placeholder).

<Tip>
  You can copy the test image to your laptop to view it:

  ```bash theme={null}
  scp car@picar.local:~/test_capture.jpg .
  ```

  Open the file on your computer to confirm the camera captured a real photo.
</Tip>

<AccordionGroup>
  <Accordion title="&#x22;Camera not found&#x22; or capture failed">
    The CSI ribbon cable is likely loose. Power off the Pi, gently reseat the flat ribbon cable where it plugs into the camera port on the Pi, and make sure the locking clip is pushed down. Then power back on and re-run the test.
  </Accordion>

  <Accordion title="File size is 0 or very small">
    The camera module may be defective or the ribbon cable is partially disconnected. Try reseating the cable at both ends (the camera board and the Pi board).
  </Accordion>
</AccordionGroup>

***

### Test 6 — Battery and speaker

This test has two parts.

#### Battery voltage

<Accordion title="What does this test do?">
  The script reads the battery voltage from the Robot HAT's ADC (analog-to-digital converter) on channel **A4**. It converts the raw ADC reading to a voltage estimate.

  ```
  ADC raw value : 3150
  Est. voltage  : 7.62 V
  [INFO] Battery looks healthy (> 6V)
  ```
</Accordion>

The PiCar-X uses **2S 18650 Li-ion batteries** (two cells in series). Here is how to interpret the voltage reading:

| Voltage     | Status      | Action                                                                       |
| ----------- | ----------- | ---------------------------------------------------------------------------- |
| \~8.4 V     | Full charge | You're good to go                                                            |
| 7.0–8.4 V   | OK          | Normal operating range                                                       |
| 6.0–7.0 V   | Low         | Charge soon — some features (speaker, motors) may underperform               |
| Below 6.0 V | Critical    | **Stop and charge immediately** — the cells can be damaged by deep discharge |

<Note>
  You can monitor battery voltage at any time without running the full test suite:

  ```bash theme={null}
  python3 ~/camp/day1/battery_check.py
  ```

  For live monitoring that updates every 2 seconds, add the `--watch` flag:

  ```bash theme={null}
  python3 ~/camp/day1/battery_check.py --watch
  ```

  Press **Ctrl-C** to stop the live monitor.
</Note>

#### Speaker

<Accordion title="What does this test do?">
  The script plays a **4-second sine wave test tone** through the Robot HAT's onboard speaker, then follows up with a **text-to-speech** phrase ("Hello. Picar X speaker test.") using `espeak`.
</Accordion>

**What you should hear:** a steady tone for about 4 seconds, then a robotic voice saying "Hello. Picar X speaker test."

**PASS criteria:** you hear the tone and/or the voice clearly.

<Info>
  The speaker is powered through the battery, not the USB port. You need **charged batteries (above 7 V)** for the onboard amplifier to produce audible sound. If you don't hear anything, check your battery voltage first.
</Info>

***

## Results summary

After you finish all six tests (or whenever you want a status check), press **r** at the menu to see the summary:

```
============================================================
  TEST RESULTS SUMMARY
============================================================
  [PASS]  Ultrasonic Sensor
  [PASS]  Grayscale Sensor
  [PASS]  Servos
  [PASS]  DC Motors
  [PASS]  Camera
  [SKIP]  Battery / Speaker

  5/6 passed, 0 failed, 1 skipped, 0 not run
============================================================
```

**Your goal: all 6 tests show \[PASS].**

<Note>
  It's OK if the speaker shows **\[SKIP]** because your batteries are low. You can always test the speaker later after charging. Everything else should be **\[PASS]** before you move on to Day 2.
</Note>

***

## Troubleshooting

| Symptom                                   | Likely cause                | Fix                                                                     |
| ----------------------------------------- | --------------------------- | ----------------------------------------------------------------------- |
| All tests fail or script errors on launch | Robot HAT not powered on    | Turn on the power switch on the Robot HAT board                         |
| Ultrasonic always reads `—` (no echo)     | Sensor not connected        | Check the 4-pin cable between the HC-SR04 module and the Robot HAT      |
| Servos don't move                         | Low battery                 | Charge batteries above 7 V and re-run                                   |
| Camera error or "not found"               | CSI ribbon cable loose      | Power off, reseat the ribbon cable, power on                            |
| No speaker sound                          | Battery below 7 V           | Charge batteries — the amplifier needs sufficient voltage               |
| Motors go the wrong direction             | Not calibrated              | Run `sudo python3 ~/camp/day1/calibrate_picar.py` and use option 2      |
| Only one motor spins                      | Loose motor cable           | Check both motor connectors on the Robot HAT                            |
| Grayscale values don't change             | Sensor too far from surface | Make sure the robot sits flat with the sensor module close to the table |

<Tip>
  **Quick fixes with the troubleshoot script:**

  * **Speaker not working?** Run `bash ~/camp/troubleshoot.sh` and select option 1.
  * **Camera not working?** Run `bash ~/camp/troubleshoot.sh` and select option 2.
</Tip>

***

## Day 1 wrap-up

<Check>
  **Checkpoint:** every student ends Day 1 with all sensors showing **\[PASS]** and a confirmed SSH connection to their robot.
</Check>

### What you accomplished today

* Imaged an SD card with Raspberry Pi OS and configured Wi-Fi, SSH, and Pi Connect.
* Connected to your PiCar-X over SSH for the first time.
* Installed all SunFounder libraries (robot-hat, vilib, picar-x).
* Calibrated the steering servo, motor direction, and grayscale cliff threshold.
* Validated every sensor and actuator on the robot with the test suite.

### What's coming on Day 2

Tomorrow you start writing real programs for your robot:

* **Movement programs** — drive in patterns, steer with code, and control speed.
* **Text-to-speech** — make the robot talk using `espeak`.
* **Line following** — use the grayscale sensor to follow a track.
* **Computer vision** — process camera frames to detect objects and colors.

<Note>
  **Homework:** leave your robot **powered on** and **connected to Wi-Fi** overnight. Tomorrow morning you should be able to SSH right in and start coding without any setup delay.
</Note>
