Hi,
I’ve got my hands on a Raspberry Pi 4 (8GB version) and a Suptronic x872 SSD NVMe shield for the system boot. Now with this setup there was a question how to cool it all down. I like Pimoroni heatsink case since it is just a big chunk of metal that tries to look like a case - good for passive cooling.
It is not exactly tied to EOS-ARM but I hope someone find this interesting.
In normal operation I saw that everyone was using the case in a horizontal position (CPU facing up). But it would mean that the SSD below the Pi would be sitting directly on the table. So I made a little testing of how much different orientation of the case changed effectiveness of the cooling.
Sadly, this ssd shield doesn’t allow me to read ssh’s temperature (I am not sure right now if it is only my incompetence or some missing feature).
So, these positions were tested:
This is a small stress test script I used:
click to show
#!/usr/bin/env python3
import subprocess
import time
FILE_NAME = "stress_result"
FILE_TMP_STORAGE = "/tmp/"
SEPARATOR = ";"
NEWLINE = "\n"
LOOP_SLEEP = 1.0 # delay between each loop iterations
COUNT_PRE_STRESS = 600 # number of loops before stress is applied
COUNT_STRESS = 2100
COUNT_POST_STRESS = 900 # cooldown after stress cycles
iterator = 0
# header, [args], [string parse], multiplier, print format
commands = [
['datetime', ['date', '--iso-8601=ns'], [None, -1], None, ''],
['temperature_core_[°C]', ['vcgencmd', 'measure_temp'], [5, -3], 1.0 , '.1f'],
['clock_arm_[GHz]', ['vcgencmd', 'measure_clock', 'arm'], [14, -1], 0.000000001 , '.3f'],
['clock_core_[GHz]', ['vcgencmd', 'measure_clock', 'core'], [13, -1], 0.000000001 , '.3f'],
['throttled', ['vcgencmd', 'get_throttled'], [10, -1], None , '']
]
header = 'iterator'
header += SEPARATOR + 'phase'
for command in commands:
header += SEPARATOR + command[0]
header += NEWLINE
with open(FILE_TMP_STORAGE + FILE_NAME, "w") as f:
f.write(header)
# phase: 0==pre, 1==stress, 2==post
phase = 0
phase_last = 0
iterator = 0
while(phase < 3):
line = str(iterator)
phase_last = phase # copy phase of the last cycle
if(iterator >= COUNT_PRE_STRESS + COUNT_STRESS + COUNT_POST_STRESS):
phase = 3
elif(iterator >= COUNT_PRE_STRESS + COUNT_STRESS):
phase = 2
elif(iterator >= COUNT_PRE_STRESS):
phase = 1
else:
phase = 0
line += SEPARATOR + str(phase)
if(phase == 1 and phase_last == 0):
pipe = subprocess.Popen(['stress-ng', '-c4', '-l100'], shell=False)
elif(phase == 2 and phase_last == 1):
pipe.terminate()
for command in commands:
proc = subprocess.run(command[1], capture_output=True, text=True)
result = proc.stdout
result = result[command[2][0]:command[2][1]]
if(command[3] != None):
result = float(result) * command[3]
line += SEPARATOR + '{1:{0}}'.format(command[4], result)
line += NEWLINE
with open(FILE_TMP_STORAGE + FILE_NAME, "a") as f:
f.write(line)
iterator += 1
time.sleep(LOOP_SLEEP)
print('iter: ' + str(iterator) + '\tphase: ' + str(phase))
print('done')
And this is the result - first it is idle (less then 5% load) then 100% load on all CPUs and then again idle. This is a plot from running averages (10 points).
Ambient temperature was 21.5-22.0°C. The runs were in order 1, 2 and 3 so it is not like the device could be influenced by previous runs (except for the on_side_3 which obvously didn’t cool down enough from the previous run when idle - the script could use longer idle periods but I didn’t want to wait).
Truth be told I didn’t expect such difference between horizontal and on_side run since when the case is on the side the ribs of the heatsink are not in direction of a natural air flow.
I also didn’t see any case of thermal throttling but with some dust collection it will probably change.