{"id":18870504,"url":"https://github.com/robseb/django2fpgademo","last_synced_at":"2025-04-14T15:23:37.532Z","repository":{"id":240748098,"uuid":"234716745","full_name":"robseb/Django2FPGAdemo","owner":"robseb","description":"Demonstration how to build a Management Web interface to interact with the FPGA fabric and change the FPGA configuration with the Django Framework ","archived":false,"fork":false,"pushed_at":"2021-06-27T10:53:07.000Z","size":2493,"stargazers_count":12,"open_issues_count":0,"forks_count":5,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-28T04:13:37.115Z","etag":null,"topics":["adc","altera","cyclone-v","de10-nano","de10-standard","de10nano","django","django-framework","fpga-configuration","fpga-data","fpga-fabric","intel-fpga","rsyocto","sensor-data","soc-fpga"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/robseb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"robseb"}},"created_at":"2020-01-18T10:19:50.000Z","updated_at":"2025-03-23T01:53:13.000Z","dependencies_parsed_at":"2024-05-20T19:28:09.619Z","dependency_job_id":null,"html_url":"https://github.com/robseb/Django2FPGAdemo","commit_stats":null,"previous_names":["robseb/django2fpgademo"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robseb%2FDjango2FPGAdemo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robseb%2FDjango2FPGAdemo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robseb%2FDjango2FPGAdemo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robseb%2FDjango2FPGAdemo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/robseb","download_url":"https://codeload.github.com/robseb/Django2FPGAdemo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248904853,"owners_count":21180865,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["adc","altera","cyclone-v","de10-nano","de10-standard","de10nano","django","django-framework","fpga-configuration","fpga-data","fpga-fabric","intel-fpga","rsyocto","sensor-data","soc-fpga"],"created_at":"2024-11-08T05:20:58.971Z","updated_at":"2025-04-14T15:23:37.492Z","avatar_url":"https://github.com/robseb.png","language":"Python","funding_links":["https://github.com/sponsors/robseb"],"categories":[],"sub_categories":[],"readme":"# Demonstration how to build with the Django Framework a Management Web interface to interact with the FPGA fabric and change the FPGA configuration\n\n\n ![Alt text](pic/pic00.jpg?raw=true \"Concept\")\n\n\n**This step by step guide shows how to log Sensor Data from a Soft-IP ADC interface within a SQLite-Database and how to plot these data on a web interface. In addition, it is demonstrated how to manage and change the FPGA Configuration with just a web browser.**\n\nComplex web interfaces for controlling and monitoring on embedded systems are standard today. Especially for low quantity FPGA applications, the development of these web applications is often time-consuming. To accelerate this process, it is important to use powerful web development frameworks with simple to use IDEs such as Django. A huge community on desktop site uses that and if the same version of Django runs on the embedded Linux, it is possible to benefit from their knowledge. Django has a comprehensive documentation with many demos. However, these demos are for typical Desktop- and Cloud- applications and not for embedded ones. The important part of embedded management web applications is the interaction between the web interface and Sensor- or FPGA-data.\n\nTo demonstrate this, the ADC converter (*Analog Devices LTC2308*) of a *Terasic DE10-Nano*- or *DE10-Standard* Board (Intel Cyclon V SoC-FPGA) with a Soft-IP interface is connected via the *Lightweight HPS to FPGA Bridge* to the Hard Processor System (HPS). \nOn the ARM Cortex-A9 of the HPS my embedded Linux, called [*rsYocto*](https://github.com/robseb/rsyocto), customized for Intel SoC-FPGA is running.\n\nOn *rsYocto* the **Django Framework  (Version 3.0.2)** with all necessary components, like the **Apache Webserver** and the **SQLite database**, is pre-installed. \n\n**This approach is the monitoring and management of embedded FPGA systems with a web interface**. This cannot be consider for low latency real-time applications. \nThe advantage of the usage of SQLite and HTTP with Linux is that these are standard in the desktop world. It allows for example to connect the data with a cloud service by adding a few extensions.\n\n\u003cbr\u003e\n\n\n### Screenshot of the Web interface\n\n![Alt text](pic/FinalWebinterface.PNG?raw=true \"Screenshot of the final Web interface\")\n\u003cbr\u003e\n\n* **Features** \n  * **Plotting the ADC convention voltage from a Soft-IP ADC**\n  * **Uploading and managing of FPGA configuration files**\n  * **Configuration of the FPGA fabric**\n  * **Controlling a FPGA LED**\n\n___\n\n### Reading a Sensor Value with the Django web framework - Sequence Diagram\n\nThe following sequence Diagram shows all involved actors and the data flow by reading an ADC Value to a *SQLite* Database. If an user opens the web page, Django plots the complete data into the web interface as shown below. \n![Alt text](pic/SequenceDiagram.jpg?raw=true \"Sequence Diagramm of the Sensor Reading\")\n\nA HTTP GET-command (here by calling the URL *http://127.0.1:8181/ADCtrigger*) triggers the Django web application. It calls the “*read Sensor*” application. This is a python script, which reads the Soft-IP ADC Interface and returns the ADC convention. Then Django adds the value with a time stamp to the *SQLite* database. \n\nTo repeat and time sync the readout of the ADC a Shell script or the tool `crontab` can be considered.\n\nIn case an user is going to open the web application, Django loads the complete data of the ADC from the database and plots them graphically into the webpage.  \nThis is one part of the final application. The interface for managing FPGA Configurations works similarly. \n\n\u003cbr\u003e\n\n___\n\n### Table of Content\n\n1. [**Project Preparations**](https://github.com/robseb/Django2FPGAdemo#project-preparations)\n2. [**Installing the finshed Web interface**](https://github.com/robseb/Django2FPGAdemo#installing-the-finshed-web-interface)\n3. [**Creating a new Django Project on the SoC-FPGA**](https://github.com/robseb/Django2FPGAdemo#creating-a-new-django-project-on-the-soc-fpga)\n4. [**Creating a new Django App to interact with the FPGA fabric**](https://github.com/robseb/Django2FPGAdemo#creating-a-new-django-app-to-interact-with-the-fpga-fabric)\n5. [**Testing the Web Appilcation**](https://github.com/robseb/Django2FPGAdemo#testing-the-web-application)\n6. [**Reading of a Soft-IP ADC interface and writing the data into a SQLite datbase**](https://github.com/robseb/Django2FPGAdemo#reading-of-a-soft-ip-adc-interface-and-writing-the-data-into-a-sqlite-datbase)\n7. [**Configuring the plotting of an ADC Channel**](https://github.com/robseb/Django2FPGAdemo#configuring-the-plotting-of-an-adc-channel)\n8. [**Reading and plotting the data time triggered**](https://github.com/robseb/Django2FPGAdemo#reading-and-plotting-the-data-time-triggered)\n___\n\u003cbr\u003e\n\n# Project Preparations \n\n* Boot up [*rsYocto*](https://github.com/robseb/rsyocto) on your Intel SoC-FPGA Board by following the [getting started Guide](https://github.com/robseb/rsyocto/blob/rsYocto-1.03/doc/guides/1_Booting.md)\n* Setup Visual Studio Code Insider with [this instruction guide](https://github.com/robseb/rsyocto/blob/rsYocto-1.03/doc/guides/4_Python.md)\n* On *rsYocto* (Version. 1.031+) are following compunets for this project pre-installed:\n  * `Django 3.0.2`\n  *  [*rstools*](https://github.com/robseb/meta-rstools) for accessing the FPGA fabric\n  *  During the boot are following modules connected to the Lightweight HPS to FPGA Bridge\n     * PIO-Controller for controlling the on-Board LEDs on the Address offset [0x20](https://raw.githubusercontent.com/robseb/rsyocto/rsYocto-1.03/doc/symbols/DE10Nano_pinout.png)\n     * *Analog Devices LTC2308* Interface IP on the Address offset [0x40](https://raw.githubusercontent.com/robseb/rsyocto/rsYocto-1.03/doc/symbols/DE10Nano_pinout.png)\n\n\n\n# Installing the finshed Web interface\n\nFor installing and testing the final project do the following steps:\n * Clone this repository by executing the following Linux Terminal command on *rsYocto*\n   ````bash\n   git clone https://github.com/robseb/Django2FPGAdemo.git\n   ````\n * Navigate inside the project folder\n   ````bash\n   cd DjangoFPGA/DjangoFPGA\n   ````\n * Generate an administration interface with your login information\n   ````bash\n   python3 manage.py createsuperuser\n   ````\n* Please follow: [Testing the Web Appilcation](https://github.com/robseb/Django2FPGAdemo#testing-the-web-application)\n___\n\u003ch3\u003e\u003cu\u003e Or build it by your own with this step by step guide: \u003c/u\u003e \u003c/h3\u003e\n\u003cbr\u003e\n\n# Creating a new Django Project on the SoC-FPGA\n\n* Use the Linux Terminal, which is reachable inside *Visual Studio Code Insider* to create a new Django project with the name \"DjangoFPGA\" by executing the following command:\n  ````bash\n  django-admin startproject DjangoFPGA\n  ````\n  ![Alt text](pic/pic01.jpg?raw=true \"Django Development with Visual Studio Code\")\n \n * **Note:** Use in the drop-down menu (blue arrow) the point \"*sh*\" to access the Linux Terminal. In case the point is not there, press the “**+**”-icon to add it. \n * Navigate with the Linux Terminal inside Visual Studio code to this project\n   ````bash\n   cd DjangoFPGA\n   ````\n \n## Testing the empty Django Project by accessing it with a web browser\n\n* By default the Django web server is only reachable internally by the embedded Linux\n* To access Django applications within your network do the following steps:\n  1. Open the Django project settings file (*settings.py*) with *Visual Studio Code* (as shown above) and allow everybody to connect with the following lines:\n      ````python\n      ALLOWED_HOSTS = [\n       '*'\n     ]\n     ````\n  2. After some change of the settings file a **migration** of the project is necessary:\n      ````bash\n      python3 manage.py migrate \n      ````\n    * The output of this command should look like this:\n      ````bash\n      root@cyclone5:~/DjangoFPGA# python3 manage.py migrate\n      Operations to perform:\n      Apply all migrations: admin, auth, contenttypes, sessions\n      Running migrations:\n      Applying contenttypes.0001_initial... OK\n      Applying auth.0001_initial... OK\n      Applying admin.0001_initial... OK\n      Applying admin.0002_logentry_remove_auto_add... OK\n      Applying admin.0003_logentry_add_action_flag_choices... OK\n      Applying contenttypes.0002_remove_content_type_name... OK\n      Applying auth.0002_alter_permission_name_max_length... OK\n      Applying auth.0003_alter_user_email_max_length... OK\n      Applying auth.0004_alter_user_username_opts... OK\n      Applying auth.0005_alter_user_last_login_null... OK\n      Applying auth.0006_require_contenttypes_0002... OK\n      Applying auth.0007_alter_validators_add_error_messages... OK\n      Applying auth.0008_alter_user_username_max_length... OK\n      Applying auth.0009_alter_user_last_name_max_length... OK\n      Applying auth.0010_alter_group_name_max_length... OK\n      Applying auth.0011_update_proxy_permissions... OK\n      Applying sessions.0001_initial... OK\n      ````\n  3. Use the next command to **start the web server** (here on Port 8181)\n      ````bash\n      python3 manage.py runserver 0:8181\n      ````\n    * The output of this command should look like this:\n      ````bash\n      root@cyclone5:~/DjangoFPGA# python3 manage.py runserver 0:8181\n      Watching for file changes with StatReloader\n      Performing system checks...\n\n      System check identified no issues (0 silenced).\n      January 18, 2020 - 15:35:44\n      Django version 3.0.2, using settings 'DjangoFPGA.settings'\n      Starting development server at http://0:8181/\n      Quit the server with CONTROL-C.\n      ````\n    * **Note:** The default port 8080 is used by the *Apache web server*\n  \n* Go with a web browser on a device inside this network (computer, tablet, smart-phone) to the URL:\n     ````txt\n      http://\u003ciPv4-Address of the Board\u003e:8181/ \n     ````\n* If you see a *rocket lunch* your Django project works properly \n\n  ![Alt text](pic/pic02.jpg?raw=true \"Django Start screen\")\n\n\n* All **HTTP**-attaches are listed on the terminal as well\n\n\n# Creating a new Django App to interact with the FPGA fabric\nEvery Django project requires at least one application (App). We will build an App to readout the Soft-IP ADC Interface (*Analog Devices LTC2308*) of a Terasic DE10-Standard- or Terasic DE10-Nano-Board and present the data in the web browser.\nAs a second feature, we will build a management interface for changing the FPGA configuration. \n\n*  The following command adds a new app called \"*BoardInteraction*\" to the project.\n   ````bash\n   python3 manage.py startapp BoardInteraction\n   ````\n  * **Note:** Be sure that this command is executed inside the project-folder (*DjangoFPGA/*)\n* The project folder contains the following structure now:\n  * All important files are marked\n  \n  ![Alt text](pic/pic03.jpg?raw=true \"Django Folder structure\")\n  \n* Add this application to the Django project by adding the following line to the variable **INSTALLED_APPS** iniside  *settings.py*:\n  ````python\n  # Application definition\n  INSTALLED_APPS = [\n      'BoardInteraction.apps.BoardinteractionConfig', # Add this line \n      'django.contrib.admin',\n      'django.contrib.auth',\n      'django.contrib.contenttypes',\n      'django.contrib.sessions',\n      'django.contrib.messages',\n      'django.contrib.staticfiles',\n  ]\n  ````\n  * **Note:** This is a connection to the *main-function* *BoardinteractionConfig()* that is located in the *\"app.py\"* file\n  * **Migrate** the project again\n   ````bash\n   python3 manage.py migrate \n   ````\n\n## Creating a model to store the Sensor data and FPGA configuration files into a SQLite database\n* Add the following python code to the model file (*DjangoFPGA/BoardInteraction/models.py*)\n  ````python\n  '''\n  Django FPGA Interaction demo application - \"models.py\"\n  '''\n  from django.db import models\n  from datetime import datetime\n   #\n   # Class for reading an analog Sensor \n   #\n   class ADCSensorReading(models.Model):\n       # Sensor value as Char Text Field type   \n       reading = models.FloatField()         \n       timestamp = models.DateTimeField(default=datetime.now, db_index=True)    # Time stamp\n\n       def __unicode__(self):\n           return self.reading\n\n   # \n   # Class for connecting an Analog Devices LTC LTC2308 ADC Channel\n   #\n   class ADCchannel(models.Model):\n       name     = models.CharField(max_length=200)          # a name for the Sensor on the ADC Channel\n       slug     = models.SlugField(unique=True)             # an unique working handler name\n       readings = models.ManyToManyField(ADCSensorReading)  # the sensor data object\n       ch       = models.IntegerField() # the used ADC Channel Number\n\n       def __unicode__(self):\n           return self.name\n\n   # \n   # FPGA .rbf Configuration File Database\n   # \n   class FPGAconfFiles(models.Model):\n       docfile = models.FileField(upload_to='FPGAconfigDatabase/%Y/%m/%d')      # local storge folder  \n       timestamp = models.DateTimeField(default=datetime.now, db_index=True)    # Time stamp\n  ````\n \n ## Creating an Administrator page to allow an access to the database\n * Create an user who can do the login to the admin site. Run the following command:\n    ````bash\n    python3 manage.py createsuperuser\n    ````\n * Enter an Username, an Email-Address and a Passwort\n    ````bash\n    Password: **********\n    Password (again): *********\n    Superuser created successfully.\n    ````\n * Allow the Admin to access all database models by adding the following code lines to the Admin-file (*DjangoFPGA/BoardInteraction/admin.py*)\n   ````python\n   '''\n   Django FPGA Interaction demo application  - \"admin.py\"\n   '''\n\n   from django.contrib import admin\n   from BoardInteraction.models import ADCSensorReading, ADCchannel, FPGAconfFiles\n\n   # Allow access to all ADC data models and FPGA configuration files inside the SQLite Database\n   admin.site.register(ADCchannel)\n   admin.site.register(ADCSensorReading)\n   admin.site.register(FPGAconfFiles) \n\n   # Personalisation of the admin page\n   admin.site.site_header = 'rsYocto'                                         # Headline title           \n   admin.site.index_title = 'Django FPGA interaction Demo Administration'     # Sub-Headline title       \n   admin.site.site_title = 'rsYocto'                                          # HTML Headline\n   ````\n   \n ## Testing the Administrator page\n * Save all open files\n * To generate a SQLite database with these settings execude the following Linux Shell commands (*DjangoFPGA/*):\n   ````bash\n   python3 manage.py makemigrations\n   python3 manage.py migrate\n   python3 manage.py migrate --run-syncdb\n   ````\n * Start the Django Server\n   ````bash \n   python3 manage.py runserver 0:8181\n   ```` \n * Open the following URL with a web browser:\n   ````txt\n   http://\u003ciPv4-Address of the Board\u003e:8181/admin \n   ```` \n * The Yocto Login Screen should appear:\n   \n  ![Alt text](pic/pic04.jpg?raw=true \"Django Adim Login Screen\")\n \n * Use your login credentials to login\n \n  ![Alt text](pic/pic05.jpg?raw=true \"Django Adim interface\")\n  \n * Here are all created databases accessible\n * At this point it is possible to add the sensor data manuelly \n \n \n ## Presenting the Sensor Data and FPGA configuration on a web page\n  * To view this data in a graphic the library [plotly](https://plot.ly/python/) is used\n    * That is an easy way to implement such kind of UI-elemets to a web page. \n    * In the same way it is possible to add any kind of diagramms to this web App (please follow the [official documentation](https://plot.ly/python/)\n  * To display something on a web page it is necessary to add some lines of code to the \"*views.py*\"-file (*DjangoFPGA/AccSensor/views.py*):\n    ````python\n    '''\n    Django FPGA Interaction demo application  - \"views.py\"\n    '''\n\n    from django.http import Http404\n    from django.shortcuts import render, HttpResponse, HttpResponseRedirect\n    from .models import ADCSensorReading\n    from subprocess import call\n\n    # use \"pip install plotly\" to add this package\n    from plotly.graph_objs import Scatter\n    from plotly.offline import plot \n    import plotly.graph_objects as go\n\n\n    # For accessing the FPGA configuration\n    from subprocess import call\n\n    # For working with a file upload box \n    from .forms import DocumentForm\n    from .models import FPGAconfFiles\n\n    # For accessing the the Project settings\n    from django.conf import settings\n\n    # import trigger function for reading the ADC\n    from BoardInteraction.services import ReadADCchannel\n\n\n    # \n    # Called in case the user opened the main web page of the App\n    # the complete UI will be built and transmitted to the web browser\n    #\n    def detail(request):\n\n        # Handle file upload for the FPGA configuration file\n        if request.method == 'POST':\n            form = DocumentForm(request.POST, request.FILES)\n            if form.is_valid(): \n                # Upload the File to the Database\n                newdoc = FPGAconfFiles(docfile = request.FILES['docfile'])\n                newdoc.save()\n                # Write FPGA Configuration\n                call('FPGA-writeConfig -f '+settings.BASE_DIR+\"/\"+newdoc.docfile.url, shell=True)\n        else:\n            form = DocumentForm() \n\n        # Load all stored FPGA configuration files\n        try:\n            FPGAconfigFiles = FPGAconfFiles.objects.all()\n        except ADCSensorReading.DoesNotExist:   \n            raise Http404(\"FPGA Configuration data does not exist\")\n\n        # Load the ADC Value database\n        try:\n            adcChvalue = ADCSensorReading.objects.all() \n        except ADCSensorReading.DoesNotExist:        \n            raise Http404(\"ADC data does not exist\")  # In case of an Error display an Error 404 Screeen\n\n        ### Plot the ADC Values #####\n\n        # Plot the latest 100 data points in time order \n        adcData = adcChvalue.order_by('-timestamp')[:100]\n        \n        # pre-process the ADC data of the database\n        y_data= []\n        x_data= []\n\n        for b in adcData:\n            y_data.append(b.reading)\n            x_data.append(b.timestamp)\n\n        # create a new line plot element \n        fig = go.Figure()\n        fig.add_trace(go.Scatter(x=x_data, y=y_data, name='Sensor Voltage',\n                                line = dict(color='royalblue', width=4, dash='dashdot')))\n        # Edit the layout\n        fig.update_layout(title='Plot of recorded ADC data from a Soft IP-interface',\n                        xaxis_title='Time (UTC)  [HH:MM:SS]',\n                        yaxis_title='ADC Voltage (V)')\n\n        # store the plot object \n        plot_div = plot(fig, output_type='div', include_plotlyjs=False)\n\n        # render the HTML template with all values\n        return render(request, \"BoardInteraction/DisplayTemplate.html\", context=\n        { \n            'plot_div': plot_div,           # Plot object \n            'obj':adcData,                  # ADC raw data \n            'documents': FPGAconfigFiles,   # FPGA Configuration files \n            'form': form                    # Upload File form\n        })\n\n    ````\n  * For displaying the FPGA Configuration management interface extend the *views.py*-file with the following lines of python code \n    ```python\n    #\n    # If the user select a FPGA Configuration file this function will be called \n    # to insert the file to the data base and the FPGA will be configured with it\n    #\n    def change_FPGAconfiguration(request):\n        # \u003cURL\u003e/?subjectID=\u003cConfiguration file path\u003e\n        subjectID = request.GET.get(\"subjectID\")\n\n        # Write this file on the FPGA fabric \n        call('FPGA-writeConfig -f '+settings.BASE_DIR+\"/\"+subjectID, shell=True)\n\n        # Relaod the main app page again \n        return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))\n\n\n    #\n    # If the user select the rool back to the boot FPGA Configuration this function will be called \n    #\n    def change_FPGAconfigurationBack(request):\n        # \u003cURL\u003e/?subjectID=\u003cConfiguration file path\u003e\n        subjectID = request.GET.get(\"subjectID\")\n\n        # Write the FPGA fabric back to the boot state\n        call('FPGA-writeConfig -r', shell=True)\n\n        # Relaod the main app page again \n        return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))\n    ```\n    * These are two event functions, which are triggered in the case a FPGA-Configuration button was pressed\n  * To allow to collect and update the ADC Sensor data add the following function to the *\"views.py\"*-file\n    ````python\n    #\n    # ADC Store data trigger function \n    #\n    def ADCtrigger(request):\n        ReadADCchannel()\n        return HttpResponse('')\n    ````\n\n  * With these functions two events are declared, this allows to control the FPGA LED 0 with a push button:\n    * Add them to the \"*views.py*\"-file as well\n     ````python\n      #\n      # Function to turn FPGA LED 0 on called in case the ON-button was pressed \n      #\n      def LED0_ON(request):\n          # Turn FPGA LED0 on \n          call('FPGA-writeBridge -lw 20 -b 0 1 -b', shell=True)\n          # Relaod the main app page again \n          return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))\n\n\n      #\n      # Function to turn FPGA LED 0 off called in case the OFF-button was pressed \n      #\n      def LED0_OFF(request):\n          # Turn FPGA LED0 off\n          call('FPGA-writeBridge -lw 20 -b 0 0 -b', shell=True)\n          # Relaod the main app page again \n          return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))\n      ````\n\n  * The *render*-function uses the \"*DisplayTemplate.html*\" HTML file to build the canvas of the web interface\n  * Django only looks for this kind of template file in this folder structure: *\u003cApp\u003e/templates/\u003cApp\u003e/*\n  * That meens, that this file must be located here:\n    ````txt\n    DjangoFPGA/BoardInteraction/templates/BoardInteraction/DisplayTemplate.html\n    ````\n    * Creat the file with all folders with *Visual Studio Code Insider*\n  * For building a simple UI add the following to the HTML file:\n    ````html\n    \u003c!-- Django FPGA Interaction demo application - DisplayTemplate.html --\u003e\n    \u003c!DOCTYPE HTML\u003e\n    \u003chtml\u003e\n      \u003chead\u003e\n        \u003c!--Load the ploty Library script --\u003e\n        \u003cscript src=\"https://cdn.plot.ly/plotly-latest.min.js\"\u003e\u003c/script\u003e\n        \u003cmeta charset=\"utf-8\"\u003e\n        \u003c/script\u003e\n        \u003ctitle\u003ersYocto Django Demo\u003c/title\u003e\n      \u003c/head\u003e\n      \u003cbody\u003e\n        \u003ccenter\u003e\n        \u003cp\u003e\u003cembed src=\"https://raw.githubusercontent.com/robseb/rsyocto/rsYocto-1.03/doc/symbols/rsYoctoLogo.jpg?raw=true\" width=\"300\" height=\"120\" title=\"rsYocto Logo\" /\u003e\u003c/p\u003e\n        \u003ch2\u003eSimple Django demo application for using a web interface to control and access the FPGA fabric\u003c/h2\u003e\n        \u003cbr\u003e\n        \u003c!--Load the ploty UI--\u003e\n        \u003ch3\u003eFPGA IP data plot \u003c/h3\u003e\n\n        {% autoescape off %}\n        {{ plot_div }}\n        {% endautoescape %}\n        \u003cbr\u003e  \n\n        \u003c!--Show the FPGA Configuration File upload box--\u003e\n        \u003ch3\u003eChnage the FPGA Configuration \u003c/h3\u003e\n        \u003cform action=\"{% url 'main' %}\" method=\"post\" enctype=\"multipart/form-data\"\u003e\n              {% csrf_token %}\n              \u003cp\u003e{{ form.non_field_errors }}\u003c/p\u003e\n              \u003cp\u003e{{ form.docfile.label_tag }} {{ form.docfile.help_text }}\u003c/p\u003e\n              \u003cp\u003e\n                  {{ form.docfile.errors }}\n                  {{ form.docfile }}\n              \u003c/p\u003e\n              \u003cp\u003e\u003cinput type=\"submit\" value=\"Upload\"/\u003e\u003c/p\u003e\n          \u003c/form\u003e\n          \u003c!--Show a list of all stored FPGA configuration files--\u003e\n          \u003cbr\u003e\n          \u003ch3\u003eFPGA configuration manager \u003c/h3\u003e\n          \u003ch4\u003eList of all saved FPGA configuration files\u003c/h4\u003e\n          {% if documents %}\n          \u003cul\u003e\n            \u003ctable  border=\"1\"\u003e\n              \u003ctr\u003e\n                \u003cth\u003eFile Name\u003c/th\u003e\n                \u003cth\u003eUpload Date\u003c/th\u003e\n                \u003cth\u003eLoad to the FPGA fabric\u003c/th\u003e\n              \u003c/tr\u003e\n            {% for document in documents %}\n                  \u003ctr\u003e\n                    \u003ctd\u003e{{document.docfile.name}}\u003c/td\u003e\n                    \u003ctd\u003e{{document.timestamp}}\u003c/td\u003e\n                    \u003ctd\u003e\u003ca href=\"{% url 'scriptFPGAconf' %}?subjectID={{document.docfile.url}}\"\u003eConfigure FPGA\u003c/a\u003e\u003c/td\u003e\n                  \u003c/tr\u003e\n            {% endfor %}\n            \u003ctr\u003e\n              \u003ctd\u003eBootloader FPGA Configuration\u003c/td\u003e\n              \u003ctd\u003e-\u003c/td\u003e\n              \u003ctd\u003e\u003ca href=\"{% url 'BootloaderFPGAconf' %}\"\u003eRoll back\u003c/a\u003e\u003c/td\u003e\n            \u003c/tr\u003e\n        \u003c/table\u003e\n\n          \u003c/ul\u003e\n        {% else %}\n            \u003cp\u003eNo documents.\u003c/p\u003e\n        {% endif %}\n          \u003c!--Create two push buttons to control the FPGA LED 0--\u003e\n          \u003cbr\u003e\n          \u003ch4\u003eFPGA LED 0 Control \u003c/h4\u003e\n          \u003cbutton onclick=\"location.href='{% url 'scriptLED0N' %}'\"\u003eLED 0 ON\u003c/button\u003e\n          \u003cbutton onclick=\"location.href='{% url 'scriptLED0F' %}'\"\u003eLED 0 OFF\u003c/button\u003e\n          \u003c/center\u003e\n        \u003c/body\u003e\n    \u003c/html\u003e  \n    ````\n* To show a File Upload box for the selecting of a FPGA configuration file these steps are requiered\n * Create inside the App the new file \"*form.py*\" (*DjangoFPGA/BoardInteraction/forms.py*)\n * Add the following code to this file\n   ````python\n   '''\n   Django FPGA Interaction demo application - \"form.py\"\n   '''\n   from django import forms\n\n   # \n   # Build the Upload File Box for selecting \n   # a FPGA configuration file \n   #\n   class DocumentForm(forms.Form):\n\n       docfile = forms.FileField(\n           label='Select a \".rbf\"- FPGA configuration file',\n           help_text='Click Upload to save the file and configure the FPGA fabric'\n       )\n   ````\n## Routing the URLs of the Application\n* By default nothing will be routed to the front page of this application (http://\u003ciPv4-Address of the Board\u003e:8181/)\n* To link the front page to the App, add the following lines of code to the global url configuration file (*DjangoFPGA/DjangoFPGA/urls.py*):\n  ````python\n  # DjangoFPGA URL Configuration\n  from django.contrib import admin\n  from django.urls import path\n\n  # Include the \"BoardInteraction\" App  \n  from BoardInteraction import views\n\n  # URL linkages of this project \n  urlpatterns = [\n\n      # UI \n      path('', views.detail,name=\"main\"),                 # Front page -\u003e linked to the \"BoardInteraction\" App \n      path('admin/', admin.site.urls),                    # /admin     -\u003e Admin interface\n\n      # HPS LED 0 \n      path('LED0_ON',views.LED0_ON,name=\"scriptLED0N\"),   # /LED0_ON   -\u003e triggered by pushing the LED0 ON Button \n      path('LED0_OFF',views.LED0_OFF,name=\"scriptLED0F\"), # /LED0_OFF  -\u003e triggered by pushing the LED0 OFF Button \n\n      # e.g. views.LED0_ON is the name of the viewer function  \n      # With e.g. the name=\"scriptLED0N\" the linkage is taken to the HTML event handler: '{% url 'scriptLED0N' %}'\n\n      # FPGA Configuration \n      path('FPGA',views.change_FPGAconfiguration,name=\"scriptFPGAconf\"),\n      path('BOOTFPGA',views.change_FPGAconfigurationBack,name=\"BootloaderFPGAconf\"),\n\n      # ADC Sensor Trigger\n      path('ADCtrigger',views.ADCtrigger,name=\"scriptADCtrigger\")\n  ]\n  ````\n  * Save all open files\n\n ## Testing the Web Application \n * Now all configurations of the user elements are done and it is time to test this state\n * Import the Python pip-package \"plotly\" using for the plotting of the data:\n   ````bash\n   pip install plotly\n   ````\n * Execude the following Linux Shell commands again (*DjangoFPGA/*):\n   ````bash\n   python3 manage.py makemigrations\n   python3 manage.py migrate\n   python3 manage.py migrate --run-syncdb\n   ````\n * Start the Django Server\n   ````bash \n   python3 manage.py runserver 0:8181\n   ```` \n * Open the following URL with a web browser:\n   ````txt\n   http://\u003ciPv4-Address of the Board\u003e:8181/admin \n   ```` \n * The front page should now look like this: \n   \n   ![Alt text](pic/pic08.jpg?raw=true \"Django App \")\n\n * Test the Webinterface:\n   * Change the FPGA configuration (the required type is described [here](https://github.com/robseb/rsyocto/blob/rsYocto-1.03/doc/guides/6_newFPGAconf.md))\n * Turn the FPGA LED ON or OFF\n \nAt this point the ADC plot is empty, because no application has written to the database. This will be solved in the next steps.\n\n# Reading of a Soft-IP ADC interface and writing the data into a SQLite datbase\nAs it is shwon in the sequence diagram above the readout of the FPGA data is triggered by calling the URL *http://127.0.1:8181/ADCtrigger*. Then the web interface starts an application to collect the ADC sensor data into the database. \n\nTo implement that two extensions of the project are required: \n 1.\tA function handler, that calls this application and writes the received values to the database \n   * Create a new python file called “services.py” (*DjangoFPGA/BoardInteraction/services.py*)\n   * Add the following code to it:\n      ````python\n      '''\n      Django FPGA Interaction demo application  - \"sevices.py\"\n      '''\n      import subprocess\n\n      from BoardInteraction.models import ADCSensorReading, ADCchannel \n\n      # For accessing the Project settings\n      from django.conf import settings\n\n      #\n      # Start a python application to read the ADC value \n      # and write the value to a database\n      #\n      def ReadADCchannel():\n          # For every activ ADC Channel \n          for sensor in ADCchannel.objects.all():   \n              adc_u = 0\n              # Start the Python Script \"adcReadChannel.py\" to read the ADC Channel\n              try: \n                  adc_u = float(subprocess.check_output(['python3',settings.BASE_DIR+'/BoardInteraction/adcReadChannel.py',str(sensor.ch)],stderr=subprocess.STDOUT, timeout=None))\n              except ValueError:\n                  adc_u = 0\n                  subprocess.call('echo Value Error ', shell=True)\n\n              # Write the value to the database\n              ADCSensorReading.reading = adc_u \n\n              newreading = ADCSensorReading(reading= ADCSensorReading.reading)\n              newreading.save()\n              sensor.readings.add(newreading)\n              sensor.save()\n\n          return True\n\n      ````\n2. An application to read an ADC Channel of the Soft-IP ADC interface\n  * *service.py* will call the following python script to read the ADC\n    ````text\n    Django2FPGAdemo/DjangoFPGA/BoardInteraction/adcReadChannel.py \n    ````\n  * Create this file \"adcReadChannel.py\" on this location and add the following lines to it\n    ````python\n    #!/usr/bin/env python\n    # coding: utf-8\n\n    '''\n    @disc:  Single Shoot ADC Channel readout (Analog Devices LTC2308)\n            Fast way over the virtual memory\n\n    @date:   21.01.2020\n    @device: Intel Cyclone V \n    @author: Robin Sebastian\n             (https://github.com/robseb)\n    '''\n    import os\n    import time\n    import math\n    import sys\n    # \n    # This demo uses the python class \"devmen\" (https://github.com/kylemanna/pydevmem)\n    # be sure that this file is on the same directory \n    #\n    import devmem\n\n    # the Lightweight HPS-to-FPGA Bus base address offset\n    HPS_LW_ADRS_OFFSET = 0xFF200000 \n\n    # LTC2308 Address offset\n    ADC_ADDRES_OFFSET = 0x40\n\n    # Register set of the LTC2308\n    ADC_CMD_REG_OFFSET  = 0x0\n    ADC_DATA_REG_OFFSET = 0x4\n\n\n    ### FIFO Convention Data Size for average calculation\n    FIFO_SIZE = 255 # MAX=1024 \n\n    if __name__ == '__main__':\n\n        # Read selected ADC Channel as input argument [1]\n        # python3 adcReadChannl \u003cCH\u003e \n        ch = 0\n        ch_selet = str(sys.argv[1])\n\n        try: \n            ch = int(ch_selet)\n        except ValueError:\n            ch = 0\n\n        if(not(ch \u003e=0 and ch \u003c 6)):\n            ch = 0\n\n        # open the memory Access to the Lightweight HPS-to-FPGA bridge\n        #                  (Base address, byte length to acceses, interface)\n        de = devmem.DevMem(HPS_LW_ADRS_OFFSET, ADC_ADDRES_OFFSET+0x8, \"/dev/mem\")\n\n\n        # Set FIFO size for ADC value averaging\n        de.write(ADC_ADDRES_OFFSET+ADC_DATA_REG_OFFSET,[FIFO_SIZE])\n\n        # Enable the convention with the selected Channel\n        de.write(ADC_ADDRES_OFFSET+ADC_CMD_REG_OFFSET, [(ch \u003c\u003c1) | 0x00])\n        de.write(ADC_ADDRES_OFFSET+ADC_CMD_REG_OFFSET, [(ch \u003c\u003c1) | 0x01])\n        de.write(ADC_ADDRES_OFFSET+ADC_CMD_REG_OFFSET, [(ch \u003c\u003c1) | 0x00])\n\n        timeout = 300 #ms\n        # Wait until convention is done or a timeout occurred\n        while (not(timeout == 0)):\n            if(de.read(ADC_ADDRES_OFFSET+ADC_CMD_REG_OFFSET,1)[0] \u0026 (1\u003c\u003c0)): \n                break\n\n            timeout = timeout -1\n            time.sleep(.001) # delay 1ms \n\n        # calculate the average of the FIFO\n        rawValue = 0\n        for i in range(FIFO_SIZE): \n            rawValue = rawValue+ (de.read(ADC_ADDRES_OFFSET+ADC_DATA_REG_OFFSET,1))[0]\n\n        value = rawValue / FIFO_SIZE\n\n        # Convert ADC Value to Volage\n        volage = round(value/1000,2)\n        # print the Value\n        print(str(volage))\n\n    ````\n  # Configuring the plotting of an ADC Channel\n  This Django application needs a new database entry for all ADC Channels to read.\n  This will be stored inside the database “ADCchannel“. This is only possible by hand as an Admin with the admin interface. \n \n * Start the Django Server\n   ````bash \n   python3 manage.py runserver 0:8181\n   ```` \n  * Open the following URL with a web browser:\n    ````txt\n    http://\u003ciPv4-Address of the Board\u003e:8181/admin \n    ```` \n* On the Admin page select  **+**-Icon in the menu \"Ad cchannels\" \n* Inside the opend view press the \"**ADD AD CCHANNEL**\" Button\n\n   ![Alt text](pic/pic06.jpg?raw=true \"Django Adim interface - add Channel 1\")\n   \n* Then insert the following to the web form to add a new Sensor to the ADC Channel\n   * **Name**:   The name of the Sensor\n   * **Slug**:   A unique ID for the Sensor \n   * **Reading**: The databebase with all sensor values\n   * **CH**:      The choosed ADC Channel\n \n \n ![Alt text](pic/pic07.jpg?raw=true \"Django Adim interface - add Channel 2\")\n \n * Press save\n * **Note:** It is necessary to add one sensor value to the \"readings\" at least\n   \n\n # Reading and plotting the data time triggered\n \n* Open the Application with the following URL on a web browser:\n   ````txt\n   http://\u003ciPv4-Address of the Board\u003e:8181/ \n   ```` \nAt this point only one ADC Value is inside the plot. To manually read the ADC channel it is possible to open\nthe following URL with a web browser:\n   ````txt\n   http://\u003ciPv4-Address of the Board\u003e:8181/ADCtrigger \n   ```` \nThen reload the application page. The new collected value is plotted now too. \n\nTo automatically read the ADC Channel in a time interval are two approaches shown here\n1.\t**Usage of a shell script**\n   * For example, run the following Linux shell script to read the ADC every 100 milliseconds for 500 times\n      ````console \n      #!/bin/sh\n      # Run script\n      echo \"*********************************\"\n      echo \"read ADC Channel every 100ms \"\n\n      for nvar in {1..500}\n      do\n        curl -s http://127.0.0.1:8181/ADCtrigger\n\n        sleep  0.1\n      done \n\n      echo \"*********************************\"\n      ````\n2.\t**Usage of the Linux task automation tool `crontab`**\n   * This is on *rsYocto* pre-installed\n   * A good documentation is available[here](https://www.computerhope.com/unix/ucrontab.htm)\n   *  Open the \"crontab\" configuration file\n      ```bash\n      sudo nano /etc/crontab\n      ````\n   * Insert the following line to it\n     ````console\n      * * * * * root curl -s http:/127.0.0.1:8181/ADCtrigger\n     ````\n     * The Sensor will read this every minute\n     * **Note:** To execute this change a restart of Linux is required  \n  \n* Refresh the management interface to recognize the time synced plotting of the ADC data\n\n\u003cbr\u003e\n\n# Author\n \n* *rsyocto*; **Robin Sebastian,M.Sc. [(LinkedIn)](https://www.linkedin.com/in/robin-sebastian-a5080220a)**\n\n*Django2FPGAdemo* and *rsyocto* are self-developed projects in which no other companies are involved. \nIt is specifically designed to serve students and the Linux/FPGA open-source community with its publication on GitHub and its open-source MIT license. \nIn the future, *rsyocto* will retain its open-source status and it will be further developed. \n\nDue to the enthusiasm of commercial users, special features for industrial, scientific and automotive applications \nwere developed and ready for the implementation in a highly optimazed closed commercial version. \nPartnerships as an embedded SoC-FPGA design service to fulfil these specific commercial requirements are offered. \nIt should help, besides students with the *rsyocto* open-source version, commercial users, as well.   \n\n**For commercial users, please visit the *rsyocto* embedded service provider website:** \n[**rsyocto.com**](https://rsyocto.com/)\n\n[![Gitter](https://badges.gitter.im/rsyocto/community.svg)](https://gitter.im/rsyocto/community?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge)\n[![Email me!](https://img.shields.io/badge/Ask%20me-anything-1abc9c.svg)](mailto:git@robseb.de)\n\n[![GitHub stars](https://img.shields.io/github/stars/robseb/Django2FPGAdemo?style=social)](https://GitHub.com/robseb/Django2FPGAdemo/stargazers/)\n[![GitHub watchers](https://img.shields.io/github/watchers/robseb/Django2FPGAdemo?style=social)](https://github.com/robseb/Django2FPGAdemo/watchers)\n[![GitHub followers](https://img.shields.io/github/followers/robseb?style=social)](https://github.com/robseb)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobseb%2Fdjango2fpgademo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobseb%2Fdjango2fpgademo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobseb%2Fdjango2fpgademo/lists"}