Monday, 23 August 2021

ESP8266 examples

ESP8266 examples

This page captures our experience reading and executing the examples provided with standard esp8266 RTOS SDK.

1. Hello world

Peripherals folder

2. I2C

3. SPI: generic is strange, one with OLED is understandable but can't really test without an oled

WIFI folder
Reading: esp_wifi
Basics: Internet protocol suite (wikipedia)
  • 802.11 - PHY, MAC, bands speed
  • IP - IP address, fragmentation, re-assembly, MTU
  • TCP - sequence, ACK, error check, port, window size
  • UDP - checksum, port, multi/broadcast
  • HTTP - request-response, connection reuse

TCP 3 way handshake



Example wifi->getting started folder


4. Station example


Connecting esp8266 as station to iPhone hotspot

Connecting as in blue line appears on iPhone but no IP displayed on terminal

Seems to be a problem with iPhone


Links read:


https://apple.stackexchange.com/questions/114435/how-do-i-troubleshoot-personal-hotspot-mode-failing-to-issue-ip-addresses


https://osxdaily.com/2013/01/11/get-new-ip-address-ios-renew-dhcp-lease/


https://serverfault.com/questions/278567/dealing-with-ipad-dhcp-issue


https://www.net.princeton.edu/apple-ios/ios41-allows-lease-to-expire-keeps-using-IP-address-workaround.html


https://discussions.apple.com/thread/8599697


https://www.iphonehacks.com/2018/08/fix-wifi-problems-ios-12.html


https://www.saintlad.com/fix-personal-hotspot-issues-in-ios-13/#method7


Tried:

  1. iPhone switched OFF and ON, connected to power, different iPhone
  2. DHCP timeout 2->10 minutes
  3. Auto IP works with iPhone, assigns IP 169.254.27.79. At same time, MacBook connects via wifi to same iPhone, gets IP 172.20.10.3, can ping esp
  4. Android phones (tried 2) works, esp gets IP 192.168.43.118, MacBook gets 192.168.43.5, can ping esp
  5. AutoIP with android phone, assigns DHCP IP 192.168.43.118 but after 2-6 failed tries, still does not use autoIP

How to switch AutoIP ON: make menuconfig: component—>LWIP—>enable IPV4 link local addressing

How to change DHCP timeout: make menuconfig: component—>config—>tcpip adapter—>IP address lost timer interval


Final approach for now: #3


Autoip approach did not work for further examples that required connection with internet

Bought new SIM to put in an android phone. That is working fine.


nvs, tcp-adapter, wifi ON


5. softAP example: worked without any problem


Protocols folder


Using protcol_examples_common.h and connect.c (example_connect/disconnect) for all examples in this folder


6. httprequest example

in addition to nvs, tcp-adapter, wifi ON, creating a socket connection using 'addressinfo', then send a GET request and receive  response (full page from example.com)

main functions: get_task(), getaddreinfo()


7. httpserver example - simple

  • esp connected to android phone in station mode with IP 192.168.43.118 and becomes a server
  • laptop connected to same phone with IP 192.168.43.5 and becomes a client
  • Tried GET, PUT and POST
  • Chrome browser can
    • send GET request in URL
    • send query string in URL
    • show response body in main page
    • show request/response headers in browser (view->developer->inspect elements->network, re-send request)
  • Curl can
  • Modheader can (chrome plugin)
    • Add request / response headers to a particular URL
  • Restman can (chrome plugin)
    • send GET, PUT and POST with parameters
    • show response along with headers etc.
    • not sure how to send file in POST
8. httpserver example - persistent socket
  • http_req_t structure in esp_http_server.h
  • use of user_ctx to maintain and show visitor count
  • use of sess_ctx to send any number and accumulate it
  • use of local pointers to update value stored in global pointers like user_ctx and sess_ctx
  • All 3 (GET, PUT and POST) add 1 to visitor count & start a session if sess_ctx is NULL
  • Once sess_ctx is not NULL, the session can only be terminated by calling 'free' function. In this case, it gets called when webserver and hence the socket is closed
  • POST allows user to send a number that is added to sess_ctx
  • GET shows the current value of sess_ctx
  • PUT allows user to send a number, sess_ctx value is reset to that value
9. httpserver example - advanced tests
  • read esp_http_server.h (to understand get/set sess_ctx, get/set transport_ctx, get_global_user_ctx, get_global_transport_ctx, sess_trigger_close, sess_update_lru_counter)
  • 8 handlers doing simple things
  • printing remaining heap
  • using httpd_queue_work
  • async_get_handler not working properly
10. esp_http_client_example
  • read esp_http_client.h
  • additional methods PATCH, DELETE, HEAD
  • EAGAIN message/error
  • Authentication types: basic v digest
  • Certification: SSL (confirms identity of server & encrypts data), PEM file
  • Redirection requests: absolute v relative (not full path but only page), make source relative, not destination
  • httpbin.org
11. https_request_example_main
  • basically to establish a secure connection SSL/TLS
  • esp_tls.h
  • simply using the wrapper API in file above
  • https_mbedtls_example_main: using esp_tls_mbedtls.h, complex API, lots of functions

12. openssl demo example

  • ssl.h
  • hosting structure with in-addr = 32 bit int to store IP address
  • get host by name
  • create ssl context (v1.1)
  • verify ssl context (verify none)
  • create socket
  • bind socket to local port (9999)
  • connect socket to remote server (IP, port 443)
  • create SSL
  • connect SSL to socket
  • check heap size / stack depth
  • send request to SSL (write)
  • read response


13. openssl client example (different points from demo)

  • extra certificates (ca, server, client - pem files and keys)
  • different version while creating context (v1.2)
  • load certificates and keys to context
  • verify ssl context (verify peer)
  • when run, client-server connected, server (laptop) showed request received but client could not get a response back


14. open ssl server example (different points)

  • after create context and socket, listen (instead of connect)
  • create ssl, then accept (server socket accept client)
  • connect ssl with new (client) socket
  • ssl accept (ssl server accept client)
  • write/read
  • same as client example, server could not get a response back from client (laptop)
15. sockets/tcp client & server example
  • using standard sockets.h
  • using python script to create server/client (on the other end of esp)
  • port is important, 50000 did not work, 3333 worked
  • BCD socket (link)
16. udp client example
  • destinationAddress = server’s
  • create socket with SOCK_DGRAM (datagram)
  • another while (1)
  • sendto (sock, payload, destAddr)
  • recvfrom (sock, buf, sourceAddr (blank)): you get data & sourceAddr
  • no 3 way handshake
17. udp server example
  • destAddr: INADDR_ANY (same as tcp)
  • create socket
  • bind socket and destAddr
  • another while(1)
  • recvfrom(sock, buf, sourceAddr (blank)): you get data & sourceAddr
  • sendto (sock, buf, sourceAddr)
18. udp multicast example: lots of new APIs, not clear

19. COAP
  • client, server
  • machine to machine
  • UDP based
  • methods similar to http
20. Multicast DNS (mdns)
  • resolves hostname to IP address within small (local) network that does not have a dedicated DNS
  • designed to enable simple, constrained devices to join the IoT even through constrained networks with low bandwidth and low availability
  • generally used for machine-to-machine (M2M) applications such as smart energy and building automation
  • app_main
    • mdns example task
    • generate hostname
    • initialise mdns
    • mdns print results
    • query mdns service
    • query mdns host
    • initialise button
    • while (1) check button, mdns example task
21. SNTP (simple network time protocol)
  • synchronizes system time with official world time / coordinated universal time
  • simpler (needs fewer algorithms) than NTP (network time protocol) but less accurate
  • not used much if processing power enough to run NTP
  • UDP port 123, TZ for India is Asia/Kolkata (not working), UTC-5:30 worked
  • app_main
    • sntp example task
    • initialise sntp
    • obtain time
22. MQTT (IBM MQ telemetry transport)
  • Useful links: internetofthingsagendaespressif
  • Light weight IOT messaging, publish-subscribe architecture
  • client (pub) --> broker --> client (sub)
  • you subscribe to topics, if you publish topic gets created (if does not exist)
  • if broker->pub is broken, cached msg sent to all subs
  • if broker->sub is broken, values buffered & sent when back online
  • port 1883 (non encrypted), 8883 (encrypted)
  • client side certificates are also verified during handshake
  • connection-->authentication-->communication-->termination
  • 2 byte fixed header+variable length optional header+256MB payload+QoS level
  • BLOBs - binary large objects
  • mqtt://mqtt.eclipse.org
  • graceful shutdown, easy reconnect
  • MQTT tcp client example
    • events: connected, published, subscribed, unsubscribed, disconnected
    • if data present with broker, no subscribe event called, direct data event
    • make erase_flash to get rid of prev data
    • test1: subscribe to qos0 only: print event_sub
    • test2: subscribe to qos1 only: event sub+event data (previously kept with broker, end less loop, msg id different every time). topic+event: unique msg id; topic / event change: msg id change
    • test3: qos0 sub & unsub: event_sub (diff msg ids)
    • test4: qos1 sub & unsub: event_sub, event_data, event_unsub (all diff msg ids)
    • test 5: qos0 sub, publish within event sub body; event_sub, event_data
    • test6: no prev data stored with broker in case of qos0
    • test7: qos0-sub, publish, unsub: event_sub, event_unsub (no data event!) unsub happens before data!
    • test8: qos0 pub-sub, qos1 sub-unsub: no data for qos0 unless you publish 'within sub event'. event_sub for qos0, event_data for qos1, event_unsub for qos1
    • test9: qos0 sub (publish within sub), qos1 sub-unsub: event_sub qos0, event_data qos1, event_unsub qos1, event_data qos0 (comes last event when published much earlier! priority less than qos1?)
  • MQTT webserver example
    • same code, only config for WS instead of TCP
  • MQTT webserver secure example
    • certificate of broker procured and added in config
  • MQTT on SSL example
    • same as WSS
  • MQTT SSL mutual auth example
    • additional client certificate with pem file & key
    • url hardcoded in config struct
    • used eclipse's mosquitto
22. SPIFFS - SPI flash file system (link). Various inbuilt C functions to handle files - great! stdio.h

Tested with Increased storage partition to (almost) maximum memory available in esp flash. partition tables



24. SoftAP provisioning example
  • About creating ‘provision’ (like electrical/plumbing) to update something (like wifi ssid/pwd in this case) while device is active (doing it’s main job)

  • Components

    • protocomm: manages secure session (app_prov.h/.c): can work over wifi (softap+httpd), BLE and console
    • protobuf: google’s protocol for serialised data transfer of structures
    • wifi provisoning: exchange of userid/pwd (wifi_init_sta/connect/mode)
  • Flow

    • app_main
      • tcp adapter init, loop create default, nvs init, security 0 or 1
      • is provisioned? if yes, wifi_init_sta (register events, wifi start, mode)
      • if no, read esp softap ssid from config & send to app_prov_start_softap_provisioning
    • app_prov.h
      • app_prov_get_wifi_state, disconnect reason
      • event handler
      • is provisioned
      • configure sta
      • start softap provisioning
      • app_prov_data: protocol handler, security, pop, timer, wifi state, disconnect reason

  • Running experience

    • install google’s protobuf
    • copied 1 missing file (wifi_scan.py) in sdk\tools\esp_prov\prov\
    • updated 1 outdated file (security1.py) in sdk\tools\esp_prov\security\
    • laptop and esp connect to each other and are also able to exchange data but does not work beyond a point 
    • keeps saying ‘connecting’, does not say ‘connected’ and does not proceed to close softap etc.
    • system_events are not happening, no way to trigger system events from user code
    • latest SDK/example code available on GitHub seems to be different from ours (downloaded 2 months ago)

  • Custom config: extra config / end-point in protocomm

25. System folder examples
  • Console

    • components
      • linenoise lib
      • argtable2 lib
      • esp_console.h, esp_vfs_dev.h
      • cmdwifi.c, cmdsystem.c
    • app_main
      • nvs init
      • console init
      • esp console register help command
      • register system
      • register wifi
      • linenoiseprobe
      • linenoise
      • esp console run
    • Runs fine
    • Reading: VFS
      • wrapper on top of file systems like FAT, SPIFFS etc. Skimmed through link, review when needed


  • OTA
    • Reading: partition tables (link)
      • single factory app, no OTA: nvs, phy-init, factory (bootloader will run this by default)
      • nvs, otadata, phy_init, ota_0, ota_1 (bootloader will read otadata to know which app to run; if empty, will run 1st 'app' partition (ota_0/factory/test_app)
      • nvs (size 0x4000 or 0x2000) is for working data, can create extra 'data' partitions for storage like SPIFFS
      • 1st app partition is starting at 0x10000 (64kB) in both default cases
      • app should be in integrated 1M partition - not clear
    • Reading: bootloader (link)
      • Bootloader is at 0x1000
      • it can update newer SDK code but not older
      • With old code, keep bootloader copy also!!
      • so don't upload (flash) ESP-IDF unless the code (forumware) is also updated and tested and can be uploaded (flashed) along with
    • ESP-IDF versions link
    • OTA links: main link having esp_ota_ops.h, link related to https
    • App rollback needs some thinking specially related to versioning & inability of bootloader to update older versions
    • simple_ota_example
      • read_me & ota_workflow.png is good
    • Running experience
      • Error1: hostname / common name not valid, certificate cannot be verified. While creating cert pem key, give hostname = IP address of server (laptop).
      • Error2: E (3220) esp-tls-mbedtls: mbedtls_ssl_handshake returned -0x2700

        I (3223) esp-tls-mbedtls: Failed to verify peer certificate!

        I (3226) esp-tls-mbedtls: verification info:   ! The certificate Common Name (CN) does not match with the expected CN

          ! The certificate is not

        E (3247) esp-tls: Failed to open new connection

        E (3255) TRANS_SSL: Failed to open a new connection

        E (3267) HTTP_CLIENT: Connection failed, sock < 0

        E (3272) esp_https_ota: Failed to open HTTP connection: 28674

        E (3281) simple_ota_example: Firmware Upgrades Failed

      • Sometimes returned 0x4c (instead of 0x2700)
      • Links studied: link1link2
      • Worked when retried, working but still this error appears
                                    E (13685) esp-tls-mbedtls: read error :-76:

                      E (13687) TRANS_SSL: esp_tls_conn_read error, errno=Socket is not connected




No comments:

Post a Comment