Week 17: Project Development
This page gives further detail on development of:
Other topics were covered in week 15.
- project programs
- slide & video creation
Project Programs
The programs were made in Arduino IDE, and with help from perplexity.ai. We used the method of spiral development in our programs we start from using each one of our peripherals, making sure we understood its code and proper use separately before bringing them together.
Here's the minimalistic program to read values of Hall Effect sensor:
void setup() {
Serial.begin(9600);
}
void loop() {
int sensorValue = analogRead(D1);
Serial.println(sensorValue);
delay(1);
}
Here's minimalistic usage of RFID card reader:
#include
#include
#define RST_PIN D3
#define SS_PIN D7
MFRC522 mfrc522(SS_PIN, RST_PIN);
void setup() {
Serial.begin(115200);
SPI.begin();
mfrc522.PCD_Init();
Serial.println("Place your card near the reader...");
}
String uidToString() {
String uid = "";
for (byte i = 0; i < mfrc522.uid.size; i++) {
uid += (mfrc522.uid.uidByte[i] < 0x10 ? "0" : "");
uid += String(mfrc522.uid.uidByte[i], HEX);
}
uid.toUpperCase();
return uid;
}
void loop() {
// Look for a new card
if (!mfrc522.PICC_IsNewCardPresent()) {
return;
}
// Select one of the cards
if (!mfrc522.PICC_ReadCardSerial()) {
return;
}
// Convert UID to string
String UID = uidToString();
// Lookup name by UID (REPLACE these UIDs with your actual card UIDs)
String personName = "Unknown Card";
if (UID == "04A1B2C3") {
personName = "John Doe";
} else if (UID == "83BE0715") {
personName = "Saheen Smith";
} else if (UID == "045A100AD17780") {
personName = "Turkish Delight";
} else if (UID == "057441AF") {
personName = "Mr Tom";
}
// Print to serial monitor
Serial.println("=== CARD DETECTED ===");
Serial.print("UID: ");
Serial.println(UID);
Serial.print("Name: ");
Serial.println(personName);
Serial.println("====================");
Serial.println();
// Halt PICC
mfrc522.PICC_HaltA();
}
Here's the minimal usage of the VEX 393 Motor, used as a servo with values of 1000/1500/2000 for pulse widths. The following program simply rotates the motor in one way for a second, then the other way for a second, with one second pauses in between.
// 360° (continuous rotation) servo control
// for Seeed XIAO ESP32-C6 with ESP32 core 3.x
// Use any suitable digital pin; D2 is fine.
const int SERVO_PIN = D6;
// LEDC (PWM) config
const int LEDC_FREQUENCY = 50; // 50 Hz for servos
const int LEDC_RESOLUTION = 16; // 16-bit resolution
// Pulse widths in microseconds
const int PULSE_MIN_US = 1000; // full speed one direction
const int PULSE_STOP_US = 1500; // stop (tune this for your servo)
const int PULSE_MAX_US = 2000; // full speed other direction
// Convert microseconds to LEDC duty value
uint32_t pulseUsToDuty(int us) {
const float periodUs = 1000000.0f / LEDC_FREQUENCY; // 1/f (50 Hz -> 20000 us)
uint32_t maxDuty = (1 << LEDC_RESOLUTION) - 1; // e.g. 65535 for 16-bit
return (uint32_t)((us / periodUs) * maxDuty);
}
// Set servo pulse width
void setServoPulse(int us) {
uint32_t duty = pulseUsToDuty(us);
// In core 3.x, ledcWrite takes the *pin* instead of the channel
ledcWrite(SERVO_PIN, duty);
}
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("XIAO ESP32-C6 360-degree servo demo (core 3.x)");
// New API in ESP32 core 3.x:
// ledcAttach(pin, freq, resolutionBits)
ledcAttach(SERVO_PIN, LEDC_FREQUENCY, LEDC_RESOLUTION);
// Start with servo stopped
setServoPulse(PULSE_STOP_US);
}
void loop() {
Serial.println("Stop");
setServoPulse(PULSE_STOP_US);
delay(1000);
Serial.println("Rotate direction A (full speed)");
setServoPulse(PULSE_MIN_US); // one direction
delay(1000);
Serial.println("Stop");
setServoPulse(PULSE_STOP_US);
delay(1000);
Serial.println("Rotate direction B (full speed)");
setServoPulse(PULSE_MAX_US); // opposite direction
delay(1000);
}
Finally, here's the minimal usage of OLED displays
#include
#include
#include
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
// Display 1 at address 0x3C (default)
Adafruit_SSD1306 display1(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Display 2 at address 0x3D (modified)
Adafruit_SSD1306 display2(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup() {
Serial.begin(115200);
// Init display 1
if(!display1.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("Display1 failed"));
for(;;);
}
// Init display 2
if(!display2.begin(SSD1306_SWITCHCAPVCC, 0x3D)) {
Serial.println(F("Display2 failed"));
for(;;);
}
display1.clearDisplay(); display1.setTextSize(1); display1.setTextColor(SSD1306_WHITE);
display1.setCursor(0,0); display1.println(F("Display 1 - Temp")); display1.display();
display2.clearDisplay(); display2.setTextSize(1); display2.setTextColor(SSD1306_WHITE);
display2.setCursor(0,0); display2.println(F("Display 2 - Uptime")); display2.display();
}
void loop() {
// Update Display 1 (e.g., fake temp)
display1.clearDisplay(); display1.setCursor(0,0);
display1.print(F("Temp: ")); display1.print(random(20,30)); display1.println(F("C"));
display1.display();
// Update Display 2 (uptime)
display2.clearDisplay(); display2.setCursor(0,0);
display2.print(F("Uptime: ")); display2.print(millis()/1000); display2.println(F("s"));
display2.display();
delay(1000);
}
Now that we have verified that each of 2 input and each of 2 output sensors work, we can proceed to combining and developing their use in the project.
Slide & Video Creation
The slide was made in inkscape...
The video was made in capcut desktop...