pymcu-micropython 0.1.0a1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ # pymcu_micropython -- MicroPython stdlib flavor for PyMCU
2
+ # This package provides MicroPython-compatible modules that compile to bare-metal firmware.
@@ -0,0 +1,121 @@
1
+ # MicroPython-compatible avr module for PyMCU
2
+ #
3
+ # AVR-specific peripherals:
4
+ # EEPROM -- non-volatile byte storage (shim over pymcu.hal.eeprom)
5
+ # SoftSPI -- bit-bang SPI (shim over pymcu.hal.softspi)
6
+ # SoftI2C -- bit-bang I2C (shim over pymcu.hal.softi2c)
7
+ #
8
+ # All classes follow ZCA (zero-cost abstraction) rules:
9
+ # - All methods are @inline
10
+ # - No SRAM instance structs emitted beyond the wrapped HAL object
11
+ #
12
+ # Usage:
13
+ # from avr import EEPROM, SoftSPI, SoftI2C
14
+ # from machine import Pin
15
+ #
16
+ # ee = EEPROM()
17
+ # ee.write(0, 42)
18
+ # val = ee.read(0)
19
+ #
20
+ # scl = Pin(5, Pin.OUT)
21
+ # sda = Pin(4, Pin.OUT)
22
+ # i2c = SoftI2C(scl, sda)
23
+ #
24
+ # sck = Pin(13, Pin.OUT)
25
+ # mosi = Pin(11, Pin.OUT)
26
+ # miso = Pin(12, Pin.IN)
27
+ # spi = SoftSPI(sck, mosi, miso, baudrate=500)
28
+
29
+ from pymcu.types import uint8, uint16, uint32, inline
30
+ from pymcu.hal.eeprom import EEPROM as _EEPROM
31
+ from pymcu.hal.softspi import SoftSPI as _SoftSPI
32
+ from pymcu.hal.softi2c import SoftI2C as _SoftI2C
33
+
34
+
35
+ # ---------------------------------------------------------------------------
36
+ # EEPROM
37
+ # ---------------------------------------------------------------------------
38
+
39
+ class EEPROM:
40
+ @inline
41
+ def __init__(self):
42
+ self._ee = _EEPROM()
43
+
44
+ @inline
45
+ def read(self, addr: uint16) -> uint8:
46
+ return self._ee.read(addr)
47
+
48
+ @inline
49
+ def write(self, addr: uint16, value: uint8):
50
+ self._ee.write(addr, value)
51
+
52
+
53
+ # ---------------------------------------------------------------------------
54
+ # SoftSPI
55
+ # ---------------------------------------------------------------------------
56
+
57
+ class SoftSPI:
58
+ CONTROLLER = 0
59
+ PERIPHERAL = 1
60
+
61
+ @inline
62
+ def __init__(self, sck, mosi, miso, baudrate: uint16 = 500, mode: uint8 = 0):
63
+ # sck, mosi, miso: machine.Pin instances.
64
+ # baudrate: target SCK frequency in kHz (controller mode only).
65
+ # mode: SoftSPI.CONTROLLER (0) or SoftSPI.PERIPHERAL (1).
66
+ self._spi = _SoftSPI(sck._pin, mosi._pin, miso._pin, mode, None, baudrate)
67
+
68
+ @inline
69
+ def transfer(self, data: uint8) -> uint8:
70
+ return self._spi.transfer(data)
71
+
72
+ @inline
73
+ def write(self, data: uint8):
74
+ self._spi.write(data)
75
+
76
+ @inline
77
+ def select(self):
78
+ self._spi.select()
79
+
80
+ @inline
81
+ def deselect(self):
82
+ self._spi.deselect()
83
+
84
+
85
+ # ---------------------------------------------------------------------------
86
+ # SoftI2C
87
+ # ---------------------------------------------------------------------------
88
+
89
+ class SoftI2C:
90
+ @inline
91
+ def __init__(self, scl, sda, freq: uint32 = 100000):
92
+ # scl, sda: machine.Pin instances (must have external pull-ups).
93
+ # freq: bus frequency in Hz; converted to half-period microseconds
94
+ # as half_us = 500_000 // freq (compile-time fold when freq is literal).
95
+ # 100 kHz -> half_us=5, 400 kHz -> half_us=1.
96
+ half_us: uint8 = 500000 // freq
97
+ self._i2c = _SoftI2C(scl._pin, sda._pin, half_us)
98
+ self._i2c.init()
99
+
100
+ @inline
101
+ def scan(self) -> uint8:
102
+ # Returns count of responding devices (not a list -- no heap on MCU).
103
+ count: uint8 = 0
104
+ addr: uint8 = 1
105
+ while addr < 128:
106
+ if self._i2c.ping(addr):
107
+ count = count + 1
108
+ addr = addr + 1
109
+ return count
110
+
111
+ @inline
112
+ def writeto(self, addr: uint8, data: uint8) -> uint8:
113
+ return self._i2c.write_to(addr, data)
114
+
115
+ @inline
116
+ def readfrom(self, addr: uint8) -> uint8:
117
+ return self._i2c.read_from(addr)
118
+
119
+ @inline
120
+ def ping(self, addr: uint8) -> uint8:
121
+ return self._i2c.ping(addr)
@@ -0,0 +1,33 @@
1
+ # Board -> chip mapping for boards known to the MicroPython flavor.
2
+ # The PyMCU build driver merges this into its own BOARD_CHIPS dict at build time.
3
+ # Extension entries take precedence over the built-in driver mapping.
4
+
5
+ BOARD_CHIPS: dict = {
6
+ # Common MicroPython boards
7
+ "pyboard": "stm32f405",
8
+ "pyboard_v11": "stm32f405",
9
+ "rp2040": "rp2040",
10
+ "esp32_generic": "esp32",
11
+ "esp8266_generic": "esp8266",
12
+ # Arduino / AVR
13
+ "arduino_uno": "atmega328p",
14
+ "arduino_nano": "atmega328p",
15
+ "arduino_mega": "atmega2560",
16
+ "arduino_micro": "atmega32u4",
17
+ # ATtiny named dev boards
18
+ "digispark": "attiny85",
19
+ "adafruit_trinket": "attiny85",
20
+ # ATtiny bare chips -- 8-pin
21
+ "attiny85": "attiny85",
22
+ "attiny45": "attiny45",
23
+ "attiny25": "attiny25",
24
+ "attiny13": "attiny13",
25
+ "attiny13a": "attiny13a",
26
+ # ATtiny bare chips -- 14-pin
27
+ "attiny84": "attiny84",
28
+ "attiny44": "attiny44",
29
+ "attiny24": "attiny24",
30
+ # ATtiny bare chips -- 20-pin
31
+ "attiny2313": "attiny2313",
32
+ "attiny4313": "attiny4313",
33
+ }
@@ -0,0 +1,2 @@
1
+ # Board pin definitions for the MicroPython flavor.
2
+ # Each board file maps integer Arduino pin numbers to PyMCU port strings.
@@ -0,0 +1,51 @@
1
+ # MicroPython-style board constants for Arduino Mega 2560 (ATmega2560 @ 16 MHz)
2
+ #
3
+ # The Mega has 54 digital + 16 analog pins. Since machine._arduino_pin_name
4
+ # only covers the Uno's D0-D13 mapping, pin constants here use port strings
5
+ # directly. Pass them to Pin() or HAL functions as-is.
6
+
7
+ # Digital pins D0-D13
8
+ D0 = "PE0"; D1 = "PE1"; D2 = "PE4"; D3 = "PE5"
9
+ D4 = "PG5"; D5 = "PE3"; D6 = "PH3"; D7 = "PH4"
10
+ D8 = "PH5"; D9 = "PH6"; D10 = "PB4"; D11 = "PB5"
11
+ D12 = "PB6"; D13 = "PB7"
12
+
13
+ # Digital pins D14-D21 (serial / I2C)
14
+ D14 = "PJ1"; D15 = "PJ0"; D16 = "PH1"; D17 = "PH0"
15
+ D18 = "PD3"; D19 = "PD2"; D20 = "PD1"; D21 = "PD0"
16
+
17
+ # Digital pins D22-D29 (Port A)
18
+ D22 = "PA0"; D23 = "PA1"; D24 = "PA2"; D25 = "PA3"
19
+ D26 = "PA4"; D27 = "PA5"; D28 = "PA6"; D29 = "PA7"
20
+
21
+ # Digital pins D30-D37 (Port C, reversed)
22
+ D30 = "PC7"; D31 = "PC6"; D32 = "PC5"; D33 = "PC4"
23
+ D34 = "PC3"; D35 = "PC2"; D36 = "PC1"; D37 = "PC0"
24
+
25
+ # Digital pins D38-D41
26
+ D38 = "PD7"; D39 = "PG2"; D40 = "PG1"; D41 = "PG0"
27
+
28
+ # Digital pins D42-D49 (Port L, reversed)
29
+ D42 = "PL7"; D43 = "PL6"; D44 = "PL5"; D45 = "PL4"
30
+ D46 = "PL3"; D47 = "PL2"; D48 = "PL1"; D49 = "PL0"
31
+
32
+ # Digital pins D50-D53 (SPI)
33
+ D50 = "PB3"; D51 = "PB2"; D52 = "PB1"; D53 = "PB0"
34
+
35
+ # Analog pins A0-A7 (Port F)
36
+ A0 = "PF0"; A1 = "PF1"; A2 = "PF2"; A3 = "PF3"
37
+ A4 = "PF4"; A5 = "PF5"; A6 = "PF6"; A7 = "PF7"
38
+
39
+ # Analog pins A8-A15 (Port K)
40
+ A8 = "PK0"; A9 = "PK1"; A10 = "PK2"; A11 = "PK3"
41
+ A12 = "PK4"; A13 = "PK5"; A14 = "PK6"; A15 = "PK7"
42
+
43
+ # Named aliases
44
+ LED = "PB7"
45
+ LED_BUILTIN = "PB7"
46
+ TX = "PE1"; RX = "PE0"
47
+ TX1 = "PD3"; RX1 = "PD2"
48
+ TX2 = "PH1"; RX2 = "PH0"
49
+ TX3 = "PJ1"; RX3 = "PJ0"
50
+ SCL = "PD0"; SDA = "PD1"
51
+ SCK = "PB1"; MOSI = "PB2"; MISO = "PB3"; SS = "PB0"
@@ -0,0 +1,17 @@
1
+ # MicroPython-style board constants for Arduino Micro (ATmega32U4 @ 16 MHz)
2
+ #
3
+ # Port strings are used directly since machine._arduino_pin_name covers Uno only.
4
+
5
+ D0 = "PD2"; D1 = "PD3"; D2 = "PD1"; D3 = "PD0"
6
+ D4 = "PD4"; D5 = "PC6"; D6 = "PD7"; D7 = "PE6"
7
+ D8 = "PB4"; D9 = "PB5"; D10 = "PB6"; D11 = "PB7"
8
+ D12 = "PD6"; D13 = "PC7"
9
+
10
+ A0 = "PF7"; A1 = "PF6"; A2 = "PF5"; A3 = "PF4"
11
+ A4 = "PF1"; A5 = "PF0"
12
+
13
+ LED = "PC7"
14
+ LED_BUILTIN = "PC7"
15
+ TX = "PD3"; RX = "PD2"
16
+ SCL = "PD0"; SDA = "PD1"
17
+ SCK = "PB1"; MOSI = "PB2"; MISO = "PB3"; SS = "PB0"
@@ -0,0 +1,36 @@
1
+ # MicroPython-style board constants for Arduino Nano (ATmega328P @ 16 MHz)
2
+ #
3
+ # Identical pinout to Arduino Uno. Integer pin numbers match silk-screen.
4
+ # MicroPython uses integer pin numbers resolved to port strings by the compiler.
5
+
6
+ # Digital pins (same numbering as Arduino silk-screen)
7
+ D0 = 0 # PD0 / RX
8
+ D1 = 1 # PD1 / TX
9
+ D2 = 2 # PD2 / INT0
10
+ D3 = 3 # PD3 / INT1 / OC2B
11
+ D4 = 4 # PD4
12
+ D5 = 5 # PD5 / OC0B
13
+ D6 = 6 # PD6 / OC0A
14
+ D7 = 7 # PD7
15
+ D8 = 8 # PB0
16
+ D9 = 9 # PB1 / OC1A
17
+ D10 = 10 # PB2 / SS / OC1B
18
+ D11 = 11 # PB3 / MOSI / OC2A
19
+ D12 = 12 # PB4 / MISO
20
+ D13 = 13 # PB5 / SCK / LED
21
+
22
+ # Analog pins (port-string form; no standard integer offset on Nano)
23
+ A0 = "PC0"
24
+ A1 = "PC1"
25
+ A2 = "PC2"
26
+ A3 = "PC3"
27
+ A4 = "PC4" # SDA
28
+ A5 = "PC5" # SCL
29
+ A6 = "ADC6" # ADC-only (no GPIO; not connected to a port pin)
30
+ A7 = "ADC7" # ADC-only (no GPIO; not connected to a port pin)
31
+
32
+ # Named aliases
33
+ LED = 13
34
+ LED_BUILTIN = 13
35
+ TX = 1
36
+ RX = 0
@@ -0,0 +1,39 @@
1
+ # MicroPython-style board constants for Arduino Uno (ATmega328P @ 16 MHz)
2
+ #
3
+ # MicroPython uses integer pin numbers matching the Arduino silk-screen numbering.
4
+ # These are compile-time constants resolved to port strings by the compiler.
5
+ #
6
+ # Usage:
7
+ # from machine import Pin
8
+ # led = Pin(13, Pin.OUT) # D13 = PB5 (built-in LED)
9
+ #
10
+ # Note: explicit string literals are required here because the pymcu compiler
11
+ # only registers module-level globals for explicit assignments.
12
+
13
+ # Digital pins (same numbering as Arduino silk-screen)
14
+ D0 = 0 # PD0 / RX
15
+ D1 = 1 # PD1 / TX
16
+ D2 = 2 # PD2 / INT0
17
+ D3 = 3 # PD3 / INT1 / OC2B
18
+ D4 = 4 # PD4
19
+ D5 = 5 # PD5 / OC0B
20
+ D6 = 6 # PD6 / OC0A
21
+ D7 = 7 # PD7
22
+ D8 = 8 # PB0
23
+ D9 = 9 # PB1 / OC1A
24
+ D10 = 10 # PB2 / SS / OC1B
25
+ D11 = 11 # PB3 / MOSI / OC2A
26
+ D12 = 12 # PB4 / MISO
27
+ D13 = 13 # PB5 / SCK / LED
28
+
29
+ # Analog pins (also usable as digital GPIO via integer 14-19)
30
+ A0 = "PC0"
31
+ A1 = "PC1"
32
+ A2 = "PC2"
33
+ A3 = "PC3"
34
+ A4 = "PC4" # SDA
35
+ A5 = "PC5" # SCL
36
+
37
+ # Named aliases
38
+ LED = 13 # Built-in LED (PB5 / D13)
39
+ LED_BUILTIN = 13
@@ -0,0 +1,11 @@
1
+ # MicroPython-style board constants for ATtiny13 bare chip (8-pin DIP)
2
+ # Also covers ATtiny13A (improved oscillator) -- same pinout.
3
+ # Very minimal: 1KB flash, 64B SRAM. No UART, no USI.
4
+
5
+ PB0 = "PB0"; PB1 = "PB1"; PB2 = "PB2"
6
+ PB3 = "PB3"; PB4 = "PB4"
7
+ PB5 = "PB5" # RESET by default -- GPIO requires RSTDISBL fuse!
8
+
9
+ A0 = "PB5"; A1 = "PB2"; A2 = "PB4"; A3 = "PB3"
10
+
11
+ INT0 = "PB1"
@@ -0,0 +1,10 @@
1
+ # MicroPython-style board constants for ATtiny13A bare chip (8-pin DIP)
2
+ # Same pinout as ATtiny13. See attiny13.py for details.
3
+
4
+ PB0 = "PB0"; PB1 = "PB1"; PB2 = "PB2"
5
+ PB3 = "PB3"; PB4 = "PB4"
6
+ PB5 = "PB5" # RESET by default -- GPIO requires RSTDISBL fuse!
7
+
8
+ A0 = "PB5"; A1 = "PB2"; A2 = "PB4"; A3 = "PB3"
9
+
10
+ INT0 = "PB1"
@@ -0,0 +1,12 @@
1
+ # MicroPython-style board constants for ATtiny2313 bare chip (20-pin DIP)
2
+ # Also covers ATtiny4313 (4KB flash, 256B SRAM) -- same pinout.
3
+
4
+ D0 = "PD0"; D1 = "PD1"; D2 = "PD2"; D3 = "PD3"
5
+ D4 = "PD4"; D5 = "PD5"; D6 = "PD6"
6
+ D7 = "PB0"; D8 = "PB1"; D9 = "PB2"; D10 = "PB3"
7
+ D11 = "PB4"; D12 = "PB5"; D13 = "PB6"; D14 = "PB7"
8
+
9
+ TX = "PD1"; RX = "PD0"
10
+ SCK = "PB2"; MOSI = "PB0"; MISO = "PB1"
11
+ SCL = "PB2"; SDA = "PB0"
12
+ INT0 = "PD2"; INT1 = "PD3"
@@ -0,0 +1,12 @@
1
+ # MicroPython-style board constants for ATtiny24 bare chip (14-pin DIP)
2
+ # Same pinout as ATtiny84. See attiny84.py for details.
3
+
4
+ D0 = "PA0"; D1 = "PA1"; D2 = "PA2"; D3 = "PA3"
5
+ D4 = "PA4"; D5 = "PA5"; D6 = "PA6"; D7 = "PA7"
6
+ D8 = "PB0"; D9 = "PB1"; D10 = "PB2"
7
+
8
+ A0 = "PA0"; A1 = "PA1"; A2 = "PA2"; A3 = "PA3"
9
+ A4 = "PA4"; A5 = "PA5"; A6 = "PA6"; A7 = "PA7"
10
+
11
+ SCK = "PB2"; MOSI = "PB0"; MISO = "PB1"
12
+ SCL = "PB2"; SDA = "PB0"; INT0 = "PB2"
@@ -0,0 +1,11 @@
1
+ # MicroPython-style board constants for ATtiny25 bare chip (8-pin DIP)
2
+ # Same pinout as ATtiny85. See attiny85.py for details.
3
+
4
+ PB0 = "PB0"; PB1 = "PB1"; PB2 = "PB2"
5
+ PB3 = "PB3"; PB4 = "PB4"
6
+ PB5 = "PB5" # RESET by default -- GPIO requires RSTDISBL fuse!
7
+
8
+ A0 = "PB5"; A1 = "PB2"; A2 = "PB4"; A3 = "PB3"
9
+
10
+ SCK = "PB2"; MOSI = "PB0"; MISO = "PB1"
11
+ SCL = "PB2"; SDA = "PB0"; INT0 = "PB2"
@@ -0,0 +1,12 @@
1
+ # MicroPython-style board constants for ATtiny4313 bare chip (20-pin DIP)
2
+ # Same pinout as ATtiny2313. See attiny2313.py for details.
3
+
4
+ D0 = "PD0"; D1 = "PD1"; D2 = "PD2"; D3 = "PD3"
5
+ D4 = "PD4"; D5 = "PD5"; D6 = "PD6"
6
+ D7 = "PB0"; D8 = "PB1"; D9 = "PB2"; D10 = "PB3"
7
+ D11 = "PB4"; D12 = "PB5"; D13 = "PB6"; D14 = "PB7"
8
+
9
+ TX = "PD1"; RX = "PD0"
10
+ SCK = "PB2"; MOSI = "PB0"; MISO = "PB1"
11
+ SCL = "PB2"; SDA = "PB0"
12
+ INT0 = "PD2"; INT1 = "PD3"
@@ -0,0 +1,12 @@
1
+ # MicroPython-style board constants for ATtiny44 bare chip (14-pin DIP)
2
+ # Same pinout as ATtiny84. See attiny84.py for details.
3
+
4
+ D0 = "PA0"; D1 = "PA1"; D2 = "PA2"; D3 = "PA3"
5
+ D4 = "PA4"; D5 = "PA5"; D6 = "PA6"; D7 = "PA7"
6
+ D8 = "PB0"; D9 = "PB1"; D10 = "PB2"
7
+
8
+ A0 = "PA0"; A1 = "PA1"; A2 = "PA2"; A3 = "PA3"
9
+ A4 = "PA4"; A5 = "PA5"; A6 = "PA6"; A7 = "PA7"
10
+
11
+ SCK = "PB2"; MOSI = "PB0"; MISO = "PB1"
12
+ SCL = "PB2"; SDA = "PB0"; INT0 = "PB2"
@@ -0,0 +1,11 @@
1
+ # MicroPython-style board constants for ATtiny45 bare chip (8-pin DIP)
2
+ # Same pinout as ATtiny85. See attiny85.py for details.
3
+
4
+ PB0 = "PB0"; PB1 = "PB1"; PB2 = "PB2"
5
+ PB3 = "PB3"; PB4 = "PB4"
6
+ PB5 = "PB5" # RESET by default -- GPIO requires RSTDISBL fuse!
7
+
8
+ A0 = "PB5"; A1 = "PB2"; A2 = "PB4"; A3 = "PB3"
9
+
10
+ SCK = "PB2"; MOSI = "PB0"; MISO = "PB1"
11
+ SCL = "PB2"; SDA = "PB0"; INT0 = "PB2"
@@ -0,0 +1,12 @@
1
+ # MicroPython-style board constants for ATtiny84 bare chip (14-pin DIP)
2
+ # Also covers ATtiny44 (4KB flash) and ATtiny24 (2KB flash) -- same pinout.
3
+
4
+ D0 = "PA0"; D1 = "PA1"; D2 = "PA2"; D3 = "PA3"
5
+ D4 = "PA4"; D5 = "PA5"; D6 = "PA6"; D7 = "PA7"
6
+ D8 = "PB0"; D9 = "PB1"; D10 = "PB2"
7
+
8
+ A0 = "PA0"; A1 = "PA1"; A2 = "PA2"; A3 = "PA3"
9
+ A4 = "PA4"; A5 = "PA5"; A6 = "PA6"; A7 = "PA7"
10
+
11
+ SCK = "PB2"; MOSI = "PB0"; MISO = "PB1"
12
+ SCL = "PB2"; SDA = "PB0"; INT0 = "PB2"
@@ -0,0 +1,11 @@
1
+ # MicroPython-style board constants for ATtiny85 bare chip (8-pin DIP)
2
+ # Also covers ATtiny45 (4KB flash) and ATtiny25 (2KB flash) -- same pinout.
3
+
4
+ PB0 = "PB0"; PB1 = "PB1"; PB2 = "PB2"
5
+ PB3 = "PB3"; PB4 = "PB4"
6
+ PB5 = "PB5" # RESET by default -- GPIO requires RSTDISBL fuse!
7
+
8
+ A0 = "PB5"; A1 = "PB2"; A2 = "PB4"; A3 = "PB3"
9
+
10
+ SCK = "PB2"; MOSI = "PB0"; MISO = "PB1"
11
+ SCL = "PB2"; SDA = "PB0"; INT0 = "PB2"
@@ -0,0 +1,13 @@
1
+ # MicroPython-style board constants for Digispark (ATtiny85 @ 16.5 MHz USB)
2
+ # Port strings used directly (no integer mapping for ATtiny in machine.py).
3
+
4
+ P0 = "PB0"; P1 = "PB1"; P2 = "PB2"
5
+ P3 = "PB3"; P4 = "PB4"
6
+ P5 = "PB5" # RESET by default -- GPIO requires RSTDISBL fuse!
7
+
8
+ A0 = "PB5"; A1 = "PB2"; A2 = "PB4"; A3 = "PB3"
9
+
10
+ LED = "PB1"
11
+ LED_BUILTIN = "PB1"
12
+ SCK = "PB2"; MOSI = "PB0"; MISO = "PB1"
13
+ SCL = "PB2"; SDA = "PB0"
@@ -0,0 +1,40 @@
1
+ # LM35 precision temperature sensor driver (MicroPython style)
2
+ #
3
+ # API:
4
+ # sensor = LM35(ADC(Pin(14))) # A0 = Pin(14) on Arduino Uno
5
+ # sensor.read() -- raw ADC count (0-1023)
6
+ # sensor.temperature() -- degrees Celsius as float (e.g. 24.8)
7
+ #
8
+ # Conversion formula (5 V reference, 10-bit ADC):
9
+ # V_out = ADC_raw * 5000.0 / 1024 (mV)
10
+ # Temp_C = V_out / 10.0 (LM35 outputs 10 mV/C)
11
+ # => Temp_C = ADC_raw * 0.4882813
12
+ #
13
+ # Wiring (Arduino Uno / ATmega328P, 5 V supply):
14
+ # LM35 VS -> +5 V
15
+ # LM35 GND -> GND
16
+ # LM35 VOUT -> A0 (or any analog input)
17
+ #
18
+ # Note: The LM35 does not require calibration. For accurate results use
19
+ # the 5 V rail as the ADC reference (default on Arduino Uno). With a 3.3 V
20
+ # supply replace the constant 500 with 330 and 5000 with 3300.
21
+
22
+ from pymcu.types import uint16, inline
23
+ from machine import ADC as _ADC
24
+
25
+
26
+ class LM35:
27
+ @inline
28
+ def __init__(self, adc: _ADC):
29
+ # adc: machine.ADC instance (e.g. ADC(Pin(14)) for A0).
30
+ self._adc = adc
31
+
32
+ @inline
33
+ def read(self) -> uint16:
34
+ # Raw ADC count, 0-1023
35
+ return self._adc.read()
36
+
37
+ @inline
38
+ def temperature(self):
39
+ raw: uint16 = self._adc.read()
40
+ return raw * 0.4882813