NodeMCU Projects: Difference between revisions

 
(41 intermediate revisions by the same user not shown)
Line 3:
<br/>
 
= Micropython =
 
= Small Projects =
== Basics ==
 
== LED ON/OFF ==
*Installing:
sudo pip install esptool
esptool.py --port /dev/ttyUSB0 erase_flash
esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=detect 0 ~/Desktop/esp8266-20171101-v1.9.3.bin
 
<syntaxhighlight lang="python">
*Connecting via Terminal:
from machine import Pin
sudo apt install picocom
picocom /dev/ttyUSB0 -b115200
 
led = Pin(2, Pin.OUT)
*Connecting via REPL(web):
import webrepl_setup
 
led.value()
If you disabled automatic start-up on boot, you may run configured daemon on demand using:
led.value(1)
import webrepl
led.value(0)
webrepl.start()
</syntaxhighlight>
 
== Toggle GPIO ==
*Checking filesystem:
import os
os.listdir()
 
<syntaxhighlight lang="python">
*Create directories:
import machine
os.mkdir('dir')
import time
import urandom
 
pin = machine.Pin(2, machine.Pin.OUT)
*Remove Files:
os.remove('data.txt')
 
def toggle(p):
*Writing Data to files:
p.value(not p.value())
f = open('data.txt', 'w')
f.write('some data')
f.close()
 
while True:
*Reading data:
time.sleep_ms(urandom.getrandbits(8))
f = open('data.txt')
toggle(pin)
f.read()
</syntaxhighlight>
f.close()
 
* Checking Machine Frequency & Overclocking:
import machine
machine.freq() # get the current frequency of the CPU
machine.freq(160000000) # set the CPU frequency to 160 MHz
 
== Fading an LED ==
<syntaxhighlight lang="python">
import time, math
import machine
 
led = machine.PWM(machine.Pin(2), freq=1000)
*Check AP Name:
import network;
ap = network.WLAN(network.AP_IF);
print(ap.config('essid'));
 
def pulse(l, t):
*Change AP name and password:
for i in range(20):
import network;
l.duty(int(math.sin(i / 10 * math.pi) * 500 + 500))
ap = network.WLAN(network.AP_IF);
time.sleep_ms(t)
ap.active(True);
ap.config(essid='MyESP8266', authmode=network.AUTH_WPA_WPA2_PSK, password='mypassword');
print(ap.config('essid'));
 
while True:
== Projects ==
pulse(led, 20)
</syntaxhighlight>
 
 
*Playing with GPIO:
== Control a hobby servo ==
#Hobby servo motors can be controlled using PWM.
#They require a frequency of 50Hz and a duty between about 40 and 115, with 77 being the center value.
 
*Manual Movements
<syntaxhighlight lang="python">
servo = machine.PWM(machine.Pin(12), freq=50)
servo.duty(40)
servo.duty(115)
servo.duty(77)
</syntaxhighlight>
 
*Random movements:
<syntaxhighlight lang="python">
servo = machine.PWM(machine.Pin(12), freq=50)
while True:
servo.duty(urandom.getrandbits(8))
time.sleep(1)
</syntaxhighlight>
 
== One Wire DS18B20 Temp Sensor ==
<syntaxhighlight lang="python">
import time
import machine
import onewire, ds18x20
 
# the device is on GPIO12
dat = machine.Pin(12)
 
# create the onewire object
ds = ds18x20.DS18X20(onewire.OneWire(dat))
 
# scan for devices on the bus
roms = ds.scan()
print('found devices:', roms)
 
# loop 10 times and print all temperatures
for i in range(10):
print('temperatures:', end=' ')
ds.convert_temp()
time.sleep_ms(750) # delay should be atleast 750ms between 2 readings
for rom in roms:
print(ds.read_temp(rom), end=' ')
print()
</syntaxhighlight>
 
== LM35 Temp Sensor ==
 
{{UC}}
 
== DHT11 Temp Sensor ==
 
Source: [https://github.com/lvidarte/esp8266/wiki/MicroPython:-DHT11 github.com]
 
*Use DHT11 Module driectly, Do not use Sensor board with Pull Up resistor.
*Testing Sensor:
 
<syntaxhighlight lang="python">
>>> from machine import Pin
>>> from dht import DHT11
>>> d = DHT11(Pin(14)) # Pin D5
>>> d.measure()
>>> d.temperature()
28
>>> d.humidity()
16
</syntaxhighlight>
 
*Printing Temperature to I2C LCD
 
<syntaxhighlight lang="python">
import time
from machine import I2C, Pin
from dht import DHT11
from esp8266_i2c_lcd import I2cLcd
 
time.sleep(1)
 
d = DHT11(Pin(14)) # Pin D5
 
i2c = I2C(scl=Pin(5), sda=Pin(4), freq=400000) # Pin D1 & D2
lcd = I2cLcd(i2c, 63, 2, 16)
 
while True:
try:
d.measure()
print("temp: ", d.temperature(), "humidity: ", d.humidity())
lcd.putstr("Temperature: " + str(d.temperature()) + "C")
lcd.putstr("Humidity: " + str(d.humidity()) + "%")
time.sleep(10)
lcd.clear()
except OSError:
print("Sensor read error!!")
lcd.putstr("Sensor read error!!")
time.sleep(5)
lcd.clear()
</syntaxhighlight>
 
== Deep-sleep mode ==
 
*This shut down the ESP8266 and all its peripherals & also WiFi.
*But not including the real-time-clock, which is used to wake the chip.
*This drastically reduces current consumption and is a good way to make devices that can run for a while on a battery.
*You Must connect GPIO16 to the reset pin.
 
<syntaxhighlight lang="python">
import machine
 
# configure RTC.ALARM0 to be able to wake the device
rtc = machine.RTC()
rtc.irq(trigger=rtc.ALARM0, wake=machine.DEEPSLEEP)
 
# check if the device woke from a deep sleep
if machine.reset_cause() == machine.DEEPSLEEP_RESET:
print('woke from a deep sleep')
 
# set RTC.ALARM0 to fire after 10 seconds (waking the device)
rtc.alarm(rtc.ALARM0, 10000)
 
# put the device to sleep
machine.deepsleep()
</syntaxhighlight>
 
= Analog Temperature Meter =
 
Requirements:
DS18B20 Temperature sensor
Servo Motor
Micropython based NodeMCU
 
Wiring details:
Servo motor = D4 => GPIO 2
DS18B20 = D7 => GPIO 13
 
<syntaxhighlight lang="python">
import time
import machine
import onewire, ds18x20
 
# the device is on GPIO13
dat = machine.Pin(13)
 
# create the onewire object
ds = ds18x20.DS18X20(onewire.OneWire(dat))
 
# scan for devices on the bus
roms = ds.scan()
print('found devices:', roms)
 
# servo is connected to GPIO2
servo = machine.PWM(machine.Pin(2), freq=50)
 
# Function for mapping range
def translate(value, leftMin, leftMax, rightMin, rightMax):
# Figure out how 'wide' each range is
leftSpan = leftMax - leftMin
rightSpan = rightMax - rightMin
 
# Convert the left range into a 0-1 range (float)
valueScaled = float(value - leftMin) / float(leftSpan)
 
# Convert the 0-1 range into a value in the right range.
return rightMin + (valueScaled * rightSpan)
# print all temperatures
while True:
ds.convert_temp()
time.sleep_ms(1000)
for rom in roms:
print(ds.read_temp(rom))
temp = ds.read_temp(rom)
srv = translate(temp, 20, 35, 115, 40)
print(int(srv))
if (temp>=20) & (temp<=35):
servo.duty(int(srv))
else:
print("Out of Range")
</syntaxhighlight>
 
= NeoPixel =
 
<syntaxhighlight lang="python">
import machine
import neopixel
import time
import urandom
 
pin = machine.Pin(214, machine.Pin.OUT) # WS2812 data pin connected to GPIO 14 or Pin D5
np = neopixel.NeoPixel(pin, 16) #16 Pixels or LEDs in strip
 
def togglerand(p):
return urandom.getrandbits(7)
p.value(not p.value())
 
def cycle():
for i in range(16):
np[i] = (128,0,0)
np.write()
time.sleep_ms(25)
 
for i in range(16):
np[i] = (0,128,0)
np.write()
time.sleep_ms(25)
 
for i in range(16):
np[i] = (0,0,128)
np.write()
time.sleep_ms(25)
 
def circle():
for j in range(10):
x,y,z = rand(),rand(),rand()
for i in range(16):
np[i] = (x,y,z)
np.write()
time.sleep_ms(25)
 
def circle_rainbow():
for j in range(10):
for i in range(16):
np[i] = (rand(),rand(),rand())
np.write()
time.sleep_ms(25)
 
def fade():
for i in range(0, 4 * 256, 8):
for j in range(16):
if (i // 256) % 2 == 0:
val = i & 0xff
else:
val = 255 - (i & 0xff)
np[j] = (val, 0, 0)
np.write()
 
for i in range(0, 4 * 256, 8):
for j in range(16):
if (i // 256) % 2 == 0:
val = i & 0xff
else:
val = 255 - (i & 0xff)
np[j] = (0, val, 0)
np.write()
 
for i in range(0, 4 * 256, 8):
for j in range(16):
if (i // 256) % 2 == 0:
val = i & 0xff
else:
val = 255 - (i & 0xff)
np[j] = (0, 0, val)
np.write()
 
def clock():
for k in range(10):
for i in range(16):
if i%2 == 0:
np[i] = (64,0,10)
np.write()
else:
np[i] = (10,64,0)
np.write()
time.sleep_ms(200)
 
for j in range(16):
if j%2 == 0:
np[j] = (10,64,0)
np.write()
else:
np[j] = (64,10,0)
np.write()
time.sleep_ms(200)
 
def bounce():
for i in range(3):
x,y,z = rand(),rand(),rand()
for i in range(4 * 16):
for j in range(16):
np[j] = (x,y,z)
if (i // 16) % 2 == 0:
np[i % 16] = (0, 0, 0)
else:
np[16 - 1 - (i % 16)] = (0, 0, 0)
np.write()
time.sleep_ms(60)
 
def off():
for i in range(16):
np[i] = (0,0,0)
np.write()
 
cycle()
off()
time.sleep(1)
 
circle()
off()
time.sleep(1)
 
circle_rainbow()
off()
time.sleep(1)
 
fade()
off()
time.sleep(1)
 
clock()
off()
time.sleep(1)
 
bounce()
off()
</syntaxhighlight>
 
= Morse Code =
 
<syntaxhighlight lang="python">
import machine
import sys
import time
 
CODE = {'A': '.-', 'B': '-...', 'C': '-.-.',
'D': '-..', 'E': '.', 'F': '..-.',
'G': '--.', 'H': '....', 'I': '..',
'J': '.---', 'K': '-.-', 'L': '.-..',
'M': '--', 'N': '-.', 'O': '---',
'P': '.--.', 'Q': '--.-', 'R': '.-.',
'S': '...', 'T': '-', 'U': '..-',
'V': '...-', 'W': '.--', 'X': '-..-',
'Y': '-.--', 'Z': '--..', ' ': ' ',
'0': '-----', '1': '.----', '2': '..---',
'3': '...--', '4': '....-', '5': '.....',
'6': '-....', '7': '--...', '8': '---..',
'9': '----.'
}
 
pin = machine.Pin(14, machine.Pin.OUT) # Laser Module connected to GPIO 14 or Pin D5
pin.off()
a = 300
 
def morse(x):
c = []
for i in x:
c.append(CODE[i.upper()])
c.append(" ")
 
for i in range(len(c)):
for j in c[i]:
if j == ".":
pin.on()
print("DOT")
time.sleep_ms(a)
pin.off()
time.sleep_ms(a*2)
elif j == "-":
pin.on()
print("DASH")
time.sleep_ms(a*3)
pin.off()
time.sleep_ms(a*2)
elif j == " ":
pin.off()
print(" ")
time.sleep_ms(a*4)
else:
print("ERROR")
pin.off()
print("END")
 
morse("amandeep")
</syntaxhighlight>
 
= I2C LCD =
 
Source: [https://forum.micropython.org/viewtopic.php?f=16&t=2858 forum.micropython.org] & [https://forum.micropython.org/viewtopic.php?f=16&t=2858&start=30 forum.micropython.org]
 
*Download the below library files from below link & upload them to NodeMCU:
https://github.com/dhylands/python_lcd/tree/master/lcd
- esp8266_i2c_lcd.py
- lcd_api.py
 
*Connect the NodeMCU to I2C LCD-1602 as below:
D1 SCL ------------ SCL
D2 SDA ------------ SDA
GND --------------- GND
5V ---------------- VCC
 
 
*There are many versions of this device - the difference is the controller IC.
*If you have the PCF8574T. the default I2C bus address is 0x27.
*If you have the PCF8574AT the default I2C bus address is 0x3F(63).
*Defining Address:
lcd=I2cLcd(i2c, 0x27, 2, 16)
lcd=I2cLcd(i2c, 39, 2, 16)
 
*An i2c.scan() should reveal which address to use:
 
<syntaxhighlight lang="python">
>>> from machine import I2C
>>> i2c = I2C(scl=Pin(5), sda=Pin(4), freq=400000)
>>> print(i2c.scan())
[63]
>>> lcd=I2cLcd(i2c, 63, 2, 16)
</syntaxhighlight>
 
*Print the output on the LCD:
 
<syntaxhighlight lang="python">
import time
from machine import I2C, Pin
from esp8266_i2c_lcd import I2cLcd
 
i2c = I2C(scl=Pin(5), sda=Pin(4), freq=400000)
 
lcd = I2cLcd(i2c, 63, 2, 16)
while True:
lcd.putstr("Hello Tester..\nIt's working!")
time.sleep_ms(urandom.getrandbits(8))
toggletime.sleep(pin2)
lcd.clear()
lcd.putstr("Test 2\nMicropython_lcd")
time.sleep(2)
lcd.clear()
</syntaxhighlight>
 
= MAX7219 based 8x8 LED Matrix =
 
Source: [https://github.com/vrialland/micropython-max7219 github.com]
 
*Download below Library and upload it to NodeMCU:
https://github.com/vrialland/micropython-max7219/blob/master/max7219.py
 
*Connections:
 
ESP8266 MAX7219
5V VCC
GND GND
D7 (GPIO13) DIN
D8 (GPIO15) CS
D5 (GPIO14) CLK
 
* Static Testing:
<syntaxhighlight lang="python">
from machine import Pin, SPI
import max7219
 
spi = SPI(1, baudrate=10000000)
screen = max7219.Max7219(32, 8, spi, Pin(15))
screen.text('ABCD', 0, 0, 1) #
screen.show()
</syntaxhighlight>
 
* Command explaination
screen.text("ABCD",x,y,z)
 
ABCD = Text to be displayed
x = Horizontal Position
y = Vertical Position
 
* Scroll Text:
<syntaxhighlight lang="python">
def disp(txt,n,t):
for i in range(-n,n):
screen.text(txt,-i,0,1)
screen.show()
time.sleep(t)
screen.init_display()
</syntaxhighlight>
 
 
== Auto Marque Library ==
 
Source: [https://github.com/jgbrown32/ESP8266_MAX7219 github.com]
 
*Download below Library and upload it to NodeMCU:
https://github.com/jgbrown32/ESP8266_MAX7219/blob/master/max7219.py
 
<syntaxhighlight lang="python">
from machine import Pin, SPI
import max7219, utime
 
spi = SPI(1, 10000000)
d = max7219.Max7219(32, 8, spi, Pin(15), False)
d.text("Aman", 0, 0)
d.show()
utime.sleep(5)
 
while True:
d.marquee("This code is working fine now...")
</syntaxhighlight>
 
* Flash all the LEDs
<syntaxhighlight lang="python">
def flash(x,y,z):
for i in range(x):
d.fill(1)
d.show()
time.sleep(y)
d.fill(0)
d.show()
time.sleep(z)
 
flash(3,0.2,0.2)
</syntaxhighlight>
 
== Display Info using Urequests ==
 
<syntaxhighlight lang="python">
import machine
import max7219, utime
import urequests as requests
import time
 
# LCD Config
spi = machine.SPI(1, 10000000)
d = max7219.Max7219(32, 8, spi, machine.Pin(15), False)
 
cntry = ["India", "Canada", "Ireland", "USA", "Germany", "Italy", "France", "Spain", "Pakistan", "Korea"]
 
 
# Flash all LEDs
for i in range(3):
d.fill(1)
d.show()
time.sleep(0.2)
d.fill(0)
d.show()
time.sleep(0.2)
 
 
# Print Global Data
try:
res = requests.get(url='http://coronavirus-19-api.herokuapp.com/all')
if res.status_code == 200:
flash_led(1,0.1,0.1)
else:
flash_led(2,0.5,0.1)
data = res.json()
print("Global: " + str(data["cases"]))
d.marquee("Global: " + str(data["cases"]))
except OSError:
print("Global: Error")
d.marquee("Global: Error")
time.sleep(5)
 
 
# Print Country Data
for i in cntry:
link = 'http://coronavirus-19-api.herokuapp.com/countries/%s' %i
try:
res = requests.get(url=link)
if res.status_code == 200:
flash_led(1,0.1,0.1)
else:
flash_led(2,0.5,0.1)
data = res.json()
print(str(data["country"]) + ": " + str(data["cases"]) + " Today: " + str(data["todayCases"]))
d.marquee(str(data["country"]) + ": " + str(data["cases"]) + " Today: " + str(data["todayCases"]))
except OSError:
print(i, ": Error")
d.marquee(i + ": Error")
time.sleep(5)
continue
 
 
# Sleep for 30 minutes
sleep = 5
d.marquee("Sleep " + str(sleep) + " min")
flash_led(5,0.1,0.1)
deep_sleep(sleep)
</syntaxhighlight>
 
= TM1637 CLock =
 
Download Library:
https://github.com/mcauser/micropython-tm1637/blob/master/tm1637.py
 
{{UC}}