From 768c168a59e652759aeae874483dc5f6091e74ee Mon Sep 17 00:00:00 2001 From: Zhen Yang Date: Sat, 4 Jul 2020 18:33:08 -0700 Subject: [PATCH 1/3] finished activity for lesson10 --- blink/main.py | 15 +++++-- boot.py | 8 ++-- passwords.txt | 3 +- simple_web_server/main.py | 45 ++++++++++++++++++- web_server/main.py | 61 ++++++++++++++++++++++---- web_server/main_old.py | 91 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 204 insertions(+), 19 deletions(-) create mode 100644 web_server/main_old.py diff --git a/blink/main.py b/blink/main.py index 09c2286..1933248 100644 --- a/blink/main.py +++ b/blink/main.py @@ -1,12 +1,19 @@ +# A led blinking every half second for five times. import time from machine import Pin +# create an output pin on pin #2 +# because for ESP-12 board the led light using GPIO2 which is pin2. +# the led operate in "inverted" mode, which means the pin value is '1' will set +# the led off, and pin value "0" will set the led on. led = Pin(2, Pin.OUT) -for i in range(3): - time.sleep(.5) - led.value(1) +# set the value high to turn the led off. +led.value(1) +time.sleep(1) +for i in range(5): time.sleep(.5) led.value(0) - + time.sleep(.5) + led.value(1) diff --git a/boot.py b/boot.py index 91135a5..609df63 100644 --- a/boot.py +++ b/boot.py @@ -7,7 +7,8 @@ import time import machine -sta_if = network.WLAN(network.STA_IF); sta_if.active(True) +sta_if = network.WLAN(network.STA_IF) +sta_if.active(True) try: with open("passwords.txt") as f: @@ -24,8 +25,9 @@ sta_if.connect(station, password) - for i in range(15): - print(".") + #for i in range(15): + for i in range(30): + print(".", end=' ') if sta_if.isconnected(): break diff --git a/passwords.txt b/passwords.txt index 9f2747f..566eaa9 100644 --- a/passwords.txt +++ b/passwords.txt @@ -1,2 +1 @@ -EarlGreyTea HotHotHot -MyHomeAccessPoint aueiUeh73NB +Jia2 Maint002 diff --git a/simple_web_server/main.py b/simple_web_server/main.py index b860471..41f8630 100644 --- a/simple_web_server/main.py +++ b/simple_web_server/main.py @@ -3,12 +3,22 @@ except: import socket +response_404 = """HTTP/1.0 404 NOT FOUND + +

404 Not Found

+""" + +response_500 = """HTTP/1.0 500 INTERNAL SERVER ERROR + +

500 Internal Server Error

+""" response_template = """HTTP/1.0 200 OK %s """ import machine -import ntptime, utime +import ntptime +import utime from machine import RTC from time import sleep @@ -19,6 +29,7 @@ seconds = 0 rtc.datetime(utime.localtime(seconds)) +# time view def time(): body = """ @@ -30,6 +41,17 @@ def time(): return response_template % body +# dummy view +def dummy(): + body = "This is a dummy endpoint" + return response_templage % body + +# routing dictionary for different view functions. +handlers = [ + 'time': time, + 'dummy': dummy, +] + def main(): s = socket.socket() ai = socket.getaddrinfo("0.0.0.0", 8080) @@ -50,7 +72,26 @@ def main(): print("Request:") print(req) - response = time() + # This first line of a request looks like "GET /arbitrary/path/ HTTP/1.1 " + # It has three parts and seperated by a space char (' '). + # So the first part is the GET method, second is the path, the third is the + # HTTP version used. We only need the second part. + # The first line of a request is: req.decode().split('\r\n')[0] + # The second part of first line is: + # req.decode().split('\r\n')[0].split(" ")[1] + try: + path = req.decode().split('\r\n')[0].split(' ')[1] + # the path like /dummy/dog/, we want to only get 'dummy' + # so we need to strip slashes from the left or right side of the path. + # and then get the first string from the remaining path. + handler = handlers[path.strip('/').split('/')[0]] + # if the handler is 'dummy', then we will call dummy(). + response = handler() + except KeyError: + response = response_404 + except Exception as e: + response = response_500 + print(str(e)) client_s.send(b"\r\n".join([line.encode() for line in response.split("\n")])) diff --git a/web_server/main.py b/web_server/main.py index dd66055..c0350ff 100644 --- a/web_server/main.py +++ b/web_server/main.py @@ -12,25 +12,24 @@

500 Internal Server Error

""" - response_template = """HTTP/1.0 200 OK %s """ - import machine -import ntptime, utime +import ntptime +import utime from machine import RTC from time import sleep +rtc = RTC() try: seconds = ntptime.time() except: seconds = 0 - -rtc = RTC() rtc.datetime(utime.localtime(seconds)) +# time view function def time(): body = """ @@ -42,16 +41,50 @@ def time(): return response_template % body +# dummy view function def dummy(): body = "This is a dummy endpoint" + return response_template % body + +from machine import Pin +led = Pin(14, Pin.OUT) +# create a light_on view function. +def light_on(): + led.value(1) + sleep(5) + led.value(0) + body = 'Your LED is turned on for 5 second then turned off.' + return response_template % body + +# create a light_off view function. +def light_off(): + led.value(0) + sleep(5) + led.value(1) + body = 'Your LED is turned off for 5 second then truned on.' + return response_template % body + +# create a switch_state view function. +switch = Pin(12, Pin.IN) +def switch_state(): + body = 'Switch State: {}'.format(switch.value()) + return response_template % body +# create a light_state view function. +adc = machine.ADC(0) +def light_state(): + body = 'Light state:{}'.format(adc.read()) return response_template % body -pin = machine.Pin(10, machine.Pin.IN) +# routing dictionary for different view functions. handlers = { 'time': time, 'dummy': dummy, + 'light_on': light_on, + 'light_off': light_off, + 'switch': switch_state, + 'light': light_state, } def main(): @@ -63,9 +96,10 @@ def main(): s.bind(addr) s.listen(5) - print("Listening, connect your browser to http://:8080") + print("Listening, connect your browser to http://:8080/") while True: + sleep(.5) res = s.accept() client_s = res[0] client_addr = res[1] @@ -73,9 +107,20 @@ def main(): print("Request:") print(req) + # This first line of a request looks like "GET /arbitrary/path/ HTTP/1.1 " + # It has three parts and seperated by a space char (' '). + # So the first part is the GET method, second is the path, the third is the + # HTTP version used. We only need the second part. + # The first line of a request is: req.decode().split('\r\n')[0] + # The second part of first line is: + # req.decode().split('\r\n')[0].split(" ")[1] try: - path = req.decode().split("\r\n")[0].split(" ")[1] + path = req.decode().split('\r\n')[0].split(' ')[1] + # the path like /dummy/dog/, we want to only get 'dummy' + # so we need to strip slashes from the left or right side of the path. + # and then get the first string from the remaining path. handler = handlers[path.strip('/').split('/')[0]] + # if the handler is 'dummy', then we will call dummy() view function. response = handler() except KeyError: response = response_404 diff --git a/web_server/main_old.py b/web_server/main_old.py new file mode 100644 index 0000000..dd66055 --- /dev/null +++ b/web_server/main_old.py @@ -0,0 +1,91 @@ +try: + import usocket as socket +except: + import socket + +response_404 = """HTTP/1.0 404 NOT FOUND + +

404 Not Found

+""" + +response_500 = """HTTP/1.0 500 INTERNAL SERVER ERROR + +

500 Internal Server Error

+""" + +response_template = """HTTP/1.0 200 OK + +%s +""" + +import machine +import ntptime, utime +from machine import RTC +from time import sleep + +try: + seconds = ntptime.time() +except: + seconds = 0 + +rtc = RTC() +rtc.datetime(utime.localtime(seconds)) + +def time(): + body = """ + +

Time

+

%s

+ + +""" % str(rtc.datetime()) + + return response_template % body + +def dummy(): + body = "This is a dummy endpoint" + + return response_template % body + +pin = machine.Pin(10, machine.Pin.IN) + +handlers = { + 'time': time, + 'dummy': dummy, +} + +def main(): + s = socket.socket() + ai = socket.getaddrinfo("0.0.0.0", 8080) + addr = ai[0][-1] + + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + + s.bind(addr) + s.listen(5) + print("Listening, connect your browser to http://:8080") + + while True: + res = s.accept() + client_s = res[0] + client_addr = res[1] + req = client_s.recv(4096) + print("Request:") + print(req) + + try: + path = req.decode().split("\r\n")[0].split(" ")[1] + handler = handlers[path.strip('/').split('/')[0]] + response = handler() + except KeyError: + response = response_404 + except Exception as e: + response = response_500 + print(str(e)) + + client_s.send(b"\r\n".join([line.encode() for line in response.split("\n")])) + + client_s.close() + print() + +main() From 0068322f07f9a5dd6d57516b7aa2177ea32b85a2 Mon Sep 17 00:00:00 2001 From: Zhen Yang Date: Sat, 4 Jul 2020 18:34:20 -0700 Subject: [PATCH 2/3] finished activity for lesson10 --- passwords.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passwords.txt b/passwords.txt index 566eaa9..97eab85 100644 --- a/passwords.txt +++ b/passwords.txt @@ -1 +1 @@ -Jia2 Maint002 +Jia2 123456 From 58d7e09cc13d9f1296f30d736889a556b8831958 Mon Sep 17 00:00:00 2001 From: Zhen Yang Date: Sat, 11 Jul 2020 13:51:29 -0700 Subject: [PATCH 3/3] finished assignment for lesson10 --- boot.py | 2 + dc_motor/DC_motor_control_over_WiFi.txt | 21 +++ dc_motor/main.py | 201 ++++++++++++++++++++++++ simple_web_server/main.py | 10 +- 4 files changed, 230 insertions(+), 4 deletions(-) create mode 100644 dc_motor/DC_motor_control_over_WiFi.txt create mode 100644 dc_motor/main.py diff --git a/boot.py b/boot.py index 609df63..28a5587 100644 --- a/boot.py +++ b/boot.py @@ -38,3 +38,5 @@ break else: print("Connection could not be made.\n") +if sta_if.isconnected(): + print("\nConnected as: {}".format(sta_if.ifconfig()[0])) diff --git a/dc_motor/DC_motor_control_over_WiFi.txt b/dc_motor/DC_motor_control_over_WiFi.txt new file mode 100644 index 0000000..4016894 --- /dev/null +++ b/dc_motor/DC_motor_control_over_WiFi.txt @@ -0,0 +1,21 @@ +DC motor control over WiFi +1. The NodeMCU board pin 12 and pin 13 is connected to the motor driver (L293D) +pin 2 and pin 7 to control the motor rotating forward or backward or stop. +The pin values corresponding to motor direction is as follows: +Pin2 = 0 Pin7 = 0 ---> motor stop +Pin2 = 1 Pin7 = 0 ---> motor forward +Pin2 = 0 Pin7 = 1 ---> motor backward +There are four buttons on our motor control web page for controlling motor's +on/off/forward/backward. + +2. The speed of the motor is also controlled by sending different PWM duty cycle +through pin14 to the L293D enable pin. +We have four button on our motor control web page for controlling the speed: +25 duty cycle, 50 duty cycle, 75 duty cycle and 100 duty cycle. + +3. The speed of the motor can also be controlled by a position transducer using +the only analog input pin A0. The analogy input pin converts the position +transducer voltage output into digital value(0, 1023). This digital value is then +used as input parameter for the pwm.duty() function to control the speed of the +motor seamlessly. We have a button on our motor control web page to test this +stepless speed control. diff --git a/dc_motor/main.py b/dc_motor/main.py new file mode 100644 index 0000000..062598e --- /dev/null +++ b/dc_motor/main.py @@ -0,0 +1,201 @@ +# This code controls a DC motor speed and direction over Wifi using +# Nodemcu esp8266 and L293D motor driver. +# http://localhost:8080/motor_control is the homepage for DC motor control. +try: + import usocket as socket +except: + import socket + +response_404 = """HTTP/1.0 404 NOT FOUND + +

404 Not Found

+""" + +response_500 = """HTTP/1.0 500 INTERNAL SERVER ERROR + +

500 Internal Server Error

+""" + + +response_template = """HTTP/1.0 200 OK + +%s +""" +import machine +from time import sleep +from machine import Pin + +# set up the pins of nodeMCU and L293D +# 1. We use GPIN 12 and 13 of nodeMCU as output control pins. +# GPIO12 and 13 is connected to the INPUT Pin 2 and 7 of L293D. +# Pin2 = 0 Pin7 = 0 ---> motor off +# Pin2 = 1 Pin7 = 0 ---> motor forward +# Pin2 = 0 Pin7 = 1 ---> motor backward +out1 = Pin(12, Pin.OUT) +out2 = Pin(13, Pin.OUT) + +# 2. We use GPID14 of nodeMCU to send the PWM signal to control the speed of motor. +# GPID14 of nodeMCU is connected to the enable 1,2 (Pin 1) of L293D. +pwm = Pin(14) +pwm = machine.PWM(pwm) +pwm.duty(1023) + +# 3. We use Analog input pin A0 to connect a transducer to change the speed of +# the motor. +adc = machine.ADC(0) + +home_page_str = """ + + +

NodeMCU DC motor control over WiFi



+

+ + + + +
+
+ + + + +
+
+ +
+
+
+""" +# create homepage veiw function. +def home_page(): + body = home_page_str + '' + return response_template % body + +# create a motor on view function. +def motor_on(): + out1.value(1) + out2.value(0) + pwm.duty(1023) + body = home_page_str + '

Motor is on

' + return response_template % body + +# create a motor off view function. +def motor_off(): + out1.value(0) + out2.value(0) + body = home_page_str + 'Motor is stopped.' + return response_template % body + +# create a motor forward veiw function. +def motor_forward(): + out1.value(0) + out2.value(0) + sleep(3) + out1.value(1) + out2.value(0) + #pwm.duty(1023) + body = home_page_str + 'Motor rotating in forward direction.' + return response_template % body + +# create a motor backward veiw function. +def motor_backward(): + out1.value(0) + out2.value(0) + sleep(3) + out1.value(0) + out2.value(1) + #pwm.duty(1023) + body = home_page_str + 'Motor rotating in backward direction.' + return response_template % body + +# create PWM duty cycle = 25 veiw function. +def duty_25(): + pwm.duty(255) + body = home_page_str + 'PWM duty cycle 25%.' + return response_template % body + +# create PWM duty cycle = 50 veiw function. +def duty_50(): + pwm.duty(512) + body = home_page_str + 'PWM duty cycle 50%.' + return response_template % body + +# create PWM duty cycle = 75 veiw function. +def duty_75(): + pwm.duty(767) + body = home_page_str + 'PWM duty cycle 75%.' + return response_template % body + +# create PWM duty cycle = 100 veiw function. +def duty_100(): + pwm.duty(1023) + body = home_page_str + 'PWM duty cycle 100%.' + return response_template % body + +# create analog input duty cycle veiw function. +def analog_duty(): + motor_duty_cycle = adc.read() + pwm.duty(motor_duty_cycle) + body = home_page_str + 'PWM duty cycle {}'.format(motor_duty_cycle) + return response_template % body + +# routing dictionary for different view functions. +handlers = { + 'motor_control': home_page, + 'motor_on': motor_on, + 'motor_off': motor_off, + 'motor_forward': motor_forward, + 'motor_backward': motor_backward, + 'duty_100': duty_100, + 'duty_75': duty_75, + 'duty_50': duty_50, + 'duty_25': duty_25, + 'analog_duty': analog_duty, +} + +def main(): + s = socket.socket() + ai = socket.getaddrinfo("0.0.0.0", 8080) + addr = ai[0][-1] + + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + + s.bind(addr) + s.listen(5) + print("Listening, connect your browser to http://:8080/") + + while True: + sleep(.5) + print("Before accept:") + res = s.accept() + print("After accept:") + client_s = res[0] + client_addr = res[1] + req = client_s.recv(4096) + print("Request:") + print(req) + + # This first line of a request looks like "GET /arbitrary/path/ HTTP/1.1 " + # It has three parts and seperated by a space char (' '). + # So the first part is the GET method, second is the path, the third is the + # HTTP version used. We only need the second part. + # The first line of a request is: req.decode().split('\r\n')[0] + # The second part of first line is: + # req.decode().split('\r\n')[0].split(" ")[1] + try: + path = req.decode().split('\r\n')[0].split(' ')[1] + # http://localhost:8080/motor_control is the homepage. + handler = handlers[path.strip('/').split('/')[0]] + response = handler() + except KeyError: + response = response_404 + except Exception as e: + response = response_500 + print(str(e)) + + client_s.send(b"\r\n".join([line.encode() for line in response.split("\n")])) + + client_s.close() + print() + +main() diff --git a/simple_web_server/main.py b/simple_web_server/main.py index 41f8630..9e2382c 100644 --- a/simple_web_server/main.py +++ b/simple_web_server/main.py @@ -44,13 +44,13 @@ def time(): # dummy view def dummy(): body = "This is a dummy endpoint" - return response_templage % body + return response_template % body # routing dictionary for different view functions. -handlers = [ +handlers = { 'time': time, 'dummy': dummy, -] +} def main(): s = socket.socket() @@ -61,10 +61,12 @@ def main(): s.bind(addr) s.listen(5) - print("Listening, connect your browser to http://:8080/") + print("Listening, connect your browser to http://", end='') + print(addr) while True: sleep(.5) + print("Before accept") res = s.accept() client_s = res[0] client_addr = res[1]