Code does not work

This is the list of parts I’m working with:

1x ESP32‑WROOM
1x Piezo buzzer
1x TCA9548A I²C multiplexer:
4x LPS22HB barometric sensor breakout
1x ~40 cm Long, 2cm wide silicon tube: Need to find
1x 18650 Li‑ion Battery
?x M2/M3 screws, Dupont wires, heat‑shrink (sink?), zip ties, and standoffs: Need to find
1x SSD1306 I2C OLED

The idea was to create a motion tracker inspired by the one from Aliens. It keys off air pressure, and I’ve seen a couple of papers that prove this works. The air pressure idea was also from Alien.

Imagine a room full of floating balls, and you had a device that could detect the density of these balls. Say an object moves through this room and disturbs the balls. You would be able to detect the movement with the device. Now replace floating balls with air, and that’s the idea!

The main issue I’m currently having is the monitor is not displaying anything, and I've narrowed it down to a code issue. Here's the code I've been using.

/* ============================================================
   Aliens-Style Pressure Tracker (UNO/Nano Port, 4 sensors)
   - AVR-friendly (low RAM), page-buffered OLED with U8g2
   - 50 Hz sampling, drift removal, 0.2–10 Hz band-limit
   - Common-mode cancel, simple event score, 2D direction
   Hardware:
     - Arduino UNO/Nano (ATmega328P)
     - TCA9548A I2C mux @ 0x70
     - 4x LPS22HB/LPS22DF sensor breakouts (channels 0..3)
     - SSD1306 128x64 I2C OLED @ 0x3C
   ============================================================ */

#include <Arduino.h>
#include <AceWire.h>
#include <TCA9548A.h>
#include <Adafruit_LPS2X.h>
#include <U8g2lib.h>

// -------- Display (U8g2 page buffer = AVR friendly) ----------
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);

// -------- I2C Mux & Sensors ---------------------------------
TCA9548A tca;
Adafruit_LPS22 lps[4];  // 0:N, 1:E, 2:S, 3:W

// -------- Pins ----------------------------------------------
const int BUZZ_PIN = 7;       // set to -1 to disable buzzer

// -------- Sampling config -----------------------------------
const float FS = 50.0f;       // 50 Hz per sensor (good on AVR)
const float DT = 1.0f / FS;

// Simple 1st-order filters (lightweight math)
// High-pass ~0.2 Hz
const float HP_FC = 0.2f;
const float HP_ALPHA = (1.0f / (2.0f * 3.14159f * HP_FC)) / ((1.0f / (2.0f * 3.14159f * HP_FC)) + DT);

// Low-pass ~10 Hz
const float LP_FC = 10.0f;
const float LP_ALPHA = DT / ((1.0f / (2.0f * 3.14159f * LP_FC)) + DT);

// Slow EMA for drift removal (~5 s)
const float DC_ALPHA = DT / (5.0f + DT);

// Event detection
float noise_floor = 0.05f;
float thresh_mult = 4.0f;

// Per-channel filter state
struct ChanState {
  float dc;   // slow drift estimate
  float hp;   // high-pass state
  float lp;   // low-pass state
  float xprev;
};
ChanState st[4];

uint8_t chanIdx[4] = {0,1,2,3};  // TCA channels N,E,S,W

// Timing
unsigned long lastTick = 0;
const unsigned long TICK_US = (unsigned long)(DT * 1000000.0f);

void safeBeep(uint16_t ms=25) {
  if (BUZZ_PIN < 0) return;
  digitalWrite(BUZZ_PIN, HIGH);
  delay(ms);
  digitalWrite(BUZZ_PIN, LOW);
}

bool selectChannel(uint8_t ch) {
  tca.closeAll();
  tca.openChannel(ch);
  delayMicroseconds(150);
  return true;
}

bool readPressurePa(uint8_t i, float &p) {
  selectChannel(chanIdx[i]);
  sensors_event_t temp, pres;
  if (!lps[i].getEvent(&pres, &temp)) return false;
  p = pres.pressure * 100.0f;  // hPa -> Pa
  return true;
}

void drawRadar(float vx, float vy, float energy, bool ev) {
  u8g2.clearBuffer();

  // Simple HUD numbers
  u8g2.setFont(u8g2_font_5x8_tf);
  u8g2.setCursor(0, 8);
  u8g2.print(F("E:"));
  u8g2.print(energy, 2);
  u8g2.print(F(" NF:"));
  u8g2.print(noise_floor, 2);

  // Radar at bottom center
  const int cx = 64;
  const int cy = 63;
  const int r  = 26;

  // Ground line
  u8g2.drawHLine(0, cy, 128);
  // Circles
  u8g2.drawCircle(cx, cy, r, U8G2_DRAW_ALL);
  u8g2.drawCircle(cx, cy, r/2, U8G2_DRAW_ALL);

  // Scale vector to fit circle
  float mag = sqrt(vx*vx + vy*vy);
  float scale = (mag > 1e-6f) ? (r * 0.9f / mag) : 0.0f;
  int bx = cx + int(vx * scale);
  int by = cy - int(vy * scale);

  if (ev) {
    u8g2.drawDisc(bx, by, 3, U8G2_DRAW_ALL);
  } else {
    u8g2.drawCircle(bx, by, 2, U8G2_DRAW_ALL);
  }

  // NESW labels (assume +vy is "north" up)
  u8g2.setCursor(60, 12);
  u8g2.print(F("N"));
  u8g2.setCursor(118, 34);
  u8g2.print(F("E"));
  u8g2.setCursor(60, 63 - r - 2);
  // already have circle; optional label for clarity

  u8g2.sendBuffer();
}

void setup() 
{
  if (BUZZ_PIN >= 0) {
    pinMode(BUZZ_PIN, OUTPUT);
    digitalWrite(BUZZ_PIN, LOW);
  }

  Wire.begin();
  Wire.setClock(400000); // fast I2C helps

  u8g2.begin();
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_6x10_tf);
  u8g2.drawStr(0,12,"Pressure Tracker (AVR)");
  u8g2.sendBuffer();
  
/* Error, "no matching function for call to 'TCA9548A::begin(int)'"
 openChannel does not work either, "expected primary-expression  before numeric constant" WHAT IS THE PRIMARY EXPRESSION!?!? 
  if (!tca.openChannel(uint8_t 0x70 address)) {
    u8g2.clearBuffer();
    u8g2.drawStr(0,12,"TCA9548A not found!");
    u8g2.sendBuffer();
    while(1);
  }
*/
  // Init sensors
  for (uint8_t i=0;i<4;i++) {
    selectChannel(chanIdx[i]);
    if (!lps[i].begin_I2C()) {
      u8g2.clearBuffer();
      u8g2.drawStr(0,12,"LPS22 init fail ch:");
      u8g2.setCursor(110,12); u8g2.print(i);
      u8g2.sendBuffer();
      while(1);
    }
    // 50 Hz ODR is fine (some LPS variants: 25/50/75/100)
    lps[i].setDataRate(LPS22_RATE_50_HZ);
    st[i] = {0,0,0,0};
    delay(10);
  }

  delay(300);
  safeBeep(15);
  lastTick = micros();
}

void loop() {
  unsigned long now = micros();
  if ((now - lastTick) < TICK_US) return;
  lastTick += TICK_US; // keep steady cadence

  // 1) Read sensors
  float raw[4];
  for (uint8_t i=0;i<4;i++) {
    float p;
    if (readPressurePa(i, p)) raw[i] = p;
    else raw[i] = raw[i]; // noop on fail
  }

  // 2) Per-channel: drift removal -> HP -> LP
  float y[4];
  for (uint8_t i=0;i<4;i++) {
    float x = raw[i];

    // Slow DC removal (EMA)
    st[i].dc += DC_ALPHA * (x - st[i].dc);
    float x_dc = x - st[i].dc;

    // 1st-order high-pass (0.2 Hz)
    st[i].hp = HP_ALPHA * (st[i].hp + x_dc - st[i].xprev);
    st[i].xprev = x_dc;

    // 1st-order low-pass (10 Hz) on HP output
    st[i].lp += LP_ALPHA * (st[i].hp - st[i].lp);

    y[i] = st[i].lp;
  }

  // 3) Common-mode rejection
  float mean = 0;
  for (int i=0;i<4;i++) mean += y[i];
  mean *= 0.25f;
  for (int i=0;i<4;i++) y[i] -= mean;

  // 4) Energy (simple L2 norm)
  float energy = 0;
  for (int i=0;i<4;i++) energy += y[i]*y[i];
  energy = sqrt(energy);

  // Auto noise floor (slowly adapts)
  static float nfEMA = 0.05f;
  nfEMA += 0.01f * (energy - nfEMA);
  if (nfEMA < 0.02f) nfEMA = 0.02f;
  noise_floor = nfEMA;

  // 5) Direction vector (E-W, N-S)
  float vx = y[1] - y[3]; // +vx -> East
  float vy = y[0] - y[2]; // +vy -> North

  bool detected = (energy > (thresh_mult * noise_floor));

  // 6) Beep on rising edge
  static bool prev = false;
  if (detected && !prev) safeBeep(15);
  prev = detected;

  // 7) Draw
  drawRadar(vx, vy, energy, detected);
}

Also, here’s an issue with the code I’m having: it won’t let me bug fix. It says there’s something wrong with one of the libraries and stops unexpectedly.

Here's the serial monitor for that.

Waiting for gdb server to start...[2025-11-12T00:07:54.537Z] SERVER CONSOLE DEBUG: onBackendConnect: gdb-server session connected. You can switch to "DEBUG CONSOLE" to see GDB interactions.
"C:\\Users\\Erik\\AppData\\Local\\Arduino15\\packages\\esp32\\tools\\openocd-esp32\\v0.12.0-esp32-20250707/bin/openocd" -c "gdb_port 50000" -c "tcl_port 50001" -c "telnet_port 50002" -s "c:\\Users\\Erik\\Downloads\\sketch_aug25a" -f "C:/Program Files/Arduino IDE/resources/app/plugins/cortex-debug/extension/support/openocd-helpers.tcl" -f board/esp32-wrover-kit-3.3v.cfg
Open On-Chip Debugger v0.12.0-esp32-20250707 (2025-07-06-17:44)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
DEPRECATED! use 'gdb port', not 'gdb_port'
DEPRECATED! use 'tcl port' not 'tcl_port'
DEPRECATED! use 'telnet port', not 'telnet_port'
CDRTOSConfigure
Info : Listening on port 50001 for tcl connections
Info : Listening on port 50002 for telnet connections
Error: unable to open ftdi device with description '*', serial '*' at bus location '*'
C:/Users/Erik/AppData/Local/Arduino15/packages/esp32/tools/openocd-esp32/v0.12.0-esp32-20250707/bin/../share/openocd/scripts/target/esp_common.cfg:9: Error: 
Traceback (most recent call last):
  File "C:/Users/Erik/AppData/Local/Arduino15/packages/esp32/tools/openocd-esp32/v0.12.0-esp32-20250707/bin/../share/openocd/scripts/target/esp_common.cfg", line 9, in script
[2025-11-12T00:07:55.299Z] SERVER CONSOLE DEBUG: onBackendConnect: gdb-server session closed
GDB server session ended. This terminal will be reused, waiting for next session to start...

Here are some of the diagrams of the wiring setups I have tried.

It also includes what went wrong with each iteration. Also for some reason it won't let me post the fourth one. I'll include it in the comments.

If you’re wondering why the monitor is different, it’s because I originally bought the wrong one.

I will say I got the parts and the code from ChatGPT.

Here is the original message I got, sorry if it's a bit lengthy:

Yep! Here’s a memory-safe Arduino (UNO/Nano) version using the U8g2 display library (page-buffered, so it fits on AVR) plus Adafruit’s LPS22 + TCA9548A libs. It samples at ~50 Hz per channel, does drift removal, band-limits, common-mode cancel, and shows a little radar blip. Works on UNO/Nano/Pro Mini (5V or 3V3) as long as your sensors are 3V3-safe (use a level shifter if needed).

Libraries (install via Library Manager)

  • U8g2 by olikraus
  • Adafruit LPS2X
  • Adafruit TCA9548A
  • Adafruit BusIO (dependency)

Wiring notes

  • I²C: UNO/Nano → SDA (A4), SCL (A5)
  • TCA9548A @ 0x70 → 4× LPS22 breakouts on channels 0..3 (N/E/S/W)
  • OLED SSD1306 128×64 I²C @ 0x3C
  • Optional buzzer on D9 (change pin if needed)

(The code went here)

Quick setup checklist

  1. Wire UNO → TCA9548A → 4× LPS22 (channels 0..3) and OLED @ 0x3C.
  2. Install the four libraries listed above.
  3. Flash the sketch. Let it sit still for ~30–60 s so the noise floor stabilizes.
  4. Wave your hand a couple of meters away—the blip should lean toward you, and the buzzer should chirp on new events.
  5. If it’s too twitchy: increase thresh_mult to 5–6, or lengthen your inlet capillaries a bit to attenuate higher-frequency noise.

Want the ESP32 version with richer UI and faster sampling? I can drop that too, but this AVR build is classroom-friendly and runs on the classic boards.

Feel free to ask me any questions.

Also, this is my first time doing a project like this. So if I do something that goes against engineering convention, sorry in advance.

Post the complete error message.

I will say I got the parts and the code from ChatGPT

No wonder you are having trouble.

1 Like

Yeah I don't know C++ all that well so that's why I used it. Also just edited the post to include that.

Maybe try to ask chatgpt why it doesn’t work.

I just compiled it, ok. I won't comment further. I have never seen so many non-descriptive variable names. Good luck.

Here's that fourth image.

Uhh, are those even connected in the first place?

̶T̶o̶ ̶b̶e̶ ̶c̶o̶n̶t̶i̶n̶u̶e̶d̶ got a last minute urgency, so later…

Take a photo (make sure it is readable) of your hand-drawn wiring diagram with labels where not obvious.

Simplify the code. Comment out all the display code to start.

I'm using a breadboard, and I didn't want to include the power because that'd make the images even more cluttered.

Here are some images of the breadboard, if that helps.

Delete

Delete

Delete

Delete

Delete

Why go through all that learning curve work anyway? It’s only for beginners who want to write their own bugs.

Listen, I know NOTHING. It's hard to make something like this even when you're experienced. I just don't have the time, or knowledge to do this. So I'm sorry if I can't magically learn C++ in a day.

(post deleted by author)

I will say that although AI is useful for some code 'ideas' it has no clue what will and won't work on your compiler, and it has no clue how real world electronics work.
Picture this instead of floating balls:
A computer program that's intended to attempt to replace the knowledge of millions of humans with real world experience.
I'm a beginner too and I bought a C++ book and spent three days getting my first display working with an ESP32 S3.
If you aren't willing to learn through experience and put in the work your project won't succeed.
I hope you do get it to work, and understand what I'm telling you.
First off get a display with an ILI9341 driver it's much easier to use than Chinese stuff.
Learn to use the SPI bus on the ESP32 you'll have much better results.
Freenove makes excellent ESP32 boards, and the make low cost breakout boards for them as well that are labeled with onboard LEDs. The only other ESP32 id suggest is buy the genuine Espressif from Digikey. Youll have less trouble and it just works

I'm in a mechanical engineering course, and I'm doing this for a club. The main reason is I had an idea, and said, "why not?"

I am not saying I won't. But I am not a programmer at the moment. I'll try to see if I can find a course.

Take your project apart piece by piece.
Make the pieces work then put them together 1 by one. That's my suggestion

Please stay on topic. I will not answer any questions like this again. I came here to get some help with programing, not life advice. But I do appreciate the help.

1 Like

Okay. Your request is absurd, but how would you like to proceed? I know nothing about your idea, but if you can do it, I can do it. Where do we start?