diff --git a/bootcamp_sessions/3_led_bar.ipynb b/bootcamp_sessions/3_led_bar.ipynb index 44fd859..a4b9cb4 100644 --- a/bootcamp_sessions/3_led_bar.ipynb +++ b/bootcamp_sessions/3_led_bar.ipynb @@ -207,7 +207,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -227,9 +227,21 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 2, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'ledbar' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mj\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mledbar\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwrite_binary\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0melement\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mj\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0msleep\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0.25\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mNameError\u001b[0m: name 'ledbar' is not defined" + ] + } + ], "source": [ "for i in range(5):\n", " for j in range(10):\n", diff --git a/breakout_sessions/1_1_sensors_and_board_to_board.ipynb b/breakout_sessions/1_1_sensors_and_board_to_board.ipynb index 26af88c..72e359b 100644 --- a/breakout_sessions/1_1_sensors_and_board_to_board.ipynb +++ b/breakout_sessions/1_1_sensors_and_board_to_board.ipynb @@ -60,7 +60,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ diff --git a/breakout_sessions/1_2_temp_sensor_AHT20.ipynb b/breakout_sessions/1_2_temp_sensor_AHT20.ipynb index eb43f2d..589726c 100644 --- a/breakout_sessions/1_2_temp_sensor_AHT20.ipynb +++ b/breakout_sessions/1_2_temp_sensor_AHT20.ipynb @@ -78,7 +78,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -95,15 +95,21 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Humidity: 38.73 %\n", - "Temperature: 27.34 °C\n" + "ename": "RuntimeError", + "evalue": "Timeout when writing IIC.", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mpy_ht\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mGrove_AHT20\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbase\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mPMODB\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mPMOD_GROVE_G3\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mhumidity\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpy_ht\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_humidity\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mtemperature\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpy_ht\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_temp\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Humidity: '\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfloat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"{0:.2f}\"\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhumidity\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'%'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/grove/pmod_grove_aht20.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, pmod_id, gr_pins)\u001b[0m\n\u001b[1;32m 78\u001b[0m \u001b[0msuper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__init__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mpmod_id\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mscl_pin\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msda_pin\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0x38\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 79\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 80\u001b[0;31m \u001b[0mstatus\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_status\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 81\u001b[0m \u001b[0;32mif\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mnot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mbin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstatus\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m4\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 82\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Device not calibrated\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/grove/pmod_grove_aht20.py\u001b[0m in \u001b[0;36mget_status\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 108\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 109\u001b[0m \"\"\"\n\u001b[0;32m--> 110\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0x71\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 111\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreceive\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 112\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.6/dist-packages/pynq/lib/pmod/pmod_iic.py\u001b[0m in \u001b[0;36msend\u001b[0;34m(self, iic_bytes)\u001b[0m\n\u001b[1;32m 196\u001b[0m \u001b[0mtimeout\u001b[0m \u001b[0;34m-=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 197\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mtimeout\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 198\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mRuntimeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Timeout when writing IIC.\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 199\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 200\u001b[0m \u001b[0msleep\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mI2C_DELAY\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mRuntimeError\u001b[0m: Timeout when writing IIC." ] } ], @@ -115,6 +121,13 @@ "print('Humidity: ', float(\"{0:.2f}\".format(humidity)), '%')\n", "print('Temperature: ', float(\"{0:.2f}\".format(temperature)), '°C')" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/breakout_sessions/sds_trace_data.dat b/breakout_sessions/sds_trace_data.dat new file mode 100644 index 0000000..6b7d177 Binary files /dev/null and b/breakout_sessions/sds_trace_data.dat differ diff --git a/extra/sds_trace_data.dat b/extra/sds_trace_data.dat new file mode 100644 index 0000000..eeee3df Binary files /dev/null and b/extra/sds_trace_data.dat differ diff --git a/extra/temp_ledbar_example_ATH20.ipynb b/extra/temp_ledbar_example_ATH20.ipynb new file mode 100644 index 0000000..df5bbca --- /dev/null +++ b/extra/temp_ledbar_example_ATH20.ipynb @@ -0,0 +1,277 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Displaying Sensor Data on the LED Bar\n", + "\n", + "A key concept in computers is taking an input from a sensor, processing that data in a meaningful way, and outputting that to the user in a format that is intuitive and easy to read. This concept can be found in almost every computing system. \n", + "\n", + "We are going to create this type of system with our sensor and LED bar. The end product will be a sort of \"digital thermometer\".\n", + "\n", + "### This notebook will walk you through using both the ATH20 sensor\n", + "\n", + "\n", + "As usual, apply the base overlay to the board:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "\n", + "require(['notebook/js/codecell'], function(codecell) {\n", + " codecell.CodeCell.options_default.highlight_modes[\n", + " 'magic_text/x-csrc'] = {'reg':[/^%%microblaze/]};\n", + " Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n", + " Jupyter.notebook.get_cells().map(function(cell){\n", + " if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n", + " });\n", + "});\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from pynq.overlays.base import BaseOverlay\n", + "base = BaseOverlay(\"base.bit\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 1. Read Temperature Data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## ATH02 Sensor\n", + "\n", + "If your sensor looks like this, it is an ATH20. If not, you should use the TH02 notebook [here](temp_ledbar_example_TH02.ipynb).\n", + "\n", + "![ATH20](https://static-cdn.seeedstudio.site/media/catalog/product/cache/b2267b506d4e4594666ef83a79896a9a/1/0/101990644_4_.png)\n", + "\n", + "### Install Driver\n", + "\n", + "First, install the driver that will allow your board to communicate with this sensor (you may already have downloaded it, but run this cell just in case)." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Collecting git+https://github.com/LewisMcL/pynq_drivers\n", + " Cloning https://github.com/LewisMcL/pynq_drivers to /tmp/pip-wqhg2o6g-build\n", + " Requirement already satisfied (use --upgrade to upgrade): pmod-grove-aht20==1.0 from git+https://github.com/LewisMcL/pynq_drivers in /usr/local/lib/python3.6/dist-packages\n" + ] + } + ], + "source": [ + "!pip3 install git+https://github.com/LewisMcL/pynq_drivers --no-deps" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Plug in your ATH20 Sensor\n", + "\n", + "Connect you ATH20 Sensor to the port labeled G3 on your PMOD to Grove Adaptor (pictured below). Plug the adaptor into the port labeled PMODB on your PYNQ Board.\n", + "\n", + "![pmod_adaptor](https://ce8dc832c.cloudimg.io/fit/640x480/n@a5b92b913168a98c8e5229bb3b0b33a39779b8b3/_cdn_/8F/91/A0/00/0/662008_1.jpg?mark_url=_tme-wrk_%2Ftme_new.png&mark_pos=center&mark_size=100pp)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Import Libraries\n", + "\n", + "Make sure your PMOD to Grove adapter is connected to the PMODB port. We are importing PMOD_GROVE_G3, because the AHT20 sensor is connected to the 3rd Grove adaptor port. If you have it plugged into G4, you will have to do `from pynq.lib.pmod import PMOD_GROVE_G4` instead. " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "from grove import Grove_AHT20\n", + "from pynq.lib.pmod import PMOD_GROVE_G3" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 4. Receiving Measurements\n", + "We instantiate the sensor using the Grove_ATH20 constructor. This is very similar to a function, but it returns an object that represents our sensor that we can then use to call functions like get_temp()." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Humidity: 33.32 %\n", + "Temperature: 27.5 °C\n" + ] + } + ], + "source": [ + "py_ht = Grove_AHT20(base.PMODB, PMOD_GROVE_G3)\n", + "\n", + "humidity = py_ht.get_humidity()\n", + "temp_c = py_ht.get_temp()\n", + "print('Humidity: ', float(\"{0:.2f}\".format(humidity)), '%')\n", + "print('Temperature: ', float(\"{0:.2f}\".format(temp_c)), '°C')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 2. Display on LED bar" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Setup:\n", + "\n", + "Attached the arduino shield to the top of your board. Connect the LED bar to the G7 port on the Arduino shield. Connect the ATH20 to port G3 on the PMOD to Grove adaptor. Run the following code to initiate connection with the LED bar:" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [], + "source": [ + "from pynq.lib.arduino import Grove_LEDbar\n", + "from pynq.lib.arduino import ARDUINO_GROVE_G7\n", + "\n", + "ledbar = Grove_LEDbar(base.ARDUINO, ARDUINO_GROVE_G7)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Reset the LED Bar\n", + "\n", + "The default state of the LED could be all sorts of things. Let's turn it fully of so we have somewhere to work from." + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [], + "source": [ + "# Turn the LED bar off\n", + "ledbar.reset()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Decide on Your Temperature Scale\n", + "\n", + "We want to make a visual thermometer that displays the temperature across a range that we care about. Perhaps this is simply comfortable room temperature (somewhere between 60 and 80 degrees fahrenheit), or it's the temperature of industrial equipment that cannot get above 150 degrees fahrenheit. What we will do next is establish this range and \"map\" it to the 10 bars on the LED indicator, with the red being the highest end of the range and the green being the lowest. For this example, lets the temperature we might find in a house in Colorado, 60 to 80 degrees fahrenheit, or about 15 to 25 degrees celsius (remember, our sensors read celsius, so make sure to convert when necessary)" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [], + "source": [ + "max_temp = 25\n", + "min_temp = 15\n", + "temp_range = max_temp - min_temp" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We should consider \"edge cases\" where our temperature falls above or below our range. These are always good to check before we proceed. In this situation, we will illuminate all LEDs if the temperature is above the range, and 1 LED if it is below the range.\n", + "\n", + "Once we have ruled out edge cases, we can deal with the case where our temperature falls within our allotted range. Because there are 10 bars, we can only only display the temperature in tenths of our range. Knowing what our range is, we can calculate a number between 0 and 10 to represent where within the range we fall. Note that we multiply by 10 and round to the nearest whole number to make sure we pass an integer between 0 and 10 to the function up_to().\n", + "\n", + "Because our LED bar speaks in binary, We are going to use a function \"up_to\" which produces the binary value required to light up the bars \"up to\" a certain index on the led bar, given that index. This is covered more in depth in the [LED Bar notebook](../bootcamp_sessions/3_led_bar.ipynb)." + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [], + "source": [ + "def up_to(index):\n", + " return ~(2**(10 - index) - 1)" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [], + "source": [ + "# if temperature is above our range of measurement\n", + "if temp_c > max_temp:\n", + " ledbar.write_binary(up_to(10))\n", + "# if temperature is below our range of measurement\n", + "elif temp_c < min_temp:\n", + " ledbar.write_binary(up_to(0))\n", + "# otherwise is falls within our range\n", + "else:\n", + " temp_index = int(round(((temp_c - min_temp)/temp_range)*10))\n", + " ledbar.write_binary(up_to(temp_index))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/extra/temp_ledbar_example_TH02.ipynb b/extra/temp_ledbar_example_TH02.ipynb new file mode 100644 index 0000000..32c40d1 --- /dev/null +++ b/extra/temp_ledbar_example_TH02.ipynb @@ -0,0 +1,268 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Displaying Sensor Data on the LED Bar\n", + "\n", + "A key concept in computers is taking an input from a sensor, processing that data in a meaningful way, and outputting that to the user in a format that is intuitive and easy to read. This concept can be found in almost every computing system. \n", + "\n", + "We are going to create this type of system with our sensors and LED bar. The end product will be a sort of \"digital thermometer\".\n", + "\n", + "### This notebook will walk you through using the TH02 sensor\n", + "\n", + "If your sensor looks like this, it is a TH02 and you should follow this notebook. If not, you should use the ATH20 sensor notebook [here](temp_ledbar_example_ATH20.ipynb).\n", + "\n", + "![TH02](https://files.seeedstudio.com/wiki/Grove-TemptureAndHumidity_Sensor-High-Accuracy_AndMini-v1.0/img/main.jpg)\n", + "\n", + "As usual, apply the base overlay to the board:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "\n", + "require(['notebook/js/codecell'], function(codecell) {\n", + " codecell.CodeCell.options_default.highlight_modes[\n", + " 'magic_text/x-csrc'] = {'reg':[/^%%microblaze/]};\n", + " Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n", + " Jupyter.notebook.get_cells().map(function(cell){\n", + " if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n", + " });\n", + "});\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from pynq.overlays.base import BaseOverlay\n", + "base = BaseOverlay(\"base.bit\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 1. Read Temperature Data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Import Libraries" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from pynq.lib.arduino import Grove_TH02\n", + "from pynq.lib.arduino import ARDUINO_GROVE_I2C" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Plugging in your TH02 Sensor\n", + "\n", + "This sensor uses the Arduino shield to communicate with your PYNQ Board. Attach the Arduino shield to the top of your PYNQ Board. Then, plug in the TH02 Sensor to one of the ports labeled I2C on the Arduino shield.\n", + "\n", + "![grove_adaptor](https://cdn10.bigcommerce.com/s-7gavg/products/531/images/4194/PYNQ_Shield_-_Oblique_-_600__81639.1473444236.1280.1280.png?c=2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Initialize the Temperature Sensor\n", + "\n", + "We create an variable called \"th02\" that represents the sensor. From this object we can call functions that retrieve data from the sensor." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "th02 = Grove_TH02(base.ARDUINO,ARDUINO_GROVE_I2C)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Read the Temperature and Humidity\n", + "Calling the function read() returns a tuple (two values separated by a comma). The first value is temperature and the second value is humidity." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The temperature is 28.21875 degrees celsius and the relative humidity is 40.0625 %\n" + ] + } + ], + "source": [ + "temp_c, humidity = th02.read()\n", + "print('The temperature is {} degrees celsius and the relative humidity is {} %'.format(temp_c, humidity))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Display the Data to the LED Bar\n", + "\n", + "## Connecting the LED Bar\n", + "\n", + "Plug the LED bar into the port labeled G1 on your PMOD to Grove Adaptor. Then plug the PMOD to Grove adaptor into the port labeled PMODB on your PYNQ-Z2 Board" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Setup\n", + "\n", + "When the hardware is connected, run the following code to tell the PYNQ Board how you connected everything. If you plugged into a port besides G1, such as G2, then you will need to import `PMOD_GROVE_G2` instead." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "from pynq.lib.pmod import Grove_LEDbar\n", + "from pynq.lib.pmod import PMOD_GROVE_G1\n", + "\n", + "ledbar = Grove_LEDbar(base.PMODB, PMOD_GROVE_G1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Reset the LED Bar\n", + "\n", + "The default state of the LED could be all sorts of things. Let's turn it fully of so we have somewhere to work from." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# Turn the LED bar off\n", + "ledbar.reset()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Decide on Your Temperature Scale\n", + "\n", + "We want to make a visual thermometer that displays the temperature across a range that we care about. Perhaps this is simply comfortable room temperature (somewhere between 60 and 80 degrees fahrenheit), or it's the temperature of industrial equipment that cannot get above 150 degrees fahrenheit. What we will do next is establish this range and \"map\" it to the 10 bars on the LED indicator, with the red being the highest end of the range and the green being the lowest. For this example, lets the temperature we might find in a house in Colorado, 60 to 80 degrees fahrenheit, or about 15 to 25 degrees celsius (remember, our sensors read celsius, so make sure to convert when necessary)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "max_temp = 25\n", + "min_temp = 15\n", + "temp_range = max_temp - min_temp" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We should consider \"edge cases\" where our temperature falls above or below our range. These are always good to check before we proceed. In this situation, we will illuminate all LEDs if the temperature is above the range, and 1 LED if it is below the range.\n", + "\n", + "Once we have ruled out edge cases, we can deal with the case where our temperature falls within our allotted range. Because there are 10 bars, we can only only display the temperature in tenths of our range. Knowing what our range is, we can calculate a number between 0 and 10 to represent where within the range we fall. Note that we multiply by 10 and round to the nearest whole number to make sure we pass an integer between 0 and 10 to the function up_to().\n", + "\n", + "Because our LED bar speaks in binary, We are going to use a function \"up_to\" which produces the binary value required to light up the bars \"up to\" a certain index on the led bar, given that index. This is covered more in depth in the [LED Bar notebook](../bootcamp_sessions/3_led_bar.ipynb)." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "def up_to(index):\n", + " return ~(2**(10 - index) - 1)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "# if temperature is above our range of measurement\n", + "if temp_c > max_temp:\n", + " ledbar.write_binary(up_to(10))\n", + "# if temperature is below our range of measurement\n", + "elif temp_c < min_temp:\n", + " ledbar.write_binary(up_to(0))\n", + "# otherwise is falls within our range\n", + "else:\n", + " temp_index = int(round(((temp_c - min_temp)/temp_range)*10))\n", + " ledbar.write_binary(up_to(temp_index))" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}