When the lower sensor failed, it was time to change them out.
I used two Madison sensors (which ironically is the same as beelite is now using in their 'new' sensor).
My panel was made to fit the old Beelite sensor, but I am NOT buying anything from them again. So I am going to create my own unit for displaying the fuel level.
Employing a Arduino Nano Every board. I've done some basic Arduino programming before, but not for 15 years. Figured I would give ChatGPT a try. OMG... WOW. I did not expect that level of detail... now to see if the code it spit out works.
Removed the tank... had 3 new bungs welded in. The first two are for the two new Madison magnetic sensors (sourced from Amazon... $27 each). And since I was at it, move the return line from the center of the tank to the forward corner.
WOW. One day and its up and running / burning in. Going to let it run on the bench for a couple days and see if there are any problems. ChatGPT sure made this simpler.
As soon as I told it this was going in an aircraft it hardened the code and added a bunch more watchdog timers. I already had some of this included, but it added more. There was some minor glitches in the code, and I explained what it was doing or not doing, it fixed it. Unreal.
Code below:
/*Aircraft Header Tank Advisory IndicatorArduino Nano Every (ATmega4809)Industrial / Aviation Version*/#include <avr/io.h>#include <avr/wdt.h>// ================= PIN DEFINITIONS =================const uint8_t level1Pin = 2;const uint8_t level2Pin = 3;const uint8_t green1Pin = 5;const uint8_t red1Pin = 6;const uint8_t green2Pin = 9;const uint8_t red2Pin = 10;// ================= TIMING =================const unsigned long debounceTime = 3000;const unsigned long redFlashInterval = 250;const unsigned long heartbeatInterval = 10000;const unsigned long heartbeatPulse = 100;const unsigned long startupDuration = 1000;// ================= STATE =================bool level1State = false;bool level2State = false;bool lastReading1 = false;bool lastReading2 = false;unsigned long lastDebounce1 = 0;unsigned long lastDebounce2 = 0;unsigned long lastRedFlash = 0;bool redFlashState = false;unsigned long lastHeartbeat = 0;bool heartbeatActive = false;unsigned long heartbeatStart = 0;unsigned long startupStart;bool startupActive = true;// ===================================================// WATCHDOG// ===================================================void enableWatchdog(){RSTCTRL.RSTFR = RSTCTRL_WDRF_bm;CCP = CCP_IOREG_gc;WDT.CTRLA = WDT_PERIOD_8KCLK_gc; // ~8 seconds}void resetWatchdog(){__asm__ __volatile__("wdr");}// ===================================================void setup(){// Safe startup statedigitalWrite(green1Pin, LOW);digitalWrite(red1Pin, LOW);digitalWrite(green2Pin, LOW);digitalWrite(red2Pin, LOW);pinMode(green1Pin, OUTPUT);pinMode(red1Pin, OUTPUT);pinMode(green2Pin, OUTPUT);pinMode(red2Pin, OUTPUT);pinMode(level1Pin, INPUT_PULLUP);pinMode(level2Pin, INPUT_PULLUP);Serial.begin(115200);delay(200);logResetCause();startupStart = millis();enableWatchdog();}// ===================================================void loop(){unsigned long now = millis();if (startupActive){handleStartup(now);resetWatchdog();return;}handleDebounce(level1Pin, level1State, lastReading1, lastDebounce1, 1);handleDebounce(level2Pin, level2State, lastReading2, lastDebounce2, 2);handleRedFlash(now);handleHeartbeat(now);updateOutputs();resetWatchdog();}// ===================================================void handleDebounce(uint8_t pin, bool &state,bool &lastReading,unsigned long &lastDebounce,uint8_t channel){bool reading = (digitalRead(pin) == LOW);if (reading != lastReading)lastDebounce = millis();if ((millis() - lastDebounce) >= debounceTime){if (state != reading){state = reading;Serial.print("Level ");Serial.print(channel);Serial.print(": ");Serial.println(state ? "FLUID PRESENT" : "NO FLUID");}}lastReading = reading;}// ===================================================void handleRedFlash(unsigned long now){if (now - lastRedFlash >= redFlashInterval){lastRedFlash = now;redFlashState = !redFlashState;}}// ===================================================void handleHeartbeat(unsigned long now){if (now - lastHeartbeat >= heartbeatInterval){heartbeatActive = true;heartbeatStart = now;lastHeartbeat = now;Serial.println("Heartbeat OK");}if (heartbeatActive &&(now - heartbeatStart > heartbeatPulse)){heartbeatActive = false;}}// ===================================================// *** FIXED OUTPUT LOGIC ***void updateOutputs(){// LEVEL 1bool green1 = level1State;bool red1 = (!level1State) ? redFlashState : LOW;// LEVEL 2bool green2 = level2State;bool red2 = (!level2State) ? redFlashState : LOW;// Heartbeat overlays green LEDsif (heartbeatActive){green1 = !green1;green2 = !green2;}digitalWrite(green1Pin, green1);digitalWrite(red1Pin, red1);digitalWrite(green2Pin, green2);digitalWrite(red2Pin, red2);}// ===================================================void handleStartup(unsigned long now){if (now - startupStart >= startupDuration){startupActive = false;Serial.println("Startup Complete");return;}if ((now / 250) % 2 == 0){digitalWrite(green1Pin, HIGH);digitalWrite(green2Pin, HIGH);digitalWrite(red1Pin, LOW);digitalWrite(red2Pin, LOW);}else{digitalWrite(green1Pin, LOW);digitalWrite(green2Pin, LOW);digitalWrite(red1Pin, HIGH);digitalWrite(red2Pin, HIGH);}}// ===================================================void logResetCause(){uint8_t flags = RSTCTRL.RSTFR;Serial.println("---- RESET DETECTED ----");if (flags & RSTCTRL_PORF_bm) Serial.println("Power-On Reset");if (flags & RSTCTRL_BORF_bm) Serial.println("Brown-Out Reset");if (flags & RSTCTRL_EXTRF_bm) Serial.println("External Reset");if (flags & RSTCTRL_WDRF_bm) Serial.println("Watchdog Reset");if (flags & RSTCTRL_SWRF_bm) Serial.println("Software Reset");Serial.println("------------------------");RSTCTRL.RSTFR = flags;}
I tested everything and it worked great. Then tested it while running the engine at full power. Still great. This was a worthwhile change.
Header tank after welding... refinishing before installation.
No comments:
Post a Comment