Advertisement
Arbitrator

Untitled

May 29th, 2019
6,707
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.04 KB | None | 0 0
  1. # Adafruit BNO055 WebGL Example
  2. #
  3. # Requires the flask web framework to be installed.  See http://flask.pocoo.org/
  4. # for installation instructions, however on a Linux machine like the Raspberry
  5. # Pi or BeagleBone black you can likely install it by running:
  6. #  sudo apt-get update
  7. #  sudo apt-get install python3-flask
  8. #
  9. # Copyright (c) 2015 Adafruit Industries
  10. # Author: Tony DiCola
  11. # 2019 update: Carter Nelson
  12. #
  13. # Permission is hereby granted, free of charge, to any person obtaining a copy
  14. # of this software and associated documentation files (the "Software"), to deal
  15. # in the Software without restriction, including without limitation the rights
  16. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  17. # copies of the Software, and to permit persons to whom the Software is
  18. # furnished to do so, subject to the following conditions:
  19. #
  20. # The above copyright notice and this permission notice shall be included in
  21. # all copies or substantial portions of the Software.
  22. #
  23. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  24. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  25. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  26. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  27. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  28. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  29. # THE SOFTWARE.
  30. import json
  31. import logging
  32. import threading
  33. import time
  34.  
  35. from flask import *
  36.  
  37. import neopixel
  38. i2c = busio.I2C(board.SCL, board.SDA)
  39.  
  40. # Create the BNO sensor connection.
  41. bno = adafruit_bno055.BNO055(i2c)
  42.  
  43. # Application configuration below.  You probably don't need to change these values.
  44.  
  45. # How often to update the BNO sensor data (in hertz).
  46. BNO_UPDATE_FREQUENCY_HZ = 10
  47.  
  48. # Name of the file to store calibration data when the save/load calibration
  49. # button is pressed.  Calibration data is stored in JSON format.
  50. CALIBRATION_FILE = 'calibration.json'
  51.  
  52. # BNO sensor axes remap values.  These are the parameters to the BNO.set_axis_remap
  53. # function.  Don't change these without consulting section 3.4 of the datasheet.
  54. # The default axes mapping below assumes the Adafruit BNO055 breakout is flat on
  55. # a table with the row of SDA, SCL, GND, VIN, etc pins facing away from you.
  56. #BNO_AXIS_REMAP = { 'x': BNO055.AXIS_REMAP_X,
  57. #                   'y': BNO055.AXIS_REMAP_Z,
  58. #                   'z': BNO055.AXIS_REMAP_Y,
  59. #                   'x_sign': BNO055.AXIS_REMAP_POSITIVE,
  60. #                   'y_sign': BNO055.AXIS_REMAP_POSITIVE,
  61. #                   'z_sign': BNO055.AXIS_REMAP_NEGATIVE }
  62.  
  63.  
  64. # Create flask application.
  65. app = Flask(__name__)
  66.  
  67. # Global state to keep track of the latest readings from the BNO055 sensor.
  68. # This will be accessed from multiple threads so care needs to be taken to
  69. # protect access with a lock (or else inconsistent/partial results might be read).
  70. # A condition object is used both as a lock for safe access across threads, and
  71. # to notify threads that the BNO state has changed.
  72. bno_data = {}
  73. bno_changed = threading.Condition()
  74.  
  75. # Background thread to read BNO sensor data.  Will be created right before
  76. # the first request is served (see start_bno_thread below).
  77. bno_thread = None
  78.  
  79.  
  80. def read_bno():
  81.     """Function to read the BNO sensor and update the bno_data object with the
  82.    latest BNO orientation, etc. state.  Must be run in its own thread because
  83.    it will never return!
  84.    """
  85.     while True:
  86.         # Capture the lock on the bno_changed condition so the bno_data shared
  87.         # state can be updated.
  88.         with bno_changed:
  89.             bno_data['euler'] = bno.euler
  90.             bno_data['temp'] = bno.temperature
  91.             bno_data['quaternion'] = bno.quaternion
  92.             bno_data['calibration'] = bno.calibration_status
  93.             # Notify any waiting threads that the BNO state has been updated.
  94.             bno_changed.notifyAll()
  95.         # Sleep until the next reading.
  96.         time.sleep(1.0/BNO_UPDATE_FREQUENCY_HZ)
  97.  
  98. def bno_sse():
  99.     """Function to handle sending BNO055 sensor data to the client web browser
  100.    using HTML5 server sent events (aka server push).  This is a generator function
  101.    that flask will run in a thread and call to get new data that is pushed to
  102.    the client web page.
  103.    """
  104.     # Loop forever waiting for a new BNO055 sensor reading and sending it to
  105.     # the client.  Since this is a generator function the yield statement is
  106.     # used to return a new result.
  107.     while True:
  108.         # Capture the bno_changed condition lock and then wait for it to notify
  109.         # a new reading is available.
  110.         with bno_changed:
  111.             bno_changed.wait()
  112.             # A new reading is available!  Grab the reading value and then give
  113.             # up the lock.
  114.             heading, roll, pitch = bno_data['euler']
  115.             temp = bno_data['temp']
  116.             x, y, z, w = bno_data['quaternion']
  117.             sys, gyro, accel, mag = bno_data['calibration']
  118.         # Send the data to the connected client in HTML5 server sent event format.
  119.         data = {'heading': heading, 'roll': roll, 'pitch': pitch, 'temp': temp,
  120.                 'quatX': x, 'quatY': y, 'quatZ': z, 'quatW': w,
  121.                 'calSys': sys, 'calGyro': gyro, 'calAccel': accel, 'calMag': mag }
  122.         yield 'data: {0}\n\n'.format(json.dumps(data))
  123.  
  124.  
  125. @app.before_first_request
  126. def start_bno_thread():
  127.     # Start the BNO thread right before the first request is served.  This is
  128.     # necessary because in debug mode flask will start multiple main threads so
  129.     # this is the only spot to put code that can only run once after starting.
  130.     # See this SO question for more context:
  131.     #   http://stackoverflow.com/questions/24617795/starting-thread-while-running-flask-with-debug
  132.     global bno_thread
  133.     # Kick off BNO055 reading thread.
  134.     bno_thread = threading.Thread(target=read_bno)
  135.     bno_thread.daemon = True  # Don't let the BNO reading thread block exiting.
  136.     bno_thread.start()
  137.  
  138. @app.route('/bno')
  139. def bno_path():
  140.     # Return SSE response and call bno_sse function to stream sensor data to
  141.     # the webpage.
  142.     return Response(bno_sse(), mimetype='text/event-stream')
  143.  
  144. @app.route('/save_calibration', methods=['POST'])
  145. def save_calibration():
  146.     # Save calibration data to disk.
  147.     #
  148.     # TODO: implement this
  149.     #
  150.     return 'OK'
  151.  
  152. @app.route('/load_calibration', methods=['POST'])
  153. def load_calibration():
  154.     # Load calibration from disk.
  155.     #
  156.     # TODO: implement this
  157.     #
  158.     return 'OK'
  159.  
  160. @app.route('/')
  161. def root():
  162.     return render_template('index.html')
  163.  
  164.  
  165. if __name__ == '__main__':
  166.     # Create a server listening for external connections on the default
  167.     # port 5000.  Enable debug mode for better error messages and live
  168.     # reloading of the server on changes.  Also make the server threaded
  169.     # so multiple connections can be processed at once (very important
  170.     # for using server sent events).
  171.     app.run(host='0.0.0.0', debug=True, threaded=True)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement