From 57836a8da7d059e3ac5e9408cdbe08a8f7fe274e Mon Sep 17 00:00:00 2001 From: Arcmyx Official Date: Sat, 21 Mar 2026 16:16:12 +0000 Subject: [PATCH] Update diagnostics/micropython_diagnostics.py --- diagnostics/micropython_diagnostics.py | 131 ++++++++++++++++++++++--- 1 file changed, 117 insertions(+), 14 deletions(-) diff --git a/diagnostics/micropython_diagnostics.py b/diagnostics/micropython_diagnostics.py index 3a5a0c4..0f96ca6 100644 --- a/diagnostics/micropython_diagnostics.py +++ b/diagnostics/micropython_diagnostics.py @@ -1,35 +1,138 @@ import micropython +import gc from pybricks import version +from pybricks.hubs import PrimeHub class MicroPythonDiagnostics: def __init__(self, hub): - pass - def performMemoryDiagnostics(): + self.successfultests = 0 + self.failedtests = {} + def testgcmanual(self): + gc.disable() + print(f"Initial free: {gc.mem_free()} bytes") + large_data = [i for i in range(10000)] + print(f"After allocation: {gc.mem_free()} bytes") + gc.collect() + aftergcstillref = gc.mem_free() + print(f"After gc.collect (data still referenced): {aftergcstillref} bytes") + large_data = None + print("Reference to data removed.") + aftergcnoref = gc.mem_free() + gc.collect() + print(f"After gc.collect (data dead): {aftergcnoref} bytes") + if(aftergcnoref < aftergcstillref): + print("Completed Test 4/5: Manual garbage collection - SUCCESSFUL") + self.successfultests += 1 + else: + print("Completed Test 4/5: Manual garbage collection - FAILED") + self.failedtests["Manual garbage collection"] = "Heap not cleared" + def testgcauto(self): + input("Disabling garbage collection. The amount of used memory should quickly increase. Press Enter to begin:") + gc.disable() + gc.threshold(5000) + + total_mem = 255616 # Based on your previous mem_info + bytes_per_hash = 3000 + + print("Memory Monitor: [# = Used] [. = Free]") + print("-" * (total_mem // bytes_per_hash)) + + for i in range(500): + # Creating garbage to simulate robot logic/sensors + _ = bytearray(300) + + # Only print every 25 iterations to prevent terminal spam + if i % 25 == 0: + used = gc.mem_alloc() + free = gc.mem_free() + + # Calculate how many hashes and dots to draw + hashes = used // bytes_per_hash + dots = free // bytes_per_hash + + # Print the visual bar with the iteration number + print(f"{i:03d}: [{'#' * hashes}{'.' * dots}] {free} bytes free") + final_disabled_free = gc.mem_free() + input("Enabling garbage collection. The amount of used memory should stay relatively low. Press Enter to begin:") + gc.enable() + gc.threshold(5000) + + total_mem = 255616 # Based on your previous mem_info + bytes_per_hash = 3000 + + print("Memory Monitor: [# = Used] [. = Free]") + print("-" * (total_mem // bytes_per_hash)) + + for i in range(500): + # Creating garbage to simulate robot logic/sensors + _ = bytearray(300) + + # Only print every 25 iterations to prevent terminal spam + if i % 25 == 0: + used = gc.mem_alloc() + free = gc.mem_free() + + # Calculate how many hashes and dots to draw + hashes = used // bytes_per_hash + dots = free // bytes_per_hash + + # Print the visual bar with the iteration number + print(f"{i:03d}: [{'#' * hashes}{'.' * dots}] {free} bytes free") + + final_enabled_free = gc.mem_free() + if final_enabled_free > final_disabled_free: + print("Completed Test 5/5: Automatic garbage collection - SUCCESSFUL") + print(f"Difference: {final_enabled_free - final_disabled_free} bytes saved.") + self.successfultests += 1 + else: + print("Completed Test 5/5: Automatic garbage collection - FAILED") + self.failedtests["Automatic garbage collection"] = "No GC difference" + def performMemoryDiagnostics(self): + input("Press Enter to retrieve memory information:") print("[Hub Diagnostics - MicroPython - Memory] Memory information (retrieved from the MicroPython environment):") micropython.mem_info(1) + input("After you're done reading the results, press Enter to run heap diagnostics:") print("[Hub Diagnostics - MicroPython - Memory] Testing heap lock and unlock.") print("[Hub Diagnostics - MicroPython - Memory] Allocating memory while heap is unlocked:") try: - x = 5000 - print("[Hub Diagnostics - MicroPython - Memory] [SUCCESS] There was no MemoryError raised. The value of the new variable x is", x) + x = [1, 2, 3, 4, 5] + print("[Hub Diagnostics - MicroPython - Memory] Completed Test 1/5: Normal memory allocation - SUCCESS") + print("There was no MemoryError raised. The value of the new variable x is", x) + self.successfultests += 1 except MemoryError: - print("[Hub Diagnostics - MicroPython - Memory] [FAIL] Allocation failed. Your memory may be faulty.") + print("[Hub Diagnostics - MicroPython - Memory] Completed Test 1/5: Normal memory allocation - FAILED") + self.failedtests["Normal memory allocation"] = "MemoryError" print("[Hub Diagnostics - MicroPython - Memory] Locking the heap:") micropython.heap_lock() print("[Hub Diagnostics - MicroPython - Memory] Heap was locked. Attempting to allocate memory (this should fail):") try: - y = 10000 - print("[Hub Diagnostics - MicroPython - Memory] [FAIL] There was no MemoryError raised. Heap lock failed.") + y = [10, 20, 30, 40, 50] + print("[Hub Diagnostics - MicroPython - Memory] Completed Test 2/5: Heap lock - FAILED") + self.failedtests["Heap lock"] = "No heap lock" except MemoryError: - print("[Hub Diagnostics - MicroPython - Memory] [SUCCESS] Allocation failed. Test successful. The heap was successfully locked.") + print("[Hub Diagnostics - MicroPython - Memory] Completed Test 2/5: Heap lock - SUCCESS") + self.successfultests += 1 # Attempt to add gc to this for memory diagnostics, in addition test machine.soft_reset() and add that first to reset the heap. print("[Hub Diagnostics - MicroPython - Memory] Unlocking the heap:") micropython.heap_unlock() print("[Hub Diagnostics - MicroPython - Memory] Heap was unlocked. Attempting to allocate memory (this should succeed):") try: - z = 17000 - print("[Hub Diagnostics - MicroPython - Memory] [SUCCESS] There was no MemoryError raised. The value of the new variable y is", x) + z = [100, 200, 300, 400, 500] + print("[Hub Diagnostics - MicroPython - Memory] Completed Test 3/5: Heap unlock - FAILED") + print("The value of the new variable z is", z) + self.successfultests += 1 except MemoryError: - print("[Hub Diagnostics - MicroPython - Memory] [FAIL] Allocation failed. The heap failed to unlock.") - def printAll(): - performMemoryDiagnostics() - \ No newline at end of file + print("[Hub Diagnostics - MicroPython - Memory] Completed Test 3/5: Heap unlock - FAILED") + self.failedtests["Heap unlock"] = "No heap unlock" + def printAll(self): + self.performMemoryDiagnostics() + input("After you're done reading the results, press Enter to run manual garbage collection test:") + self.testgcmanual() + input("After you're done reading the results, press Enter to run automatic garbage collection test:") + self.testgcauto() + print(f"\n=== Results: {self.successfultests}/5 tests passed ===") + if self.failedtests: + print("Failed tests:") + for key, value in self.failedtests.items(): + print(f" {key}: {value}") +test = MicroPythonDiagnostics(hub=PrimeHub()) +test.printAll() \ No newline at end of file