close

Example1: (Station mode)
Python as Server SIde:

 

  1. #!/usr/bin/python             
    prg_n = 'ServerSocketDemo-from-v29'
    #
    # This needs to be running on 'Server' BEFORE starting ESP8266 routine
    #
    import time; import socket; import os; import glob
    port = 1247
    i_cnt=0
    #
    # **** While True Loop ****
    while True:
      s = socket.socket()
      host = socket.gethostname()
      print host, port
      s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # added allow to reuse when re-run
      s.bind(('',port)) # Needed (('',port)) or client never saw it
      s.listen(5)
      c, addr = s.accept()
      # end of setting socket
      #
      print 'c, addr: ', c, addr
      print 'Waiting for data from ESP8266...'
      # it printed... c, addr:  <socket._socketobject object at 0x7ff4d063c670> ('192.168.1.200', 3073)
      print("Connection accepted from " + repr(addr[1]) + "  Server ready for file transfer...\n")
      # it printed... Connection accepted from xxxx  Server ready for file transfer...
      #
      # ACK the client, get filename and open file for writes
      starttime = time.time()    # measure start of ET to get and write file
      c.send("ACK...\n")         # SEND MESSAGE TO CLIENT TO SEND DATA
      #
      tfile = "Server-WIP"
      fobj = open(tfile, "w")
      #
      # Incoming Data, loop until "FILE-EOF", then repeat for additional file(s)
      # get next line...
      client_sent = c.recv(1026)
      #
      while client_sent != 'EOF\n' :
        print client_sent,  # comma supresses a linefeed from printer (string already has a linefeed)
        fobj.write(client_sent)
        client_sent = c.recv(1026)
        #
      ######### HIT EOF\n
      localtime = time.asctime( time.localtime(time.time()) )
      print (localtime)
      E_Time = (time.time() - starttime)
      print "Elapsed Time:  %.2f Seconds" % E_Time
      fobj.write("Server:,,,,,Elapsed Time:  %.2f Seconds" %  E_Time + '\n' )
      fobj.write("Server:,,,,,Program Name:  %s " %prg_n + '\n' )
      fobj.close()
      os.chmod(tfile,0o666) # assign RW- to Owner, Group, Other
      os.rename(tfile, tfile[0:18] + '-' + str(i_cnt))
      i_cnt += 1
      print ('addr[1]: '+repr(addr[1])+' FILE XFER DONE for: '+tfile[0:18]+'-'+ str(i_cnt))
      #
      ### close the socket
      ### a new socket will be created for next upload;
      ### as the client closes its socket after uploads
      ###
      print ('ALL FILES RCVD this session')
      print ('close socket, open new socket and wait for next upload')
      print ('Back to top level # "**** While True Loop ****"\nServer Prog: ' + prg_n)
      s.close()

ESP8266 as Client (Station mode)

  1. prg_n='ESP_SocketDemo.py'
    #
    # NOTE - Server socket must be up and running first
    # This prog uploads the first file found in '/DATA' dir on the ESP8266
    # Must first create '/DATA' and save a text file there
    #
    print(prg_n)
    host='192.168.1.100';port=1247
    my_ssid='ENTER-YOUR_SSID_HERE'
    my_wifi_pw='ENTER_YOUR_NETWORK_PASSWORD_HERE'
    #
    import sys,time,utime,socket,network,machine
    from ntptime import settime
    from machine import Pin
    #
    uos.chdir('/DATA')# must be pre set up on ESP8266, add a text file demo here
    #
    # main code loop below, afer defs...
    #
    def set_WIFI(cntrl):
      i=0;sta_if=network.WLAN(network.STA_IF)
      if cntrl=='ON':
        if not sta_if.isconnected():
          print('conn WiFi')
          sta_if.active(True)
          sta_if.connect(my_ssid,my_wifi_pw)
          while not sta_if.isconnected():
            print(".",end="")
            time.sleep(1);i+=1
            if i>9:return#>>
      else:sta_if.active(False)
      print('NW CFG:',sta_if.ifconfig())
    #
    #
    def upld_data():
      sd=.3 # delay between sends - experiment with this
      df='' # data file name
      p16.high();red_LED=False
      fl=uos.listdir()
      df=fl[0]
      print('fl: ',fl,'   dl:  ',dl) 
      #    
      set_WIFI('ON')
      s=socket.socket();time.sleep(sd)
      try:
        s.connect((host,port))
      except Exception as err:
        print('SockConn-ERR#: ',err)
        return('NOP')#>>
      #
      cmd=s.recv(1024)
      if cmd.startswith('ACK'): # I have Server send 'ACK' on connect
        print('SRV-ACK')
      else:#catch???
        print(cmd+' SRV-NO-ACK')
        s.close();return('NOP')#>>
      #
      print(df)
      s.send(df);time.sleep(sd)
      with open(df,'r') as fobj:
        for line in fobj: # will loop here until end-of-file
          print(line,end='')
          if red_LED == False:#toggle LED during sends
            p16.low();red_LED=True
          else:
            p16.high();red_LED=False
          s.send(line);time.sleep(sd)
      p16.low();red_LED=True
      #
      # following is extra info I send after the file has been read
      s.send('\nprg_n: '+prg_n+', Free MEM:,'+str(gc.mem_free())+'\n')
      time.sleep(sd)
      s.send('fl is: '+str(fl)+'\n')
      time.sleep(sd)
      fl=uos.statvfs('/')
      fl='Tot/Used/Free %d blocks: %d/%d/%d\n' %(fl[0],fl[2],fl[2]-fl[3],fl[3])
      print(fl)
      s.send(fl);time.sleep(sd)
      s.send('EOF\n') # Server will look for EOF message from ESP, finish,
                      # close/open its socket, loop back, wait for next upload
      p16.high()
      return('DONE')#>>
    #
    #END DEF
    #
    while True: # upload every 60 seconds
      if utime.time() % 60 == 0:
        df_status = upld_data()
        print (df_status)
        time.sleep(1)
        gc.collect()
      #
    #

EXample2 : AP mode

ESP8266 As Http Server

  1. import network
    import socket
     
    def log(msg):
        print(msg)
     
     
    def do_connect():
        sta_if = network.WLAN(network.STA_IF)
        if not sta_if.isconnected():
            log('connecting to network...')
            sta_if.active(True)
            sta_if.connect('<SSID>', '<PASSWORD>')
            while not sta_if.isconnected():
                pass
        log('network config:'+str( sta_if.ifconfig()))
     
    def start_myserver():
        log('start server method')
        addr = socket.getaddrinfo('192.168.0.1', 80)[0][-1]
        s = socket.socket()
        s.bind(addr)
        s.listen(1)
        log('listening on'+str( addr))
        while True:
            cl, addr = s.accept()
            log('client connected from'+str(addr))
            cl.send(html)
            cl.close()
     
    #main part
    html = """<!DOCTYPE html>
    <html>
        <head> <title>ESP8266</title> </head>
        <body>
            Hello ESP8266 Server
        </body>
    </html>
    """
     
    do_connect()     # connect to your home router & get a ip address
    start_myserver() # create server according the above get address 
      

ESP8266 As TCP Server


  1. #Start TCP server
  2.  
  3. import network
    import socket
  4.  
  5. def do_connect():
  6.     ap_if = network.WLAN(network.AP_IF)
  7. }

        addr = socket.getaddrinfo('192.168.0.121', 868)[0][-1]
        s = socket.socket()
        s.setblocking(False)
        s.bind(addr)
        s.listen(1)
        while True:
            start = time.ticks_ms()
            socket = (str)(s)
            if len(socket) > 43:
                cl, addr2 = s.accept()
                cl_str = (str)(cl)
                while cl_str[14] == "2":
                    cl_str = (str)(cl)
                data = cl.recv(32)
                print(data)
                cl.close()
                delta = time.ticks_diff(time.ticks_ms(), start)
                print(delta)
     

 

下列測試 1 使用 ESP8266 AP 模式的固定 IP=192.168.4.1 當伺服端位址並綁定 80 埠監聽是否有客戶端連線進來, 有的話就回應 "Hello World" 網頁給遠端客戶.

測試 1 : 簡單的 HTTP 網頁伺服器 

#main.py
import socket
addr=socket.getaddrinfo('192.168.4.1', 80)[0][-1]

s=socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  #設定 socket 位址可重複使用
s.bind(addr)       #Server socket 綁定本身 AP 的網址與 80 埠
s.listen(5)           #設定連線等候佇列最大連線數目為 5
print('listening on', addr)

html='<!DOCTYPE html><html><body>Hello!World</body></html>'

while True:
    cs, addr=s.accept()    #等候連線進來, 接受後傳回與該連線通訊之新 socket 與遠端位址
    print('client connected from', addr)   #輸出遠端網址
    cs.send(html)    #以網頁回應遠端客戶
    cs.close()           #關閉新 socket
s.close()    #關閉 Server socket

將上面程式存成 main.py, 使用 ampy 上傳到 ESP8266 模組 :

D:\test>ampy --port COM4 put main.py

然後開啟 Putty 連線 ESP8266, 按 Ctrl+D 軟開機或插拔 ESP8266 電源重新執行 main.py, 由於進入無窮迴圈之故 REPL 介面最初會無反應.

分別使用筆電或手機以 WiFi 連線 ESP8266 的 AP 基地台 (SSID 是 MicroPython-xxxxxx, 其中 xxxxxx 是 MAC 位址後六碼, 而密碼預設是 micropythoN, 注意最後字元是大寫的 N),

參考資料:
https://forum.micropython.org/viewtopic.php?f=16&t=2804
https://thejeshgn.com/2016/05/05/python-on-esp8266-using-micropython/
https://pydigger.com/pypi/micropython-wifimanager
https://forum.micropython.org/viewtopic.php?t=2512
https://www.tapatalk.com/topic/182447-micropython-forum/2512-wifimanager-script-template
http://yhhuang1966.blogspot.tw/2017/07/micropython-on-esp8266.html

 

arrow
arrow
    全站熱搜

    stanley 發表在 痞客邦 留言(0) 人氣()