Board-dat/ESP/ESP1000-dat/ESP1000-MP-dat/2640-1.py
... ...
@@ -0,0 +1,73 @@
1
+import camera
2
+import machine
3
+import time
4
+
5
+
6
+
7
+# Initialize camera with debug and smaller frame size
8
+print("Initializing camera...")
9
+try:
10
+ camera.init(0,
11
+ d0=5, d1=18, d2=19, d3=21, d4=36, d5=39, d6=34, d7=35,
12
+ format=camera.JPEG,
13
+ framesize=camera.FRAME_QQVGA,
14
+ xclk_freq=camera.XCLK_20MHz,
15
+ href=23, vsync=25, reset=-1, pwdn=32, sioc=27, siod=26, xclk=0, pclk=22
16
+ )
17
+ print("Camera initialized successfully.")
18
+except Exception as e:
19
+ print("Camera init failed:", e)
20
+ # Stop further execution
21
+ while True:
22
+ machine.idle()
23
+
24
+
25
+# Initialize IO4 (GPIO4) as output
26
+led = machine.Pin(4, machine.Pin.OUT)
27
+
28
+
29
+while True:
30
+ print("Starting capture cycle...")
31
+ # Blink LED for status
32
+ for _ in range(2):
33
+ led.value(1)
34
+ machine.idle()
35
+ time.sleep(0.05)
36
+ machine.idle()
37
+ led.value(0)
38
+ machine.idle()
39
+ time.sleep(0.05)
40
+ machine.idle()
41
+
42
+ machine.idle()
43
+ print("Capturing image...")
44
+ try:
45
+ buf = camera.capture()
46
+ print("Captured image, size =", len(buf))
47
+ except Exception as e:
48
+ print("Capture failed:", e)
49
+ # wait before retry
50
+ time.sleep(1)
51
+ continue
52
+ machine.idle()
53
+
54
+ # Generate a timestamped filename
55
+ ts = time.localtime()
56
+ filename = 'capture_{:04d}{:02d}{:02d}_{:02d}{:02d}{:02d}.jpg'.format(ts[0], ts[1], ts[2], ts[3], ts[4], ts[5])
57
+ print("Saving to file:", filename)
58
+ try:
59
+ with open(filename, 'wb') as f:
60
+ f.write(buf)
61
+ machine.idle()
62
+ print("File saved.")
63
+ except Exception as e:
64
+ print("File write error:", e)
65
+ machine.idle()
66
+ print("Sleeping before next cycle...")
67
+ for _ in range(50):
68
+ time.sleep(0.05)
69
+ machine.idle()
70
+
71
+
72
+
73
+
Board-dat/ESP/ESP1000-dat/ESP1000-MP-dat/ESP1000-1-dat.py
... ...
@@ -0,0 +1,51 @@
1
+
2
+# mpremote connect COM6 fs cp esp1000-1-dat.py :
3
+# mpremote connect COM6 run esp1000-1-dat.py
4
+
5
+from machine import I2C, Pin, UART
6
+import ssd1306
7
+from bmp280 import *
8
+import time
9
+
10
+# I2C setup (adjust pins as needed)
11
+i2c = I2C(0, scl=Pin(13), sda=Pin(15))
12
+
13
+# OLED setup
14
+oled = ssd1306.SSD1306_I2C(128, 64, i2c)
15
+
16
+# BMP280 setup
17
+bmp = BMP280(i2c)
18
+bmp.use_case(BMP280_CASE_WEATHER)
19
+bmp.oversample(BMP280_OS_HIGH)
20
+bmp.temp_os = BMP280_TEMP_OS_8
21
+bmp.press_os = BMP280_PRES_OS_4
22
+bmp.standby = BMP280_STANDBY_250
23
+bmp.iir = BMP280_IIR_FILTER_2
24
+bmp.spi3w = BMP280_SPI3W_ON
25
+bmp.power_mode = BMP280_POWER_NORMAL
26
+
27
+# Deinit UART0 (GPIO3 is RX)
28
+# uart0 = UART(0)
29
+# uart0.deinit()
30
+# GPIO3 setup with internal pull-down
31
+gpio3 = Pin(3, Pin.IN, Pin.PULL_DOWN)
32
+
33
+while True:
34
+ try:
35
+ bmp.force_measure()
36
+ temperature = bmp.temperature
37
+ pressure = bmp.pressure
38
+ gpio3_status = gpio3.value()
39
+
40
+ oled.fill(0)
41
+ oled.text("BMP280 Sensor:", 0, 0)
42
+ oled.text("T={:.2f}C".format(temperature), 0, 16)
43
+ oled.text("P={:.2f}hPa".format(pressure), 0, 32)
44
+ oled.text("GPIO3: {}".format(gpio3_status), 0, 48)
45
+ oled.show()
46
+ except Exception as e:
47
+ oled.fill(0)
48
+ oled.text("Error:", 0, 0)
49
+ oled.text(str(e), 0, 16)
50
+ oled.show()
51
+ time.sleep(2)
... ...
\ No newline at end of file
Board-dat/ESP/ESP1000-dat/ESP1000-MP-dat/ESP1000-2-dat.py
... ...
@@ -0,0 +1,141 @@
1
+# mpremote connect COM6 fs cp esp1000-1-dat.py :
2
+# mpremote connect COM6 run esp1000-1-dat.py
3
+
4
+from machine import I2C, Pin, UART
5
+import machine # type: ignore
6
+import camera # type: ignore
7
+import ssd1306
8
+from bmp280 import *
9
+import time
10
+import gc # type: ignore
11
+
12
+# init_i2c: use fixed bus without scanning devices
13
+def init_i2c():
14
+ # I2C setup (bus 1, 400kHz)
15
+ i2c = I2C(1, scl=Pin(13), sda=Pin(15), freq=400000)
16
+ return i2c
17
+
18
+
19
+def init_oled(i2c):
20
+ # Use fixed address 0x3C for SSD1306
21
+ try:
22
+ oled = ssd1306.SSD1306_I2C(128, 64, i2c, addr=0x3C)
23
+ print("OLED initialized at 0x3C.")
24
+ return oled
25
+ except Exception as e:
26
+ print("OLED init failed:", e)
27
+ return None
28
+
29
+
30
+def init_bmp(i2c):
31
+ print("Initializing BMP280 at fixed address 0x76...")
32
+ try:
33
+ bmp = BMP280(i2c, 0x76)
34
+ bmp.use_case(BMP280_CASE_WEATHER)
35
+ bmp.oversample(BMP280_OS_HIGH)
36
+ bmp.temp_os = BMP280_TEMP_OS_8
37
+ bmp.press_os = BMP280_PRES_OS_4
38
+ bmp.standby = BMP280_STANDBY_250
39
+ bmp.iir = BMP280_IIR_FILTER_2
40
+ bmp.spi3w = BMP280_SPI3W_ON
41
+ bmp.power_mode = BMP280_POWER_NORMAL
42
+ print("BMP280 initialized.")
43
+ return bmp
44
+ except Exception as e:
45
+ print("BMP280 init failed:", e)
46
+ return None
47
+
48
+
49
+def read_bmp(bmp):
50
+ try:
51
+ bmp.force_measure()
52
+ temp = bmp.temperature
53
+ pressure = bmp.pressure
54
+ # power down sensor after reading
55
+ bmp.sleep()
56
+ return temp, pressure
57
+ except Exception as e:
58
+ print("BMP read error:", e)
59
+ return None, None
60
+
61
+
62
+def read_gpio(pin):
63
+ return pin.value()
64
+
65
+
66
+def init_camera():
67
+ try:
68
+ camera.init(0,
69
+ d0=5, d1=18, d2=19, d3=21, d4=36, d5=39, d6=34, d7=35,
70
+ format=camera.JPEG,
71
+ framesize=camera.FRAME_QQVGA,
72
+ xclk_freq=camera.XCLK_20MHz,
73
+ href=23, vsync=25, reset=-1, pwdn=32,
74
+ sioc=27, siod=26, xclk=0, pclk=22
75
+ )
76
+ print("Camera initialized.")
77
+ return True
78
+ except Exception as e:
79
+ print("Camera init failed:", e)
80
+ return False
81
+
82
+
83
+def capture_image():
84
+ buf = camera.capture()
85
+ print("Captured image size:", len(buf))
86
+ ts = time.localtime()
87
+ filename = 'capture_{:04d}{:02d}{:02d}_{:02d}{:02d}{:02d}.jpg'.format(*ts[:6])
88
+ with open(filename, 'wb') as f:
89
+ f.write(buf)
90
+ print("Saved file:", filename)
91
+ return filename
92
+
93
+
94
+def update_display(oled, temp, pressure, gpio_status, filename=None):
95
+ if not oled:
96
+ return
97
+ oled.fill(0)
98
+ if filename:
99
+ oled.text(filename[:16], 0, 0)
100
+ oled.text(filename[16:], 0, 16)
101
+ oled.text("GPIO3: {}".format(gpio_status), 0, 32)
102
+ if temp is not None:
103
+ oled.text("T={:.1f}C".format(temp), 0, 48)
104
+ else:
105
+ oled.text("BMP280 Sensor:", 0, 0)
106
+ if temp is not None:
107
+ oled.text("T={:.2f}C".format(temp), 0, 16)
108
+ if pressure is not None:
109
+ oled.text("P={:.2f}hPa".format(pressure), 0, 32)
110
+ oled.text("GPIO3: {}".format(gpio_status), 0, 48)
111
+ oled.show()
112
+
113
+
114
+def main():
115
+ i2c = init_i2c()
116
+ # oled = init_oled(i2c)
117
+ bmp = init_bmp(i2c)
118
+ gpio3 = Pin(3, Pin.IN, Pin.PULL_DOWN)
119
+ camera_ready = False
120
+
121
+ while True:
122
+ temp, pressure = (read_bmp(bmp) if bmp else (None, None))
123
+ gpio_status = read_gpio(gpio3)
124
+
125
+ if gpio_status:
126
+ if not camera_ready:
127
+ camera_ready = init_camera()
128
+ if camera_ready:
129
+ filename = capture_image()
130
+ else:
131
+ filename = None
132
+ update_display(oled, temp, pressure, gpio_status, filename)
133
+ else:
134
+ update_display(oled, temp, pressure, gpio_status)
135
+
136
+ print("Loop end, free mem:", gc.mem_free())
137
+ time.sleep(2)
138
+
139
+
140
+# Entry point
141
+main()
... ...
\ No newline at end of file
Board-dat/ESP/ESP1000-dat/ESP1000-MP-dat/ESP1000-MP-dat.md
... ...
@@ -0,0 +1,44 @@
1
+
2
+# ESP1000-MP-dat.md
3
+
4
+- [[esp1000-dat]] - [[OV2640-lemariva-dat]]
5
+
6
+- [[micropython-dat]]
7
+
8
+- [[camera-sdk-dat]]
9
+
10
+flash camera driver firmware
11
+
12
+ esptool --port COM6 erase_flash
13
+ esptool --port COM6 --baud 460800 write-flash 0x1000 micropython_camera_feeeb5ea3_esp32_idf4_4.bin
14
+
15
+ mpremote connect COM6 fs cp bmp280.py :
16
+ mpremote connect COM6 fs cp ssd1306.py :
17
+ mpremote connect COM6 fs cp esp1000-2-dat.py :
18
+
19
+
20
+ mpremote connect COM6 run esp1000-2-dat.py
21
+
22
+ mpremote connect COM6 fs cp 2640-1.py :
23
+ mpremote connect COM6 run 2640-1.py
24
+
25
+- [[micropython_camera_feeeb5ea3_esp32_idf4_4.bin]] - micropython camera driver firmware, has memory error with [[BMP280-dat]]
26
+
27
+ Guru Meditation Error: Core 1 panic'ed (StoreProhibited). Exception was unhandled.
28
+
29
+ Core 1 register dump:
30
+ PC : 0x400869fc PS : 0x00060031 A0 : 0x80086bb2
31
+ A1 : 0x3ffb1190
32
+ A2 : 0x3ffaf894 A3 : 0x00000000 A4 : 0x00000000
33
+ A5 : 0x00000800
34
+ A6 : 0x00060023 A7 : 0x00060021 A8 : 0x3ffbbf88
35
+ A9 : 0x00000901
36
+ A10 : 0x3ffb1208 A11 : 0x00000001 A12 : 0x00000001
37
+ A13 : 0x3ffbbf8c
38
+ A14 : 0x00000000 A15 : 0x3ff53000 SAR : 0x0000000d
39
+ EXCCAUSE: 0x0000001d
40
+ EXCVADDR: 0x00000008 LBEG : 0x4008d9a0 LEND : 0x4008d9bc
41
+ LCOUNT : 0x00000000
42
+
43
+
44
+ Backtrace:0x400869f9:0x3ffb11900x40086baf:0x3ffb11d0 0x40083f85:0x3ffb1200 0x40089ea9:0x3ffca150 0x40091141:0x3ffca170 0x4012628b:0x3ffca1b0 0x40119b16:0x3ffca200 0x401169a9:0x3ffca230 0x40116a21:0x3ffca270 0x400e20bd:0x3ffca2b0 0x400e8819:0x3ffca2e0 0x400e8951:0x3ffca300 0x40085ca5:0x3ffca320 0x400e205a:0x3ffca3c0 0x400e8819:0x3ffca430 0x400e8951:0x3ffca450 0x40085ca5:0x3ffca470 0x400e205a:0x3ffca510 0x400e8819:0x3ffca580 0x400e8951:0x3ffca5a0 0x400e7641:0x3ffca5c0 0x400e725e:0x3ffca620 0x400e8819:0x3ffca640 0x40085c29:0x3ffca660 0x400e205a:0x3ffca700 0x400e8819:0x3ffca730 0x400e8842:0x3ffca750 0x40118bdd:0x3ffca770 0x40118d9a:0x3ffca800 0x400f89b6:0x3ffca850
... ...
\ No newline at end of file
Board-dat/ESP/ESP1000-dat/ESP1000-MP-dat/bmp280.py
... ...
@@ -0,0 +1,322 @@
1
+from micropython import const
2
+from ustruct import unpack as unp
3
+
4
+# Author David Stenwall (david at stenwall.io)
5
+
6
+# Power Modes
7
+BMP280_POWER_SLEEP = const(0)
8
+BMP280_POWER_FORCED = const(1)
9
+BMP280_POWER_NORMAL = const(3)
10
+
11
+BMP280_SPI3W_ON = const(1)
12
+BMP280_SPI3W_OFF = const(0)
13
+
14
+BMP280_TEMP_OS_SKIP = const(0)
15
+BMP280_TEMP_OS_1 = const(1)
16
+BMP280_TEMP_OS_2 = const(2)
17
+BMP280_TEMP_OS_4 = const(3)
18
+BMP280_TEMP_OS_8 = const(4)
19
+BMP280_TEMP_OS_16 = const(5)
20
+
21
+BMP280_PRES_OS_SKIP = const(0)
22
+BMP280_PRES_OS_1 = const(1)
23
+BMP280_PRES_OS_2 = const(2)
24
+BMP280_PRES_OS_4 = const(3)
25
+BMP280_PRES_OS_8 = const(4)
26
+BMP280_PRES_OS_16 = const(5)
27
+
28
+# Standby settings in ms
29
+BMP280_STANDBY_0_5 = const(0)
30
+BMP280_STANDBY_62_5 = const(1)
31
+BMP280_STANDBY_125 = const(2)
32
+BMP280_STANDBY_250 = const(3)
33
+BMP280_STANDBY_500 = const(4)
34
+BMP280_STANDBY_1000 = const(5)
35
+BMP280_STANDBY_2000 = const(6)
36
+BMP280_STANDBY_4000 = const(7)
37
+
38
+# IIR Filter setting
39
+BMP280_IIR_FILTER_OFF = const(0)
40
+BMP280_IIR_FILTER_2 = const(1)
41
+BMP280_IIR_FILTER_4 = const(2)
42
+BMP280_IIR_FILTER_8 = const(3)
43
+BMP280_IIR_FILTER_16 = const(4)
44
+
45
+# Oversampling setting
46
+BMP280_OS_ULTRALOW = const(0)
47
+BMP280_OS_LOW = const(1)
48
+BMP280_OS_STANDARD = const(2)
49
+BMP280_OS_HIGH = const(3)
50
+BMP280_OS_ULTRAHIGH = const(4)
51
+
52
+# Oversampling matrix
53
+# (PRESS_OS, TEMP_OS, sample time in ms)
54
+_BMP280_OS_MATRIX = [
55
+ [BMP280_PRES_OS_1, BMP280_TEMP_OS_1, 7],
56
+ [BMP280_PRES_OS_2, BMP280_TEMP_OS_1, 9],
57
+ [BMP280_PRES_OS_4, BMP280_TEMP_OS_1, 14],
58
+ [BMP280_PRES_OS_8, BMP280_TEMP_OS_1, 23],
59
+ [BMP280_PRES_OS_16, BMP280_TEMP_OS_2, 44]
60
+]
61
+
62
+# Use cases
63
+BMP280_CASE_HANDHELD_LOW = const(0)
64
+BMP280_CASE_HANDHELD_DYN = const(1)
65
+BMP280_CASE_WEATHER = const(2)
66
+BMP280_CASE_FLOOR = const(3)
67
+BMP280_CASE_DROP = const(4)
68
+BMP280_CASE_INDOOR = const(5)
69
+
70
+_BMP280_CASE_MATRIX = [
71
+ [BMP280_POWER_NORMAL, BMP280_OS_ULTRAHIGH, BMP280_IIR_FILTER_4, BMP280_STANDBY_62_5],
72
+ [BMP280_POWER_NORMAL, BMP280_OS_STANDARD, BMP280_IIR_FILTER_16, BMP280_STANDBY_0_5],
73
+ [BMP280_POWER_FORCED, BMP280_OS_ULTRALOW, BMP280_IIR_FILTER_OFF, BMP280_STANDBY_0_5],
74
+ [BMP280_POWER_NORMAL, BMP280_OS_STANDARD, BMP280_IIR_FILTER_4, BMP280_STANDBY_125],
75
+ [BMP280_POWER_NORMAL, BMP280_OS_LOW, BMP280_IIR_FILTER_OFF, BMP280_STANDBY_0_5],
76
+ [BMP280_POWER_NORMAL, BMP280_OS_ULTRAHIGH, BMP280_IIR_FILTER_16, BMP280_STANDBY_0_5]
77
+]
78
+
79
+_BMP280_REGISTER_ID = const(0xD0)
80
+_BMP280_REGISTER_RESET = const(0xE0)
81
+_BMP280_REGISTER_STATUS = const(0xF3)
82
+_BMP280_REGISTER_CONTROL = const(0xF4)
83
+_BMP280_REGISTER_CONFIG = const(0xF5) # IIR filter config
84
+
85
+_BMP280_REGISTER_DATA = const(0xF7)
86
+
87
+
88
+class BMP280:
89
+ def __init__(self, i2c_bus, addr=0x76, use_case=BMP280_CASE_HANDHELD_DYN):
90
+ self._bmp_i2c = i2c_bus
91
+ self._i2c_addr = addr
92
+
93
+ # read calibration data
94
+ # < little-endian
95
+ # H unsigned short
96
+ # h signed short
97
+ self._T1 = unp('<H', self._read(0x88, 2))[0]
98
+ self._T2 = unp('<h', self._read(0x8A, 2))[0]
99
+ self._T3 = unp('<h', self._read(0x8C, 2))[0]
100
+ self._P1 = unp('<H', self._read(0x8E, 2))[0]
101
+ self._P2 = unp('<h', self._read(0x90, 2))[0]
102
+ self._P3 = unp('<h', self._read(0x92, 2))[0]
103
+ self._P4 = unp('<h', self._read(0x94, 2))[0]
104
+ self._P5 = unp('<h', self._read(0x96, 2))[0]
105
+ self._P6 = unp('<h', self._read(0x98, 2))[0]
106
+ self._P7 = unp('<h', self._read(0x9A, 2))[0]
107
+ self._P8 = unp('<h', self._read(0x9C, 2))[0]
108
+ self._P9 = unp('<h', self._read(0x9E, 2))[0]
109
+
110
+ # output raw
111
+ self._t_raw = 0
112
+ self._t_fine = 0
113
+ self._t = 0
114
+
115
+ self._p_raw = 0
116
+ self._p = 0
117
+
118
+ self.read_wait_ms = 0 # interval between forced measure and readout
119
+ self._new_read_ms = 200 # interval between
120
+ self._last_read_ts = 0
121
+
122
+ if use_case is not None:
123
+ self.use_case(use_case)
124
+
125
+ def _read(self, addr, size=1):
126
+ return self._bmp_i2c.readfrom_mem(self._i2c_addr, addr, size)
127
+
128
+ def _write(self, addr, b_arr):
129
+ if not type(b_arr) is bytearray:
130
+ b_arr = bytearray([b_arr])
131
+ return self._bmp_i2c.writeto_mem(self._i2c_addr, addr, b_arr)
132
+
133
+ def _gauge(self):
134
+ # TODO limit new reads
135
+ # read all data at once (as by spec)
136
+ d = self._read(_BMP280_REGISTER_DATA, 6)
137
+
138
+ self._p_raw = (d[0] << 12) + (d[1] << 4) + (d[2] >> 4)
139
+ self._t_raw = (d[3] << 12) + (d[4] << 4) + (d[5] >> 4)
140
+
141
+ self._t_fine = 0
142
+ self._t = 0
143
+ self._p = 0
144
+
145
+ def reset(self):
146
+ self._write(_BMP280_REGISTER_RESET, 0xB6)
147
+
148
+ def load_test_calibration(self):
149
+ self._T1 = 27504
150
+ self._T2 = 26435
151
+ self._T3 = -1000
152
+ self._P1 = 36477
153
+ self._P2 = -10685
154
+ self._P3 = 3024
155
+ self._P4 = 2855
156
+ self._P5 = 140
157
+ self._P6 = -7
158
+ self._P7 = 15500
159
+ self._P8 = -14600
160
+ self._P9 = 6000
161
+
162
+ def load_test_data(self):
163
+ self._t_raw = 519888
164
+ self._p_raw = 415148
165
+
166
+ def print_calibration(self):
167
+ print("T1: {} {}".format(self._T1, type(self._T1)))
168
+ print("T2: {} {}".format(self._T2, type(self._T2)))
169
+ print("T3: {} {}".format(self._T3, type(self._T3)))
170
+ print("P1: {} {}".format(self._P1, type(self._P1)))
171
+ print("P2: {} {}".format(self._P2, type(self._P2)))
172
+ print("P3: {} {}".format(self._P3, type(self._P3)))
173
+ print("P4: {} {}".format(self._P4, type(self._P4)))
174
+ print("P5: {} {}".format(self._P5, type(self._P5)))
175
+ print("P6: {} {}".format(self._P6, type(self._P6)))
176
+ print("P7: {} {}".format(self._P7, type(self._P7)))
177
+ print("P8: {} {}".format(self._P8, type(self._P8)))
178
+ print("P9: {} {}".format(self._P9, type(self._P9)))
179
+
180
+ def _calc_t_fine(self):
181
+ # From datasheet page 22
182
+ self._gauge()
183
+ if self._t_fine == 0:
184
+ var1 = (((self._t_raw >> 3) - (self._T1 << 1)) * self._T2) >> 11
185
+ var2 = (((((self._t_raw >> 4) - self._T1)
186
+ * ((self._t_raw >> 4)
187
+ - self._T1)) >> 12)
188
+ * self._T3) >> 14
189
+ self._t_fine = var1 + var2
190
+
191
+ @property
192
+ def temperature(self):
193
+ self._calc_t_fine()
194
+ if self._t == 0:
195
+ self._t = ((self._t_fine * 5 + 128) >> 8) / 100.
196
+ return self._t
197
+
198
+ @property
199
+ def pressure(self):
200
+ # From datasheet page 22
201
+ self._calc_t_fine()
202
+ if self._p == 0:
203
+ var1 = self._t_fine - 128000
204
+ var2 = var1 * var1 * self._P6
205
+ var2 = var2 + ((var1 * self._P5) << 17)
206
+ var2 = var2 + (self._P4 << 35)
207
+ var1 = ((var1 * var1 * self._P3) >> 8) + ((var1 * self._P2) << 12)
208
+ var1 = (((1 << 47) + var1) * self._P1) >> 33
209
+
210
+ if var1 == 0:
211
+ return 0
212
+
213
+ p = 1048576 - self._p_raw
214
+ p = int((((p << 31) - var2) * 3125) / var1)
215
+ var1 = (self._P9 * (p >> 13) * (p >> 13)) >> 25
216
+ var2 = (self._P8 * p) >> 19
217
+
218
+ p = ((p + var1 + var2) >> 8) + (self._P7 << 4)
219
+ self._p = p / 256.0
220
+ return self._p
221
+
222
+ def _write_bits(self, address, value, length, shift=0):
223
+ d = self._read(address)[0]
224
+ m = int('1' * length, 2) << shift
225
+ d &= ~m
226
+ d |= m & value << shift
227
+ self._write(address, d)
228
+
229
+ def _read_bits(self, address, length, shift=0):
230
+ d = self._read(address)[0]
231
+ return d >> shift & int('1' * length, 2)
232
+
233
+ @property
234
+ def standby(self):
235
+ return self._read_bits(_BMP280_REGISTER_CONFIG, 3, 5)
236
+
237
+ @standby.setter
238
+ def standby(self, v):
239
+ assert 0 <= v <= 7
240
+ self._write_bits(_BMP280_REGISTER_CONFIG, v, 3, 5)
241
+
242
+ @property
243
+ def iir(self):
244
+ return self._read_bits(_BMP280_REGISTER_CONFIG, 3, 2)
245
+
246
+ @iir.setter
247
+ def iir(self, v):
248
+ assert 0 <= v <= 4
249
+ self._write_bits(_BMP280_REGISTER_CONFIG, v, 3, 2)
250
+
251
+ @property
252
+ def spi3w(self):
253
+ return self._read_bits(_BMP280_REGISTER_CONFIG, 1)
254
+
255
+ @spi3w.setter
256
+ def spi3w(self, v):
257
+ assert v in (0, 1)
258
+ self._write_bits(_BMP280_REGISTER_CONFIG, v, 1)
259
+
260
+ @property
261
+ def temp_os(self):
262
+ return self._read_bits(_BMP280_REGISTER_CONTROL, 3, 5)
263
+
264
+ @temp_os.setter
265
+ def temp_os(self, v):
266
+ assert 0 <= v <= 5
267
+ self._write_bits(_BMP280_REGISTER_CONTROL, v, 3, 5)
268
+
269
+ @property
270
+ def press_os(self):
271
+ return self._read_bits(_BMP280_REGISTER_CONTROL, 3, 2)
272
+
273
+ @press_os.setter
274
+ def press_os(self, v):
275
+ assert 0 <= v <= 5
276
+ self._write_bits(_BMP280_REGISTER_CONTROL, v, 3, 2)
277
+
278
+ @property
279
+ def power_mode(self):
280
+ return self._read_bits(_BMP280_REGISTER_CONTROL, 2)
281
+
282
+ @power_mode.setter
283
+ def power_mode(self, v):
284
+ assert 0 <= v <= 3
285
+ self._write_bits(_BMP280_REGISTER_CONTROL, v, 2)
286
+
287
+ @property
288
+ def is_measuring(self):
289
+ return bool(self._read_bits(_BMP280_REGISTER_STATUS, 1, 3))
290
+
291
+ @property
292
+ def is_updating(self):
293
+ return bool(self._read_bits(_BMP280_REGISTER_STATUS, 1))
294
+
295
+ @property
296
+ def chip_id(self):
297
+ return self._read(_BMP280_REGISTER_ID, 1)
298
+
299
+ @property
300
+ def in_normal_mode(self):
301
+ return self.power_mode == BMP280_POWER_NORMAL
302
+
303
+ def force_measure(self):
304
+ self.power_mode = BMP280_POWER_FORCED
305
+
306
+ def normal_measure(self):
307
+ self.power_mode = BMP280_POWER_NORMAL
308
+
309
+ def sleep(self):
310
+ self.power_mode = BMP280_POWER_SLEEP
311
+
312
+ def use_case(self, uc):
313
+ assert 0 <= uc <= 5
314
+ pm, oss, iir, sb = _BMP280_CASE_MATRIX[uc]
315
+ p_os, t_os, self.read_wait_ms = _BMP280_OS_MATRIX[oss]
316
+ self._write(_BMP280_REGISTER_CONFIG, (iir << 2) + (sb << 5))
317
+ self._write(_BMP280_REGISTER_CONTROL, pm + (p_os << 2) + (t_os << 5))
318
+
319
+ def oversample(self, oss):
320
+ assert 0 <= oss <= 4
321
+ p_os, t_os, self.read_wait_ms = _BMP280_OS_MATRIX[oss]
322
+ self._write_bits(_BMP280_REGISTER_CONTROL, p_os + (t_os << 3), 2)
Board-dat/ESP/ESP1000-dat/ESP1000-MP-dat/micropython_camera_feeeb5ea3_esp32_idf4_4.bin
... ...
Binary files /dev/null and b/Board-dat/ESP/ESP1000-dat/ESP1000-MP-dat/micropython_camera_feeeb5ea3_esp32_idf4_4.bin differ
Board-dat/ESP/ESP1000-dat/ESP1000-MP-dat/ssd1306.py
... ...
@@ -0,0 +1,154 @@
1
+# MicroPython SSD1306 OLED driver, I2C and SPI interfaces
2
+
3
+from micropython import const
4
+import framebuf
5
+
6
+# register definitions
7
+SET_CONTRAST = const(0x81)
8
+SET_ENTIRE_ON = const(0xA4)
9
+SET_NORM_INV = const(0xA6)
10
+SET_DISP = const(0xAE)
11
+SET_MEM_ADDR = const(0x20)
12
+SET_COL_ADDR = const(0x21)
13
+SET_PAGE_ADDR = const(0x22)
14
+SET_DISP_START_LINE = const(0x40)
15
+SET_SEG_REMAP = const(0xA0)
16
+SET_MUX_RATIO = const(0xA8)
17
+SET_COM_OUT_DIR = const(0xC0)
18
+SET_DISP_OFFSET = const(0xD3)
19
+SET_COM_PIN_CFG = const(0xDA)
20
+SET_DISP_CLK_DIV = const(0xD5)
21
+SET_PRECHARGE = const(0xD9)
22
+SET_VCOM_DESEL = const(0xDB)
23
+SET_CHARGE_PUMP = const(0x8D)
24
+
25
+# Subclassing FrameBuffer provides support for graphics primitives
26
+# http://docs.micropython.org/en/latest/pyboard/library/framebuf.html
27
+class SSD1306(framebuf.FrameBuffer):
28
+ def __init__(self, width, height, external_vcc):
29
+ self.width = width
30
+ self.height = height
31
+ self.external_vcc = external_vcc
32
+ self.pages = self.height // 8
33
+ self.buffer = bytearray(self.pages * self.width)
34
+ super().__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB)
35
+ self.init_display()
36
+
37
+ def init_display(self):
38
+ for cmd in (
39
+ SET_DISP | 0x00, # off
40
+ # address setting
41
+ SET_MEM_ADDR,
42
+ 0x00, # horizontal
43
+ # resolution and layout
44
+ SET_DISP_START_LINE | 0x00,
45
+ SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0
46
+ SET_MUX_RATIO,
47
+ self.height - 1,
48
+ SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0
49
+ SET_DISP_OFFSET,
50
+ 0x00,
51
+ SET_COM_PIN_CFG,
52
+ 0x02 if self.width > 2 * self.height else 0x12,
53
+ # timing and driving scheme
54
+ SET_DISP_CLK_DIV,
55
+ 0x80,
56
+ SET_PRECHARGE,
57
+ 0x22 if self.external_vcc else 0xF1,
58
+ SET_VCOM_DESEL,
59
+ 0x30, # 0.83*Vcc
60
+ # display
61
+ SET_CONTRAST,
62
+ 0xFF, # maximum
63
+ SET_ENTIRE_ON, # output follows RAM contents
64
+ SET_NORM_INV, # not inverted
65
+ # charge pump
66
+ SET_CHARGE_PUMP,
67
+ 0x10 if self.external_vcc else 0x14,
68
+ SET_DISP | 0x01,
69
+ ): # on
70
+ self.write_cmd(cmd)
71
+ self.fill(0)
72
+ self.show()
73
+
74
+ def poweroff(self):
75
+ self.write_cmd(SET_DISP | 0x00)
76
+
77
+ def poweron(self):
78
+ self.write_cmd(SET_DISP | 0x01)
79
+
80
+ def contrast(self, contrast):
81
+ self.write_cmd(SET_CONTRAST)
82
+ self.write_cmd(contrast)
83
+
84
+ def invert(self, invert):
85
+ self.write_cmd(SET_NORM_INV | (invert & 1))
86
+
87
+ def show(self):
88
+ x0 = 0
89
+ x1 = self.width - 1
90
+ if self.width == 64:
91
+ # displays with width of 64 pixels are shifted by 32
92
+ x0 += 32
93
+ x1 += 32
94
+ self.write_cmd(SET_COL_ADDR)
95
+ self.write_cmd(x0)
96
+ self.write_cmd(x1)
97
+ self.write_cmd(SET_PAGE_ADDR)
98
+ self.write_cmd(0)
99
+ self.write_cmd(self.pages - 1)
100
+ self.write_data(self.buffer)
101
+
102
+
103
+class SSD1306_I2C(SSD1306):
104
+ def __init__(self, width, height, i2c, addr=0x3C, external_vcc=False):
105
+ self.i2c = i2c
106
+ self.addr = addr
107
+ self.temp = bytearray(2)
108
+ self.write_list = [b"\x40", None] # Co=0, D/C#=1
109
+ super().__init__(width, height, external_vcc)
110
+
111
+ def write_cmd(self, cmd):
112
+ self.temp[0] = 0x80 # Co=1, D/C#=0
113
+ self.temp[1] = cmd
114
+ self.i2c.writeto(self.addr, self.temp)
115
+
116
+ def write_data(self, buf):
117
+ self.write_list[1] = buf
118
+ self.i2c.writevto(self.addr, self.write_list)
119
+
120
+
121
+class SSD1306_SPI(SSD1306):
122
+ def __init__(self, width, height, spi, dc, res, cs, external_vcc=False):
123
+ self.rate = 10 * 1024 * 1024
124
+ dc.init(dc.OUT, value=0)
125
+ res.init(res.OUT, value=0)
126
+ cs.init(cs.OUT, value=1)
127
+ self.spi = spi
128
+ self.dc = dc
129
+ self.res = res
130
+ self.cs = cs
131
+ import time
132
+
133
+ self.res(1)
134
+ time.sleep_ms(1)
135
+ self.res(0)
136
+ time.sleep_ms(10)
137
+ self.res(1)
138
+ super().__init__(width, height, external_vcc)
139
+
140
+ def write_cmd(self, cmd):
141
+ self.spi.init(baudrate=self.rate, polarity=0, phase=0)
142
+ self.cs(1)
143
+ self.dc(0)
144
+ self.cs(0)
145
+ self.spi.write(bytearray([cmd]))
146
+ self.cs(1)
147
+
148
+ def write_data(self, buf):
149
+ self.spi.init(baudrate=self.rate, polarity=0, phase=0)
150
+ self.cs(1)
151
+ self.dc(1)
152
+ self.cs(0)
153
+ self.spi.write(buf)
154
+ self.cs(1)
... ...
\ No newline at end of file
Board-dat/ESP/ESP1000-dat/ESP1000-dat.md
... ...
@@ -18,13 +18,24 @@ Module based on [[SCM1030-dat]]
18 18
| 34 | CAM | | CLK | | | 21 | CAM | |
19 19
| 35 | CAM | | SD0 | PSRAM | | -- | | |
20 20
| 32 | CAM_PWR | | SD1 | PSRAM | | 19 | CAM | |
21
-| 33 | | | 15 | microSD | SDA | 18 | CAM | |
22
-| 25 | | | 2 | microSD | I2S_WS | 5 | CAM | |
21
+| 33 | LED2 | | 15 | microSD | SDA | 18 | CAM | |
22
+| 25 | CAM | | 2 | microSD | I2S_WS | 5 | CAM | |
23 23
| 26 | CAM | | | | | 17 | PSRAM | |
24 24
| 27 | CAM | | | | | 16 | PSRAM | |
25 25
| 14 | microSD | I2S_SD | | | | 4 | microSD, flash | |
26 26
| 12 | microSD | I2S_SCLK | | | | 0 | CAM | |
27 27
28
+pin definitions:
29
+
30
+ #define I2S_WS 02
31
+ #define I2S_SD 14
32
+ #define I2S_SCK 12
33
+ SSD1306Wire display(0x3c, 15, 13);
34
+ BMx280I2C bmx280(0x76, 15, 13);
35
+
36
+ #define flash 4
37
+ #define PIR 3
38
+ #define obLED 33
28 39
29 40
## Board map
30 41
... ...
@@ -68,7 +79,7 @@ Verion 1.0
68 79
69 80
## In Use
70 81
71
-- [[I2S-dat]] - [[I2S-microphone-dat]]
82
+- [[I2S-dat]] - [[I2S-microphone-dat]] - [[MSM261S4030H0R-dat]]
72 83
73 84
- [[PIR-sensor-dat]] - [[OLED-dat]]
74 85
... ...
@@ -100,16 +111,7 @@ code test:
100 111
- T2: T2-CameraWebServer.ino == Camera test please use official code
101 112
- T3: T3-I2S-mem-mic.ino == test for [[I2S-microphone-dat]]
102 113
103
-pin definitions:
104
-
105
- #define I2S_WS 02
106
- #define I2S_SD 14
107
- #define I2S_SCK 12
108
- SSD1306Wire display(0x3c, 15, 13);
109
- BMx280I2C bmx280(0x76);
110 114
111
- #define flash 4
112
- #define PIR 3
113 115
114 116
## Demo Video
115 117
Board-dat/SCM/SCM1030-dat/SCM1030-dat.md
... ...
@@ -91,7 +91,7 @@ pin define
91 91
module pin to board pin
92 92
93 93
| L_Pin | custom | M_Pin | custom | R_Pin | custom |
94
-|-------|---------|-------|---------|-------|----------------|
94
+| ----- | ------- | ----- | ------- | ----- | -------------- |
95 95
| GND | | GND2 | | GND | |
96 96
| 3V3 | | 13 | microSD | 23 | CAM |
97 97
| EN | | SD2 | PSRAM | 22 | CAM |
... ...
@@ -100,7 +100,7 @@ module pin to board pin
100 100
| 34 | CAM | CLK | | 21 | CAM |
101 101
| 35 | CAM | SD0 | PSRAM | -- | |
102 102
| 32 | CAM_PWR | SD1 | PSRAM | 19 | CAM |
103
-| 33 | | 15 | microSD | 18 | CAM |
103
+| 33 | LED2 | 15 | microSD | 18 | CAM |
104 104
| 25 | | 2 | microSD | 5 | CAM |
105 105
| 26 | CAM | | | 17 | PSRAM |
106 106
| 27 | CAM | | | 16 | PSRAM |
Chip-cn-dat/Espressif-dat/ESP32-dat/ESP32-HDK-dat/ESP32-HDK-dat.md
... ...
@@ -4,6 +4,15 @@
4 4
5 5
- [[ESP32-modules-dat]] - [[ESP32-WROOM-DAT]]
6 6
7
+- [[esp32-chip-error-dat]]
8
+
9
+## pins
10
+
11
+You can use almost any GPIO, except:
12
+
13
+GPIO6–11: used for flash
14
+
15
+GPIO34–39: input-only (not usable as output like SCL)
7 16
8 17
### RMT
9 18
... ...
@@ -34,15 +43,6 @@ ref
34 43
35 44
36 45
37
-## NC Pins
38
-
39
-V3 Chips
40
-- Pins GPIO6 to GPIO11 on the ESP32-D0WD-V3/ESP32-D0WDR2-V3 chip are connected to the SPI flash integrated on the module and are not led out.
41
-
42
-V2 Chips
43
-- Pins SCK/CLK, SDO/SD0, SDI/SD1, SHD/SD2, SWP/SD3, and SCS/CMD, i.e. GPIO6 to GPIO11 are used to connect to the module integrated SPI flash, not recommended for other functions.
44
-
45
-
46 46
## Module Compare
47 47
48 48
![](2024-12-27-18-11-21.png)
Chip-cn-dat/Espressif-dat/ESP32-dat/ESP32-chip-error-dat.md
... ...
@@ -21,6 +21,20 @@ https://github.com/orgs/micropython/discussions/10521
21 21
solder a 10UF capacitor between EN and GND pins to prevent the watchdog timer from resetting the board.
22 22
23 23
24
+
25
+
26
+## NC Pins
27
+
28
+V3 Chips
29
+- Pins GPIO6 to GPIO11 on the ESP32-D0WD-V3/ESP32-D0WDR2-V3 chip are connected to the SPI flash integrated on the module and are not led out.
30
+
31
+V2 Chips
32
+- Pins SCK/CLK, SDO/SD0, SDI/SD1, SHD/SD2, SWP/SD3, and SCS/CMD, i.e. GPIO6 to GPIO11 are used to connect to the module integrated SPI flash, not recommended for other functions.
33
+
34
+
35
+
36
+
37
+
24 38
## ref
25 39
26 40
- [[ESP32-dat]]
... ...
\ No newline at end of file
Chip-dat/NXP-dat/NXP-dat.md
... ...
@@ -16,11 +16,15 @@ PCF85176 == 40 x 4 universal LCD driver for low multiplex rates
16 16
17 17
[PCF8523 == Real-Time Clock (RTC) and calendar](https://www.nxp.com.cn/docs/en/data-sheet/PCF8523.pdf)
18 18
19
-## PCF8566
19
+### PCF8566
20 20
21 21
![](2025-07-23-15-01-27.png)
22 22
23 23
24
+## I2S
25
+
26
+- [[UDA1334-dat]]
27
+
24 28
## ref
25 29
26 30
- [[CAN-dat]]
... ...
\ No newline at end of file
Chip-dat/NXP-dat/UDA1334-dat/UDA1334-dat.md
... ...
@@ -0,0 +1,19 @@
1
+
2
+# UDA1334-dat
3
+
4
+Low power audio DAC with PLL
5
+
6
+https://www.nxp.com/docs/en/data-sheet/UDA1334ATS.pdf
7
+
8
+| UDA1334A board pin | Pyboard V1.1 pin | Pyboard D pin | ESP32 pin | Pico Pin | Teensy 4.1 pin |
9
+|--------------------|------------------|---------------|-----------|----------|-----------------|
10
+| 3V0 | 3V3 | 3V3 | 3V3 | 3V3 | 3.3V |
11
+| GND | GND | GND | GND | GND | GND |
12
+| BCLK | Y6 | Y6 | 32 | 16 | 4 |
13
+| WSEL | Y5 | Y5 | 25 | 17 | 3 |
14
+| DIN | Y8 | Y8 | 33 | 18 | 2 |
15
+
16
+
17
+## ref
18
+
19
+https://github.com/miketeachman/micropython-i2s-examples
... ...
\ No newline at end of file
SDK-dat/microPython-dat/ESP32_GENERIC-20250415-v1.25.0.bin
... ...
Binary files a/SDK-dat/microPython-dat/ESP32_GENERIC-20250415-v1.25.0.bin and /dev/null differ
SDK-dat/microPython-dat/MP-ESP32-dat/ESP32_GENERIC-20250415-v1.25.0.bin
... ...
Binary files /dev/null and b/SDK-dat/microPython-dat/MP-ESP32-dat/ESP32_GENERIC-20250415-v1.25.0.bin differ
SDK-dat/microPython-dat/MP-ESP32-dat/MP-ESP32-dat.md
... ...
@@ -9,6 +9,12 @@ https://micropython.org/resources/firmware/ESP32_GENERIC-20250415-v1.25.0.bin
9 9
10 10
- [[ESP32-SDK-dat]] - [[ESP32-dat]]
11 11
12
+esp32
13
+
14
+ esptool --port COM6 erase_flash
15
+ esptool --port COM6 --baud 460800 write-flash 0x1000 ESP32_GENERIC-20250415-v1.25.0.bin
16
+
17
+
12 18
## For ESP32-S3
13 19
14 20
- [[ESP32-S3-dat]]
SDK-dat/microPython-dat/Thonny.md
... ...
@@ -1,2 +1,4 @@
1 1
2
-# thonny
... ...
\ No newline at end of file
0
+# thonny
1
+
2
+https://thonny.org/
... ...
\ No newline at end of file
SDK-dat/microPython-dat/bmp280-1-dat.py
... ...
@@ -0,0 +1,44 @@
1
+
2
+
3
+# mpremote connect COM6 fs cp bmp280-1-dat.py :
4
+# mpremote connect COM6 run bmp280-1-dat.py
5
+
6
+from machine import I2C, Pin
7
+from bmp280 import *
8
+
9
+bus = I2C(0, scl=Pin(13), sda=Pin(15))
10
+bmp = BMP280(bus)
11
+
12
+bmp.use_case(BMP280_CASE_WEATHER)
13
+bmp.oversample(BMP280_OS_HIGH)
14
+
15
+bmp.temp_os = BMP280_TEMP_OS_8
16
+bmp.press_os = BMP280_PRES_OS_4
17
+
18
+bmp.standby = BMP280_STANDBY_250
19
+bmp.iir = BMP280_IIR_FILTER_2
20
+
21
+bmp.spi3w = BMP280_SPI3W_ON
22
+
23
+bmp.power_mode = BMP280_POWER_FORCED
24
+# or
25
+bmp.force_measure()
26
+
27
+bmp.power_mode = BMP280_POWER_NORMAL
28
+# or
29
+bmp.normal_measure()
30
+# also
31
+print("In normal mode:", bmp.in_normal_mode)
32
+
33
+bmp.power_mode = BMP280_POWER_SLEEP
34
+# or
35
+bmp.sleep()
36
+
37
+print(bmp.temperature)
38
+print(bmp.pressure)
39
+
40
+#True while measuring
41
+bmp.is_measuring
42
+
43
+#True while copying data to registers
44
+bmp.is_updating
SDK-dat/microPython-dat/bmp280-2-dat.py
... ...
@@ -0,0 +1,60 @@
1
+
2
+
3
+# mpremote connect COM6 fs cp bmp280-2-dat.py :
4
+# mpremote connect COM6 run bmp280-2-dat.py
5
+
6
+from machine import I2C, Pin
7
+from bmp280 import *
8
+import time
9
+
10
+bus = I2C(0, scl=Pin(13), sda=Pin(15))
11
+bmp = BMP280(bus)
12
+
13
+bmp.use_case(BMP280_CASE_WEATHER)
14
+bmp.oversample(BMP280_OS_HIGH)
15
+
16
+bmp.temp_os = BMP280_TEMP_OS_8
17
+bmp.press_os = BMP280_PRES_OS_4
18
+
19
+bmp.standby = BMP280_STANDBY_250
20
+bmp.iir = BMP280_IIR_FILTER_2
21
+
22
+bmp.spi3w = BMP280_SPI3W_ON
23
+
24
+bmp.power_mode = BMP280_POWER_FORCED
25
+# or
26
+bmp.force_measure()
27
+
28
+bmp.power_mode = BMP280_POWER_NORMAL
29
+# or
30
+bmp.normal_measure()
31
+# also
32
+print("In normal mode:", bmp.in_normal_mode)
33
+
34
+# Infinite loop to continuously read sensor data
35
+while True:
36
+ try:
37
+ print("Loop start: measuring:", bmp.is_measuring, "updating:", bmp.is_updating)
38
+ # Force a measurement
39
+ print("Before force_measure")
40
+ bmp.force_measure()
41
+ print("After force_measure")
42
+ # Read temperature
43
+ print("Before temperature read")
44
+ temperature = bmp.temperature
45
+ print("After temperature read, value:", temperature)
46
+ # Read pressure
47
+ print("Before pressure read")
48
+ pressure = bmp.pressure
49
+ print("After pressure read, value:", pressure)
50
+ # Display the readings with simple string formatting
51
+ print("Before printing readings")
52
+ print("Temperature:", temperature, "°C")
53
+ print("Pressure:", pressure, "hPa")
54
+ print("Is measuring:", bmp.is_measuring)
55
+ print("Is updating:", bmp.is_updating)
56
+ print("------------------------------")
57
+ except Exception as e:
58
+ print("Exception occurred:", repr(e))
59
+ # Wait 2 seconds before next reading
60
+ time.sleep(2)
SDK-dat/microPython-dat/bmp280-3-dat.py
... ...
@@ -0,0 +1,10 @@
1
+from machine import I2C, Pin
2
+import time
3
+
4
+import bmp280_1 as bmp280
5
+
6
+b = bmp280.BMP280(I2C(1, scl=Pin(13), sda=Pin(15)))
7
+
8
+while True:
9
+ time.sleep_ms(500)
10
+ b.get()
SDK-dat/microPython-dat/i2s-dat/i2s_recording.py
... ...
@@ -0,0 +1,125 @@
1
+# The MIT License (MIT)
2
+# Copyright (c) 2022 Mike Teachman
3
+# https://opensource.org/licenses/MIT
4
+
5
+# Purpose: Read audio samples from an I2S microphone and write to SD card
6
+#
7
+# - read 32-bit audio samples from I2S hardware, typically an I2S MEMS Microphone
8
+# - convert 32-bit samples to specified bit size
9
+# - write samples to a SD card file in WAV format
10
+# - samples will be continuously written to the WAV file
11
+# until a keyboard interrupt (ctrl-c) is detected
12
+#
13
+# Blocking version
14
+# - the readinto() method blocks until
15
+# the supplied buffer is filled
16
+
17
+import os
18
+from machine import Pin
19
+from machine import I2S
20
+from machine import AUDIO_I2S_98_MHZ, freq
21
+
22
+if os.uname().machine.count("CY8CPROTO-062-4343W"):
23
+
24
+ # ======= I2S CONFIGURATION =======
25
+ SCK_PIN = "P5_4"
26
+ WS_PIN = "P5_5"
27
+ SD_PIN = "P5_6"
28
+ I2S_ID = 0
29
+ BUFFER_LENGTH_IN_BYTES = 40000
30
+ # ======= I2S CONFIGURATION =======
31
+
32
+else:
33
+ print("Warning: program not tested with this board")
34
+
35
+# ======= AUDIO CONFIGURATION =======
36
+WAV_FILE = "mic.wav"
37
+RECORD_TIME_IN_SECONDS = 10
38
+WAV_SAMPLE_SIZE_IN_BITS = 32
39
+FORMAT = I2S.STEREO
40
+SAMPLE_RATE_IN_HZ = 8000
41
+# ======= AUDIO CONFIGURATION =======
42
+
43
+format_to_channels = {I2S.MONO: 1, I2S.STEREO: 2}
44
+NUM_CHANNELS = format_to_channels[FORMAT]
45
+WAV_SAMPLE_SIZE_IN_BYTES = WAV_SAMPLE_SIZE_IN_BITS // 8
46
+RECORDING_SIZE_IN_BYTES = (
47
+ RECORD_TIME_IN_SECONDS * SAMPLE_RATE_IN_HZ * WAV_SAMPLE_SIZE_IN_BYTES * NUM_CHANNELS
48
+)
49
+
50
+# Set the I2S clock frequency
51
+freq(AUDIO_I2S_98_MHZ) # Set clock frequency to 98 MHz for 8kHz sample rate
52
+
53
+
54
+def create_wav_header(sampleRate, bitsPerSample, num_channels, num_samples):
55
+ datasize = num_samples * num_channels * bitsPerSample // 8
56
+ o = bytes("RIFF", "ascii") # (4byte) Marks file as RIFF
57
+ o += (datasize + 36).to_bytes(
58
+ 4, "little"
59
+ ) # (4byte) File size in bytes excluding this and RIFF marker
60
+ o += bytes("WAVE", "ascii") # (4byte) File type
61
+ o += bytes("fmt ", "ascii") # (4byte) Format Chunk Marker
62
+ o += (16).to_bytes(4, "little") # (4byte) Length of above format data
63
+ o += (1).to_bytes(2, "little") # (2byte) Format type (1 - PCM)
64
+ o += (num_channels).to_bytes(2, "little") # (2byte)
65
+ o += (sampleRate).to_bytes(4, "little") # (4byte)
66
+ o += (sampleRate * num_channels * bitsPerSample // 8).to_bytes(4, "little") # (4byte)
67
+ o += (num_channels * bitsPerSample // 8).to_bytes(2, "little") # (2byte)
68
+ o += (bitsPerSample).to_bytes(2, "little") # (2byte)
69
+ o += bytes("data", "ascii") # (4byte) Data Chunk Marker
70
+ o += (datasize).to_bytes(4, "little") # (4byte) Data size in bytes
71
+ return o
72
+
73
+
74
+wav = open("/{}".format(WAV_FILE), "wb")
75
+
76
+# create header for WAV file and write to SD card
77
+wav_header = create_wav_header(
78
+ SAMPLE_RATE_IN_HZ,
79
+ WAV_SAMPLE_SIZE_IN_BITS,
80
+ NUM_CHANNELS,
81
+ SAMPLE_RATE_IN_HZ * RECORD_TIME_IN_SECONDS,
82
+)
83
+num_bytes_written = wav.write(wav_header)
84
+
85
+audio_in = I2S(
86
+ I2S_ID,
87
+ sck=SCK_PIN,
88
+ ws=WS_PIN,
89
+ sd=SD_PIN,
90
+ mode=I2S.RX,
91
+ bits=WAV_SAMPLE_SIZE_IN_BITS,
92
+ format=FORMAT,
93
+ rate=SAMPLE_RATE_IN_HZ,
94
+ ibuf=BUFFER_LENGTH_IN_BYTES,
95
+)
96
+
97
+# allocate sample arrays
98
+# memoryview used to reduce heap allocation in while loop
99
+mic_samples = bytearray(10000)
100
+mic_samples_mv = memoryview(mic_samples)
101
+
102
+num_sample_bytes_written_to_wav = 0
103
+
104
+print("Recording size: {} bytes".format(RECORDING_SIZE_IN_BYTES))
105
+print("========== START RECORDING ==========")
106
+try:
107
+ while num_sample_bytes_written_to_wav < RECORDING_SIZE_IN_BYTES:
108
+ # read a block of samples from the I2S microphone
109
+ num_bytes_read_from_mic = audio_in.readinto(mic_samples_mv)
110
+ if num_bytes_read_from_mic > 0:
111
+ num_bytes_to_write = min(
112
+ num_bytes_read_from_mic, RECORDING_SIZE_IN_BYTES - num_sample_bytes_written_to_wav
113
+ )
114
+ # write samples to WAV file
115
+ num_bytes_written = wav.write(mic_samples_mv[:num_bytes_to_write])
116
+ num_sample_bytes_written_to_wav += num_bytes_written
117
+
118
+ print("========== DONE RECORDING ==========")
119
+except (KeyboardInterrupt, Exception) as e:
120
+ print("caught exception {} {}".format(type(e).__name__, e))
121
+
122
+# cleanup
123
+wav.close()
124
+
125
+audio_in.deinit()
... ...
\ No newline at end of file
SDK-dat/microPython-dat/micropython-dat.md
... ...
@@ -2,6 +2,8 @@
2 2
# micropython dat
3 3
4 4
5
+- [[CircuitPython-dat]]
6
+
5 7
- [[MP-ESP32-dat]] - [[MP-STM32-dat]]
6 8
7 9
... ...
@@ -45,37 +47,7 @@ Open the USB flash drive, edit the main.py file, click Save, and reset the MCU t
45 47
46 48
## relevant other useful tools
47 49
48
-- [[ampy-dat]]
49
-
50
-pip install mpremote
51
-
52
-mpremote connect COM6 fs ls
53
-
54
-mpremote connect COM6 fs cp 2640-1.py :
55
-mpremote connect COM6 fs cp :capture.jpg .
56
-
57
-mpremote connect COM6 fs rm :capture.jpg
58
-
59
-mpremote connect COM6
60
-
61
-mpremote connect COM6 run 2640-1.py
62
-
63
- mpremote connect COM6
64
- Connected to MicroPython at COM6
65
- Use Ctrl-] or Ctrl-x to exit this shell
66
-
67
-capture script run
68
-
69
- import test2
70
- >>> print(os.listdir())
71
- ['boot.py', 'capture.jpg', 'test2.py']
72
- >>>
73
-
74
-rename a file == mpremote connect COM6 fs mv :2640-2.py :main.py
75
-
76
- mpremote connect COM6 fs cp :2640-2.py :main.py
77
-
78
-reboot == mpremote connect COM6 reset
50
+- [[ampy-dat]] - [[rshell-dat]] - [[mpremote-dat]]
79 51
80 52
81 53
## flash
... ...
@@ -128,6 +100,27 @@ List Files in Current Directory
128 100
129 101
Run main.py
130 102
103
+- [[boot.py]] - [[main.py]]
104
+
105
+## hardware
106
+
107
+- [[I2C-dat]] - [[ESP32-HDK-dat]]
108
+
109
+📌 Common ESP32 I2C Pins
110
+
111
+| Function | GPIO | Notes |
112
+|----------|------|-------|
113
+| SDA | 21 | Common default SDA pin |
114
+| SCL | 22 | Common default SCL pin |
115
+
116
+- [[mp-i2c-1-dat.py]]
117
+
118
+- [[mp-ssd1306-1-dat.py]]
119
+
120
+
121
+## code library
122
+
123
+https://github.com/micropython-Chinese-Community/mpy-lib
131 124
132 125
133 126
## ref
SDK-dat/microPython-dat/mp-i2c-1-dat.py
... ...
@@ -0,0 +1,22 @@
1
+
2
+# mpremote connect COM6 fs cp mp-i2c-1-dat.py :
3
+# mpremote connect COM6 run mp-i2c-1-dat.py
4
+
5
+# I2C devices found: ['0x3c', '0x76']
6
+# I2C devices found: ['0x3c', '0x76']
7
+
8
+
9
+from machine import Pin, I2C
10
+import time
11
+
12
+# Define I2C pins (adjust to your wiring)
13
+i2c = I2C(0, scl=Pin(13), sda=Pin(15), freq=100000)
14
+
15
+# Scan and print all detected device addresses
16
+while True:
17
+ devices = i2c.scan()
18
+ if devices:
19
+ print("I2C devices found:", [hex(addr) for addr in devices])
20
+ else:
21
+ print("No I2C devices found.")
22
+ time.sleep(2)
... ...
\ No newline at end of file
SDK-dat/microPython-dat/mp-ssd1306-1-dat.py
... ...
@@ -0,0 +1,12 @@
1
+
2
+# mpremote connect COM6 fs cp mp-ssd1306-1-dat.py :
3
+# mpremote connect COM6 run mp-ssd1306-1-dat.py
4
+
5
+from machine import I2C, Pin
6
+import ssd1306
7
+
8
+i2c = I2C(0, scl=Pin(13), sda=Pin(15))
9
+oled = ssd1306.SSD1306_I2C(128, 64, i2c)
10
+
11
+oled.text("Hello, ESP32!", 0, 0)
12
+oled.show()
... ...
\ No newline at end of file
SDK-dat/microPython-dat/mp-ssd1306-2-dat.py
... ...
@@ -0,0 +1,48 @@
1
+
2
+# mpremote connect COM6 fs cp mp-i2c-dat.py :
3
+# mpremote connect COM6 run mp-i2c-dat.py
4
+
5
+import machine
6
+import ssd1306
7
+import time
8
+
9
+# create I2C interface
10
+i2c = machine.I2C(1, sda=machine.Pin(15), scl=machine.Pin(13)) # I have my display hooked up to pins 14 and 15 (for I2C)
11
+print(i2c.scan()) # 0x3c is the I2C address of the SSD1306. As an integer, 60.
12
+
13
+# create SSD1306 interface
14
+display_width:int = 128
15
+display_height:int = 64
16
+oled = ssd1306.SSD1306_I2C(128, 64, i2c)
17
+
18
+# turn on all pixels
19
+oled.fill(1) # make the change
20
+oled.show() # show the update
21
+time.sleep(1)
22
+
23
+# turn off all pixels (blank display)
24
+oled.fill(0)
25
+oled.show()
26
+time.sleep(1)
27
+
28
+# fill in a single pixel
29
+oled.pixel(0, 0, 1) # turn on pixel at (0, 0) (top left)
30
+oled.pixel(64, 0, 1) # turn on pixel at (64, 0), middle top
31
+oled.pixel(127, 63, 1) # turn on pixel at (127, 63) (absolute bottom right on my 128x64 display)
32
+oled.show() # show the update
33
+time.sleep(1)
34
+
35
+# turn off all pixels again
36
+oled.fill(0)
37
+oled.show()
38
+time.sleep(1)
39
+
40
+# display text
41
+oled.text("Hello, world!", 0, 0) # print text "Hello, world!" at position (0, 0) (top left)
42
+oled.show()
43
+time.sleep(1)
44
+
45
+# turn off all pixels again
46
+oled.fill(0)
47
+oled.show()
48
+time.sleep(1)
... ...
\ No newline at end of file
SDK-dat/microPython-dat/mpremote-dat/mpremote-dat.md
... ...
@@ -0,0 +1,34 @@
1
+
2
+# mpremote-dat.md
3
+
4
+
5
+pip install mpremote
6
+
7
+mpremote connect COM6 fs ls
8
+
9
+mpremote connect COM6 fs cp 2640-1.py :
10
+mpremote connect COM6 fs cp :capture.jpg .
11
+
12
+mpremote connect COM6 fs rm :capture.jpg
13
+
14
+mpremote connect COM6
15
+
16
+mpremote connect COM6 run 2640-1.py
17
+
18
+ mpremote connect COM6
19
+ Connected to MicroPython at COM6
20
+ Use Ctrl-] or Ctrl-x to exit this shell
21
+
22
+capture script run
23
+
24
+ import test2
25
+ >>> print(os.listdir())
26
+ ['boot.py', 'capture.jpg', 'test2.py']
27
+ >>>
28
+
29
+rename a file == mpremote connect COM6 fs mv :2640-2.py :main.py
30
+
31
+ mpremote connect COM6 fs cp :2640-2.py :main.py
32
+
33
+reboot == mpremote connect COM6 reset
34
+
SDK-dat/python-dat/circuitpython-dat/adafruit_ov2640.py
... ...
@@ -0,0 +1,1364 @@
1
+# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
2
+# SPDX-FileCopyrightText: Copyright (c) 2021 Jeff Epler for Adafruit Industries
3
+#
4
+# SPDX-License-Identifier: MIT
5
+"""
6
+`adafruit_ov2640`
7
+================================================================================
8
+
9
+CircuitPython driver for OV2640 Camera.
10
+
11
+
12
+* Author(s): Jeff Epler
13
+
14
+Implementation Notes
15
+--------------------
16
+
17
+**Hardware:**
18
+
19
+* `ESP32-S2 Kaluga Dev Kit featuring ESP32-S2 WROVER <https://www.adafruit.com/product/4729>`_
20
+
21
+**Software and Dependencies:**
22
+
23
+* Adafruit CircuitPython firmware for the supported boards:
24
+ https://github.com/adafruit/circuitpython/releases
25
+
26
+* Adafruit's Bus Device library: https:# github.com/adafruit/Adafruit_CircuitPython_BusDevice
27
+"""
28
+
29
+# imports
30
+
31
+__version__ = "0.0.0+auto.0"
32
+__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_OV7670.git"
33
+
34
+import time
35
+
36
+import digitalio
37
+import imagecapture
38
+import pwmio
39
+from adafruit_bus_device.i2c_device import I2CDevice
40
+from micropython import const
41
+
42
+try:
43
+ from typing import List, Optional, Type, Union
44
+
45
+ from busio import I2C
46
+ from circuitpython_typing import WriteableBuffer
47
+ from microcontroller import Pin
48
+except ImportError:
49
+ pass
50
+
51
+CTRLI = const(0x50)
52
+_R_BYPASS = const(0x05)
53
+_QS = const(0x44)
54
+_CTRLI = const(0x50)
55
+_HSIZE = const(0x51)
56
+_VSIZE = const(0x52)
57
+_XOFFL = const(0x53)
58
+_YOFFL = const(0x54)
59
+_VHYX = const(0x55)
60
+_DPRP = const(0x56)
61
+_TEST = const(0x57)
62
+_ZMOW = const(0x5A)
63
+_ZMOH = const(0x5B)
64
+_ZMHH = const(0x5C)
65
+_BPADDR = const(0x7C)
66
+_BPDATA = const(0x7D)
67
+_CTRL2 = const(0x86)
68
+_CTRL3 = const(0x87)
69
+_SIZEL = const(0x8C)
70
+_HSIZE8 = const(0xC0)
71
+_VSIZE8 = const(0xC1)
72
+_CTRL0 = const(0xC2)
73
+_CTRL1 = const(0xC3)
74
+_R_DVP_SP = const(0xD3)
75
+_IMAGE_MODE = const(0xDA)
76
+_RESET = const(0xE0)
77
+_MS_SP = const(0xF0)
78
+_SS_ID = const(0xF7)
79
+_SS_CTRL = const(0xF7)
80
+_MC_BIST = const(0xF9)
81
+_MC_AL = const(0xFA)
82
+_MC_AH = const(0xFB)
83
+_MC_D = const(0xFC)
84
+_P_CMD = const(0xFD)
85
+_P_STATUS = const(0xFE)
86
+_BANK_SEL = const(0xFF)
87
+
88
+_CTRLI_LP_DP = const(0x80)
89
+_CTRLI_ROUND = const(0x40)
90
+
91
+_CTRL0_AEC_EN = const(0x80)
92
+_CTRL0_AEC_SEL = const(0x40)
93
+_CTRL0_STAT_SEL = const(0x20)
94
+_CTRL0_VFIRST = const(0x10)
95
+_CTRL0_YUV422 = const(0x08)
96
+_CTRL0_YUV_EN = const(0x04)
97
+_CTRL0_RGB_EN = const(0x02)
98
+_CTRL0_RAW_EN = const(0x01)
99
+
100
+_CTRL2_DCW_EN = const(0x20)
101
+_CTRL2_SDE_EN = const(0x10)
102
+_CTRL2_UV_ADJ_EN = const(0x08)
103
+_CTRL2_UV_AVG_EN = const(0x04)
104
+_CTRL2_CMX_EN = const(0x01)
105
+
106
+_CTRL3_BPC_EN = const(0x80)
107
+_CTRL3_WPC_EN = const(0x40)
108
+
109
+_R_DVP_SP_AUTO_MODE = const(0x80)
110
+
111
+_R_BYPASS_DSP_EN = const(0x00)
112
+_R_BYPASS_DSP_BYPAS = const(0x01)
113
+
114
+OV2640_COLOR_RGB = 0
115
+OV2640_COLOR_YUV = 1
116
+OV2640_COLOR_JPEG = 2
117
+
118
+_IMAGE_MODE_Y8_DVP_EN = const(0x40)
119
+_IMAGE_MODE_JPEG_EN = const(0x10)
120
+_IMAGE_MODE_YUV422 = const(0x00)
121
+_IMAGE_MODE_RAW10 = const(0x04)
122
+_IMAGE_MODE_RGB565 = const(0x08)
123
+_IMAGE_MODE_HREF_VSYNC = const(0x02)
124
+_IMAGE_MODE_LBYTE_FIRST = const(0x01)
125
+
126
+_RESET_MICROC = const(0x40)
127
+_RESET_SCCB = const(0x20)
128
+_RESET_JPEG = const(0x10)
129
+_RESET_DVP = const(0x04)
130
+_RESET_IPU = const(0x02)
131
+_RESET_CIF = const(0x01)
132
+
133
+_MC_BIST_RESET = const(0x80)
134
+_MC_BIST_BOOT_ROM_SEL = const(0x40)
135
+_MC_BIST_12KB_SEL = const(0x20)
136
+_MC_BIST_12KB_MASK = const(0x30)
137
+_MC_BIST_512KB_SEL = const(0x08)
138
+_MC_BIST_512KB_MASK = const(0x0C)
139
+_MC_BIST_BUSY_BIT_R = const(0x02)
140
+_MC_BIST_MC_RES_ONE_SH_W = const(0x02)
141
+_MC_BIST_LAUNCH = const(0x01)
142
+
143
+
144
+_BANK_DSP = const(0)
145
+_BANK_SENSOR = const(1)
146
+
147
+# Sensor register bank FF=0x01
148
+_GAIN = const(0x00)
149
+_COM1 = const(0x03)
150
+_REG04 = const(0x04)
151
+_REG08 = const(0x08)
152
+_COM2 = const(0x09)
153
+_REG_PID = const(0x0A)
154
+_REG_VER = const(0x0B)
155
+_COM3 = const(0x0C)
156
+_COM4 = const(0x0D)
157
+_AEC = const(0x10)
158
+_CLKRC = const(0x11)
159
+_COM7 = const(0x12)
160
+_COM8 = const(0x13)
161
+_COM9 = const(0x14) # AGC gain ceiling
162
+_COM10 = const(0x15)
163
+_HSTART = const(0x17)
164
+_HSTOP = const(0x18)
165
+_VSTART = const(0x19)
166
+_VSTOP = const(0x1A)
167
+_MIDH = const(0x1C)
168
+_MIDL = const(0x1D)
169
+_AEW = const(0x24)
170
+_AEB = const(0x25)
171
+_VV = const(0x26)
172
+_REG2A = const(0x2A)
173
+_FRARL = const(0x2B)
174
+_ADDVSL = const(0x2D)
175
+_ADDVSH = const(0x2E)
176
+_YAVG = const(0x2F)
177
+_HSDY = const(0x30)
178
+_HEDY = const(0x31)
179
+_REG32 = const(0x32)
180
+_ARCOM2 = const(0x34)
181
+_REG45 = const(0x45)
182
+_FLL = const(0x46)
183
+_FLH = const(0x47)
184
+_COM19 = const(0x48)
185
+_ZOOMS = const(0x49)
186
+_COM22 = const(0x4B)
187
+_COM25 = const(0x4E)
188
+_BD50 = const(0x4F)
189
+_BD60 = const(0x50)
190
+_REG5D = const(0x5D)
191
+_REG5E = const(0x5E)
192
+_REG5F = const(0x5F)
193
+_REG60 = const(0x60)
194
+_HISTO_LOW = const(0x61)
195
+_HISTO_HIGH = const(0x62)
196
+
197
+_REG04_DEFAULT = const(0x28)
198
+_REG04_HFLIP_IMG = const(0x80)
199
+_REG04_VFLIP_IMG = const(0x40)
200
+_REG04_VREF_EN = const(0x10)
201
+_REG04_HREF_EN = const(0x08)
202
+_REG04_SET = lambda x: (_REG04_DEFAULT | x)
203
+
204
+_COM2_STDBY = const(0x10)
205
+_COM2_OUT_DRIVE_1x = const(0x00)
206
+_COM2_OUT_DRIVE_2x = const(0x01)
207
+_COM2_OUT_DRIVE_3x = const(0x02)
208
+_COM2_OUT_DRIVE_4x = const(0x03)
209
+
210
+_COM3_DEFAULT = const(0x38)
211
+_COM3_BAND_50Hz = const(0x04)
212
+_COM3_BAND_60Hz = const(0x00)
213
+_COM3_BAND_AUTO = const(0x02)
214
+_COM3_BAND_SET = lambda x: (_COM3_DEFAULT | x)
215
+
216
+_COM7_SRST = const(0x80)
217
+_COM7_RES_UXGA = const(0x00) # UXGA
218
+_COM7_RES_SVGA = const(0x40) # SVGA
219
+_COM7_RES_CIF = const(0x20) # CIF
220
+_COM7_ZOOM_EN = const(0x04) # Enable Zoom
221
+_COM7_COLOR_BAR = const(0x02) # Enable Color Bar Test
222
+
223
+_COM8_DEFAULT = const(0xC0)
224
+_COM8_BNDF_EN = const(0x20) # Enable Banding filter
225
+_COM8_AGC_EN = const(0x04) # AGC Auto/Manual control selection
226
+_COM8_AEC_EN = const(0x01) # Auto/Manual Exposure control
227
+_COM8_SET = lambda x: (_COM8_DEFAULT | x)
228
+
229
+_COM9_DEFAULT = const(0x08)
230
+_COM9_AGC_GAIN_2x = const(0x00) # AGC: 2x
231
+_COM9_AGC_GAIN_4x = const(0x01) # AGC: 4x
232
+_COM9_AGC_GAIN_8x = const(0x02) # AGC: 8x
233
+_COM9_AGC_GAIN_16x = const(0x03) # AGC: 16x
234
+_COM9_AGC_GAIN_32x = const(0x04) # AGC: 32x
235
+_COM9_AGC_GAIN_64x = const(0x05) # AGC: 64x
236
+_COM9_AGC_GAIN_128x = const(0x06) # AGC: 128x
237
+_COM9_AGC_SET = lambda x: (_COM9_DEFAULT | (x << 5))
238
+
239
+_COM10_HREF_EN = const(0x80) # HSYNC changes to HREF
240
+_COM10_HSYNC_EN = const(0x40) # HREF changes to HSYNC
241
+_COM10_PCLK_FREE = const(0x20) # PCLK output option: free running PCLK
242
+_COM10_PCLK_EDGE = const(0x10) # Data is updated at the rising edge of PCLK
243
+_COM10_HREF_NEG = const(0x08) # HREF negative
244
+_COM10_VSYNC_NEG = const(0x02) # VSYNC negative
245
+_COM10_HSYNC_NEG = const(0x01) # HSYNC negative
246
+
247
+_CTRL1_AWB = const(0x08) # Enable AWB
248
+
249
+_VV_AGC_TH_SET = lambda h, l: ((h << 4) | (l & 0x0F))
250
+
251
+_REG32_UXGA = const(0x36)
252
+_REG32_SVGA = const(0x09)
253
+_REG32_CIF = const(0x89)
254
+
255
+_CLKRC_2X = const(0x80)
256
+_CLKRC_2X_UXGA = const(0x01 | _CLKRC_2X)
257
+_CLKRC_2X_SVGA = _CLKRC_2X
258
+_CLKRC_2X_CIF = _CLKRC_2X
259
+
260
+_OV2640_MODE_CIF = const(0)
261
+_OV2640_MODE_SVGA = const(1)
262
+_OV2640_MODE_UXGA = const(2)
263
+
264
+OV2640_SIZE_96X96 = 0 # 96x96
265
+OV2640_SIZE_QQVGA = 1 # 160x120
266
+OV2640_SIZE_QCIF = 2 # 176x144
267
+OV2640_SIZE_HQVGA = 3 # 240x176
268
+OV2640_SIZE_240X240 = 4 # 240x240
269
+OV2640_SIZE_QVGA = 5 # 320x240
270
+OV2640_SIZE_CIF = 6 # 400x296
271
+OV2640_SIZE_HVGA = 7 # 480x320
272
+OV2640_SIZE_VGA = 8 # 640x480
273
+OV2640_SIZE_SVGA = 9 # 800x600
274
+OV2640_SIZE_XGA = 10 # 1024x768
275
+OV2640_SIZE_HD = 11 # 1280x720
276
+OV2640_SIZE_SXGA = 12 # 1280x1024
277
+OV2640_SIZE_UXGA = 13 # 1600x1200
278
+
279
+_ASPECT_RATIO_4X3 = const(0)
280
+_ASPECT_RATIO_3X2 = const(1)
281
+_ASPECT_RATIO_16X10 = const(2)
282
+_ASPECT_RATIO_5X3 = const(3)
283
+_ASPECT_RATIO_16X9 = const(4)
284
+_ASPECT_RATIO_21X9 = const(5)
285
+_ASPECT_RATIO_5X4 = const(6)
286
+_ASPECT_RATIO_1X1 = const(7)
287
+_ASPECT_RATIO_9X16 = const(8)
288
+
289
+_resolution_info = [
290
+ [96, 96, _ASPECT_RATIO_1X1], # 96x96
291
+ [160, 120, _ASPECT_RATIO_4X3], # QQVGA
292
+ [176, 144, _ASPECT_RATIO_5X4], # QCIF
293
+ [240, 176, _ASPECT_RATIO_4X3], # HQVGA
294
+ [240, 240, _ASPECT_RATIO_1X1], # 240x240
295
+ [320, 240, _ASPECT_RATIO_4X3], # QVGA
296
+ [400, 296, _ASPECT_RATIO_4X3], # CIF
297
+ [480, 320, _ASPECT_RATIO_3X2], # HVGA
298
+ [640, 480, _ASPECT_RATIO_4X3], # VGA
299
+ [800, 600, _ASPECT_RATIO_4X3], # SVGA
300
+ [1024, 768, _ASPECT_RATIO_4X3], # XGA
301
+ [1280, 720, _ASPECT_RATIO_16X9], # HD
302
+ [1280, 1024, _ASPECT_RATIO_5X4], # SXGA
303
+ [1600, 1200, _ASPECT_RATIO_4X3], # UXGA
304
+]
305
+
306
+_ratio_table = [
307
+ # ox, oy, mx, my
308
+ [0, 0, 1600, 1200], # 4x3
309
+ [8, 72, 1584, 1056], # 3x2
310
+ [0, 100, 1600, 1000], # 16x10
311
+ [0, 120, 1600, 960], # 5x3
312
+ [0, 150, 1600, 900], # 16x9
313
+ [2, 258, 1596, 684], # 21x9
314
+ [50, 0, 1500, 1200], # 5x4
315
+ [200, 0, 1200, 1200], # 1x1
316
+ [462, 0, 676, 1200], # 9x16
317
+]
318
+
319
+# 30fps@24MHz
320
+_ov2640_settings_cif = bytes(
321
+ [
322
+ _BANK_SEL,
323
+ _BANK_DSP,
324
+ 0x2C,
325
+ 0xFF,
326
+ 0x2E,
327
+ 0xDF,
328
+ _BANK_SEL,
329
+ _BANK_SENSOR,
330
+ 0x3C,
331
+ 0x32,
332
+ _CLKRC,
333
+ 0x01,
334
+ _COM2,
335
+ _COM2_OUT_DRIVE_3x,
336
+ _REG04,
337
+ _REG04_DEFAULT,
338
+ _COM8,
339
+ _COM8_DEFAULT | _COM8_BNDF_EN | _COM8_AGC_EN | _COM8_AEC_EN,
340
+ _COM9,
341
+ _COM9_AGC_SET(_COM9_AGC_GAIN_8x),
342
+ 0x2C,
343
+ 0x0C,
344
+ 0x33,
345
+ 0x78,
346
+ 0x3A,
347
+ 0x33,
348
+ 0x3B,
349
+ 0xFB,
350
+ 0x3E,
351
+ 0x00,
352
+ 0x43,
353
+ 0x11,
354
+ 0x16,
355
+ 0x10,
356
+ 0x39,
357
+ 0x92,
358
+ 0x35,
359
+ 0xDA,
360
+ 0x22,
361
+ 0x1A,
362
+ 0x37,
363
+ 0xC3,
364
+ 0x23,
365
+ 0x00,
366
+ _ARCOM2,
367
+ 0xC0,
368
+ 0x06,
369
+ 0x88,
370
+ 0x07,
371
+ 0xC0,
372
+ _COM4,
373
+ 0x87,
374
+ 0x0E,
375
+ 0x41,
376
+ 0x4C,
377
+ 0x00,
378
+ 0x4A,
379
+ 0x81,
380
+ 0x21,
381
+ 0x99,
382
+ _AEW,
383
+ 0x40,
384
+ _AEB,
385
+ 0x38,
386
+ _VV,
387
+ _VV_AGC_TH_SET(8, 2),
388
+ 0x5C,
389
+ 0x00,
390
+ 0x63,
391
+ 0x00,
392
+ _HISTO_LOW,
393
+ 0x70,
394
+ _HISTO_HIGH,
395
+ 0x80,
396
+ 0x7C,
397
+ 0x05,
398
+ 0x20,
399
+ 0x80,
400
+ 0x28,
401
+ 0x30,
402
+ 0x6C,
403
+ 0x00,
404
+ 0x6D,
405
+ 0x80,
406
+ 0x6E,
407
+ 0x00,
408
+ 0x70,
409
+ 0x02,
410
+ 0x71,
411
+ 0x94,
412
+ 0x73,
413
+ 0xC1,
414
+ 0x3D,
415
+ 0x34,
416
+ 0x5A,
417
+ 0x57,
418
+ _BD50,
419
+ 0xBB,
420
+ _BD60,
421
+ 0x9C,
422
+ _COM7,
423
+ _COM7_RES_CIF,
424
+ _HSTART,
425
+ 0x11,
426
+ _HSTOP,
427
+ 0x43,
428
+ _VSTART,
429
+ 0x00,
430
+ _VSTOP,
431
+ 0x25,
432
+ _REG32,
433
+ 0x89,
434
+ 0x37,
435
+ 0xC0,
436
+ _BD50,
437
+ 0xCA,
438
+ _BD60,
439
+ 0xA8,
440
+ 0x6D,
441
+ 0x00,
442
+ 0x3D,
443
+ 0x38,
444
+ _BANK_SEL,
445
+ _BANK_DSP,
446
+ 0xE5,
447
+ 0x7F,
448
+ _MC_BIST,
449
+ _MC_BIST_RESET | _MC_BIST_BOOT_ROM_SEL,
450
+ 0x41,
451
+ 0x24,
452
+ _RESET,
453
+ _RESET_JPEG | _RESET_DVP,
454
+ 0x76,
455
+ 0xFF,
456
+ 0x33,
457
+ 0xA0,
458
+ 0x42,
459
+ 0x20,
460
+ 0x43,
461
+ 0x18,
462
+ 0x4C,
463
+ 0x00,
464
+ _CTRL3,
465
+ _CTRL3_WPC_EN | 0x10,
466
+ 0x88,
467
+ 0x3F,
468
+ 0xD7,
469
+ 0x03,
470
+ 0xD9,
471
+ 0x10,
472
+ _R_DVP_SP,
473
+ _R_DVP_SP_AUTO_MODE | 0x02,
474
+ 0xC8,
475
+ 0x08,
476
+ 0xC9,
477
+ 0x80,
478
+ _BPADDR,
479
+ 0x00,
480
+ _BPDATA,
481
+ 0x00,
482
+ _BPADDR,
483
+ 0x03,
484
+ _BPDATA,
485
+ 0x48,
486
+ _BPDATA,
487
+ 0x48,
488
+ _BPADDR,
489
+ 0x08,
490
+ _BPDATA,
491
+ 0x20,
492
+ _BPDATA,
493
+ 0x10,
494
+ _BPDATA,
495
+ 0x0E,
496
+ 0x90,
497
+ 0x00,
498
+ 0x91,
499
+ 0x0E,
500
+ 0x91,
501
+ 0x1A,
502
+ 0x91,
503
+ 0x31,
504
+ 0x91,
505
+ 0x5A,
506
+ 0x91,
507
+ 0x69,
508
+ 0x91,
509
+ 0x75,
510
+ 0x91,
511
+ 0x7E,
512
+ 0x91,
513
+ 0x88,
514
+ 0x91,
515
+ 0x8F,
516
+ 0x91,
517
+ 0x96,
518
+ 0x91,
519
+ 0xA3,
520
+ 0x91,
521
+ 0xAF,
522
+ 0x91,
523
+ 0xC4,
524
+ 0x91,
525
+ 0xD7,
526
+ 0x91,
527
+ 0xE8,
528
+ 0x91,
529
+ 0x20,
530
+ 0x92,
531
+ 0x00,
532
+ 0x93,
533
+ 0x06,
534
+ 0x93,
535
+ 0xE3,
536
+ 0x93,
537
+ 0x05,
538
+ 0x93,
539
+ 0x05,
540
+ 0x93,
541
+ 0x00,
542
+ 0x93,
543
+ 0x04,
544
+ 0x93,
545
+ 0x00,
546
+ 0x93,
547
+ 0x00,
548
+ 0x93,
549
+ 0x00,
550
+ 0x93,
551
+ 0x00,
552
+ 0x93,
553
+ 0x00,
554
+ 0x93,
555
+ 0x00,
556
+ 0x93,
557
+ 0x00,
558
+ 0x96,
559
+ 0x00,
560
+ 0x97,
561
+ 0x08,
562
+ 0x97,
563
+ 0x19,
564
+ 0x97,
565
+ 0x02,
566
+ 0x97,
567
+ 0x0C,
568
+ 0x97,
569
+ 0x24,
570
+ 0x97,
571
+ 0x30,
572
+ 0x97,
573
+ 0x28,
574
+ 0x97,
575
+ 0x26,
576
+ 0x97,
577
+ 0x02,
578
+ 0x97,
579
+ 0x98,
580
+ 0x97,
581
+ 0x80,
582
+ 0x97,
583
+ 0x00,
584
+ 0x97,
585
+ 0x00,
586
+ 0xA4,
587
+ 0x00,
588
+ 0xA8,
589
+ 0x00,
590
+ 0xC5,
591
+ 0x11,
592
+ 0xC6,
593
+ 0x51,
594
+ 0xBF,
595
+ 0x80,
596
+ 0xC7,
597
+ 0x10,
598
+ 0xB6,
599
+ 0x66,
600
+ 0xB8,
601
+ 0xA5,
602
+ 0xB7,
603
+ 0x64,
604
+ 0xB9,
605
+ 0x7C,
606
+ 0xB3,
607
+ 0xAF,
608
+ 0xB4,
609
+ 0x97,
610
+ 0xB5,
611
+ 0xFF,
612
+ 0xB0,
613
+ 0xC5,
614
+ 0xB1,
615
+ 0x94,
616
+ 0xB2,
617
+ 0x0F,
618
+ 0xC4,
619
+ 0x5C,
620
+ _CTRL1,
621
+ 0xFD,
622
+ 0x7F,
623
+ 0x00,
624
+ 0xE5,
625
+ 0x1F,
626
+ 0xE1,
627
+ 0x67,
628
+ 0xDD,
629
+ 0x7F,
630
+ _IMAGE_MODE,
631
+ 0x00,
632
+ _RESET,
633
+ 0x00,
634
+ _R_BYPASS,
635
+ _R_BYPASS_DSP_EN,
636
+ ]
637
+)
638
+
639
+_ov2640_settings_to_cif = bytes(
640
+ [
641
+ _BANK_SEL,
642
+ _BANK_SENSOR,
643
+ _COM7,
644
+ _COM7_RES_CIF,
645
+ # Set the sensor output window
646
+ _COM1,
647
+ 0x0A,
648
+ _REG32,
649
+ _REG32_CIF,
650
+ _HSTART,
651
+ 0x11,
652
+ _HSTOP,
653
+ 0x43,
654
+ _VSTART,
655
+ 0x00,
656
+ _VSTOP,
657
+ 0x25,
658
+ # _CLKRC, 0x00,
659
+ _BD50,
660
+ 0xCA,
661
+ _BD60,
662
+ 0xA8,
663
+ 0x5A,
664
+ 0x23,
665
+ 0x6D,
666
+ 0x00,
667
+ 0x3D,
668
+ 0x38,
669
+ 0x39,
670
+ 0x92,
671
+ 0x35,
672
+ 0xDA,
673
+ 0x22,
674
+ 0x1A,
675
+ 0x37,
676
+ 0xC3,
677
+ 0x23,
678
+ 0x00,
679
+ _ARCOM2,
680
+ 0xC0,
681
+ 0x06,
682
+ 0x88,
683
+ 0x07,
684
+ 0xC0,
685
+ _COM4,
686
+ 0x87,
687
+ 0x0E,
688
+ 0x41,
689
+ 0x4C,
690
+ 0x00,
691
+ _BANK_SEL,
692
+ _BANK_DSP,
693
+ _RESET,
694
+ _RESET_DVP,
695
+ # Set the sensor resolution (UXGA, SVGA, CIF)
696
+ _HSIZE8,
697
+ 0x32,
698
+ _VSIZE8,
699
+ 0x25,
700
+ _SIZEL,
701
+ 0x00,
702
+ # Set the image window size >= output size
703
+ _HSIZE,
704
+ 0x64,
705
+ _VSIZE,
706
+ 0x4A,
707
+ _XOFFL,
708
+ 0x00,
709
+ _YOFFL,
710
+ 0x00,
711
+ _VHYX,
712
+ 0x00,
713
+ _TEST,
714
+ 0x00,
715
+ _CTRL2,
716
+ _CTRL2_DCW_EN | 0x1D,
717
+ _CTRLI,
718
+ _CTRLI_LP_DP | 0x00,
719
+ # _R_DVP_SP, 0x08,
720
+ ]
721
+)
722
+
723
+_ov2640_settings_to_svga = bytes(
724
+ [
725
+ _BANK_SEL,
726
+ _BANK_SENSOR,
727
+ _COM7,
728
+ _COM7_RES_SVGA,
729
+ # Set the sensor output window
730
+ _COM1,
731
+ 0x0A,
732
+ _REG32,
733
+ _REG32_SVGA,
734
+ _HSTART,
735
+ 0x11,
736
+ _HSTOP,
737
+ 0x43,
738
+ _VSTART,
739
+ 0x00,
740
+ _VSTOP,
741
+ 0x4B,
742
+ # _CLKRC, 0x00,
743
+ 0x37,
744
+ 0xC0,
745
+ _BD50,
746
+ 0xCA,
747
+ _BD60,
748
+ 0xA8,
749
+ 0x5A,
750
+ 0x23,
751
+ 0x6D,
752
+ 0x00,
753
+ 0x3D,
754
+ 0x38,
755
+ 0x39,
756
+ 0x92,
757
+ 0x35,
758
+ 0xDA,
759
+ 0x22,
760
+ 0x1A,
761
+ 0x37,
762
+ 0xC3,
763
+ 0x23,
764
+ 0x00,
765
+ _ARCOM2,
766
+ 0xC0,
767
+ 0x06,
768
+ 0x88,
769
+ 0x07,
770
+ 0xC0,
771
+ _COM4,
772
+ 0x87,
773
+ 0x0E,
774
+ 0x41,
775
+ 0x42,
776
+ 0x03,
777
+ 0x4C,
778
+ 0x00,
779
+ _BANK_SEL,
780
+ _BANK_DSP,
781
+ _RESET,
782
+ _RESET_DVP,
783
+ # Set the sensor resolution (UXGA, SVGA, CIF)
784
+ _HSIZE8,
785
+ 0x64,
786
+ _VSIZE8,
787
+ 0x4B,
788
+ _SIZEL,
789
+ 0x00,
790
+ # Set the image window size >= output size
791
+ _HSIZE,
792
+ 0xC8,
793
+ _VSIZE,
794
+ 0x96,
795
+ _XOFFL,
796
+ 0x00,
797
+ _YOFFL,
798
+ 0x00,
799
+ _VHYX,
800
+ 0x00,
801
+ _TEST,
802
+ 0x00,
803
+ _CTRL2,
804
+ _CTRL2_DCW_EN | 0x1D,
805
+ _CTRLI,
806
+ _CTRLI_LP_DP | 0x00,
807
+ # _R_DVP_SP, 0x08,
808
+ ]
809
+)
810
+
811
+_ov2640_settings_to_uxga = bytes(
812
+ [
813
+ _BANK_SEL,
814
+ _BANK_SENSOR,
815
+ _COM7,
816
+ _COM7_RES_UXGA,
817
+ # Set the sensor output window
818
+ _COM1,
819
+ 0x0F,
820
+ _REG32,
821
+ _REG32_UXGA,
822
+ _HSTART,
823
+ 0x11,
824
+ _HSTOP,
825
+ 0x75,
826
+ _VSTART,
827
+ 0x01,
828
+ _VSTOP,
829
+ 0x97,
830
+ # _CLKRC, 0x00,
831
+ 0x3D,
832
+ 0x34,
833
+ _BD50,
834
+ 0xBB,
835
+ _BD60,
836
+ 0x9C,
837
+ 0x5A,
838
+ 0x57,
839
+ 0x6D,
840
+ 0x80,
841
+ 0x39,
842
+ 0x82,
843
+ 0x23,
844
+ 0x00,
845
+ 0x07,
846
+ 0xC0,
847
+ 0x4C,
848
+ 0x00,
849
+ 0x35,
850
+ 0x88,
851
+ 0x22,
852
+ 0x0A,
853
+ 0x37,
854
+ 0x40,
855
+ _ARCOM2,
856
+ 0xA0,
857
+ 0x06,
858
+ 0x02,
859
+ _COM4,
860
+ 0xB7,
861
+ 0x0E,
862
+ 0x01,
863
+ 0x42,
864
+ 0x83,
865
+ _BANK_SEL,
866
+ _BANK_DSP,
867
+ _RESET,
868
+ _RESET_DVP,
869
+ # Set the sensor resolution (UXGA, SVGA, CIF)
870
+ _HSIZE8,
871
+ 0xC8,
872
+ _VSIZE8,
873
+ 0x96,
874
+ _SIZEL,
875
+ 0x00,
876
+ # Set the image window size >= output size
877
+ _HSIZE,
878
+ 0x90,
879
+ _VSIZE,
880
+ 0x2C,
881
+ _XOFFL,
882
+ 0x00,
883
+ _YOFFL,
884
+ 0x00,
885
+ _VHYX,
886
+ 0x88,
887
+ _TEST,
888
+ 0x00,
889
+ _CTRL2,
890
+ _CTRL2_DCW_EN | 0x1D,
891
+ _CTRLI,
892
+ 0x00,
893
+ # _R_DVP_SP, 0x06,
894
+ ]
895
+)
896
+
897
+_ov2640_color_settings = {
898
+ OV2640_COLOR_JPEG: bytes(
899
+ [
900
+ _BANK_SEL,
901
+ _BANK_DSP,
902
+ _RESET,
903
+ _RESET_JPEG | _RESET_DVP,
904
+ _IMAGE_MODE,
905
+ _IMAGE_MODE_JPEG_EN | _IMAGE_MODE_HREF_VSYNC,
906
+ 0xD7,
907
+ 0x03,
908
+ 0xE1,
909
+ 0x77,
910
+ 0xE5,
911
+ 0x1F,
912
+ 0xD9,
913
+ 0x10,
914
+ 0xDF,
915
+ 0x80,
916
+ 0x33,
917
+ 0x80,
918
+ 0x3C,
919
+ 0x10,
920
+ 0xEB,
921
+ 0x30,
922
+ 0xDD,
923
+ 0x7F,
924
+ _RESET,
925
+ 0x00,
926
+ ]
927
+ ),
928
+ OV2640_COLOR_YUV: bytes(
929
+ [
930
+ _BANK_SEL,
931
+ _BANK_DSP,
932
+ _RESET,
933
+ _RESET_DVP,
934
+ _IMAGE_MODE,
935
+ _IMAGE_MODE_YUV422,
936
+ 0xD7,
937
+ 0x01,
938
+ 0xE1,
939
+ 0x67,
940
+ _RESET,
941
+ 0x00,
942
+ ]
943
+ ),
944
+ OV2640_COLOR_RGB: bytes(
945
+ [
946
+ _BANK_SEL,
947
+ _BANK_DSP,
948
+ _RESET,
949
+ _RESET_DVP,
950
+ _IMAGE_MODE,
951
+ _IMAGE_MODE_RGB565,
952
+ 0xD7,
953
+ 0x03,
954
+ 0xE1,
955
+ 0x77,
956
+ _RESET,
957
+ 0x00,
958
+ ]
959
+ ),
960
+}
961
+
962
+
963
+class _RegBits:
964
+ def __init__(self, bank: int, reg: int, shift: int, mask: int) -> None:
965
+ self.bank = bank
966
+ self.reg = reg
967
+ self.shift = shift
968
+ self.mask = mask
969
+
970
+ def __get__(self, obj: "_SCCBCameraBase", objtype: Optional[Type] = None) -> int:
971
+ reg_value = obj._read_bank_register(self.bank, self.reg)
972
+ return (reg_value >> self.shift) & self.mask
973
+
974
+ def __set__(self, obj: "_SCCBCameraBase", value: Union[bool, int]) -> None:
975
+ if value & ~self.mask:
976
+ raise ValueError(f"Value 0x{value:02x} does not fit in mask 0x{self.mask:02x}")
977
+ reg_value = obj._read_bank_register(self.bank, self.reg)
978
+ reg_value &= ~(self.mask << self.shift)
979
+ reg_value |= value << self.shift
980
+ obj._write_register(self.reg, reg_value)
981
+
982
+
983
+class _SCCBCameraBase:
984
+ def __init__(self, i2c_bus: I2C, i2c_address: int) -> None:
985
+ self._i2c_device = I2CDevice(i2c_bus, i2c_address)
986
+ self._bank = None
987
+
988
+ def _get_reg_bits(self, bank: int, reg: int, shift: int, mask: int) -> int:
989
+ return (self._read_bank_register(bank, reg) >> shift) & mask
990
+
991
+ def _set_reg_bits(self, bank: int, reg: int, shift: int, mask: int, value: int) -> None:
992
+ reg_value = self._read_bank_register(bank, reg)
993
+ reg_value &= ~(mask << shift)
994
+ reg_value |= value << shift
995
+ self._write_register(reg, reg_value)
996
+
997
+ def _write_list(self, reg_list: List[int]) -> None:
998
+ for i in range(0, len(reg_list), 2):
999
+ self._write_register(reg_list[i], reg_list[i + 1])
1000
+ time.sleep(0.001)
1001
+
1002
+ def _write_bank_register(self, bank: int, reg: int, value: int) -> None:
1003
+ if self._bank != bank:
1004
+ self._write_register(_BANK_SEL, bank)
1005
+ self._write_register(reg, value)
1006
+
1007
+ def _read_bank_register(self, bank: int, reg: int) -> int:
1008
+ if self._bank != bank:
1009
+ self._write_register(_BANK_SEL, bank)
1010
+ result = self._read_register(reg)
1011
+ return result
1012
+
1013
+ def _write_register(self, reg: int, value: int) -> None:
1014
+ if reg == _BANK_SEL:
1015
+ if self._bank == value:
1016
+ return
1017
+ self._bank = value
1018
+ # print(f"write_register {reg:02x} {value:02x}")
1019
+ b = bytearray(2)
1020
+ b[0] = reg
1021
+ b[1] = value
1022
+ with self._i2c_device as i2c:
1023
+ i2c.write(b)
1024
+
1025
+ def _read_register(self, reg: int) -> int:
1026
+ b = bytearray(1)
1027
+ b[0] = reg
1028
+ with self._i2c_device as i2c:
1029
+ i2c.write(b)
1030
+ i2c.readinto(b)
1031
+ return b[0]
1032
+
1033
+
1034
+class OV2640(_SCCBCameraBase):
1035
+ """Library for the OV2640 digital camera"""
1036
+
1037
+ test_pattern = _RegBits(_BANK_SENSOR, _COM7, 1, 1)
1038
+ gain_ceiling = _RegBits(_BANK_SENSOR, _COM9, 5, 7)
1039
+ bpc = _RegBits(_BANK_DSP, _CTRL3, 7, 1)
1040
+ wpc = _RegBits(_BANK_DSP, _CTRL3, 6, 1)
1041
+ lenc = _RegBits(_BANK_DSP, _CTRL1, 1, 1)
1042
+
1043
+ def __init__(
1044
+ self,
1045
+ i2c_bus: I2C,
1046
+ data_pins: Pin,
1047
+ clock: Pin,
1048
+ vsync: Pin,
1049
+ href: Pin,
1050
+ shutdown: Optional[Pin] = None,
1051
+ reset: Optional[Pin] = None,
1052
+ mclk: Optional[Pin] = None,
1053
+ mclk_frequency: int = 20_000_000,
1054
+ i2c_address: int = 0x30,
1055
+ size: int = OV2640_SIZE_QQVGA,
1056
+ ):
1057
+ """
1058
+ Args:
1059
+ i2c_bus (busio.I2C): The I2C bus used to configure the OV2640
1060
+ data_pins (List[microcontroller.Pin]): A list of 8 data pins, in order.
1061
+ clock (microcontroller.Pin): The pixel clock from the OV2640.
1062
+ vsync (microcontroller.Pin): The vsync signal from the OV2640.
1063
+ href (microcontroller.Pin): The href signal from the OV2640, \
1064
+ sometimes inaccurately called hsync.
1065
+ shutdown (Optional[microcontroller.Pin]): If not None, the shutdown
1066
+ signal to the camera, also called the powerdown or enable pin.
1067
+ reset (Optional[microcontroller.Pin]): If not None, the reset signal
1068
+ to the camera.
1069
+ mclk (Optional[microcontroller.Pin]): The pin on which to create a
1070
+ master clock signal, or None if the master clock signal is
1071
+ already being generated.
1072
+ mclk_frequency (int): The frequency of the master clock to generate, \
1073
+ ignored if mclk is None, requred if it is specified
1074
+ i2c_address (int): The I2C address of the camera.
1075
+ """
1076
+
1077
+ # Initialize the master clock
1078
+ if mclk:
1079
+ self._mclk_pwm = pwmio.PWMOut(mclk, frequency=mclk_frequency)
1080
+ self._mclk_pwm.duty_cycle = 32768
1081
+ else:
1082
+ self._mclk_pwm = None
1083
+
1084
+ if shutdown:
1085
+ self._shutdown = digitalio.DigitalInOut(shutdown)
1086
+ self._shutdown.switch_to_output(True)
1087
+ time.sleep(0.1)
1088
+ self._shutdown.switch_to_output(False)
1089
+ time.sleep(0.3)
1090
+ else:
1091
+ self._shutdown = None
1092
+
1093
+ if reset:
1094
+ self._reset = digitalio.DigitalInOut(reset)
1095
+ self._reset.switch_to_output(False)
1096
+ time.sleep(0.1)
1097
+ self._reset.switch_to_output(True)
1098
+ time.sleep(0.1)
1099
+
1100
+ super().__init__(i2c_bus, i2c_address)
1101
+
1102
+ self._write_bank_register(_BANK_SENSOR, _COM7, _COM7_SRST)
1103
+ time.sleep(0.001)
1104
+
1105
+ self._write_list(_ov2640_settings_cif)
1106
+
1107
+ self._colorspace = OV2640_COLOR_RGB
1108
+ self._w = None
1109
+ self._h = None
1110
+ self._size = None
1111
+ self._test_pattern = False
1112
+ self.size = size
1113
+
1114
+ self._flip_x = False
1115
+ self._flip_y = False
1116
+
1117
+ self.gain_ceiling = _COM9_AGC_GAIN_2x
1118
+ self.bpc = False
1119
+ self.wpc = True
1120
+ self.lenc = True
1121
+
1122
+ # self._sensor_init()
1123
+
1124
+ self._imagecapture = imagecapture.ParallelImageCapture(
1125
+ data_pins=data_pins, clock=clock, vsync=vsync, href=href
1126
+ )
1127
+
1128
+ def capture(self, buf: WriteableBuffer) -> Optional[memoryview]:
1129
+ """Capture an image into the buffer.
1130
+
1131
+ Args:
1132
+ buf (WriteableBuffer): A WritableBuffer to contain the \
1133
+ captured image. Note that this can be a ulab array or a displayio Bitmap.
1134
+ """
1135
+ self._imagecapture.capture(buf)
1136
+ if self.colorspace == OV2640_COLOR_JPEG:
1137
+ eoi = buf.find(b"\xff\xd9")
1138
+ if eoi != -1:
1139
+ # terminate the JPEG data just after the EOI marker
1140
+ return memoryview(buf)[: eoi + 2]
1141
+ return None
1142
+
1143
+ @property
1144
+ def capture_buffer_size(self) -> int:
1145
+ """Return the size of capture buffer to use with current resolution & colorspace settings"""
1146
+ if self.colorspace == OV2640_COLOR_JPEG:
1147
+ return self.width * self.height // 5
1148
+ return self.width * self.height * 2
1149
+
1150
+ @property
1151
+ def mclk_frequency(self) -> Optional[int]:
1152
+ """Get the actual frequency the generated mclk, or None"""
1153
+ return self._mclk_pwm.frequency if self._mclk_pwm else None
1154
+
1155
+ @property
1156
+ def width(self) -> int:
1157
+ """Get the image width in pixels. A buffer of 2*width*height bytes \
1158
+ stores a whole image."""
1159
+ return self._w
1160
+
1161
+ @property
1162
+ def height(self) -> int:
1163
+ """Get the image height in pixels. A buffer of 2*width*height bytes \
1164
+ stores a whole image."""
1165
+ return self._h
1166
+
1167
+ @property
1168
+ def colorspace(self) -> bytes:
1169
+ """Get or set the colorspace, one of the ``OV2640_COLOR_`` constants."""
1170
+ return self._colorspace
1171
+
1172
+ @colorspace.setter
1173
+ def colorspace(self, colorspace: bytes) -> None:
1174
+ self._colorspace = colorspace
1175
+ self._set_size_and_colorspace()
1176
+
1177
+ def _set_colorspace(self) -> None:
1178
+ colorspace = self._colorspace
1179
+ settings = _ov2640_color_settings[colorspace]
1180
+
1181
+ self._write_list(settings)
1182
+ # written twice?
1183
+ self._write_list(settings)
1184
+ time.sleep(0.01)
1185
+
1186
+ def deinit(self) -> None:
1187
+ """Deinitialize the camera"""
1188
+ self._imagecapture.deinit()
1189
+ if self._mclk_pwm:
1190
+ self._mclk_pwm.deinit()
1191
+ if self._shutdown:
1192
+ self._shutdown.deinit()
1193
+ if self._reset:
1194
+ self._reset.deinit()
1195
+
1196
+ @property
1197
+ def size(self) -> int:
1198
+ """Get or set the captured image size, one of the ``OV2640_SIZE_`` constants."""
1199
+ return self._size
1200
+
1201
+ def _set_size_and_colorspace(self) -> None:
1202
+ size = self._size
1203
+ width, height, ratio = _resolution_info[size]
1204
+ offset_x, offset_y, max_x, max_y = _ratio_table[ratio]
1205
+ mode = _OV2640_MODE_UXGA
1206
+ if size <= OV2640_SIZE_CIF:
1207
+ mode = _OV2640_MODE_CIF
1208
+ max_x //= 4
1209
+ max_y //= 4
1210
+ offset_x //= 4
1211
+ offset_y //= 4
1212
+ max_y = min(max_y, 296)
1213
+
1214
+ elif size <= OV2640_SIZE_SVGA:
1215
+ mode = _OV2640_MODE_SVGA
1216
+ max_x //= 2
1217
+ max_y //= 2
1218
+ offset_x //= 2
1219
+ offset_y //= 2
1220
+
1221
+ self._set_window(mode, offset_x, offset_y, max_x, max_y, width, height)
1222
+
1223
+ @size.setter
1224
+ def size(self, size: int) -> None:
1225
+ self._size = size
1226
+ self._set_size_and_colorspace()
1227
+
1228
+ def _set_flip(self) -> None:
1229
+ bits = 0
1230
+ if self._flip_x:
1231
+ bits |= _REG04_HFLIP_IMG
1232
+ if self._flip_y:
1233
+ bits |= _REG04_VFLIP_IMG | _REG04_VREF_EN
1234
+ self._write_bank_register(_BANK_SENSOR, _REG04, _REG04_SET(bits))
1235
+
1236
+ @property
1237
+ def flip_x(self) -> bool:
1238
+ """Get or set the X-flip flag"""
1239
+ return self._flip_x
1240
+
1241
+ @flip_x.setter
1242
+ def flip_x(self, value: bool) -> None:
1243
+ self._flip_x = bool(value)
1244
+ self._set_flip()
1245
+
1246
+ @property
1247
+ def flip_y(self) -> bool:
1248
+ """Get or set the Y-flip flag"""
1249
+ return self._flip_y
1250
+
1251
+ @flip_y.setter
1252
+ def flip_y(self, value: bool) -> None:
1253
+ self._flip_y = bool(value)
1254
+ self._set_flip()
1255
+
1256
+ @property
1257
+ def product_id(self) -> int:
1258
+ """Get the product id (PID) register. The expected value is 0x26."""
1259
+ return self._read_bank_register(_BANK_SENSOR, _REG_PID)
1260
+
1261
+ @property
1262
+ def product_version(self) -> int:
1263
+ """Get the version (VER) register. The expected value is 0x41."""
1264
+ return self._read_bank_register(_BANK_SENSOR, _REG_VER)
1265
+
1266
+ def _set_window(
1267
+ self,
1268
+ mode: int,
1269
+ offset_x: int,
1270
+ offset_y: int,
1271
+ max_x: int,
1272
+ max_y: int,
1273
+ width: int,
1274
+ height: int,
1275
+ ) -> None:
1276
+ self._w = width
1277
+ self._h = height
1278
+
1279
+ max_x //= 4
1280
+ max_y //= 4
1281
+ width //= 4
1282
+ height //= 4
1283
+
1284
+ win_regs = [
1285
+ _BANK_SEL,
1286
+ _BANK_DSP,
1287
+ _HSIZE,
1288
+ max_x & 0xFF,
1289
+ _VSIZE,
1290
+ max_y & 0xFF,
1291
+ _XOFFL,
1292
+ offset_x & 0xFF,
1293
+ _YOFFL,
1294
+ offset_y & 0xFF,
1295
+ _VHYX,
1296
+ ((max_y >> 1) & 0x80)
1297
+ | ((offset_y >> 4) & 0x70)
1298
+ | ((max_x >> 5) & 0x08)
1299
+ | ((offset_y >> 8) & 0x07),
1300
+ _TEST,
1301
+ (max_x >> 2) & 0x80,
1302
+ _ZMOW,
1303
+ (width) & 0xFF,
1304
+ _ZMOH,
1305
+ (height) & 0xFF,
1306
+ _ZMHH,
1307
+ ((height >> 6) & 0x04) | ((width >> 8) & 0x03),
1308
+ ]
1309
+
1310
+ pclk_auto = 0
1311
+ pclk_div = 8
1312
+ clk_2x = 0
1313
+ clk_div = 0
1314
+
1315
+ if self._colorspace != OV2640_COLOR_JPEG:
1316
+ pclk_auto = 1
1317
+ clk_div = 7
1318
+
1319
+ if mode == _OV2640_MODE_CIF:
1320
+ regs = _ov2640_settings_to_cif
1321
+ if self._colorspace != OV2640_COLOR_JPEG:
1322
+ clk_div = 3
1323
+ elif mode == _OV2640_MODE_SVGA:
1324
+ regs = _ov2640_settings_to_svga
1325
+ else:
1326
+ regs = _ov2640_settings_to_uxga
1327
+ pclk_div = 12
1328
+
1329
+ clk = clk_div | (clk_2x << 7)
1330
+ pclk = pclk_div | (pclk_auto << 7)
1331
+
1332
+ self._write_bank_register(_BANK_DSP, _R_BYPASS, _R_BYPASS_DSP_BYPAS)
1333
+ self._write_list(regs)
1334
+ self._write_list(win_regs)
1335
+ self._write_bank_register(_BANK_SENSOR, _CLKRC, clk)
1336
+ self._write_bank_register(_BANK_DSP, _R_DVP_SP, pclk)
1337
+ self._write_register(_R_BYPASS, _R_BYPASS_DSP_EN)
1338
+ time.sleep(0.01)
1339
+
1340
+ # Reestablish colorspace
1341
+ self._set_colorspace()
1342
+
1343
+ # Reestablish test pattern
1344
+ if self._test_pattern:
1345
+ self.test_pattern = self._test_pattern
1346
+
1347
+ @property
1348
+ def exposure(self) -> int:
1349
+ """The exposure level of the sensor"""
1350
+ aec_9_2 = self._get_reg_bits(_BANK_SENSOR, _AEC, 0, 0xFF)
1351
+ aec_15_10 = self._get_reg_bits(_BANK_SENSOR, _REG45, 0, 0b111111)
1352
+ aec_1_0 = self._get_reg_bits(_BANK_SENSOR, _REG04, 0, 0b11)
1353
+
1354
+ return aec_1_0 | (aec_9_2 << 2) | (aec_15_10 << 10)
1355
+
1356
+ @exposure.setter
1357
+ def exposure(self, exposure: int) -> None:
1358
+ aec_1_0 = exposure & 0x11
1359
+ aec_9_2 = (exposure >> 2) & 0b11111111
1360
+ aec_15_10 = exposure >> 10
1361
+
1362
+ self._set_reg_bits(_BANK_SENSOR, _AEC, 0, 0xFF, aec_9_2)
1363
+ self._set_reg_bits(_BANK_SENSOR, _REG45, 0, 0b111111, aec_15_10)
1364
+ self._set_reg_bits(_BANK_SENSOR, _REG04, 0, 0b11, aec_1_0)
SDK-dat/python-dat/circuitpython-dat/circuitpython-dat.md
... ...
@@ -4,4 +4,92 @@
4 4
circuitpython
5 5
- board
6 6
- digitalio
7
-- wws_74hc165
... ...
\ No newline at end of file
0
+- wws_74hc165
1
+
2
+
3
+https://github.com/adafruit/circuitpython
4
+
5
+
6
+Start the UF2 Bootloader
7
+
8
+Nearly all CircuitPython boards ship with a bootloader called UF2 (USB Flashing Format) that makes installing and updating CircuitPython a quick and easy process. The bootloader is the mode your board needs to be in for the CircuitPython .uf2 file you downloaded to work. If the file you downloaded that matches the board name ends in uf2 then you want to continue with this section. However, if the file ends in .bin, you have to do a more complex installation - go to this page for details.
9
+
10
+Espressif Boards without UF2 Bootloaders
11
+
12
+See [this page](https://learn.adafruit.com/circuitpython-with-esp32-quick-start/installing-circuitpython) for how to load a .bin file on an ESP32 or ESP32-C3 board.
13
+
14
+https://learn.adafruit.com/welcome-to-circuitpython/non-uf2-installation
15
+
16
+https://circuitpython.org/board/doit_esp32_devkit_v1/
17
+
18
+https://downloads.circuitpython.org/bin/doit_esp32_devkit_v1/en_US/adafruit-circuitpython-doit_esp32_devkit_v1-en_US-9.2.8.bin
19
+
20
+The next step is to write your credentials to settings.toml. Make sure your board is running CircuitPython. If you just installed CircuitPython, you may to reset the board first.
21
+
22
+Successfully Completed
23
+
24
+You can edit files by going to http://000.0.0.0/code/.
25
+
26
+If the keys CIRCUITPY_WIFI_SSID and CIRCUITPY_WIFI_PASSWORD are set in settings.toml, CircuitPython will automatically connect to the given Wi-Fi network on boot and upon reload.
27
+
28
+## CircuitPython on ESP32 Quick Start
29
+
30
+https://learn.adafruit.com/circuitpython-with-esp32-quick-start
31
+
32
+ esptool.py --port COM13 erase_flash
33
+ esptool.py --chip esp32 --port /dev/tty.usbserial-1144440 erase_flash
34
+ esptool.py --port /dev/tty.usbserial-1144440 write_flash -z 0x0 firmware.bin
35
+
36
+repl
37
+
38
+ rst:0x1� �]I=9}IMQ�,boot:0x13 (SPI_FAST_FLASH_BOOT)
39
+ configsip: 0, SPIWP:0xee
40
+ �G��DIO, 덭LC!�+��0x3fff0040,len:400s0_drv:0x00,hd_drv80x00 7�E�v���0
41
+ load:0x40078000,len:14048
42
+ load:0x40080400,len:4
43
+ lod:0x40080404,len: �z
44
+ Adafruit CircuitPython 10.0.0-beta.0 on 2025-07-15; ESP32 Devkit V1 with ESP32
45
+ Board ID:doit_esp32_devkit_v1
46
+ UID:0125C196358A
47
+ MAC:18:0E:FD:3F:20:38
48
+
49
+ Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
50
+ code.py output:
51
+ Hello World!
52
+
53
+ Code done running.
54
+
55
+ Press any key to enter the REPL. Use CTRL-D to reload.
56
+
57
+installing [[settings.toml]] and using wifi
58
+
59
+ import wifi
60
+
61
+ print("My MAC addr: %02X:%02X:%02X:%02X:%02X:%02X" % tuple(wifi.radio.mac_address))
62
+ print("My IP address is", wifi.radio.ipv4_address)
63
+
64
+
65
+mpremote connect COM6 fs cp settings.toml :
66
+
67
+ mpremote connect COM6 fs put w.py :
68
+ put :w.py
69
+ put :
70
+
71
+ mpremote connect COM6 run w.py
72
+ My MAC addr: 10:52:1C:69:53:A8
73
+ My IP address is 192.168.79.226
74
+
75
+
76
+
77
+## OV2640
78
+
79
+- https://github.com/adafruit/Adafruit_CircuitPython_OV2640
80
+
81
+- https://docs.circuitpython.org/projects/ov2640/en/latest/
82
+
83
+
84
+
85
+## reference code
86
+
87
+- https://github.com/adafruit/Adafruit_Learning_System_Guides/tree/main/CircuitPython_Essentials
88
+
SDK-dat/python-dat/circuitpython-dat/ov2640_micropython_test.py
... ...
@@ -0,0 +1,49 @@
1
+# mpremote connect COM6 fs cp ov2640_micropython_test.py :
2
+# mpremote connect COM6 run ov2640_micropython_test.py
3
+
4
+import camera # type: ignore
5
+import time
6
+import sys
7
+
8
+# Initialize camera with ESP1000 pin definitions
9
+try:
10
+ camera.init(0,
11
+ d0=5, d1=18, d2=19, d3=21, d4=36, d5=39, d6=34, d7=35,
12
+ format=camera.JPEG,
13
+ framesize=camera.FRAME_QQVGA, # 160x120
14
+ xclk_freq=camera.XCLK_20MHz,
15
+ href=23, vsync=25, reset=-1, pwdn=32,
16
+ sioc=27, siod=26, xclk=0, pclk=22
17
+ )
18
+ print("Camera initialized successfully")
19
+except Exception as e:
20
+ print("Camera init failed:", e)
21
+ sys.exit()
22
+
23
+# Simple test - capture and save images
24
+count = 0
25
+while True:
26
+ try:
27
+ print("Capturing image", count)
28
+ buf = camera.capture()
29
+ print("Image size:", len(buf), "bytes")
30
+
31
+ # Save image
32
+ filename = f"test_{count:03d}.jpg"
33
+ with open(filename, 'wb') as f:
34
+ f.write(buf)
35
+ print("Saved:", filename)
36
+
37
+ count += 1
38
+ time.sleep(2)
39
+
40
+ # Stop after 5 images for testing
41
+ if count >= 5:
42
+ break
43
+
44
+ except Exception as e:
45
+ print("Capture error:", e)
46
+ break
47
+
48
+print("Test completed")
49
+camera.deinit()
SDK-dat/python-dat/circuitpython-dat/ov2640_simpletest.py
... ...
@@ -0,0 +1,74 @@
1
+# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
2
+# SPDX-FileCopyrightText: Copyright (c) 2021 Jeff Epler for Adafruit Industries
3
+#
4
+# SPDX-License-Identifier: Unlicense
5
+
6
+"""Capture an image from the camera and display it as ASCII art.
7
+
8
+This demo is designed to run on the Kaluga, but you can adapt it
9
+to other boards by changing the constructors for `bus` and `cam`
10
+appropriately.
11
+
12
+The camera is placed in YUV mode, so the top 8 bits of each color
13
+value can be treated as "greyscale".
14
+
15
+It's important that you use a terminal program that can interpret
16
+"ANSI" escape sequences. The demo uses them to "paint" each frame
17
+on top of the prevous one, rather than scrolling.
18
+
19
+Remember to take the lens cap off, or un-comment the line setting
20
+the test pattern!
21
+"""
22
+
23
+import sys
24
+import time
25
+
26
+import board
27
+import busio
28
+
29
+import adafruit_ov2640
30
+
31
+# mpremote connect COM6 fs put adafruit_ov2640.py :
32
+# mpremote connect COM6 fs put ov2640_simpletest.py :
33
+# mpremote connect COM6 fs run ov2640_simpletest.py
34
+
35
+
36
+# Pin definitions adapted from ESP1000-2-dat.py
37
+# d0=5, d1=18, d2=19, d3=21, d4=36, d5=39, d6=34, d7=35
38
+# href=23, vsync=25, sioc=27, siod=26, xclk=0, pclk=22
39
+data_pins = [board.GP5, board.GP18, board.GP19, board.GP21, board.GP36, board.GP39, board.GP34, board.GP35]
40
+
41
+bus = busio.I2C(scl=board.GP27, sda=board.GP26) # sioc=27, siod=26
42
+
43
+cam = adafruit_ov2640.OV2640(
44
+ bus,
45
+ data_pins=data_pins,
46
+ clock=board.GP22, # pclk=22
47
+ vsync=board.GP25, # vsync=25
48
+ href=board.GP23, # href=23
49
+ mclk=board.GP0, # xclk=0
50
+ mclk_frequency=20_000_000,
51
+ size=adafruit_ov2640.OV2640_SIZE_QQVGA,
52
+)
53
+cam.colorspace = adafruit_ov2640.OV2640_COLOR_YUV
54
+cam.flip_y = True
55
+# cam.test_pattern = True
56
+
57
+buf = bytearray(2 * cam.width * cam.height)
58
+chars = b" .:-=+*#%@"
59
+remap = [chars[i * (len(chars) - 1) // 255] for i in range(256)]
60
+
61
+width = cam.width
62
+row = bytearray(2 * width)
63
+
64
+sys.stdout.write("\033[2J")
65
+while True:
66
+ cam.capture(buf)
67
+ for j in range(cam.height // 2):
68
+ sys.stdout.write(f"\033[{j}H")
69
+ for i in range(cam.width // 2):
70
+ row[i * 2] = row[i * 2 + 1] = remap[buf[4 * (width * j + i)]]
71
+ sys.stdout.write(row)
72
+ sys.stdout.write("\033[K")
73
+ sys.stdout.write("\033[J")
74
+ time.sleep(0.05)
... ...
\ No newline at end of file
SDK-dat/python-dat/circuitpython-dat/settings.toml
... ...
@@ -0,0 +1,3 @@
1
+CIRCUITPY_WIFI_SSID = "111"
2
+CIRCUITPY_WIFI_PASSWORD = "electrodragon"
3
+CIRCUITPY_WEB_API_PASSWORD= "electrodragon"
... ...
\ No newline at end of file
SDK-dat/python-dat/circuitpython-dat/w.py
... ...
@@ -0,0 +1,4 @@
1
+import wifi
2
+
3
+print("My MAC addr: %02X:%02X:%02X:%02X:%02X:%02X" % tuple(wifi.radio.mac_address))
4
+print("My IP address is", wifi.radio.ipv4_address)
... ...
\ No newline at end of file
Tech-dat/Interface-dat/I2C-dat/I2C-dat.md
... ...
@@ -1,6 +1,10 @@
1 1
2 2
# I2C Dat
3 3
4
+
5
+## common I2C devices address
6
+
7
+
4 8
// I2C device found at address 0x40 ! // INA219, INA226
5 9
6 10
for [[IOD1001-dat]]
... ...
@@ -38,6 +42,20 @@ testing scan I2C
38 42
Wire.begin(4,13);
39 43
Wire.begin(2, 3);
40 44
45
+## I2C usage in Micropython
46
+
47
+- [[micropython-dat]]
48
+
49
+ from machine import I2C, Pin
50
+
51
+ # Define I2C on GPIO 15 (SDA) and GPIO 13 (SCL)
52
+
53
+ i2c = I2C(0, scl=Pin(13), sda=Pin(15), freq=400000)
54
+ i2c = I2C(0, scl=Pin(13), sda=Pin(15), freq=100000)
55
+
56
+
57
+ print("I2C scan:", i2c.scan())
58
+
41 59
## code library
42 60
43 61
the most easy to use library for ESP
Tech-dat/Interface-dat/I2S-dat/I2S-DAC-dat/I2S-DAC-dat.md
... ...
@@ -0,0 +1,40 @@
1
+
2
+# I2S-DAC-dat
3
+
4
+I2S DAC Decoder speaker
5
+
6
+- [[PCM5122-dat]] - [[MPC1083-dat]]
7
+
8
+- [[PCM5102-dat]] - [[AMP1006-dat]]
9
+
10
+- [[MAX98357-dat]]
11
+
12
+- [[UDA1334-dat]] - [[AMP1013-dat]] - [[NXP-dat]]
13
+
14
+## Pin
15
+
16
+| Name | default ESP32 | also Name | func | RPI GPIO | RPI pin |
17
+| ---- | ------------- | ------------ | ---------------------------------- | -------- | ------- |
18
+| SCK | 26 | BCLK | Serial Data Clock / Bit clock line | G18 | PIN 12 |
19
+| WS | 25 | LRCK / LRC | Serial Data-Word select line | G19 | PIN 35 |
20
+| SD | 22 | SDIN / SDOUT | At least one multiplexed data line | G21 | PIN 40 |
21
+
22
+I2S Circuit:
23
+
24
+* Arduino/Genuino Zero, MKR family and Nano 33 IoT
25
+* MAX98357:
26
+ * GND connected GND
27
+ * VIN connected 5V
28
+ * LRC connected to pin 0 (Zero) or 3 (MKR), A2 (Nano) or 25 (ESP32)
29
+ * BCLK connected to pin 1 (Zero) or 2 (MKR), A3 (Nano) or 5 (ESP32)
30
+ * DIN connected to pin 9 (Zero) or A6 (MKR), 4 (Nano) or 26 (ESP32)
31
+
32
+ DAC Circuit:
33
+ * ESP32 or ESP32-S2
34
+ * Audio amplifier
35
+ - Note:
36
+ - ESP32 has DAC on GPIO pins 25 and 26.
37
+ - ESP32-S2 has DAC on GPIO pins 17 and 18.
38
+ - Connect speaker(s) or headphones.
39
+
40
+- [[MAX98357-dat]]
... ...
\ No newline at end of file
Tech-dat/Interface-dat/I2S-dat/I2S-dat.md
... ...
@@ -11,35 +11,11 @@ One of the key features of I2S interfaces is their ability to support full-duple
11 11
12 12
This makes I2S a popular choice for high-speed data transfer applications.
13 13
14
-- [[I2S-microphone-dat]] - [[I2S-speaker-dat]]
14
+- [[I2S-microphone-dat]] - [[I2S-DAC-dat]]
15 15
16 16
- [[everest-semi-dat]]
17 17
18
-## Pin
19
-
20
-| Name | default ESP32 | also Name | func | RPI GPIO | RPI pin |
21
-| ---- | ------------- | ------------ | ---------------------------------- | -------- | ------- |
22
-| SCK | 26 | BCLK | Serial Data Clock / Bit clock line | G18 | PIN 12 |
23
-| WS | 25 | LRCK / LRC | Serial Data-Word select line | G19 | PIN 35 |
24
-| SD | 22 | SDIN / SDOUT | At least one multiplexed data line | G21 | PIN 40 |
25
-
26
-I2S Circuit:
27
-
28
-* Arduino/Genuino Zero, MKR family and Nano 33 IoT
29
-* MAX08357:
30
- * GND connected GND
31
- * VIN connected 5V
32
- * LRC connected to pin 0 (Zero) or 3 (MKR), A2 (Nano) or 25 (ESP32)
33
- * BCLK connected to pin 1 (Zero) or 2 (MKR), A3 (Nano) or 5 (ESP32)
34
- * DIN connected to pin 9 (Zero) or A6 (MKR), 4 (Nano) or 26 (ESP32)
35
-
36
- DAC Circuit:
37
- * ESP32 or ESP32-S2
38
- * Audio amplifier
39
- - Note:
40
- - ESP32 has DAC on GPIO pins 25 and 26.
41
- - ESP32-S2 has DAC on GPIO pins 17 and 18.
42
- - Connect speaker(s) or headphones.
18
+
43 19
44 20
## Common Microphone, Speaker Wiring
45 21
... ...
@@ -56,44 +32,64 @@ I2S Circuit:
56 32
57 33
58 34
59
-## Solution - control (slave module)
60 35
61
-- [[I2S-microphone-dat]]
62 36
63
-audio amplifer - [[audio-dat]] - [[amplifier-dat]] - [[CS4344-dat]]
64 37
65
-I2S speaker - [[PCM5122-dat]] - [[MPC1083-dat]] - [[MAX98357-dat]] - [[PCM5102-dat]] - [[AMP1006-dat]]
66 38
67
-- [[ES9023-dat]] - [[MPC1111-dat]] - [[ES9018-dat]]
68
-
69
-- [[WM8960-dat]] - [[WM8978-dat]]
39
+## demo video
70 40
71
-- [[UDA1334-dat]] - [[AMP1013-dat]]
41
+- [[MAX98357-dat]] works with [[ESP32-dat]] - https://x.com/electro_phoenix/status/1877255863846465989
72 42
73
-- [[bt-audio-dat]] - [[ESP32-DAC-dat]] - [[ADC-dat]] - [[DAC-dat]] - [[ESP32-I2S-dat]]
74 43
75
-- [[PCM1808-dat]]
44
+## code
76 45
77
-- [[software-i2s-dat]]
46
+https://github.com/sheaivey/ESP32-AudioInI2S
78 47
48
+https://github.com/atomic14/esp32_audio == [[platformIO-dat]]
79 49
50
+https://github.com/schreibfaul1/ESP32-audioI2S == easy
80 51
52
+https://github.com/earlephilhower/ESP8266Audio
81 53
54
+## Micropython driver
82 55
83
-## demo video
56
+- [[Micropython-dat]]
84 57
85
-- [[MAX98357-dat]] works with [[ESP32-dat]] - https://x.com/electro_phoenix/status/1877255863846465989
58
+- [[I2S-DAC-dat]] driver
86 59
60
+https://github.com/miketeachman/micropython-i2s-examples
87 61
88
-## code
62
+- [[I2S-microphone-dat]] driver
89 63
90
-https://github.com/sheaivey/ESP32-AudioInI2S
64
+#ESP32 I2S MEMS Microphone Arduino IDE Example This repository holds some samples for connecting a I2S MEMS microphone to an ESP32 board.
91 65
92
-https://github.com/atomic14/esp32_audio == [[platformIO-dat]]
66
+https://github.com/miketeachman/micropython-i2s-examples
67
+
68
+
69
+## I2S sesnors
70
+
71
+[SPL06-MEMS-barometer-micropython](https://github.com/ChangboBro/SPL06-MEMS-barometer-micropython)
72
+
73
+The SPL06 is a high precision MEMS barometer, its resolution of altitude can up to 5cm! (but I think maybe +-10cm, still very good)
74
+
75
+## ref
76
+
77
+audio amplifer - [[audio-dat]] - [[amplifier-dat]] - [[CS4344-dat]]
78
+
79
+
80
+- [[ES9023-dat]] - [[MPC1111-dat]] - [[ES9018-dat]]
81
+
82
+- [[WM8960-dat]] - [[WM8978-dat]]
83
+
84
+
85
+
86
+- [[bt-audio-dat]] - [[ESP32-DAC-dat]] - [[ADC-dat]] - [[DAC-dat]] - [[ESP32-I2S-dat]]
87
+
88
+- [[PCM1808-dat]]
89
+
90
+- [[software-i2s-dat]]
93 91
94
-https://github.com/schreibfaul1/ESP32-audioI2S == easy
95 92
96
-https://github.com/earlephilhower/ESP8266Audio
97 93
98 94
99 95
## ref
Tech-dat/Interface-dat/I2S-dat/I2S-microphone-dat/I2S-microphone-dat.md
... ...
@@ -19,7 +19,16 @@ I2S Output Digital Microphone - [[INMP441-dat]] - [[MSM261S4030H0R-dat]]
19 19
| [[SPH0645-dat]] | yes | yes | yes | yes |
20 20
21 21
22
-
22
+## wiring reference
23
+
24
+| Signal | Connection |
25
+| ------ | ----------------------------------------------- |
26
+| SEL | unconnected (only one channel, apparently left) |
27
+| LRCL | #15 |
28
+| DOUT | #32 |
29
+| BCKL | #14 |
30
+| GND | GND |
31
+| 3V | 3V |
23 32
24 33
25 34
## go advance
Tech-dat/sensor-camera-dat/camera-SDK-dat/OV2640-lemariva-dat/OV2640-lemariva-dat.md
... ...
@@ -14,6 +14,8 @@ https://github.com/lemariva/micropython-camera-driver
14 14
https://github.com/lemariva/upyCam
15 15
https://github.com/lemariva/upyCam/tree/timelapse-camera
16 16
17
+- [[MP-ESP32-dat]]
18
+
17 19
flash camera driver firmware
18 20
19 21
esptool --port COM6 --baud 460800 write-flash 0x1000 micropython_camera_feeeb5ea3_esp32_idf4_4.bin
Tech-dat/sensor-camera-dat/camera-SDK-dat/camera-SDK-dat.md
... ...
@@ -5,11 +5,16 @@
5 5
6 6
- [[camera-dat]]
7 7
8
-[[micropython-dat]] - [[script-based-SDK]]
8
+
9 9
10 10
11 11
## repro
12 12
13
+- [[openMV-dat]]
14
+
15
+- [[circuitpython-dat]] - better support for [[ESP32-S3-dat]] not well support for ESP32-CAM == [[SCM1030-dat]] == https://github.com/adafruit/Adafruit_CircuitPython_OV2640/issues/22
16
+
17
+
13 18
- https://github.com/alanesq/esp32cam-demo
14 19
- https://github.com/espressif/esp32-camera
15 20
- https://github.com/yoursunny/esp32cam
... ...
@@ -19,6 +24,11 @@
19 24
- https://github.com/donny681/ESP32_CAMERA_QR
20 25
- https://github.com/ArduCAM/Arduino
21 26
27
+
28
+
29
+
30
+[[micropython-dat]] - [[script-based-SDK]]
31
+
22 32
## OV2640
23 33
24 34
- [[OV2640-lemariva-dat]]
Tech-dat/sensor-camera-dat/camera-SDK-dat/openMV-dat/openMV-dat.md
... ...
@@ -0,0 +1,6 @@
1
+
2
+# openMV-dat
3
+
4
+- https://github.com/openmv/openmv
5
+
6
+The ESP32 is much slower than the H7 or IMX. So, it’s really just a port for the sake of it. Actual performance will be very low.
... ...
\ No newline at end of file