// --- main.ino ---
// Wokwi-friendly ESP32 test of your 5D LUT with constant inputs.
// Put your generated fis_lut.h next to this file.
#include <Arduino.h>
#include "fis_lut.h" // must define FIS_MIN[5], FIS_MAX[5], FIS_N{M,T,H,S,N}, and FIS_LUT[] in PROGMEM
#include <math.h> // for floorf
// ====== Choose ONE mode ======
#define USE_SINGLE_TEST 1
#define USE_BATCH_TEST 0
// ====== Single constant inputs (edit as you like) ======
#if USE_SINGLE_TEST
// Ranges expected by your generator (example):
// Moisture [0..876], Temp [1..45], Humidity [0..100], Solar [0..1200], Nutrient [0..100]
// Change to values you want to probe
//testX = [300, 45, 100, 100, 60];
/*static const float TEST_M = 450.0f;
static const float TEST_T = 30.0f;
static const float TEST_H = 50.0f;
static const float TEST_S = 600.0f;
static const float TEST_N = 40.0f;*/
static const float TEST_M = 300.0f;
static const float TEST_T = 45.0f;
static const float TEST_H = 100.0f;
static const float TEST_S = 100.0f;
static const float TEST_N = 60.0f;
#endif
// ====== Batch tests (add more rows if you want) ======
#if USE_BATCH_TEST
struct Vec5 { float m,t,h,s,n; };
static const Vec5 TESTS[] = {
{ 0.0f, 1.0f, 0.0f, 0.0f, 0.0f},
{876.0f, 45.0f, 100.0f, 1200.0f, 100.0f},
{450.0f, 30.0f, 50.0f, 600.0f, 40.0f},
{100.0f, 25.0f, 20.0f, 200.0f, 70.0f},
{800.0f, 10.0f, 80.0f, 1000.0f, 10.0f},
};
#endif
// ====== Helpers ======
static inline float clampf(float x, float a, float b){ return x<a?a:(x>b?b:x); }
// Map engineering value -> nearest bin index in [0 .. nBins-1]
int toBin(float v, float vmin, float vmax, int nBins){
v = clampf(v, vmin, vmax);
float t = (v - vmin) / (vmax - vmin); // 0..1
int idx = (int)floorf(t * nBins); // 0..nBins
if (idx >= nBins) idx = nBins - 1;
if (idx < 0) idx = 0;
return idx;
}
// Flatten 5D indices -> 1D index into FIS_LUT
// ((((i*NT)+j)*NH + k)*NS + l)*NN + m
uint32_t lutIndex(int i,int j,int k,int l,int m){
return (((((uint32_t)i)*FIS_NT + (uint32_t)j)*FIS_NH + (uint32_t)k)*FIS_NS + (uint32_t)l)*FIS_NN + (uint32_t)m;
}
// Read a byte from LUT in flash
uint8_t lutFetch(uint32_t idx){
// On ESP32/Arduino, pgm_read_byte works with PROGMEM arrays
return pgm_read_byte(&FIS_LUT[idx]);
}
void evalAndPrint(float M, float T, float H, float S, float N){
int bi = toBin(M, FIS_MIN[0], FIS_MAX[0], FIS_NM);
int bj = toBin(T, FIS_MIN[1], FIS_MAX[1], FIS_NT);
int bk = toBin(H, FIS_MIN[2], FIS_MAX[2], FIS_NH);
int bl = toBin(S, FIS_MIN[3], FIS_MAX[3], FIS_NS);
int bm = toBin(N, FIS_MIN[4], FIS_MAX[4], FIS_NN);
uint32_t idx = lutIndex(bi,bj,bk,bl,bm);
uint8_t flow = lutFetch(idx); // 0..255
Serial.printf("Inputs M=%.1f T=%.1f H=%.1f S=%.1f N=%.1f | "
"Bins (%d,%d,%d,%d,%d) | idx=%lu | Flow=%u\n",
M,T,H,S,N, bi,bj,bk,bl,bm, (unsigned long)idx, flow);
}
void setup(){
Serial.begin(115200);
delay(200);
Serial.println("\n=== Wokwi: 5D LUT Constant-Input Test ===");
Serial.printf("Grid: NM=%d NT=%d NH=%d NS=%d NN=%d (total=%lu entries)\n",
FIS_NM, FIS_NT, FIS_NH, FIS_NS, FIS_NN,
(unsigned long)FIS_NM*FIS_NT*FIS_NH*FIS_NS*FIS_NN);
Serial.printf("Ranges:\n Moisture %.2f .. %.2f\n Temp %.2f .. %.2f\n Humidity %.2f .. %.2f\n Solar %.2f .. %.2f\n Nutrient %.2f .. %.2f\n",
FIS_MIN[0],FIS_MAX[0], FIS_MIN[1],FIS_MAX[1], FIS_MIN[2],FIS_MAX[2],
FIS_MIN[3],FIS_MAX[3], FIS_MIN[4],FIS_MAX[4]);
#if USE_SINGLE_TEST
evalAndPrint(TEST_M, TEST_T, TEST_H, TEST_S, TEST_N);
#endif
#if USE_BATCH_TEST
for (size_t i=0; i<sizeof(TESTS)/sizeof(TESTS[0]); ++i){
evalAndPrint(TESTS[i].m, TESTS[i].t, TESTS[i].h, TESTS[i].s, TESTS[i].n);
}
#endif
}
void loop(){
// leave empty for one-shot output
}