remove web app code, add note in comment about where to find it

This commit is contained in:
foamyguy 2025-05-23 07:59:18 -05:00
parent 57d39d0fb3
commit b576e77a20
6 changed files with 1 additions and 504 deletions

View file

@ -8,6 +8,7 @@
*
* This sketch works with the web interface in the /webserial directory,
* which can be accessed at: https://adafruit.github.io/Adafruit_OPT4048/webserial/
* Code for web app is in gh-pages branch: https://github.com/adafruit/Adafruit_OPT4048/tree/gh-pages
*/
#include <Wire.h>

View file

@ -1,48 +0,0 @@
# OPT4048 CIE Color Plotter
This web interface allows you to visualize color measurements from an Adafruit OPT4048 color sensor in real-time using the Web Serial API.
## How to Use
1. **Upload the Arduino sketch**: First, upload the `opt4048_webserial.ino` sketch from the examples folder to your Arduino board.
2. **Connect to this web page**: You can access it at:
- https://adafruit.github.io/Adafruit_OPT4048/webserial/
- Or host the page locally for development
3. **Connect to your Arduino**: Click the "Connect to Arduino" button and select your Arduino from the popup menu.
4. **View measurements**: The sensor readings will appear on the CIE chromaticity diagram, showing you exactly where the measured color falls in the CIE color space.
## Features
- Displays CIE x,y coordinates in real-time
- Plots the color point on a standard CIE 1931 chromaticity diagram
- Shows lux (brightness) and color temperature (CCT) values
- Provides approximate RGB color visualization
- Monitors serial output for debugging
## Browser Compatibility
This interface uses the Web Serial API, which is currently supported in:
- Google Chrome (version 89+)
- Microsoft Edge (version 89+)
- Opera (version 75+)
It is **not** supported in Firefox or Safari due to their Web Serial API implementation status.
## About the OPT4048 Sensor
The OPT4048 is a high-precision tristimulus XYZ color sensor by Texas Instruments. The Adafruit breakout board makes it easy to interface with this sensor using I2C.
This sensor provides accurate color measurements in XYZ color space, which can be converted to standard CIE 1931 xy chromaticity coordinates.
## File Structure
- `index.html` - The main webpage
- `script.js` - JavaScript code for communication and visualization
- `cie1931_diagram.svg` - SVG image of the CIE 1931 chromaticity diagram
## License
MIT license, all text here must be included in any redistribution

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.6 KiB

View file

@ -1,158 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>OPT4048 CIE Color Plotter</title>
<!-- oEmbed Discovery Links -->
<link rel="alternate" type="application/json+oembed" href="https://adafruit.github.io/Adafruit_OPT4048/webserial/oembed.json" title="Adafruit OPT4048 Demo" />
<style>
body {
font-family: Arial, sans-serif;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
.container {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.controls {
flex: 1;
min-width: 300px;
}
.visualization {
flex: 2;
min-width: 500px;
}
#cie-diagram {
position: relative;
width: 100%;
max-width: 600px;
margin-bottom: 20px;
}
#cie-diagram img {
width: 100%;
height: auto;
display: block;
}
#data-point {
position: absolute;
width: 10px;
height: 10px;
background-color: red;
border-radius: 50%;
transform: translate(-50%, -50%);
pointer-events: none;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
z-index: 10;
}
#color-sample {
width: 30px;
height: 30px;
border: 1px solid #ccc;
margin: 0 auto;
border-radius: 50%;
}
#serial-log {
height: 200px;
overflow-y: auto;
background-color: #f5f5f5;
padding: 10px;
border: 1px solid #ddd;
font-family: monospace;
}
button {
padding: 10px 16px;
margin: 5px 0;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #45a049;
}
button:disabled {
background-color: #cccccc;
cursor: not-allowed;
}
.data-display {
display: flex;
justify-content: space-between;
margin-top: 20px;
}
.data-box {
flex: 1;
margin: 0 10px;
padding: 15px;
background-color: #f9f9f9;
border: 1px solid #ddd;
border-radius: 4px;
text-align: center;
}
.data-box h3 {
margin-top: 0;
}
.data-value {
font-size: 24px;
font-weight: bold;
}
</style>
</head>
<body>
<h1>OPT4048 CIE Color Plotter</h1>
<p>Connect your Arduino with OPT4048 sensor to visualize color measurements on a CIE diagram.</p>
<div class="container">
<div class="controls">
<button id="connect-button">Connect to Arduino</button>
<button id="disconnect-button" disabled>Disconnect</button>
<button id="clear-button">Clear Log</button>
<h2>Connection Status</h2>
<p id="status">Not connected</p>
<h2>Serial Monitor</h2>
<div id="serial-log"></div>
</div>
<div class="visualization">
<h2>CIE 1931 Chromaticity Diagram</h2>
<div id="cie-diagram">
<img src="cie1931_diagram.svg" alt="CIE 1931 Chromaticity Diagram">
<div id="data-point" style="display: none;"></div>
</div>
<div class="data-display">
<div class="data-box">
<h3>CIE x</h3>
<div id="cie-x" class="data-value">-</div>
</div>
<div class="data-box">
<h3>CIE y</h3>
<div id="cie-y" class="data-value">-</div>
</div>
<div class="data-box">
<h3>Lux</h3>
<div id="lux" class="data-value">-</div>
</div>
<div class="data-box">
<h3>CCT (K)</h3>
<div id="cct" class="data-value">-</div>
</div>
</div>
<div class="data-box">
<h3>Color Approximation</h3>
<div id="color-sample"></div>
<small>(Note: This is a rough approximation)</small>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

View file

@ -1,12 +0,0 @@
{
"version": "1.0",
"type": "rich",
"title": "Adafruit OPT4048 Library",
"provider_name": "Adafruit",
"provider_url": "https://www.adafruit.com",
"author_name": "Adafruit",
"author_url": "https://github.com/adafruit",
"width": 800,
"height": 600,
"html": "<iframe src='https://adafruit.github.io/Adafruit_OPT4048/webserial/' width='800' height='600' style='border: 1px solid #ddd; border-radius: 4px; max-width: 100%;' allow='serial; usb' loading='lazy' title='Adafruit OPT4048 Arduino Library'></iframe>"
}

View file

@ -1,283 +0,0 @@
// Global variables
let port;
let reader;
let writer;
let readTimeout;
let keepReading = false;
let decoder = new TextDecoder();
let lineBuffer = '';
// DOM Elements
const connectButton = document.getElementById('connect-button');
const disconnectButton = document.getElementById('disconnect-button');
const clearButton = document.getElementById('clear-button');
const statusDisplay = document.getElementById('status');
const serialLog = document.getElementById('serial-log');
const dataPoint = document.getElementById('data-point');
const cieXDisplay = document.getElementById('cie-x');
const cieYDisplay = document.getElementById('cie-y');
const luxDisplay = document.getElementById('lux');
const cctDisplay = document.getElementById('cct');
const colorSample = document.getElementById('color-sample');
// Check if Web Serial API is supported
if ('serial' in navigator) {
connectButton.addEventListener('click', connectToArduino);
disconnectButton.addEventListener('click', disconnectFromArduino);
clearButton.addEventListener('click', clearLog);
} else {
statusDisplay.textContent = 'Web Serial API not supported in this browser. Try Chrome or Edge.';
connectButton.disabled = true;
}
// Connect to Arduino via Web Serial
async function connectToArduino() {
try {
// Request a port and open a connection
port = await navigator.serial.requestPort();
await port.open({ baudRate: 115200 });
// Set up the reader and writer
reader = port.readable.getReader();
writer = port.writable.getWriter();
// Enable/disable buttons
connectButton.disabled = true;
disconnectButton.disabled = false;
statusDisplay.textContent = 'Connected to Arduino';
addToLog('Connected to Arduino', 'status');
// Start reading data
keepReading = true;
readSerialData();
} catch (error) {
console.error('Error connecting to Arduino:', error);
addToLog(`Error connecting: ${error.message}`, 'error');
statusDisplay.textContent = 'Connection failed';
}
}
// Disconnect from Arduino
async function disconnectFromArduino() {
if (reader) {
keepReading = false;
clearTimeout(readTimeout);
try {
await reader.cancel();
await reader.releaseLock();
reader = null;
} catch (error) {
console.error('Error releasing reader:', error);
}
}
if (writer) {
try {
await writer.close();
writer = null;
} catch (error) {
console.error('Error releasing writer:', error);
}
}
if (port) {
try {
await port.close();
port = null;
} catch (error) {
console.error('Error closing port:', error);
}
}
// Update UI
connectButton.disabled = false;
disconnectButton.disabled = true;
statusDisplay.textContent = 'Disconnected';
addToLog('Disconnected from Arduino', 'status');
hideDataPoint();
}
// Read data from the serial port
async function readSerialData() {
while (port && keepReading) {
try {
const { value, done } = await reader.read();
if (done) {
// Reader has been canceled
break;
}
// Process the received data
processSerialData(decoder.decode(value));
} catch (error) {
console.error('Error reading data:', error);
addToLog(`Error reading data: ${error.message}`, 'error');
break;
}
}
// If we exited the loop without being explicitly disconnected
if (keepReading) {
disconnectFromArduino();
}
}
// Process data received from Arduino
function processSerialData(data) {
// Add received data to the buffer
lineBuffer += data;
// Process complete lines
let lineEnd;
while ((lineEnd = lineBuffer.indexOf('\n')) !== -1) {
const line = lineBuffer.substring(0, lineEnd).trim();
lineBuffer = lineBuffer.substring(lineEnd + 1);
if (line) {
addToLog(line);
parseDataFromLine(line);
}
}
}
// Parse data from a line received from Arduino
function parseDataFromLine(line) {
// Look for CIE x value
const cieXMatch = line.match(/CIE x: ([\d.]+)/);
if (cieXMatch) {
const cieX = parseFloat(cieXMatch[1]);
cieXDisplay.textContent = cieX.toFixed(6);
}
// Look for CIE y value
const cieYMatch = line.match(/CIE y: ([\d.]+)/);
if (cieYMatch) {
const cieY = parseFloat(cieYMatch[1]);
cieYDisplay.textContent = cieY.toFixed(6);
// If we have both x and y, update the plot
if (cieXMatch) {
const cieX = parseFloat(cieXMatch[1]);
updateCIEPlot(cieX, cieY);
}
}
// Look for Lux value
const luxMatch = line.match(/Lux: ([\d.]+)/);
if (luxMatch) {
const lux = parseFloat(luxMatch[1]);
luxDisplay.textContent = lux.toFixed(2);
}
// Look for Color Temperature value
const cctMatch = line.match(/Color Temperature: ([\d.]+)/);
if (cctMatch) {
const cct = parseFloat(cctMatch[1]);
cctDisplay.textContent = cct.toFixed(0);
}
}
// Update the CIE plot with new data point
function updateCIEPlot(x, y) {
// Get the dimensions of the CIE diagram image
const cieImage = document.querySelector('#cie-diagram img');
const imageRect = cieImage.getBoundingClientRect();
// The SVG has a coordinate system where:
// - X axis is marked from 0.0 to 0.8 (matched to pixel positions 60 to 470)
// - Y axis is marked from 0.0 to 0.9 (matched to pixel positions 476 to 15)
// Define the SVG's coordinate mapping
const svgXMin = 60, svgXMax = 470; // Left and right edge pixel positions in SVG
const svgYMin = 476, svgYMax = 15; // Bottom and top edge pixel positions in SVG
const cieXMin = 0.0, cieXMax = 0.8; // Min and max x chromaticity values
const cieYMin = 0.0, cieYMax = 0.9; // Min and max y chromaticity values
// Map the CIE coordinates to percentages within the SVG viewport
const svgWidth = svgXMax - svgXMin;
const svgHeight = svgYMin - svgYMax;
// Calculate the percentage position (normalize to SVG viewBox)
const xPercent = ((x - cieXMin) / (cieXMax - cieXMin)) * 100;
const yPercent = (1 - ((y - cieYMin) / (cieYMax - cieYMin))) * 100; // Invert y-axis
// Set the data point position
dataPoint.style.left = `${xPercent}%`;
dataPoint.style.top = `${yPercent}%`;
dataPoint.style.display = 'block';
// Update the color sample with an approximate RGB color
updateColorSample(x, y);
}
// Convert CIE XYZ to RGB for color approximation
function updateColorSample(x, y) {
// Calculate XYZ from xyY (assuming Y=1 for relative luminance)
const Y = 1.0;
const X = (x * Y) / y;
const Z = ((1 - x - y) * Y) / y;
// XYZ to RGB conversion (sRGB)
// Using the standard D65 transformation matrix
let r = X * 3.2406 - Y * 1.5372 - Z * 0.4986;
let g = -X * 0.9689 + Y * 1.8758 + Z * 0.0415;
let b = X * 0.0557 - Y * 0.2040 + Z * 1.0570;
// Apply gamma correction
r = r <= 0.0031308 ? 12.92 * r : 1.055 * Math.pow(r, 1/2.4) - 0.055;
g = g <= 0.0031308 ? 12.92 * g : 1.055 * Math.pow(g, 1/2.4) - 0.055;
b = b <= 0.0031308 ? 12.92 * b : 1.055 * Math.pow(b, 1/2.4) - 0.055;
// Clamp RGB values between 0 and 1
r = Math.min(Math.max(0, r), 1);
g = Math.min(Math.max(0, g), 1);
b = Math.min(Math.max(0, b), 1);
// Convert to 8-bit color values
const ri = Math.round(r * 255);
const gi = Math.round(g * 255);
const bi = Math.round(b * 255);
// Set the background color of the sample
colorSample.style.backgroundColor = `rgb(${ri}, ${gi}, ${bi})`;
}
// Hide the data point and reset all displays
function hideDataPoint() {
dataPoint.style.display = 'none';
cieXDisplay.textContent = '-';
cieYDisplay.textContent = '-';
luxDisplay.textContent = '-';
cctDisplay.textContent = '-';
colorSample.style.backgroundColor = 'transparent';
}
// Add a message to the serial log
function addToLog(message, type = 'data') {
const entry = document.createElement('div');
entry.textContent = message;
entry.className = `log-entry ${type}`;
serialLog.appendChild(entry);
serialLog.scrollTop = serialLog.scrollHeight;
}
// Clear the serial log
function clearLog() {
serialLog.innerHTML = '';
}
// Send a command to the Arduino
async function sendCommand(command) {
if (writer) {
try {
const encoder = new TextEncoder();
await writer.write(encoder.encode(command + '\n'));
addToLog(`Sent: ${command}`, 'command');
} catch (error) {
console.error('Error sending command:', error);
addToLog(`Error sending command: ${error.message}`, 'error');
}
}
}