Welcome to N-n-n-n-NETWORKING week.
For Networking my idea was to use the touch capacitive component change the color
of the circle on my website remotely! So anywhere any time i can touch the device and it
changes the color of the circle for ANYONE viewing my website! (I also added a
button to the top of my website to simulate this :p)
Here's a video of the final product in action:
And here's how the networking feature appears on every page of this website:
I worked with Kye to program an ESP32 C6 microcontroller to make HTTP POST requests to a web server. The code below shows how we implemented the touch sensing and networking functionality:
#include
#include
#define SENSE_PIN 2 // Pin used for analog input reading (sensor pin)
#define LED_PIN 17 // Pin used to control an LED based on sensor data
#define SOUND_PIN 16 // Pin used for sound output (buzzer or speaker)
#define SETTLE 5 // Delay time (not used in this version of the code)
#define N_SAMPLES 256 // Number of samples to take for averaging the sensor readings
#define THRESHOLD 180000 // The threshold to trigger the LED and sound
#define STASSID "MIT" // Replace with your WiFi SSID
#define STAPSK "******" // Replace with your WiFi password
#define URL "https://postreqtest.glitch.me/update-value"
void setup() {
// Initialize the serial communication at 115200 baud rate for debugging or output
Serial.begin(115200);
Serial.println();
Serial.println();
Serial.println();
WiFi.begin(STASSID, STAPSK);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected! IP address: ");
Serial.println(WiFi.localIP());
// Set the analog reading resolution to 10 bits (0-1023 range)
analogReadResolution(10);
// Set the LED pin and sound pin as output pins
pinMode(LED_PIN, OUTPUT);
pinMode(SOUND_PIN, OUTPUT);
}
void loop() {
// Initialize count as a 64-bit integer to accumulate the sensor readings
int64_t count = 0;
// Loop to take N_SAMPLES (256) analog readings from the sensor pin
for (int i = 0; i < N_SAMPLES; ++i) {
// Set the sense pin to output, then drive it HIGH
pinMode(SENSE_PIN, OUTPUT);
digitalWrite(SENSE_PIN, HIGH); // Drive the pin high to charge any capacitance on the pin
// Change the sense pin back to input, so it can read the analog signal
pinMode(SENSE_PIN, INPUT);
// Read the analog value from the sensor pin and add it to the count
count += analogRead(SENSE_PIN);
}
// Check if the accumulated count from sensor readings exceeds the threshold
if (count > THRESHOLD) { // If count exceeds 180,000 (a threshold for sensor readings)
// If threshold is surpassed, turn on the LED
if ((WiFi.status() == WL_CONNECTED)) {
HTTPClient http;
Serial.print("[HTTP] begin...\n");
// configure target server and URL
http.begin(URL);
http.addHeader("Content-Type", "application/json");
Serial.print("[HTTP] POST...\n");
// Prepare JSON payload
String payload = "{\"value\": 1}";
// start connection and send HTTP header and body
int httpCode = http.POST(payload);
// httpCode will be negative on error
if (httpCode > 0) {
// HTTP header has been sent and Server response header has been handled
Serial.printf("[HTTP] POST... code: %d\n", httpCode);
// file found at server
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_CREATED) {
const String& response = http.getString();
Serial.println("Received response:\n<<");
Serial.println(response);
Serial.println(">>");
}
} else {
Serial.printf("[HTTP] POST... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
}
digitalWrite(LED_PIN, HIGH);
// Play a sound using the buzzer/speaker
tone(SOUND_PIN, 1000); // Play a 1000 Hz tone (you can change the frequency as needed)
} else {
// If the threshold is not surpassed, turn off the LED
digitalWrite(LED_PIN, LOW);
// Stop playing the sound
noTone(SOUND_PIN); // Stop any sound that is currently playing
}
// Delay for 2 milliseconds before taking the next set of samples
delay(2);
}
After consulting with Char about server implementation, I set up a server on Glitch with some help from Claude. I ran into CORS issues initially, but Kai helped me resolve them by adding CORS support using Node.js.
For the server side, I created a simple Express.js server on Glitch that listens for POST requests. The server stores the most recent value and serves it to any clients that request it. Initially, we ran into CORS issues when trying to access the server from different domains, but we resolved this by adding proper CORS middleware to the Express server.
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const cors = require('cors');
let currentValue = 0;
app.use(bodyParser.json());
app.use(cors());
// Serve the static HTML file
app.use(express.static('path_to_html_directory')); // Replace with the directory containing your HTML file
// Endpoint to get the current value
app.get('/get-value', (req, res) => {
res.json({ value: currentValue });
});
app.use(express.static(__dirname)); // Serve files from the current directory
// Endpoint to update the value
app.post('/update-value', (req, res) => {
if (req.body.value !== undefined) {
currentValue = currentValue + req.body.value;
res.status(200).send('Value updated successfully');
} else {
res.status(400).send('Invalid value');
}
});
// Start the server
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});
function windowResized() {
resizeCanvas(windowWidth, windowHeight); // Ensure canvas resizes with window
}
let val = 0;
let currentValue = 0;
let circleColor;
// p5.js setup function
function setup() {
let canvas = createCanvas(windowWidth, windowHeight);
canvas.position(0, 0);
canvas.style('z-index', '-1'); // Ensure the canvas is behind the HTML
circleColor = color(255,255,255); // Start with red
}
// p5.js draw function
function draw() {
fill(circleColor);
ellipse(mouseX, mouseY, 50, 50);
}
// Function to update the HTML content with the current value
function updateDisplay() {
if(val != currentValue){
// Change circle color when value updates
circleColor = color(
random(255),
random(255),
random(255)
);
}
val = currentValue;
}
// Listen for updates via polling mechanism
async function pollForUpdates() {
while (true) {
try {
const response = await fetch('/get-value');
if (response.ok) {
const data = await response.json();
currentValue = data.value;
updateDisplay();
}
} catch (error) {
console.error('Error fetching value:', error);
}
// Poll every 2 seconds
await new Promise(resolve => setTimeout(resolve, 2000));
}
}
// Start polling for updates
pollForUpdates();
The hardware was built for my final project