Actualizada interfaz web

This commit is contained in:
Miguel Angel de Heras 2025-03-13 18:26:32 +01:00
parent a7e45b6cb7
commit 9de20d7ede
5 changed files with 314 additions and 148 deletions

View file

@ -11,6 +11,7 @@ const char *htmlTemplate = R"rawliteral(
color: #ffffff;
font-family: Arial, sans-serif;
margin: 20px;
font-size: 12px
}
h2 {
@ -44,7 +45,7 @@ const char *htmlTemplate = R"rawliteral(
input[type="text"],
input[type="number"],
select {
width: 100px;
width: 100%;
padding: 5px;
margin: 5px 0;
background-color: #333;
@ -61,7 +62,7 @@ const char *htmlTemplate = R"rawliteral(
/* Estilo de los sliders */
input[type="range"] {
width: 30%;
width: 100%;
margin: 10px 0;
}
@ -102,7 +103,6 @@ const char *htmlTemplate = R"rawliteral(
border-radius: 10px;
margin-bottom: 20px;
border: 1px solid #333;
/* Bordes más visibles */
}
/* Estilo para centrar los formularios en la pantalla */
@ -110,52 +110,77 @@ const char *htmlTemplate = R"rawliteral(
max-width: 600px;
margin: 0 auto;
}
.device-360-container {
display: flex;
justify-content: space-between;
gap: 20px;
/* Espaciado entre columnas */
}
.device-column {
flex: 1;
text-align: center;
}
.sync-checkbox {
text-align: center;
margin-top: 20px;
}
</style>
</head>
<body>
<!-- Sección Dispositivo 360 -->
<!-- Subsección X0 -->
<h4>X0:</h4>
<label for='x0Degrees'>Grados:</label>
<input type='text' id='x0Degrees'>
<label for='x0Duration'>Duración (s):</label>
<input type='text' id='x0Duration'>
<input type='number' id='x0Read'>
<br>
<button onclick="moveMotor('test_360','x0')">Test</button>
<button onclick="moveMotor('save_360','x0')">Save</button>
<span id="x0Message" style="color: green; display: none;">Movimiento enviado correctamente</span>
<br><br>
<div class="device-360-container">
<!-- Columna X0 -->
<div class="device-column">
<h4>X0:</h4>
<label for='x0Degrees'>Grados:</label><br>
<input type='text' id='x0Degrees'><br><br>
<label for='x0Duration'>Duración (s):</label>
<input type='text' id='x0Duration'>
<input type='number' id='x0Read'>
<br><br>
<button onclick="moveMotor('test_360','x0')">Test</button>
<button onclick="moveMotor('save_360','x0')">Save</button>
<span id="x0Message" style="color: green; display: none;">Movimiento enviado correctamente</span>
</div>
<!-- Subsección X1 -->
<h4>X1:</h4>
<label for='x1Degrees'>Grados:</label>
<input type='text' id='x1Degrees'>
<label for='x1Duration'>Duración (s):</label>
<input type='text' id='x1Duration'>
<input type='number' id='x1Read'>
<br>
<button onclick="moveMotor('test_360','x1')">Test</button>
<button onclick="moveMotor('save_360','x1')">Save</button>
<span id="x1Message" style="color: green; display: none;">Movimiento enviado correctamente</span>
<br><br>
<!-- Columna X1 -->
<div class="device-column">
<h4>X1:</h4>
<label for='x1Degrees'>Grados:</label><br>
<input type='text' id='x1Degrees'><br><br>
<label for='x1Duration'>Duración (s):</label>
<input type='text' id='x1Duration'>
<input type='number' id='x1Read'>
<br><br>
<button onclick="moveMotor('test_360','x1')">Test</button>
<button onclick="moveMotor('save_360','x1')">Save</button>
<span id="x1Message" style="color: green; display: none;">Movimiento enviado correctamente</span>
</div>
<!-- Columna Y0 -->
<div class="device-column">
<h4>Y0:</h4>
<label for='y0Degrees'>Grados:</label><br>
<input type='text' id='y0Degrees'><br><br>
<label for='y0Duration'>Duración (s):</label>
<input type='text' id='y0Duration'>
<input type='number' id='y0Read'>
<br><br>
<button onclick="moveMotor('test_360','y0')">Test</button>
<button onclick="moveMotor('save_360','y0')">Save</button>
<span id="y0Message" style="color: green; display: none;">Movimiento enviado correctamente</span>
</div>
</div>
<!-- Checkbox de sincronización debajo de las tres columnas -->
<div class="sync-checkbox">
<input type='checkbox' id='syncWithInterval360'> Sincronizar con Intervalómetro
</div>
<!-- Subsección Y0 -->
<h4>Y0:</h4>
<label for='y0Degrees'>Grados:</label>
<input type='text' id='y0Degrees'>
<label for='y0Duration'>Duración (s):</label>
<input type='text' id='y0Duration'>
<input type='number' id='y0Read'>
<br>
<button onclick="moveMotor('test_360','y0')">Test</button>
<button onclick="moveMotor('save_360','y0')">Save</button>
<span id="y0Message" style="color: green; display: none;">Movimiento enviado correctamente</span>
<br><br>
<input type='checkbox' id='syncWithInterval360'> Sincronizar con Intervalómetro
<br><br>
<!-- Script para manejar las interacciones y enviar el JSON -->
<script>
function sendHeight() {
@ -165,8 +190,8 @@ const char *htmlTemplate = R"rawliteral(
window.onload = sendHeight;
window.onresize = sendHeight;
setInterval(sendHeight, 500);
setInterval(sendHeight, 500);
function showMessage(elementId) {
const messageElement = document.getElementById(elementId);
if (messageElement) {

View file

@ -1,9 +1,13 @@
#define FORWARD 0
#define BACKWARD 1
#define STOP 0
#define IN 1
#define OUT 2
#define IN_OUT 3
#define FORWARD 1
#define BACKWARD 2
#define IN 3
#define OUT 4
#define IN_OUT 5
//Posicion en la array del motor de fps
#define FPS_MOTOR 4
//Definicion de los pines del shift register
@ -39,4 +43,4 @@
//Definicion de los limites del sensor lineal
#define LINEAL_MAX 4*478
#define LINEAL_MIN 0
#define LINEAL_MIN 4

View file

@ -11,6 +11,7 @@ const char *htmlTemplate = R"rawliteral(
color: #ffffff;
font-family: Arial, sans-serif;
margin: 20px;
font-size: 12px
}
h2 {
@ -40,29 +41,26 @@ const char *htmlTemplate = R"rawliteral(
margin-top: 20px;
}
/* Estilos de los inputs */
input[type="text"],
input[type="number"],
select {
width: 100px;
padding: 5px;
margin: 5px 0;
.button-bar {
display: flex;
justify-content: space-between;
background-color: #333;
border: 1px solid #555;
color: #fff;
padding: 10px;
border-radius: 5px;
margin-bottom: 20px;
}
/* Estilos del checkbox y radio */
input[type="checkbox"],
input[type="radio"] {
margin: 10px;
}
/* Estilo de los sliders */
input[type="range"] {
width: 30%;
margin: 10px 0;
.button-bar button {
background-color: #1e88e5;
border: none;
color: white;
padding: 10px 20px;
text-align: center;
font-size: 16px;
cursor: pointer;
border-radius: 5px;
transition: background-color 0.3s ease;
}
/* Botones */
@ -85,78 +83,220 @@ const char *htmlTemplate = R"rawliteral(
background-color: #1565c0;
}
/* Dark styling for select dropdown */
select {
background-color: #333;
color: white;
border: 1px solid #555;
padding: 5px;
.button-bar button:hover {
background-color: #1565c0;
}
.columns-container {
display: flex;
justify-content: space-between;
width: 100%;
}
.section:nth-child(1) {
flex: 22%;
/* Primera columna */
}
.section:nth-child(2) {
flex: 15%;
/* Segunda columna */
}
.section:nth-child(3) {
flex: 15%;
/* Tercera columna */
}
.section:nth-child(4) {
flex: 45%;
/* Cuarta columna */
}
/* Estilo para contenedores de secciones */
.section {
background-color: #1e1e1e;
padding: 20px;
padding-top: 0px;
border-radius: 10px;
margin-bottom: 20px;
border: 1px solid #333;
/* Bordes más visibles */
margin: 5px;
}
/* Estilo para centrar los formularios en la pantalla */
.form-container {
max-width: 600px;
margin: 0 auto;
}
iframe {
display: block;
/* Estilos de los inputs */
input[type="text"],
input[type="number"],
select {
width: 100%;
min-height: 100px;
/* Evita que sea muy pequeño al inicio */
overflow: hidden !important;
/* Asegura que no haya barras de desplazamiento */
padding: 5px;
margin: 5px 0;
background-color: #333;
border: 1px solid #555;
color: #fff;
border-radius: 5px;
}
/* Estilos del checkbox y radio */
input[type="checkbox"],
input[type="radio"] {
margin: 10px;
vertical-align: middle;
margin-right: 5px;
/* Ajusta el espacio entre el input y el texto */
}
/* Estilo de los sliders */
/*input[type="range"] {
writing-mode: bt-lr;
transform: rotate(270deg);
width: auto;
height: 150px;
display: block;
}*/
input[type="range"] {
width: 100%;
margin: 10px 0;
}
/* Estilos de la capa flotante */
#monitorLayer {
display: none;
position: fixed;
top: 10%;
left: 50%;
transform: translate(-50%, 0);
background: rgba(0, 0, 0, 0.9);
padding: 20px;
border-radius: 10px;
z-index: 1000;
width: 80%;
max-width: 800px;
}
#monitorLayer iframe {
width: 100%;
height: 400px;
border: none;
}
#closeMonitor {
background: red;
border: none;
color: white;
padding: 10px;
font-size: 16px;
cursor: pointer;
margin-top: 10px;
}
.motor-camera {
display: flex;
flex-direction: column;
align-items: center;
}
.motor-columns {
display: flex;
justify-content: space-between;
width: 100%;
}
.motor-column {
flex: 1;
padding: 10px;
}
.motor-buttons {
text-align: center;
margin-top: 20px;
}
.speed-container {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
margin-bottom: 10px;
}
.speed-value {
display: flex;
align-items: center;
gap: 5px;
}
#iframe360 {
width: 100%;
height: 100%;
min-height: 400px;
/* Ajusta la altura mínima según sea necesario */
border: none;
}
</style>
</head>
<body>
<div class="form-container">
<h2>Control Bolex Paillard</h2>
<div class="button-bar">
<button onclick="accion()">REC</button>
<button onclick="corten()">STOP</button>
<button onclick="toggleMonitor()">SCREEN</button>
</div>
<div id="monitorLayer">
<iframe src="http://192.168.8.5:8000"></iframe>
<button id="closeMonitor" onclick="toggleMonitor()">Cerrar</button>
</div>
<div class="columns-container">
<div class="section">
<!-- Sección Motor Cámara -->
<h3>Motor Cámara</h3>
<h4>Counter</h4>
<input type='number' id='frames'>
<h4>Speed</h4>
<label for='fps'>FPS:</label>
<input type='range' min='0' max='48' value='24' id='speedSlider'>
<span id='speedValueDisplay'>24</span> fps
<input type='number' id='fps'>
<input type='checkbox' id='speedCheckbox'> Activar Speed
<div class="motor-columns">
<!-- Columna 1: Counter y Speed -->
<div class="motor-column">
<h4>Counter</h4>
<input type='number' id='frames'>
<h4>Intervalómetro:</h4>
<label for='intervalFrames'>Frames:</label>
<input type='number' id='intervalFrames' value='10' min='1'>
<label for='intervalSeconds'>Segundos:</label>
<input type='number' id='intervalSeconds' value='1' min='1'>
<input type='checkbox' id='intervalCheckbox'> Activar Intervalómetro
<h4>Speed</h4>
<label for='fps'>FPS:</label>
<div class="speed-container">
<input type='range' min='0' max='48' value='24' id='speedSlider'>
<div class="speed-value">
<span id='speedValueDisplay'>24</span> <span>fps</span>
</div>
</div>
<input type='number' id='fps'><br><br>
<input type='checkbox' id='speedCheckbox'>Speed
</div>
<h4>Dirección:</h4>
<input type='radio' id='forward' name='direction' value='forward' checked> Forward
<input type='radio' id='backward' name='direction' value='backward'> Backward
<br><br>
<button onclick="sendMotorCameraData('test_motor')">Test</button>
<button onclick="sendMotorCameraData('save_motor')">Save</button>
<button onclick="stop()">Stop</button>
<span id="motorCameraMessage" style="color: green; display: none;">Datos enviados correctamente</span>
<!-- Columna 2: Intervalómetro y Dirección -->
<div class="motor-column">
<h4>Intervalómetro:</h4>
<label for='intervalFrames'>Frames:</label>
<input type='number' id='intervalFrames' value='10' min='1'><br><br>
<label for='intervalSeconds'>Segundos:</label>
<input type='number' id='intervalSeconds' value='1' min='1'><br><br>
<input type='checkbox' id='intervalCheckbox'> Intervalómetro
<h4>Dirección:</h4>
<input type='radio' id='forward' name='direction' value='forward' checked> Forward<br>
<input type='radio' id='backward' name='direction' value='backward'> Backward
</div>
</div>
<!-- Botones centrados abajo -->
<div class="motor-buttons">
<button onclick="sendMotorCameraData('test_motor')">Test</button>
<button onclick="sendMotorCameraData('save_motor')">Save</button>
<button onclick="stop()">Stop</button>
<span id="motorCameraMessage" style="color: green; display: none;">Datos enviados correctamente</span>
</div>
</div>
<div class="section">
<!-- Sección Shutter -->
<h3>Shutter</h3>
<h4>Fade In/Out Frames:</h4>
<p>% apertura inicial: <span id='fadePercentDisplay'>0</span></p>
@ -166,22 +306,16 @@ const char *htmlTemplate = R"rawliteral(
<input type='range' min='0' max='100' value='10' id='fadeFramesSlider'>
<h4>Fade Activación:</h4>
<input type='checkbox' id='fadeInCheckbox'> Activar Fade In
<input type='checkbox' id='fadeOutCheckbox'> Activar Fade Out
<input type='checkbox' id='fadeInCheckbox'> Fade In
<input type='checkbox' id='fadeOutCheckbox'> Fade Out
<br><br>
<input type='checkbox' id='syncWithIntervalCheckbox'> Sincronizar con Intervalómetro
<br><br>
<br><br><br>
<button onclick="sendShutterData('save_shutter')">Save</button>
<span id="shutterMessage" style="color: green; display: none;">Datos enviados correctamente</span>
</div>
<div class="section">
<!-- Sección Monitor de Cámara -->
<h3>Monitor de Cámara</h3>
<iframe src="http://192.168.8.5:8000" width="100%" height="400px" style="border: none;"></iframe>
</div>
<div class="section">
<!-- Sección Óptica -->
<h3>Óptica</h3>
@ -213,23 +347,17 @@ const char *htmlTemplate = R"rawliteral(
</div>
<div class="section">
<!-- Sección Dispositivo 360 -->
<h3>Dispositivo 360</h3>
<iframe id="iframe360" src="http://192.168.8.3" width="100%" height="400px" style="border: none;"></iframe>
<!-- <iframe id="iframe360" src="iframe.html" width="100%" height="400px" style="border: none;"></iframe> -->
</div>
<div class="section">
<!-- Sección Rodaje -->
<h3>Rodaje</h3>
<button onclick="accion()">ACCIÓN !!!</button>
<button onclick="corten()">CORTEN !!!</button>
<span id="accionMessage" style="color: green; display: none;">Mensaje enviado correctamente</span>
<br><br>
<iframe id="iframe360" src="http://192.168.8.3"></iframe>
</div>
</div>
<!-- Script para manejar las interacciones y enviar el JSON -->
<script>
function toggleMonitor() {
let monitorLayer = document.getElementById('monitorLayer');
monitorLayer.style.display = (monitorLayer.style.display === 'none' || monitorLayer.style.display === '') ? 'block' : 'none';
}
window.addEventListener("message", function (event) {
console.log("Mensaje recibido:", event.data); // Depuración
@ -456,7 +584,7 @@ const char *htmlTemplate = R"rawliteral(
}
// Llama a updateSensors cada 500ms
setInterval(updateSensors, 100);
setInterval(updateSensors, 500);
</script>
</body>

View file

@ -15,7 +15,7 @@ bool motorIsSpeedActive = false;
int motorIntervalFrames = 1;
int motorIntervalSeconds = 1;
bool motorIsIntervalActive = false;
bool motorDirection = 1;
bool motorDirection = STOP;
// Shutter
int shutterFadePercent = 0;
@ -116,6 +116,7 @@ void linear_motor_control(int motor, int SPEED)
else stop(motor);
}
unsigned long time_lineal_motor = millis();
float time_move_for_move_position_motor[6] = {0, 0, 0, 0, 0, 0};
unsigned long time_refresh_position_motor[6] = { millis(), millis(), millis(), millis(), millis(), millis()};
float position_motor[6] = { 0, 0, 0, 0, 0, 0};
@ -130,6 +131,7 @@ void config_position_motor(int motor, float position) //Configuracion posicion e
{
position_motor_objective[motor] = position;
Setpoint_Linear = position;
time_lineal_motor = millis();
}
else
{
@ -166,10 +168,10 @@ static volatile unsigned long lastTimeDebounce = 0; //Tiempo del rebote
static volatile bool force_stop = false; //Tiempo del rebote
void fps_count_state() {
if((digitalRead(sensor_fps)&&(micros()-lastTimeDebounce>= 100))&&(!closed))
if((digitalRead(sensor_fps)&&(micros()-lastTimeDebounce>=100))&&(!closed))
{
if(motorDirection==FORWARD) FramesCount++;
else FramesCount--;
else if(motorDirection==BACKWARD) FramesCount--;
lastTimeDebounce = micros();
fps_temp = 1000000./(float)(micros()-time_fps);
if(fps_temp<70) motorSpeedRead = fps_temp;
@ -183,7 +185,7 @@ void fps_count_state() {
else if((digitalRead(sensor_fps)&&(micros()-lastTimeDebounce >= 150))&&(closed))
{
if(motorDirection==FORWARD) FramesCount++;
else FramesCount--;
else if(motorDirection==BACKWARD) FramesCount--;
lastTimeDebounce = micros();
closed = false;
force_stop = true;
@ -275,13 +277,20 @@ void ini_motors()
stop(3);*/
}
void refresh_position_motors()
{
position_motor[0] = map(read_lineal_motor(),LINEAL_MAX,LINEAL_MIN,0,100000)/1000;
#if PID_ENABLE
Input_Linear = position_motor[0];
PID_LINEAR.Compute();
linear_motor_control(0, Output_Linear);
if ((position_motor[0]>=(Setpoint_Linear+1))||(position_motor[0]<=(Setpoint_Linear-1))) time_lineal_motor = millis();
if ((millis()-time_lineal_motor)<10)
{
Input_Linear = position_motor[0];
PID_LINEAR.Compute();
linear_motor_control(0, Output_Linear);
}
/*Input = (double)fps_temp; // Lectura del encoder óptico. El valor del contador se incrementa/decrementa a través de las interrupciones extrenas (pines 2 y 3).
if(myPID.Compute())
analogWrite(EN_MOTOR[4], abs(Output)); // Por el primer pin sale la señal PWM.

View file

@ -318,7 +318,7 @@ void loop() {
client.println("Content-Type: application/json");
client.println();
String response = "{\"sensors\":[" + String(motorSpeedRead) + "," + String(FadePercentRead) + "," + String(FramesCount) + "]}";
client.print(response);
client.print(response);
} else {
// Respuesta para servir la interfaz HTML
client.println("HTTP/1.1 200 OK");