---
title: Scaffold
format:
html:
code-line-numbers: true
css: Arduino_prompts.css
execute:
enabled: false
---
```{C++}
// ===================== INCLUDES =====================
#include "Seeed_AMG8833_driver.h"
#include <Grove_I2C_Motor_Driver.h>
#include <Wire.h>
#include <stdint.h>
#include <math.h>
// ===================== CONSTANTS / GLOBALS =====================
// Motor driver settings
#define I2C_ADDRESS 0x0f
// --- CALIBRATION VALUES ---
// Replace these only after validation
float ambientTempC = AMBIENT_TEMP_C;
float boardSideCm = BOARD_SIDE_CM;
char prototypePlacement[] = PLACEMENT; // CORNER or BORDER
// --- MOTOR CONFIGURATION ---
// Keep this style similar to the original sketch
const int START_OFFSET_STEPS = 0;
int SWEEP_STEPS = 128; // update according to placement
int currentMotorPosition = 0;
// Approximate conversion between steps and angle
// AI may adjust this if needed but should keep the same idea
float stepsPerDegree = 128.0 / 90.0;
// Ultrasonic sensor pin (Grove)
const int ultrasonicPin = 5;
// Thermal camera
AMG8833 sensor;
#define ROWS 8
#define COLS 8
#define TOTAL_PIXELS 64
// ===================== HELPER FUNCTIONS =====================
// --- REQUIRED THRESHOLD FUNCTION ---
float getHotThreshold(float distanceCm, float boardSideLength, float ambientTempC) {
if (distanceCm <= 0.45 * boardSideLength) {
return 30.0;
} else if (distanceCm < 0.9 * boardSideLength) {
return ambientTempC + 38.72 * exp(-0.04661 * distanceCm);
} else {
return max(24.5, ambientTempC + 1.0);
}
}
// --- MOTOR / ANGLE HELPERS ---
// TODO:
// - set SWEEP_STEPS from placement
// - convert motor position to angle
// - keep 0° -> X° -> 0° sweep behavior
// --- ULTRASONIC HELPERS ---
long readUltrasonicDuration() {
pinMode(ultrasonicPin, OUTPUT);
digitalWrite(ultrasonicPin, LOW);
delayMicroseconds(2);
digitalWrite(ultrasonicPin, HIGH);
delayMicroseconds(10);
digitalWrite(ultrasonicPin, LOW);
pinMode(ultrasonicPin, INPUT);
return pulseIn(ultrasonicPin, HIGH, 30000);
}
float microsecondsToCentimeters(long duration) {
if (duration == 0) return -1.0;
return (duration * 0.0343) / 2.0;
}
// TODO:
// - optionally average multiple readings
// - return distance in cm
// - apply valid-range rule 5 < x < d in detection logic
// --- THERMAL HELPERS ---
// TODO:
// - read all 64 pixels
// - compute max temperature over the full matrix
// - do not use only middle columns
// --- DETECTION / REPORTING HELPERS ---
// TODO:
// - combine valid distance + thermal threshold condition
// - print:
// current distance
// current motor angle
// maximum temperature
// detection status
// ===================== SETUP =====================
void setup() {
Serial.begin(115200);
Wire.begin();
Motor.begin(I2C_ADDRESS);
Motor.stop(MOTOR1);
Motor.stop(MOTOR2);
sensor.init();
delay(1000);
// TODO:
// - choose SWEEP_STEPS based on placement
// - optionally move to starting offset
if (START_OFFSET_STEPS != 0) {
int direction = (START_OFFSET_STEPS > 0) ? 1 : -1;
int stepsToMove = abs(START_OFFSET_STEPS);
for (int i = 0; i < stepsToMove; i++) {
Motor.StepperRun(direction, 0, 0);
delay(10);
}
currentMotorPosition = START_OFFSET_STEPS;
}
}
// ===================== MAIN LOOP =====================
void loop() {
currentMotorPosition = 0;
delay(500);
// ---------- Sweep Forward 0 -> X ----------
for (int i = 0; i < SWEEP_STEPS; i++) {
Motor.StepperRun(1, 0, 0);
currentMotorPosition++;
// TODO:
// - compute current angle in degrees
// - read ultrasonic sensor
// - read all thermal pixels and max temperature
// - compute threshold
// - detect only if:
// valid distance AND maxTemp > threshold
// - print serial status
delayMicroseconds(5000);
}
delay(2000);
// ---------- Sweep Backward X -> 0 ----------
for (int i = 0; i < SWEEP_STEPS; i++) {
Motor.StepperRun(-1, 0, 0);
currentMotorPosition--;
// TODO:
// - same logic as forward sweep
// - keep angle tracking consistent
delayMicroseconds(5000);
}
delay(2000);
}
```
# Prompt blocks
## Block A - Includes
```{text}
You are editing an Arduino Uno `.ino` sketch step by step.
RULES
- Keep the code very similar to the provided sketch in structure, naming style, and general style.
- Do not redesign the project architecture.
- Keep the section order:
1. includes
2. constants / globals
3. helper functions
4. setup
5. loop
- Keep the sketch compilable after this step.
- Return the full updated sketch.
- Modify only what is needed for this step.
TASK FOR THIS STEP
Review only the INCLUDES section.
Use these includes exactly:
- #include "Seeed_AMG8833_driver.h"
- #include <Grove_I2C_Motor_Driver.h>
- #include <Wire.h>
- #include <stdint.h>
You may add only strictly necessary standard Arduino/math includes if required for compilation.
Do not change the rest of the sketch unless strictly necessary.
SECTION TO REVIEW
// ===================== INCLUDES =====================
#include "Seeed_AMG8833_driver.h"
#include <Grove_I2C_Motor_Driver.h>
#include <Wire.h>
#include <stdint.h>
#include <math.h>
CURRENT FULL CODE
[PASTE THE INITIAL SCAFFOLD HERE]
```
## Block B - Constants / Globals
```{text}
You are editing the next step of the same Arduino Uno sketch.
RULES
- Keep the code very similar to the current version.
- Return the full updated sketch.
- Work mainly on the constants / globals section.
- Make only minimal necessary edits elsewhere.
- Do not invent or replace final calibration values.
- Keep the calibration section parameterized using:
- AMBIENT_TEMP_C
- BOARD_SIDE_CM
- PLACEMENT
TASK FOR THIS STEP
Complete and refine the CONSTANTS / GLOBALS section.
Requirements:
- preserve the current coding style
- keep similar names already present
- keep:
- float ambientTempC = AMBIENT_TEMP_C;
- float boardSideCm = BOARD_SIDE_CM;
- char prototypePlacement[] = PLACEMENT;
- keep currentMotorPosition logic
- keep motor configuration simple
- keep TOTAL_PIXELS = 64
- do not implement the full loop logic yet
SECTION TO REVIEW
// ===================== CONSTANTS / GLOBALS =====================
// Motor driver settings
#define I2C_ADDRESS 0x0f
// --- CALIBRATION VALUES ---
// Replace these only after validation
float ambientTempC = AMBIENT_TEMP_C;
float boardSideCm = BOARD_SIDE_CM;
char prototypePlacement[] = PLACEMENT; // CORNER or BORDER
// --- MOTOR CONFIGURATION ---
// Keep this style similar to the original sketch
const int START_OFFSET_STEPS = 0;
int SWEEP_STEPS = 128; // update according to placement
int currentMotorPosition = 0;
// Approximate conversion between steps and angle
// AI may adjust this if needed but should keep the same idea
float stepsPerDegree = 128.0 / 90.0;
// Ultrasonic sensor pin (Grove)
const int ultrasonicPin = 5;
// Thermal camera
AMG8833 sensor;
#define ROWS 8
#define COLS 8
#define TOTAL_PIXELS 64
CURRENT FULL CODE
[PASTE FULL CODE RETURNED BY BLOCK A HERE]
```
## Block C - Threshold + monitor / angle helpers
```{text}
You are editing the next step of the same Arduino Uno sketch.
RULES
- Keep the code very similar to the current version.
- Return the full updated sketch.
- Work mainly on the threshold function and motor / angle helper section.
- Make only minimal necessary edits elsewhere.
- Do not invent or replace final calibration values.
TASK FOR THIS STEP
Complete the threshold and motor / angle helper logic.
Requirements:
- keep this threshold function exactly as required:
float getHotThreshold(float distanceCm, float boardSideLength, float ambientTempC) {
if (distanceCm <= 0.45 * boardSideLength) {
return 30.0;
} else if (distanceCm < 0.9 * boardSideLength) {
return ambientTempC + 38.72 * exp(-0.04661 * distanceCm);
} else {
return max(24.5, ambientTempC + 1.0);
}
}
- keep the original style simple
- set sweep behavior from placement
- CORNER => 90°
- BORDER => 180°
- track motor angle in degrees
- keep currentMotorPosition logic similar to the original code
- do not redesign the whole project
SECTION TO REVIEW
// --- REQUIRED THRESHOLD FUNCTION ---
float getHotThreshold(float distanceCm, float boardSideLength, float ambientTempC) {
if (distanceCm <= 0.45 * boardSideLength) {
return 30.0;
} else if (distanceCm < 0.9 * boardSideLength) {
return ambientTempC + 38.72 * exp(-0.04661 * distanceCm);
} else {
return max(24.5, ambientTempC + 1.0);
}
}
// --- MOTOR / ANGLE HELPERS ---
// TODO:
// - set SWEEP_STEPS from placement
// - convert motor position to angle
// - keep 0° -> X° -> 0° sweep behavior
CURRENT FULL CODE
[PASTE FULL CODE RETURNED BY BLOCK B HERE]
```
## Block D - Ultrasonic low-level helpers
```{text}
You are editing the next step of the same Arduino Uno sketch.
RULES
- Keep the code very similar to the current version.
- Return the full updated sketch.
- Work mainly on the low-level ultrasonic helper section.
- Make only minimal necessary edits elsewhere.
TASK FOR THIS STEP
Review and refine the low-level ultrasonic helpers.
Requirements:
- keep the existing style and structure if possible
- keep readUltrasonicDuration()
- keep microsecondsToCentimeters()
- return distance in cm from pulse duration
- keep the code simple and suitable for Arduino Uno
- do not implement full detection logic here
SECTION TO REVIEW
// --- ULTRASONIC HELPERS ---
long readUltrasonicDuration() {
pinMode(ultrasonicPin, OUTPUT);
digitalWrite(ultrasonicPin, LOW);
delayMicroseconds(2);
digitalWrite(ultrasonicPin, HIGH);
delayMicroseconds(10);
digitalWrite(ultrasonicPin, LOW);
pinMode(ultrasonicPin, INPUT);
return pulseIn(ultrasonicPin, HIGH, 30000);
}
float microsecondsToCentimeters(long duration) {
if (duration == 0) return -1.0;
return (duration * 0.0343) / 2.0;
}
CURRENT FULL CODE
[PASTE FULL CODE RETURNED BY BLOCK C HERE]
```
## Block E - Ultrasonic distance logic
```{text}
You are editing the next step of the same Arduino Uno sketch.
RULES
- Keep the code very similar to the current version.
- Return the full updated sketch.
- Work mainly on the remaining ultrasonic helper logic.
- Make only minimal necessary edits elsewhere.
TASK FOR THIS STEP
Complete the higher-level ultrasonic distance logic.
Requirements:
- you may add a helper to average multiple readings
- valid distance rule is exactly:
5 < x < d
- out-of-range values must not count as detection later
- use boardSideCm as d
- keep the code simple and readable
- do not implement final detection logic here unless minimally necessary
SECTION TO REVIEW
// TODO:
// - optionally average multiple readings
// - return distance in cm
// - apply valid-range rule 5 < x < d in detection logic
CURRENT FULL CODE
[PASTE FULL CODE RETURNED BY BLOCK D HERE]
```
## Block F - Thermal helpers
```{text}
You are editing the next step of the same Arduino Uno sketch.
RULES
- Keep the code very similar to the current version.
- Return the full updated sketch.
- Work mainly on the thermal helper section.
- Make only minimal necessary edits elsewhere.
TASK FOR THIS STEP
Complete the thermal helper logic.
Requirements:
- read the full 8x8 AMG8833 temperature matrix
- compute the maximum temperature across all 64 pixels
- do not use only middle columns
- keep the code simple and readable
- keep memory usage suitable for Arduino Uno
SECTION TO REVIEW
// --- THERMAL HELPERS ---
// TODO:
// - read all 64 pixels
// - compute max temperature over the full matrix
// - do not use only middle columns
CURRENT FULL CODE
[PASTE FULL CODE RETURNED BY BLOCK E HERE]
```
## Block G - Detection / reporting helpers
```{text}
You are editing the next step of the same Arduino Uno sketch.
RULES
- Keep the code very similar to the current version.
- Return the full updated sketch.
- Work mainly on the detection / reporting helper section.
- Make only minimal necessary edits elsewhere.
TASK FOR THIS STEP
Complete the detection and reporting logic.
Requirements:
- target is detected only if both are true:
- distance is valid
- maximum temperature > getHotThreshold(distanceCm, boardSideCm, ambientTempC)
- serial output must show:
- current distance
- current motor angle
- maximum temperature
- detection status
- keep the style similar to the original sketch
- avoid String and dynamic memory
SECTION TO REVIEW
// --- DETECTION / REPORTING HELPERS ---
// TODO:
// - combine valid distance + thermal threshold condition
// - print:
// current distance
// current motor angle
// maximum temperature
// detection status
CURRENT FULL CODE
[PASTE FULL CODE RETURNED BY BLOCK F HERE]
```
## Block H - Setup
```{text}
You are editing the next step of the same Arduino Uno sketch.
RULES
- Keep the code very similar to the current version.
- Return the full updated sketch.
- Work mainly on setup().
- Make only minimal necessary edits elsewhere.
- Do not invent or replace final calibration values.
TASK FOR THIS STEP
Complete setup() consistently with the helper logic already created.
Requirements:
- initialize Serial
- initialize Wire
- initialize motor driver
- initialize AMG8833 sensor
- keep optional start offset behavior
- set any sweep configuration needed from placement
- do not redesign the structure
SECTION TO REVIEW
// ===================== SETUP =====================
void setup() {
Serial.begin(115200);
Wire.begin();
Motor.begin(I2C_ADDRESS);
Motor.stop(MOTOR1);
Motor.stop(MOTOR2);
sensor.init();
delay(1000);
// TODO:
// - choose SWEEP_STEPS based on placement
// - optionally move to starting offset
if (START_OFFSET_STEPS != 0) {
int direction = (START_OFFSET_STEPS > 0) ? 1 : -1;
int stepsToMove = abs(START_OFFSET_STEPS);
for (int i = 0; i < stepsToMove; i++) {
Motor.StepperRun(direction, 0, 0);
delay(10);
}
currentMotorPosition = START_OFFSET_STEPS;
}
}
CURRENT FULL CODE
[PASTE FULL CODE RETURNED BY BLOCK G HERE]
```
## Block I - Main loop
```{text}
You are editing the next step of the same Arduino Uno sketch.
RULES
- Keep the code very similar to the current version.
- Return the full updated sketch.
- Work mainly on loop().
- Make only minimal necessary edits elsewhere.
- Do not invent or replace final calibration values.
TASK FOR THIS STEP
Complete the logic inside the main loop.
Requirements:
- preserve the current forward / backward sweep structure
- forward sweep must go from 0° to X°
- backward sweep must go from X° to 0°
- read sensors at each motor step
- use the already defined detection logic
- keep angle tracking consistent in both directions
- keep serial reporting active
SECTION TO REVIEW
// ===================== MAIN LOOP =====================
void loop() {
currentMotorPosition = 0;
delay(500);
// ---------- Sweep Forward 0 -> X ----------
for (int i = 0; i < SWEEP_STEPS; i++) {
Motor.StepperRun(1, 0, 0);
currentMotorPosition++;
// TODO:
// - compute current angle in degrees
// - read ultrasonic sensor
// - read all thermal pixels and max temperature
// - compute threshold
// - detect only if:
// valid distance AND maxTemp > threshold
// - print serial status
delayMicroseconds(5000);
}
delay(2000);
// ---------- Sweep Backward X -> 0 ----------
for (int i = 0; i < SWEEP_STEPS; i++) {
Motor.StepperRun(-1, 0, 0);
currentMotorPosition--;
// TODO:
// - same logic as forward sweep
// - keep angle tracking consistent
delayMicroseconds(5000);
}
delay(2000);
}
CURRENT FULL CODE
[PASTE FULL CODE RETURNED BY BLOCK H HERE]
```
## Block J - Final calibration
```{text}
You are editing the final step of the same Arduino Uno `.ino` sketch.
RULES
- Keep the code very similar to the current version.
- This is the final calibration step.
- If one or more required calibration inputs are missing, ask only for the missing ones and do not return code yet.
- If all required calibration inputs are available and valid, update only the calibration-related part of the code and return the full final sketch.
- Make only minimal necessary edits elsewhere.
- Do not redesign the code.
REQUIRED CALIBRATION INPUTS
1. Ambient temperature in °C
2. Square board side length `d` in cm, with `d <= 100`
3. Prototype placement
VALIDATION RULES
- Prototype placement must be either `CORNER` or `BORDER`
- Accept the value case-insensitively and normalize it to uppercase before validation
- If the normalized value is neither `CORNER` nor `BORDER`, ask again only for prototype placement and do not generate code
- Board size must be a numeric value in cm and must be `<= 100`
- Ambient temperature must be a numeric value in °C
- Do not invent missing calibration values
WHAT TO DO IN THIS STEP
- Check whether the required calibration inputs are already available in the conversation
- If one or more are missing, ask only for the missing ones
- If all are valid, update only this calibration section:
// --- CALIBRATION VALUES ---
// Replace these only after validation
float ambientTempC = AMBIENT_TEMP_C;
float boardSideCm = BOARD_SIDE_CM;
char prototypePlacement[] = PLACEMENT; // CORNER or BORDER
- Replace:
- AMBIENT_TEMP_C
- BOARD_SIDE_CM
- PLACEMENT
with the validated values
- Keep the rest of the sketch as unchanged as possible
- Return the full final updated sketch
CURRENT FULL CODE
[PASTE FULL CODE RETURNED BY BLOCK I HERE]
```