2022年の夏から2023年の春にかけて「ハンドクラフトの素材としての電子工作 “超” 入門」講習会を企画実施していました。木工などのクラフトを簡単にテーブルランプにできる照明ユニットを作る講習会ですが、このブログにはまったく記録に残していませんでした。今回はMicroPythonを使ってリメイクすることにしました。
照明ユニットは下の写真のケースにESP32 MH-ET Live Mini Kitに4×4シリアルフルカラーLEDをつけてユニットを作ります。

木工などのクラフトの下に置くと簡単にテーブルランプにできます。Arduino IDEで書いたプログラムで、写真は焚き火をモチーフにしたものですが、WiFiアクセスポイントからカラーセットを変更する機能もついていました。

今回はWaveshare RP2040-Zeroと8x8LEDで作ったプログラムをベースにリメイクすることにしました。MicroPythonでESP32を使うときにはThonny IDEを使ってESP32用のMicroPythonをインストールします。特に難しいこともなく終了しますが、ESP32用のneopixelライブラリはMicroPythonファームウェアに含まれているのでそれを使います。PicoやWaveshare RP2040-Zeroで使っているライブラリとは違うので、関数名NeopixelをNeoPixelに変更したり、Brightnessの機能を自分で作らないといけません。
また、4×4マトリクスは0行目は右、1行目は左、2行目は右、3行目は左とジグザグなLED番号なので変更しました。
パーリンノイズはMicroPython用のライブラリ “perlin.py” が公開されています。このライブラリをダウンロードしてマイコンのメモリに保存します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# For ESP32 MicroPython # Koji Ohashi 20241122 # perlin lib:https://github.com/sjaak31367/micropython_perlin import perlin from neopixel import NeoPixel import time, machine numpix = 16 led_pin = 16 led = NeoPixel(machine.Pin(led_pin), numpix) def led_xy_to_count(x, y): if (y % 2 == 0): count = (y * 4) + x else: count = (y * 4) + (3 - x) return count def in_range(x): if x < 0: x = 0 elif x > 255: x = 255 return(x) def heatmap(n, brightness): #n 0-255 brightness 0 to 1.0 red = int(in_range(3 * n) * brightness) green = int(in_range(3 * (n - 85)) * brightness) blue = int(in_range(3 * (n - 170)) * brightness) return((red, green, blue)) def heat_tuple(brightness): palette = [] for i in range (256): palette.append(heatmap(i, brightness)) heat_color = tuple(palette) del palette return(heat_color) def generate_intensity(): #generate intensity coefficients between 0.55-1.0 y,z,octave = 0.5, 0.7 ,3 #default value for i in range (100): x = i intensity[i] = perlin.octave_perlin(x,y,z,octave) min_intensity = min(intensity) max_intensity = max(intensity) for i in range (100): intensity[i] = ((intensity[i] - min_intensity) / (max_intensity - min_intensity)) * 0.45 + 0.55 intensity = [0.0] * 100 led_heat = [0.0]*16 led_base = [10, 20, 20, 10, 20, 60, 60, 20, 20, 60, 60, 20, 10, 20, 20, 10,] # led_base/100 list_led = [0, 1, 2, 3, 7, 6, 5, 4, 8, 9, 10, 11, 15, 14, 13, 12,] brightness = 0.5 color = heat_tuple(brightness) perlin.reseed(time.ticks_ms()) generate_intensity() intensity_index = 0 while True: for y in range (4): for x in range (4): z = 0.7 octave = 3 list_count = y * 4 + x led_count = led_xy_to_count(x, y) heat_noise = perlin.octave_perlin(x,y,z,octave) led_heat[list_count] = heat_noise * led_base[list_count] / 100 minimum = min(led_heat) maximum = max(led_heat) for list_count in range (16): heat_index = int((led_heat[list_count] - minimum) / (maximum - minimum) * 170 * intensity[intensity_index]) led[list_led[list_count]] = color[heat_index] led.write() time.sleep(0.05) perlin.reseed(time.ticks_ms()) intensity_index = intensity_index + 1 if intensity_index >=100: generate_intensity() intensity_index = 0 |

