Introduction
This is one of the best, beautiful, and beginner-friendly IDE available. We will also use Thonny Python to erase and flash new firmware to ESP32 with the help of esptool plugins.
Download the Thonny Python IDE:- Link
Flow The Step
- Installing Thonny Python IDE.
- Download the MicroPython firmware from:- Link
- Installing CP210x USB driver for ESP32 :- Link
See Messages on Serial Monitor
First, Connect ESP32 to your laptop via a USB cable.
Open Thonny IDE, then set the board & port as follows:
Code
1 2 3 |
>>> print('Hello World') Hello World >>> |
ESP32 With LED
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# Load the 'machine' module to access the hardware import machine # Create an 'led' object in pin 2 # and set the pin direction to output led = machine.Pin(2, machine.Pin.OUT) # This turns on or turns off the 'led' led.on() led.off() # This is the same as the above code # but now we are passing a value led.value(1) led.value(0) # This is the same as the above code # as you already know # 1 = True # 0 = False led.value(True) led.value(False) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# Load the 'machine' module to access the hardware import machine # Load the 'time' module which includes the 'sleep' class import time # Create an 'led' object in pin 2 # and set the pin direction to output led = machine.Pin(2, machine.Pin.OUT) # Create an eternal loop that blinks the LED # time.sleep(0.5) creates a 0.5 second delay # or 500 milli seconds while True: led.on() time.sleep(0.5) led.off() time.sleep(0.5) |
1 2 3 4 5 6 7 8 9 10 11 |
import machine import time led = machine.Pin(2, machine.Pin.OUT) counter = 0 while (counter < 5): led.on() time.sleep(0.5) led.off() time.sleep(0.5) counter += 1 print('Blinking LED is complete') |
1 2 3 4 5 6 7 8 |
import machine led = machine.Pin(2, machine.Pin.OUT) sw = machine.Pin(0, machine.Pin.IN) while True: if (sw.value() == 0): led.on() else: led.off() |
ESP32 With Push Button & LED
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
from machine import Pin from time import sleep print('JustDoElectronics.com') led = Pin(14, Pin.OUT) # 22 number in is Output push_button = Pin(13, Pin.IN) # 23 number pin is input while True: logic_state = push_button.value() if logic_state == True: # if pressed the push_button led.value(1) # led will turn ON else: # if push_button not pressed led.value(0) # led will turn OFF |
Traffic Light With LED
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
from machine import Pin from time import sleep g = Pin(23, Pin.OUT) y = Pin(25, Pin.OUT) r = Pin(26, Pin.OUT) traffic_state = ['SOLID_GRN', 'BLINK_GRN', 'SOLID_RED', 'SOLID_ORN'] while True: for x in traffic_state: if x == 'SOLID_GRN': g.on() sleep(6) g.off() if x == 'BLINK_GRN': for i in range(4): g.on() sleep(0.3) g.off() sleep(0.3) if x == 'SOLID_RED': r.on() sleep(7) r.off() if x == 'SOLID_ORN': y.on() sleep(1) y.off() |
ESP32 With 10k POT
Code
1 2 3 4 5 6 7 |
from machine import Pin, ADC p32 = Pin(32, Pin.IN) pot = ADC(p32) pot.atten(ADC.ATTN_11DB) print(pot.read()) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
from machine import Pin, ADC, PWM #importing Pin, ADC and PWM classes from time import sleep #importing sleep class led=PWM(Pin(14), 5000) #GPIO14 set as pin and 5000Hz as frequency potentiometer=ADC(Pin(12)) #creating potentiometer object potentiometer.width(ADC.WIDTH_12BIT) #setting ADC resolution to 10 bit potentiometer.atten(ADC.ATTEN_11DB) #3.3V full range of voltage while True: potentiometer_value=potentiometer.read() #reading analog pin print(potentiometer_value) led.duty(potentiometer_value) #setting duty cycle value as that of the potentiometer value sleep(0.1) |
ESP32 With Ultrasonic Sensor
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import machine import hcsr04 import time ultrasonic = hcsr04.HCSR04(trigger_pin=13, echo_pin=12, echo_timeout_us=1000000) led = machine.Pin(2, machine.Pin.OUT) buzzer = machine.PWM(machine.Pin(32, machine.Pin.OUT)) buzzer.freq(4186) buzzer.duty(0) while True: distance = ultrasonic.distance_cm() print('Distance:', distance, 'cm', '|', distance/2.54, 'inch') if distance <= 10: buzzer.duty(512) led.on() else: buzzer.duty(0) led.off() time.sleep_ms(1000) |
hcsr04.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
import machine, time from machine import Pin __version__ = '0.2.0' __author__ = 'Roberto Sánchez' __license__ = "Apache License 2.0. https://www.apache.org/licenses/LICENSE-2.0" class HCSR04: """ Driver to use the untrasonic sensor HC-SR04. The sensor range is between 2cm and 4m. The timeouts received listening to echo pin are converted to OSError('Out of range') """ # echo_timeout_us is based in chip range limit (400cm) def __init__(self, trigger_pin, echo_pin, echo_timeout_us=500*2*30): """ trigger_pin: Output pin to send pulses echo_pin: Readonly pin to measure the distance. The pin should be protected with 1k resistor echo_timeout_us: Timeout in microseconds to listen to echo pin. By default is based in sensor limit range (4m) """ self.echo_timeout_us = echo_timeout_us # Init trigger pin (out) self.trigger = Pin(trigger_pin, mode=Pin.OUT, pull=None) self.trigger.value(0) # Init echo pin (in) self.echo = Pin(echo_pin, mode=Pin.IN, pull=None) def _send_pulse_and_wait(self): """ Send the pulse to trigger and listen on echo pin. We use the method `machine.time_pulse_us()` to get the microseconds until the echo is received. """ self.trigger.value(0) # Stabilize the sensor time.sleep_us(5) self.trigger.value(1) # Send a 10us pulse. time.sleep_us(10) self.trigger.value(0) try: pulse_time = machine.time_pulse_us(self.echo, 1, self.echo_timeout_us) return pulse_time except OSError as ex: if ex.args[0] == 110: # 110 = ETIMEDOUT raise OSError('Out of range') raise ex def distance_mm(self): """ Get the distance in milimeters without floating point operations. """ pulse_time = self._send_pulse_and_wait() # To calculate the distance we get the pulse_time and divide it by 2 # (the pulse walk the distance twice) and by 29.1 becasue # the sound speed on air (343.2 m/s), that It's equivalent to # 0.34320 mm/us that is 1mm each 2.91us # pulse_time // 2 // 2.91 -> pulse_time // 5.82 -> pulse_time * 100 // 582 mm = pulse_time * 100 // 582 return mm def distance_cm(self): """ Get the distance in centimeters with floating point operations. It returns a float """ pulse_time = self._send_pulse_and_wait() # To calculate the distance we get the pulse_time and divide it by 2 # (the pulse walk the distance twice) and by 29.1 becasue # the sound speed on air (343.2 m/s), that It's equivalent to # 0.034320 cm/us that is 1cm each 29.1us cms = (pulse_time / 2) / 29.1 return cms |
ESP32 With DHT11 Sensor
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
from machine import Pin from time import sleep import dht sensor = dht.DHT22(Pin(14)) #sensor = dht.DHT11(Pin(14)) while True: try: sleep(2) sensor.measure() temp = sensor.temperature() hum = sensor.humidity() temp_f = temp * (9/5) + 32.0 print('Temperature: %3.1f C' %temp) print('Temperature: %3.1f F' %temp_f) print('Humidity: %3.1f %%' %hum) except OSError as e: print('Failed to read sensor.') |
ESP32 With TM1637 Matrix Display (I2C)
Code
1 2 3 4 5 |
import tm1637 from machine import Pin tm = tm1637.TM1637(clk=Pin(2), dio=Pin(4)) tm.show('10') #display the number 10 on the display |
tm1637.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
from micropython import const from machine import Pin from time import sleep_us, sleep_ms TM1637_CMD1 = const(64) # 0x40 data command TM1637_CMD2 = const(192) # 0xC0 address command TM1637_CMD3 = const(128) # 0x80 display control command TM1637_DSP_ON = const(8) # 0x08 display on TM1637_DELAY = const(10) # 10us delay between clk/dio pulses TM1637_MSB = const(128) # msb is the decimal point or the colon depending on your display # 0-9, a-z, blank, dash, star _SEGMENTS = bytearray(b'\x3F\x06\x5B\x4F\x66\x6D\x7D\x07\x7F\x6F\x77\x7C\x39\x5E\x79\x71\x3D\x76\x06\x1E\x76\x38\x55\x54\x3F\x73\x67\x50\x6D\x78\x3E\x1C\x2A\x76\x6E\x5B\x00\x40\x63') class TM1637(object): """Library for quad 7-segment LED modules based on the TM1637 LED driver.""" def __init__(self, clk, dio, brightness=7): self.clk = clk self.dio = dio if not 0 <= brightness <= 7: raise ValueError("Brightness out of range") self._brightness = brightness self.clk.init(Pin.OUT, value=0) self.dio.init(Pin.OUT, value=0) sleep_us(TM1637_DELAY) self._write_data_cmd() self._write_dsp_ctrl() def _start(self): self.dio(0) sleep_us(TM1637_DELAY) self.clk(0) sleep_us(TM1637_DELAY) def _stop(self): self.dio(0) sleep_us(TM1637_DELAY) self.clk(1) sleep_us(TM1637_DELAY) self.dio(1) def _write_data_cmd(self): # automatic address increment, normal mode self._start() self._write_byte(TM1637_CMD1) self._stop() def _write_dsp_ctrl(self): # display on, set brightness self._start() self._write_byte(TM1637_CMD3 | TM1637_DSP_ON | self._brightness) self._stop() def _write_byte(self, b): for i in range(8): self.dio((b >> i) & 1) sleep_us(TM1637_DELAY) self.clk(1) sleep_us(TM1637_DELAY) self.clk(0) sleep_us(TM1637_DELAY) self.clk(0) sleep_us(TM1637_DELAY) self.clk(1) sleep_us(TM1637_DELAY) self.clk(0) sleep_us(TM1637_DELAY) def brightness(self, val=None): """Set the display brightness 0-7.""" # brightness 0 = 1/16th pulse width # brightness 7 = 14/16th pulse width if val is None: return self._brightness if not 0 <= val <= 7: raise ValueError("Brightness out of range") self._brightness = val self._write_data_cmd() self._write_dsp_ctrl() def write(self, segments, pos=0): """Display up to 6 segments moving right from a given position. The MSB in the 2nd segment controls the colon between the 2nd and 3rd segments.""" if not 0 <= pos <= 5: raise ValueError("Position out of range") self._write_data_cmd() self._start() self._write_byte(TM1637_CMD2 | pos) for seg in segments: self._write_byte(seg) self._stop() self._write_dsp_ctrl() def encode_digit(self, digit): """Convert a character 0-9, a-f to a segment.""" return _SEGMENTS[digit & 0x0f] def encode_string(self, string): """Convert an up to 4 character length string containing 0-9, a-z, space, dash, star to an array of segments, matching the length of the source string.""" segments = bytearray(len(string)) for i in range(len(string)): segments[i] = self.encode_char(string[i]) return segments def encode_char(self, char): """Convert a character 0-9, a-z, space, dash or star to a segment.""" o = ord(char) if o == 32: return _SEGMENTS[36] # space if o == 42: return _SEGMENTS[38] # star/degrees if o == 45: return _SEGMENTS[37] # dash if o >= 65 and o <= 90: return _SEGMENTS[o-55] # uppercase A-Z if o >= 97 and o <= 122: return _SEGMENTS[o-87] # lowercase a-z if o >= 48 and o <= 57: return _SEGMENTS[o-48] # 0-9 raise ValueError("Character out of range: {:d} '{:s}'".format(o, chr(o))) def hex(self, val): """Display a hex value 0x0000 through 0xffff, right aligned.""" string = '{:04x}'.format(val & 0xffff) self.write(self.encode_string(string)) def number(self, num): """Display a numeric value -999 through 9999, right aligned.""" # limit to range -999 to 9999 num = max(-999, min(num, 9999)) string = '{0: >4d}'.format(num) self.write(self.encode_string(string)) def numbers(self, num1, num2, colon=True): """Display two numeric values -9 through 99, with leading zeros and separated by a colon.""" num1 = max(-9, min(num1, 99)) num2 = max(-9, min(num2, 99)) segments = self.encode_string('{0:0>2d}{1:0>2d}'.format(num1, num2)) if colon: segments[1] |= 0x80 # colon on self.write(segments) def temperature(self, num): if num < -9: self.show('lo') # low elif num > 99: self.show('hi') # high else: string = '{0: >2d}'.format(num) self.write(self.encode_string(string)) self.write([_SEGMENTS[38], _SEGMENTS[12]], 2) # degrees C def show(self, string, colon=False): segments = self.encode_string(string) if len(segments) > 1 and colon: segments[1] |= 128 self.write(segments[:4]) def scroll(self, string, delay=250): segments = string if isinstance(string, list) else self.encode_string(string) data = [0] * 8 data[4:0] = list(segments) for i in range(len(segments) + 5): self.write(data[0+i:4+i]) sleep_ms(delay) class TM1637Decimal(TM1637): """Library for quad 7-segment LED modules based on the TM1637 LED driver. This class is meant to be used with decimal display modules (modules that have a decimal point after each 7-segment LED). """ def encode_string(self, string): """Convert a string to LED segments. Convert an up to 4 character length string containing 0-9, a-z, space, dash, star and '.' to an array of segments, matching the length of the source string.""" segments = bytearray(len(string.replace('.',''))) j = 0 for i in range(len(string)): if string[i] == '.' and j > 0: segments[j-1] |= TM1637_MSB continue segments[j] = self.encode_char(string[i]) j += 1 return segments |
ESP32 With 16×2 LCD Display(I2C)
Code For Scan the I2C Pot Number
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import machine sdaPIN=machine.Pin(21) #for ESP32 sclPIN=machine.Pin(22) i2c=machine.I2C(sda=sdaPIN, scl=sclPIN, freq=10000) devices = i2c.scan() if len(devices) == 0: print("No i2c device !") else: print('i2c devices found:',len(devices)) for device in devices: print("At address: ",hex(device)) |
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import machine from machine import Pin, SoftI2C from lcd_api import LcdApi from i2c_lcd import I2cLcd from time import sleep I2C_ADDR = 0x27 totalRows = 2 totalColumns = 16 i2c = SoftI2C(scl=Pin(22), sda=Pin(21), freq=10000) #initializing the I2C method for ESP32 #i2c = I2C(scl=Pin(5), sda=Pin(4), freq=10000) #initializing the I2C method for ESP8266 lcd = I2cLcd(i2c, I2C_ADDR, totalRows, totalColumns) while True: lcd.putstr("I2C LCD Tutorial") sleep(2) lcd.clear() lcd.putstr("Lets Count 0-10!") sleep(2) lcd.clear() for i in range(11): lcd.putstr(str(i)) sleep(1) lcd.clear() |
lcd_api.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
"""Provides an API for talking to HD44780 compatible character LCDs.""" import time class LcdApi: """Implements the API for talking with HD44780 compatible character LCDs. This class only knows what commands to send to the LCD, and not how to get them to the LCD. It is expected that a derived class will implement the hal_xxx functions. """ # The following constant names were lifted from the avrlib lcd.h # header file, however, I changed the definitions from bit numbers # to bit masks. # # HD44780 LCD controller command set LCD_CLR = 0x01 # DB0: clear display LCD_HOME = 0x02 # DB1: return to home position LCD_ENTRY_MODE = 0x04 # DB2: set entry mode LCD_ENTRY_INC = 0x02 # --DB1: increment LCD_ENTRY_SHIFT = 0x01 # --DB0: shift LCD_ON_CTRL = 0x08 # DB3: turn lcd/cursor on LCD_ON_DISPLAY = 0x04 # --DB2: turn display on LCD_ON_CURSOR = 0x02 # --DB1: turn cursor on LCD_ON_BLINK = 0x01 # --DB0: blinking cursor LCD_MOVE = 0x10 # DB4: move cursor/display LCD_MOVE_DISP = 0x08 # --DB3: move display (0-> move cursor) LCD_MOVE_RIGHT = 0x04 # --DB2: move right (0-> left) LCD_FUNCTION = 0x20 # DB5: function set LCD_FUNCTION_8BIT = 0x10 # --DB4: set 8BIT mode (0->4BIT mode) LCD_FUNCTION_2LINES = 0x08 # --DB3: two lines (0->one line) LCD_FUNCTION_10DOTS = 0x04 # --DB2: 5x10 font (0->5x7 font) LCD_FUNCTION_RESET = 0x30 # See "Initializing by Instruction" section LCD_CGRAM = 0x40 # DB6: set CG RAM address LCD_DDRAM = 0x80 # DB7: set DD RAM address LCD_RS_CMD = 0 LCD_RS_DATA = 1 LCD_RW_WRITE = 0 LCD_RW_READ = 1 def __init__(self, num_lines, num_columns): self.num_lines = num_lines if self.num_lines > 4: self.num_lines = 4 self.num_columns = num_columns if self.num_columns > 40: self.num_columns = 40 self.cursor_x = 0 self.cursor_y = 0 self.implied_newline = False self.backlight = True self.display_off() self.backlight_on() self.clear() self.hal_write_command(self.LCD_ENTRY_MODE | self.LCD_ENTRY_INC) self.hide_cursor() self.display_on() def clear(self): """Clears the LCD display and moves the cursor to the top left corner. """ self.hal_write_command(self.LCD_CLR) self.hal_write_command(self.LCD_HOME) self.cursor_x = 0 self.cursor_y = 0 def show_cursor(self): """Causes the cursor to be made visible.""" self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY | self.LCD_ON_CURSOR) def hide_cursor(self): """Causes the cursor to be hidden.""" self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY) def blink_cursor_on(self): """Turns on the cursor, and makes it blink.""" self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY | self.LCD_ON_CURSOR | self.LCD_ON_BLINK) def blink_cursor_off(self): """Turns on the cursor, and makes it no blink (i.e. be solid).""" self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY | self.LCD_ON_CURSOR) def display_on(self): """Turns on (i.e. unblanks) the LCD.""" self.hal_write_command(self.LCD_ON_CTRL | self.LCD_ON_DISPLAY) def display_off(self): """Turns off (i.e. blanks) the LCD.""" self.hal_write_command(self.LCD_ON_CTRL) def backlight_on(self): """Turns the backlight on. This isn't really an LCD command, but some modules have backlight controls, so this allows the hal to pass through the command. """ self.backlight = True self.hal_backlight_on() def backlight_off(self): """Turns the backlight off. This isn't really an LCD command, but some modules have backlight controls, so this allows the hal to pass through the command. """ self.backlight = False self.hal_backlight_off() def move_to(self, cursor_x, cursor_y): """Moves the cursor position to the indicated position. The cursor position is zero based (i.e. cursor_x == 0 indicates first column). """ self.cursor_x = cursor_x self.cursor_y = cursor_y addr = cursor_x & 0x3f if cursor_y & 1: addr += 0x40 # Lines 1 & 3 add 0x40 if cursor_y & 2: # Lines 2 & 3 add number of columns addr += self.num_columns self.hal_write_command(self.LCD_DDRAM | addr) def putchar(self, char): """Writes the indicated character to the LCD at the current cursor position, and advances the cursor by one position. """ if char == '\n': if self.implied_newline: # self.implied_newline means we advanced due to a wraparound, # so if we get a newline right after that we ignore it. pass else: self.cursor_x = self.num_columns else: self.hal_write_data(ord(char)) self.cursor_x += 1 if self.cursor_x >= self.num_columns: self.cursor_x = 0 self.cursor_y += 1 self.implied_newline = (char != '\n') if self.cursor_y >= self.num_lines: self.cursor_y = 0 self.move_to(self.cursor_x, self.cursor_y) def putstr(self, string): """Write the indicated string to the LCD at the current cursor position and advances the cursor position appropriately. """ for char in string: self.putchar(char) def custom_char(self, location, charmap): """Write a character to one of the 8 CGRAM locations, available as chr(0) through chr(7). """ location &= 0x7 self.hal_write_command(self.LCD_CGRAM | (location << 3)) self.hal_sleep_us(40) for i in range(8): self.hal_write_data(charmap[i]) self.hal_sleep_us(40) self.move_to(self.cursor_x, self.cursor_y) def hal_backlight_on(self): """Allows the hal layer to turn the backlight on. If desired, a derived HAL class will implement this function. """ pass def hal_backlight_off(self): """Allows the hal layer to turn the backlight off. If desired, a derived HAL class will implement this function. """ pass def hal_write_command(self, cmd): """Write a command to the LCD. It is expected that a derived HAL class will implement this function. """ raise NotImplementedError def hal_write_data(self, data): """Write data to the LCD. It is expected that a derived HAL class will implement this function. """ raise NotImplementedError def hal_sleep_us(self, usecs): """Sleep for some time (given in microseconds).""" time.sleep_us(usecs) |
i2c_lcd.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
import utime import gc from lcd_api import LcdApi from machine import I2C # PCF8574 pin definitions MASK_RS = 0x01 # P0 MASK_RW = 0x02 # P1 MASK_E = 0x04 # P2 SHIFT_BACKLIGHT = 3 # P3 SHIFT_DATA = 4 # P4-P7 class I2cLcd(LcdApi): #Implements a HD44780 character LCD connected via PCF8574 on I2C def __init__(self, i2c, i2c_addr, num_lines, num_columns): self.i2c = i2c self.i2c_addr = i2c_addr self.i2c.writeto(self.i2c_addr, bytes([0])) utime.sleep_ms(20) # Allow LCD time to powerup # Send reset 3 times self.hal_write_init_nibble(self.LCD_FUNCTION_RESET) utime.sleep_ms(5) # Need to delay at least 4.1 msec self.hal_write_init_nibble(self.LCD_FUNCTION_RESET) utime.sleep_ms(1) self.hal_write_init_nibble(self.LCD_FUNCTION_RESET) utime.sleep_ms(1) # Put LCD into 4-bit mode self.hal_write_init_nibble(self.LCD_FUNCTION) utime.sleep_ms(1) LcdApi.__init__(self, num_lines, num_columns) cmd = self.LCD_FUNCTION if num_lines > 1: cmd |= self.LCD_FUNCTION_2LINES self.hal_write_command(cmd) gc.collect() def hal_write_init_nibble(self, nibble): # Writes an initialization nibble to the LCD. # This particular function is only used during initialization. byte = ((nibble >> 4) & 0x0f) << SHIFT_DATA self.i2c.writeto(self.i2c_addr, bytes([byte | MASK_E])) self.i2c.writeto(self.i2c_addr, bytes([byte])) gc.collect() def hal_backlight_on(self): # Allows the hal layer to turn the backlight on self.i2c.writeto(self.i2c_addr, bytes([1 << SHIFT_BACKLIGHT])) gc.collect() def hal_backlight_off(self): #Allows the hal layer to turn the backlight off self.i2c.writeto(self.i2c_addr, bytes([0])) gc.collect() def hal_write_command(self, cmd): # Write a command to the LCD. Data is latched on the falling edge of E. byte = ((self.backlight << SHIFT_BACKLIGHT) | (((cmd >> 4) & 0x0f) << SHIFT_DATA)) self.i2c.writeto(self.i2c_addr, bytes([byte | MASK_E])) self.i2c.writeto(self.i2c_addr, bytes([byte])) byte = ((self.backlight << SHIFT_BACKLIGHT) | ((cmd & 0x0f) << SHIFT_DATA)) self.i2c.writeto(self.i2c_addr, bytes([byte | MASK_E])) self.i2c.writeto(self.i2c_addr, bytes([byte])) if cmd <= 3: # The home and clear commands require a worst case delay of 4.1 msec utime.sleep_ms(5) gc.collect() def hal_write_data(self, data): # Write data to the LCD. Data is latched on the falling edge of E. byte = (MASK_RS | (self.backlight << SHIFT_BACKLIGHT) | (((data >> 4) & 0x0f) << SHIFT_DATA)) self.i2c.writeto(self.i2c_addr, bytes([byte | MASK_E])) self.i2c.writeto(self.i2c_addr, bytes([byte])) byte = (MASK_RS | (self.backlight << SHIFT_BACKLIGHT) | ((data & 0x0f) << SHIFT_DATA)) self.i2c.writeto(self.i2c_addr, bytes([byte | MASK_E])) self.i2c.writeto(self.i2c_addr, bytes([byte])) gc.collect() |
DHT11 Sensor With 16×2 LCD Display
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
from machine import Pin, SoftI2C from i2c_lcd import I2cLcd import time import dht # LCD i2c = SoftI2C(scl=Pin(22), sda=Pin(21),freq=100000) lcd = I2cLcd(i2c, 0x27,2,16) time.sleep(1) lcd.clear() # DHT11 d = dht.DHT11(Pin(23)) t = 0 h = 0 # START text = 'Starting...' lcd.putstr(text) while True: try: d.measure() time.sleep(2) t = d.temperature() h = d.humidity() temp = 'Temp: {:.0f} C'.format(t) humid = 'Humidity: {:.0f} %'.format(h) print('DHT11:', t, h) lcd.clear() lcd.putstr(temp) lcd.move_to(0,1) lcd.putstr(humid) time.sleep(5) except: pass |
RC-522 RFID With 16×2 LCD Display
mfrc522.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 |
# https://github.com/cefn/micropython-mfrc522/blob/master/mfrc522.py from machine import Pin, SPI from os import uname emptyRecv = b"" class MFRC522: GAIN_REG = 0x26 MAX_GAIN = 0x07 OK = 0 NOTAGERR = 1 ERR = 2 REQIDL = 0x26 REQALL = 0x52 AUTHENT1A = 0x60 AUTHENT1B = 0x61 def __init__(self, spi=None, gpioRst=None, gpioCs=None): if gpioRst is not None: self.rst = Pin(gpioRst, Pin.OUT) else: self.rst = None assert(gpioCs is not None, "Needs gpioCs") # TODO fails without cableSelect if gpioCs is not None: self.cs = Pin(gpioCs, Pin.OUT) else: self.cs = None # TODO CH rationalise which of these are referenced, which can be identical self.regBuf = bytearray(4) self.blockWriteBuf = bytearray(18) self.authBuf = bytearray(12) self.wregBuf = bytearray(2) self.rregBuf = bytearray(1) self.recvBuf = bytearray(16) self.recvMv = memoryview(self.recvBuf) if self.rst is not None: self.rst.value(0) if self.cs is not None: self.cs.value(1) if spi is not None: self.spi = spi else: sck = Pin(14, Pin.OUT) mosi = Pin(13, Pin.OUT) miso = Pin(12, Pin.IN) if uname()[0] == 'WiPy': self.spi = SPI(0) self.spi.init(SPI.MASTER, baudrate=1000000, pins=(sck, mosi, miso)) elif uname()[0] == 'esp8266': # TODO update to match https://github.com/cefn/avatap/blob/master/python/host/cockle.py #prepareHost() self.spi = SPI(baudrate=100000, polarity=0, phase=0, sck=sck, mosi=mosi, miso=miso) self.spi.init() else: raise RuntimeError("Unsupported platform") if self.rst is not None: self.rst.value(1) self.init() def _wreg(self, reg, val): if self.cs is not None: self.cs.value(0) buf = self.wregBuf buf[0]=0xff & ((reg << 1) & 0x7e) buf[1]=0xff & val self.spi.write(buf) if self.cs is not None: self.cs.value(1) def _rreg(self, reg): if self.cs is not None: self.cs.value(0) buf = self.rregBuf buf[0]=0xff & (((reg << 1) & 0x7e) | 0x80) self.spi.write(buf) val = self.spi.read(1) if self.cs is not None: self.cs.value(1) return val[0] def _sflags(self, reg, mask): self._wreg(reg, self._rreg(reg) | mask) def _cflags(self, reg, mask): self._wreg(reg, self._rreg(reg) & (~mask)) def _tocard(self, cmd, send, into=None): recv = emptyRecv bits = irq_en = wait_irq = n = 0 stat = self.ERR if cmd == 0x0E: irq_en = 0x12 wait_irq = 0x10 elif cmd == 0x0C: irq_en = 0x77 wait_irq = 0x30 self._wreg(0x02, irq_en | 0x80) self._cflags(0x04, 0x80) self._sflags(0x0A, 0x80) self._wreg(0x01, 0x00) for c in send: self._wreg(0x09, c) self._wreg(0x01, cmd) if cmd == 0x0C: self._sflags(0x0D, 0x80) i = 2000 while True: n = self._rreg(0x04) i -= 1 if ~((i != 0) and ~(n & 0x01) and ~(n & wait_irq)): break self._cflags(0x0D, 0x80) if i: if (self._rreg(0x06) & 0x1B) == 0x00: stat = self.OK if n & irq_en & 0x01: stat = self.NOTAGERR elif cmd == 0x0C: n = self._rreg(0x0A) lbits = self._rreg(0x0C) & 0x07 if lbits != 0: bits = (n - 1) * 8 + lbits else: bits = n * 8 if n == 0: n = 1 elif n > 16: n = 16 if into is None: recv = self.recvBuf else: recv = into pos = 0 while pos < n: recv[pos] = self._rreg(0x09) pos += 1 if into is None: recv = self.recvMv[:n] else: recv = into else: stat = self.ERR return stat, recv, bits def _assign_crc(self, data, count): self._cflags(0x05, 0x04) self._sflags(0x0A, 0x80) dataPos = 0 while dataPos < count: self._wreg(0x09, data[dataPos]) dataPos += 1 self._wreg(0x01, 0x03) i = 0xFF while True: n = self._rreg(0x05) i -= 1 if not ((i != 0) and not (n & 0x04)): break data[count] = self._rreg(0x22) data[count + 1] = self._rreg(0x21) def init(self): self.reset() self._wreg(0x2A, 0x8D) self._wreg(0x2B, 0x3E) self._wreg(0x2D, 30) self._wreg(0x2C, 0) self._wreg(0x15, 0x40) self._wreg(0x11, 0x3D) self.set_gain(self.MAX_GAIN) self.antenna_on() def reset(self): self._wreg(0x01, 0x0F) def antenna_on(self, on=True): if on and ~(self._rreg(0x14) & 0x03): self._sflags(0x14, 0x03) else: self._cflags(0x14, 0x03) def request(self, mode): self._wreg(0x0D, 0x07) (stat, recv, bits) = self._tocard(0x0C, [mode]) if (stat != self.OK) | (bits != 0x10): stat = self.ERR return stat, bits def anticoll(self): ser_chk = 0 ser = [0x93, 0x20] self._wreg(0x0D, 0x00) (stat, recv, bits) = self._tocard(0x0C, ser) if stat == self.OK: if len(recv) == 5: for i in range(4): ser_chk = ser_chk ^ recv[i] if ser_chk != recv[4]: stat = self.ERR else: stat = self.ERR # CH Note bytearray allocation here return stat, bytearray(recv) def select_tag(self, ser): # TODO CH normalise all list manipulation to bytearray, avoid below allocation buf = bytearray(9) buf[0] = 0x93 buf[1] = 0x70 buf[2:7] = ser self._assign_crc(buf, 7) (stat, recv, bits) = self._tocard(0x0C, buf) return self.OK if (stat == self.OK) and (bits == 0x18) else self.ERR def auth(self, mode, addr, sect, ser): # TODO CH void ser[:4] implicit list allocation buf = self.authBuf buf[0]=mode # A or B buf[1]=addr # block buf[2:8]=sect # key bytes buf[8:12]=ser[:4] # 4 bytes of id return self._tocard(0x0E, buf)[0] # TODO this may well need to be implemented for vault to properly back out from a card session # TODO how, why, when is 'HaltA' needed? see https://github.com/cefn/micropython-mfrc522/issues/1 def halt_a(self): pass def stop_crypto1(self): self._cflags(0x08, 0x08) def set_gain(self, gain): assert gain <= self.MAX_GAIN # clear bits self._cflags(self.GAIN_REG, 0x07<< 4) # set bits according to gain self._sflags(self.GAIN_REG, gain << 4) def read(self, addr, into = None): buf = self.regBuf buf[0]=0x30 buf[1]=addr self._assign_crc(buf, 2) (stat, recv, _) = self._tocard(0x0C, buf, into=into) # TODO this logic probably wrong (should be 'into is None'?) if into is None: # superstitiously avoid returning read buffer memoryview # CH Note bytearray allocation here recv = bytearray(recv) return recv if stat == self.OK else None def write(self, addr, data): buf = self.regBuf buf[0] = 0xA0 buf[1] = addr self._assign_crc(buf, 2) (stat, recv, bits) = self._tocard(0x0C, buf) if not (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A): stat = self.ERR else: buf = self.blockWriteBuf i = 0 while i < 16: buf[i] = data[i] # TODO CH eliminate this, accelerate it? i += 1 self._assign_crc(buf, 16) (stat, recv, bits) = self._tocard(0x0C, buf) if not (stat == self.OK) or not (bits == 4) or not ((recv[0] & 0x0F) == 0x0A): stat = self.ERR return stat |
Find the RFID Tag Number
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
from mfrc522 import MFRC522 from machine import Pin from machine import SPI spi = SPI(2, baudrate=2500000, polarity=0, phase=0) # Using Hardware SPI pins: # sck=18 # mosi=23 # miso=19 # rst=4 # cs=5 # ************************* # To use SoftSPI, # from machine import SOftSPI # spi = SoftSPI(baudrate=100000, polarity=0, phase=0, sck=sck, mosi=mosi, miso=miso) spi.init() rdr = MFRC522(spi=spi, gpioRst=4, gpioCs=5) print("Place card") while True: (stat, tag_type) = rdr.request(rdr.REQIDL) if stat == rdr.OK: (stat, raw_uid) = rdr.anticoll() if stat == rdr.OK: card_id = "uid: 0x%02x%02x%02x%02x" % (raw_uid[0], raw_uid[1], raw_uid[2], raw_uid[3]) print(card_id) |
RFID-Based Door Lock
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
from mfrc522 import MFRC522 from i2c_lcd import I2cLcd from machine import Pin from machine import SoftI2C from machine import SPI DEFAULT_I2C_ADDR = 0x20 i2c = SoftI2C(scl=Pin(22, Pin.OUT, Pin.PULL_UP), sda=Pin(21, Pin.OUT, Pin.PULL_UP), freq=400000) lcd = I2cLcd(i2c, DEFAULT_I2C_ADDR, 2, 16) red = Pin(14, Pin.OUT) grn = Pin(13, Pin.OUT) spi = SPI(2, baudrate=2500000, polarity=0, phase=0) spi.init() rdr = MFRC522(spi=spi, gpioRst=4, gpioCs=5) print("Place card") lcd.clear() lcd.move_to(0, 0) lcd.putstr("Scan RFID") while True: (stat, tag_type) = rdr.request(rdr.REQIDL) if stat == rdr.OK: (stat, raw_uid) = rdr.anticoll() if stat == rdr.OK: lcd.clear() lcd.move_to(0, 0) lcd.putstr("RFID: ") card_id = "0x%02x%02x%02x%02x" %(raw_uid[0], raw_uid[1], raw_uid[2], raw_uid[3]) print("UID:", card_id) lcd.move_to(0, 1) if card_id == "0x57c07f5a": grn.value(True) red.value(False) lcd.putstr(" Access Granted ") else: grn.value(False) red.value(True) lcd.putstr(" Access Denied! ") |
RFID Attendance System
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
from mfrc522 import MFRC522 from i2c_lcd import I2cLcd from machine import Pin from machine import SoftI2C from machine import SPI DEFAULT_I2C_ADDR = 0x20 i2c = SoftI2C(scl=Pin(22, Pin.OUT, Pin.PULL_UP), sda=Pin(21, Pin.OUT, Pin.PULL_UP), freq=400000) lcd = I2cLcd(i2c, DEFAULT_I2C_ADDR, 2, 16) red = Pin(14, Pin.OUT) grn = Pin(13, Pin.OUT) spi = SPI(2, baudrate=2500000, polarity=0, phase=0) spi.init() rdr = MFRC522(spi=spi, gpioRst=4, gpioCs=5) rfid_name = ["Teacher1", "Teacher2", "Student1", "Student2", "Student3"] rfid_uid = ["0xc97be5a2", "0xe7458e7a", "0x2907b498", "0x29eec498", "0x59e1f097"] def get_username(uid): index = 0 try: index = rfid_uid.index(uid) return rfid_name[index] except: index = -1 print("RFID is not recognized") return 0 print("Place card") lcd.clear() lcd.move_to(0, 0) lcd.putstr("Scan RFID") while True: (stat, tag_type) = rdr.request(rdr.REQIDL) if stat == rdr.OK: (stat, raw_uid) = rdr.anticoll() if stat == rdr.OK: lcd.clear() lcd.move_to(0, 0) lcd.putstr("RFID: ") card_id = "0x%02x%02x%02x%02x" %(raw_uid[0], raw_uid[1], raw_uid[2], raw_uid[3]) print("UID:", card_id) lcd.putstr(card_id) username = get_username(card_id) lcd.move_to(0, 1) if username != 0: grn.value(True) red.value(False) lcd.putstr("Welcome {}".format(username)) else: grn.value(False) red.value(True) lcd.putstr(" Access Denied! ") |