Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions Parcial 1/Homework3/Archivo_Lookup_Table.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@

"""Untitled3.ipynb

Automatically generated by Colab.

Original file is located at
https://colab.research.google.com/drive/1-ykZUAdzB6m7y0UvnUpPthAxPl4htzqB
"""

!pip -q install numpy
import numpy as np
from google.colab import files

def voltage_from_percent(p):
x = p
# f(x) = 4.60897e-09*x^5 - 1.13065e-06*x^4 + 9.13377e-05*x^3 - 0.00277445*x^2 + 0.0639597*x + 0.154238
return (((((4.60897e-09*x - 1.13065e-06)*x + 9.13377e-05)*x
- 0.00277445)*x + 0.0639597)*x + 0.154238)

# --- Parámetros LUT ---
MV_FS = 3300 # índice 0..3300 mV
USE_UINT8 = True # True: % entero (0..100); False: uint16 con x10 (0..1000)

mV/1000 ---
def percent_from_mV(mv):
target = mv / 1000.0
# Rango físico de tu poli (aprox): V(0)~0.154V, V(100)~3.168V
v0 = voltage_from_percent(0.0)
v1 = voltage_from_percent(100.0)
if target <= v0: return 0.0
if target >= v1: return 100.0
lo, hi = 0.0, 100.0
for _ in range(40): # precisión alta
mid = 0.5*(lo+hi)
vm = voltage_from_percent(mid)
if vm < target: lo = mid
else: hi = mid
return 0.5*(lo+hi)

percent = np.array([percent_from_mV(mv) for mv in range(MV_FS+1)])

if USE_UINT8:
lut_vals = np.rint(np.clip(percent, 0, 100)).astype(np.uint8) # 0..100
c_type = "uint8_t"; LUT_SCALE = 1
else:
lut_vals = np.rint(np.clip(percent*10.0, 0, 1000)).astype(np.uint16) # 0..1000
c_type = "uint16_t"; LUT_SCALE = 10

lines = []
lines.append("#ifndef LOOKUPTABLE_H")
lines.append("#define LOOKUPTABLE_H")
lines.append("")
lines.append("#include <stdint.h>")
lines.append(f"#define LUT_SIZE {MV_FS+1}")
lines.append(f"#define LUT_SCALE {LUT_SCALE} // 1:% entero; 10: décimas de %")
lines.append("#define LUT_INDEX_IS_MV 1 // índice = mV (0..3300)")
lines.append("")
lines.append(f"static const {c_type} lookup_table[LUT_SIZE] = {{")

row=[]
for i,v in enumerate(lut_vals):
row.append(str(int(v)))
if (i+1)%16==0:
lines.append(" " + ", ".join(row) + ",")
row=[]
if row:
lines.append(" " + ", ".join(row) + ",")

lines.append("};")
lines.append("")
lines.append("#endif // LOOKUPTABLE_H")

with open("lookuptable.h","w") as f:
f.write("\n".join(lines))

files.download("lookuptable.h")
print("Generado lookuptable.h (mV -> %) ✅")
6 changes: 6 additions & 0 deletions Parcial 1/Homework3/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
idf_component_register(
SRCS "oneshot_read_main.c"
INCLUDE_DIRS "."
PRIV_REQUIRES esp_timer esp_adc
)

175 changes: 175 additions & 0 deletions Parcial 1/Homework3/Generador de Polinomio.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
# -*- coding: utf-8 -*-
"""Untitled2.ipynb

Automatically generated by Colab.

Original file is located at
https://colab.research.google.com/drive/19jSibHAWRwWB1Jo3CqqgVLrz-AeG2Fxe
"""

!pip -q install openpyxl ipywidgets

import io, numpy as np, pandas as pd, matplotlib.pyplot as plt
import ipywidgets as widgets
from IPython.display import display, clear_output
from google.colab import files
from google.colab import output as colab_output
colab_output.enable_custom_widget_manager()

# ---------- Subir archivo ----------
print("Sube tu archivo Excel (.xlsx) 👇")
uploaded = files.upload()
fname = next(iter(uploaded))

# ---------- Utilidades ----------
def guess_col(cols, df, keywords):
for c in cols:
lc = str(c).lower()
if any(k in lc for k in keywords):
return c
for c in cols: # fallback: primera numérica
if pd.api.types.is_numeric_dtype(df[c]): return c
return cols[0]

def format_poly_equation(coef):
# coef en orden descendente: a_n, a_{n-1}, ..., a0
n = len(coef) - 1
terms = []
for i, a in enumerate(coef):
p = n - i
if abs(a) < 1e-12:
continue
a_str = f"{a:.6g}"
if p == 0:
terms.append(f"{a_str}")
elif p == 1:
terms.append(f"{a_str}*x")
else:
terms.append(f"{a_str}*x^{p}")
eq = " + ".join(terms)
eq = eq.replace("+ -", "- ")
return f"f(x) = {eq}" if eq else "f(x) = 0"

def r2_score(y_true, y_pred):
ss_res = np.sum((y_true - y_pred)**2)
ss_tot = np.sum((y_true - np.mean(y_true))**2)
return 1 - ss_res/ss_tot if ss_tot > 0 else np.nan

# ---------- UI: elegir hoja ----------
xls = pd.ExcelFile(io.BytesIO(uploaded[fname]))
sheet_dd = widgets.Dropdown(options=xls.sheet_names, value=xls.sheet_names[0], description='Hoja:')
load_btn = widgets.Button(description='Cargar hoja', button_style='primary')
box_out = widgets.Output()

def load_sheet(_):
with box_out:
clear_output()
df = pd.read_excel(io.BytesIO(uploaded[fname]), sheet_name=sheet_dd.value)
cols = list(df.columns)

x_dd = widgets.Dropdown(options=cols, value=guess_col(cols, df, ['agua','water','%']), description='X (% agua):')
y_dd = widgets.Dropdown(options=cols, value=guess_col(cols, df, ['volt','voltage','tensión','tension']), description='Y (Voltaje):')

model_dd = widgets.Dropdown(options=['Lineal','Polinomial','Exponencial'], value='Polinomial', description='Modelo:')
deg = widgets.IntSlider(value=2, min=1, max=5, step=1, description='Grado (poly)')
fit_btn = widgets.Button(description='Graficar y ajustar', button_style='success')
out_area = widgets.Output()

def do_fit(_):
with out_area:
clear_output()

# --- preparar datos ---
x = pd.to_numeric(df[x_dd.value], errors='coerce')
y = pd.to_numeric(df[y_dd.value], errors='coerce')
data = pd.DataFrame({'x': x, 'y': y}).dropna().sort_values('x')
x = data['x'].values.astype(float)
y = data['y'].values.astype(float)

if len(x) < 2:
print("Necesitas al menos 2 puntos.")
return

# --- ajuste según modelo ---
model = model_dd.value
eq_text, coef, yhat = "", None, None

if model == 'Lineal':
coef = np.polyfit(x, y, 1) # [m, b]
yhat = np.polyval(coef, x)
eq_text = format_poly_equation(coef)

elif model == 'Polinomial':
d = int(deg.value)
d = min(d, len(x)-1) # evitar sobreajuste sin puntos suficientes
coef = np.polyfit(x, y, d) # [a_d, ..., a0]
yhat = np.polyval(coef, x)
eq_text = format_poly_equation(coef)

else: # Exponencial: y = a * exp(b x) => ln y = ln a + b x (requiere y>0)
pos = y > 0
if pos.sum() < 2:
print("Para exponencial se requieren valores Y positivos.")
return
cx, cy = x[pos], np.log(y[pos])
b, ln_a = np.polyfit(cx, cy, 1) # cy ≈ ln_a + b*cx
a = np.exp(ln_a)
yhat = a * np.exp(b*x)
coef = (a, b) # guardar como (a, b)
eq_text = f"f(x) = {a:.6g} * exp({b:.6g}*x)"

# --- métricas ---
r2 = r2_score(y, yhat)

# --- gráfica ---
plt.figure(figsize=(7,4.5))
plt.scatter(x, y, label='Medido')
xf = np.linspace(x.min(), x.max(), 200)
if model == 'Exponencial':
yf = coef[0] * np.exp(coef[1] * xf)
else:
yf = np.polyval(coef, xf)
plt.plot(xf, yf, label='Ajuste')
plt.xlabel('Porcentaje de agua (%)')
plt.ylabel('Voltaje (V)')
plt.title('Calibración y función f(x)')
plt.grid(True)
plt.legend()
plt.show()

# --- resultados ---
print("Ecuación:")
print(eq_text)
print(f"R² = {r2:.6f}")

# código de la función en Python listo para copiar
if model == 'Exponencial':
a, b = coef
print("\nFunción f(x) en Python:")
print(f"def f(x):\n return {a:.12g} * np.exp({b:.12g} * x)")
else:
# coef es [a_n, ..., a0]
terms = []
n = len(coef)-1
for i, a in enumerate(coef):
p = n - i
if p == 0:
terms.append(f"{a:.12g}")
elif p == 1:
terms.append(f"{a:.12g}*x")
else:
terms.append(f"{a:.12g}*x**{p}")
body = " + ".join(terms).replace("+ -", "- ")
print("\nFunción f(x) en Python:")
print("def f(x):")
print(f" return {body}")

fit_btn.on_click(do_fit)
display(widgets.VBox([
widgets.HBox([x_dd, y_dd]),
widgets.HBox([model_dd, deg, fit_btn]),
out_area
]))

display(widgets.VBox([widgets.HBox([sheet_dd, load_btn]), box_out]))
load_btn.on_click(load_sheet)
Binary file added Parcial 1/Homework3/HW3 Report.pdf
Binary file not shown.
1 change: 1 addition & 0 deletions Parcial 1/Homework3/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Homework 3 Juan Pablo Larios Franco 0244215
Binary file added Parcial 1/Homework3/TablaVoltajes.xlsx
Binary file not shown.
Loading