element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
FPGA
  • Technologies
  • More
FPGA
Blog Arty S7 50 Rapid Prototyping - Environmental Monitor
  • Blog
  • Forum
  • Documents
  • Quiz
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join FPGA to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: javagoza
  • Date Created: 12 Jun 2022 3:25 PM Date Created
  • Views 17140 views
  • Likes 9 likes
  • Comments 3 comments
  • baremetal
  • fpga_projects
  • xilinx
  • fpga
  • vivado
  • PmodOLED
  • digilent
  • PmodHYGRO
  • arty s7
  • vitis
  • Spartan_Migration
  • microblaze
Related
Recommended

Arty S7 50 Rapid Prototyping - Environmental Monitor

javagoza
javagoza
12 Jun 2022
Arty S7 50 Rapid Prototyping - Environmental Monitor

For the 7 Ways to Leave Your Spartan-6 program I am writing a series of tutorials using theArty S7 50 . In the previous blogs I did two introductory tutorials to create a simple hardware-only project and another baremetal one on a MicroBlaze softprocessor. In this blog we will build a simple environmental monitor to explore the possibilities of the Arty S7 50 board for rapid prototyping using two Pmod modules: the Pmod HYGRO and the Pmod OLED  modules.

"7 Ways to Leave Your Spartan-6" related posts
1 Arty S7 50 First Power Up and Hardware-Only Blinky
2 Arty S7 50 First Baremetal Software Project
3 Arty S7 50 Rapid Prototyping Environmental Monitor
4 Arty S7 50 ArtyBot Pulse Width Modulation (PWM) for Motor Speed Control
5 Arty S7 50 ArtyBot Custom AXI4 Lite IP Peripheral for Sensing Motor Rotational Speed
6 Arty S7 50 ArtyBot How to Store MicroBlaze Program in the Quad-SPI Flash from Vivado
7 Arty S7 50 ArtyBot - Bot Application Framework
8 Arty S7 50 ArtyBot becomes Emubot, an educational robot for young children
9 Arty S7 50 ArtyBot - Color sensing and line follower
10 Arty S7 50 The Spartan-6 Migration Path Game. Learning the Differences Between Spartan-6 and Spartan-7 FPGAs
11 Arty S7 50 ArtyBot ToF Sensor for Obstacle Avoidance. Vivado Hierarchical Blocks
12 "7 Ways to Leave Your Spartan-6 FPGA" program. My summary
13 Arty S7 50 VGA Thermal Imaging Camera

The monitor in action:

The temperature measurement unit can be adjusted by a button on the board. Unit selection is indicated by two LEDs on the board. Another button executes the completion of the main loop.

Arty S7 50 Rapid Prototyping Environmental Monitor


Rapid Prototyping with The Arty S7

FPGAs are especially popular for prototyping designs, due to their superior performance and affordability.

The Arty S7 provides a range of options from Arduino Shield connectors to four Pmod ports. It has a dual row Arduino® connectors to mount one of the hundreds of hardware compatible shields available, or use the Pmod ports with Digilent's pre-made Pmod IP blocks. This allows us to incorporate pre-built and tested modules and be able to immediately focus on building the first prototypes of our solution.

The Arty S7 was designed to be MicroBlaze ready and comes out of the box ready to use with the free Xilinx WebPack licensing with the Vivado Design Suite.


Tutorial Environment

For this tutorial you´ll need, Windows 10, AMD Xilinx Vivado ML 2021.1 and the following hardware

Product Name Manufacturer Datasheet
Arty S7 50  Digilent  Buy Now
PmodHYGRO Digilent Buy Now
PmodOLED Digilent Buy Now


Digilent Pmod

Pmod is Digilent's defined standard for peripheral modules The Pmod modules are small I/O interface boards that allow us to expand the capabilities of microcontroller and programmable logic boards.

Pmods communicate with host boards via 6-, 8-, or 12-pin connectors that can carry multiple digital control signals, taking advantage of standard serial protocols such as SPI and I2C.

Pmods are designed to connect directly to Pmod host ports that adhere to the Digilent Pmod interface specification. Additionally, the Digilent Pmod standard establishes guidelines for form factor, communication protocols, and access to a target audience through reference manuals, code samples, user guides, and technical support.

Reference: PmodTm - Digilent Reference

The Arty S7 has four Pmod connectors, some of which behave differently than others. Each Pmod connector falls into one of two categories: standard or high-speed. Also, some Pmod connectors share their connections with the
inner rows of the shield connector and should not be used at the same time as a shield that requires those pins. Table 8.1 specifies which category each Pmod falls into, whether it shares any pins with the shield connector, and also lists the FPGA pins they are connected to.

image

The standard Pmod connectors are connected to the FPGA via 200 Ohm series resistors. The series resistors prevent short circuits that can occur if the user accidentally drives a signal that is supposed to be used as an input.
The downside to this added protection is that these resistors can limit the maximum switching speed of the data signals. If the Pmod being used does not require high-speed access, then the standard Pmod connector should be
used to help prevent damage to the devices.

The High-speed Pmods use the standard Pmod connector but have their data signals routed as impedance matched differential pairs for maximum switching speeds. They have pads for loading resistors for added protection, but the Arty S7 ships with these loaded as 0-Ohm shunts. With the series resistors shunted, these Pmods offer no protection against short circuits, but allow for much faster switching speeds. The signals are paired to the adjacent signals in the same row: pins 1 and 2, pins 3 and 4, pins 7 and 8, and pins 9 and 10.

Pmod pins are connected to Spartan-7 FPGA pins using a 3.3V logic standard, care should be taken not to drive these pins over 3.4V.


Digilent PmodHYGRO

The Digilent Pmod HYGRO is a relative humidity sensor with an integrated temperature sensor for highly accurate measurements at low power. With the TI HDC1080, we can determine the relative humidity of the environment with up to 14 bits of resolution.

image

References: 

  • Pmod HYGRO - Digilent Reference
  • Pmod HYGRO Reference Manual - Digilent Reference
{gallery}Digilent PmodHYGRO

Digilent PmodHYGRO - Digital humidity sensor with an integrated temperature sensor

Digilent PmodHYGRO - Unboxing

Digilent PmodHYGRO - Digital humidity sensor with an integrated temperature sensor

Digilent PmodHYGRO - Unboxing

Digilent PmodHYGRO - Digital humidity sensor with an integrated temperature sensor

Digilent PmodHYGRO - Front

Digilent PmodHYGRO - Digital humidity sensor with an integrated temperature sensor

Digilent PmodHYGRO - BACK


Digilent PmodOLED

The Digilent Pmod OLED (Revision A) is an organic LED module with a 128×32 pixel display. Primary IC  SSD1306

image

References:

  • Pmod OLED - Digilent Reference
  • Pmod OLED Reference Manual - Digilent Reference
{gallery}Digilent PmodOLED

Digilent PmodOLED unboxing

Digilent PmodOLED unboxing

PmodOLED unboxing

Digilent PmodOLED unboxing

Digilent PmodOLED unboxing

Digilent PmodOLED Front

Digilent PmodOLED Back

Digilent PmodOLED Back


Build the Hardware Platform

To create this simple environmental monitor the first thing we need to do is to create a hardware platform using Xilinx Vivado.

We create the hardware platform without writing a single line in RTL. We will only use the block designer aided by the automatisms of the Vivado IP integrator.

For the realization of this guide and this small project I have based myself on the following workshop given by Jayson Bethurem, Product Line Manager: Spartan, Artix, Zynq-7000, Zynq UltraScale+ at Xilinx

  • Arty-S7 Workshop: Part 2: Building a Custom Microcontroller in Minutes
  • Arty-S7 Workshop: Part 3: Rapid Sensor Prototyping with Digilent Peripheral Modules

Prerequisites

During the hardware creation process we are going to need certain files made by Digilent for the Arty S7 50 board and the Pmod modules that we are going to use.


A. Download Master XDC files

We will use the XDC files to constrain ports that have been omitted from the board file.

  • Go  to GitHub - Digilent/digilent-xdc: A collection of Master XDC files for Digilent FPGA and Zynq boards. and download the Arty-S7-50-Master.xdc

B. Download the Digilent Vivado Library

Digilent provides several IPs that are designed to make implementing and using a Pmod on an FPGA as straightforward as possible.

The Digilinet Vivado Library contains the Pmod IPs and Microblaze Drivers.

  • Go to GitHub - Digilent/vivado-library and clone or download the library as zip.

image


1. Create a New Vivado Project

  • Open Vivado 2021.1 and Create a new project for the Arty S7 50 Board. See previous blog: Arty S7 50 First Baremetal Software Project
  • At the Select Project Type screen, choose RTL Project and check the Do not specify sources at this time box.
  • Select Boards → Filter on Digilentinc, select Arty S7-50

2. Add the Digilent Library Repository, Installing Digilent IP

Once the project has been created, the next step is to map the Digilent Vivado Library as a repository such that we can add the Pmod into the design. This can be done by the project settings tab.

  • Go to settings under Project Manager.
  • Select IP-> Repository and click the + symbol to add a new repository.
  • Select the extracted IP Folder and apply.

image


2. Create a Vivado IP Integrator Block Design

  • Select Create Block Design under IP INTEGRATOR and accept defaults

3. Instantiate a New Microblaze Microcontroller

  • First we instantiate a MicroBlaze processor within the Spartan 7 FPGA device.
  • Select the + symbol under the BLOCK DESIGN window to add a new IP
  • Search for MicroBlaze and double-click it to add it to the block design.
  • We need, at minimum, a clock and reset input, as well as local memory from which to execute code. Vivado can automate this, click Run Block Automation.
  • MicroBlaze has several preset configurations, select the basic Microcontroller preset.

Block Design now has MicroBlaze Processor with clocking, reset, local memory, debug module, interrupt controller and AXI interconnect block.


4. Connect Clock and Reset to Board Level Inputs.

The Arty S7-50 board has an active low reset. The red reset button labeled ¨RESET¨generates a high output when at rest and a low output when pressed.

The RESET button is intended to be used in Microblaze designs to reset the processor.

image

Xilinx offers the Clocking Wizard IP core to help users generate the different clocks required for a specific design. This wizard will properly instantiate the needed MMCMs and PLLs based on the desired frequencies and phase relationships specified by the user. The wizard will then output an easy-to-use wrapper component around these clocking resources that can be inserted into the user’s design. The clocking wizard can be accessed from within the Vivado and IP Integrator tools

The clocking wizard automatically requests an output clock of 100MHz. Internal PLL’s and MMCM’s can synthesize different output clock speeds.

The Arty S7 board includes a 12 MHz crystal oscillator connected to pin F14 (an MRCC input on bank 15) and a 100 MHz crystal oscillator connected to pin R2 (an MRCC input on bank 34). The 12 MHz clock is intended to be used as a general-purpose system clock. The clock can drive MMCMs to generate clocks of various frequencies and with known phase relationships that may be needed throughout a design. The 12 MHz input clock cannot directly drive a PLL because they have a minimum input frequency of 19 MHz.

The 100 MHz clock is intended to drive the system clock input of the Memory Interface Generator (MIG) IP Core to allow for proper use of the DDR3L memory.

  • Configure the Clocking Wizard by double-clicking on the IP Block.
  • Change the Reset Type to Active Low under Output Clocks.

image


5. Connecting Clock to Board Level Inputs

  • Select the Board Tab
  • Drag System Clock to Clocking Wizard IP block

image


6. Connect Board Resets with the Designer Assistance

  • Select the Run Connection Automation, click OK when Auto Connect is done.
  • Designer assistance recognizes Reset signals have not been connected.
  • Check All Automation checkbox, click OK

image


7. Add External Processor Communication, AXI Uartlite

In order to communicate between our on-board processor and our PC, we need to add a USB-UART to the design. The Arty S7 includes an FTDI FT2232HQ USB-UART bridge (attached to connector J10) that allows you to use PC applications to communicate with the board using standard Windows COM port commands. This will allow the processor's STDIO port to communicate to your PC. Serial port data is exchanged with the FPGA using a two-wire serial port (TXD/RXD). I/O commands can be used from the PC directed to the COM port to produce serial data traffic on the V12 and R12 FPGA pins.

  • Click Add IP Icon, search for uart and double-click AXI Uartlite.
  • With the AXI_Uartlite IP block added, Run Connection Automation by clicking the hyperlink at the top of the screen.
  • In Run Connection Automation window, click top checkbox to select all nets and then click OK.
  • Verify AXI_Uartlite IP block is fully connected. It has a AXI connection to the AXI Interconnect block and well as AXI clock and reset. Additionally, it auto connected to the board’s USB UART interface.

image


8. Add Board LEDs and Push Buttons

The Arty S7 board includes two tri-color LEDs, 4 switches, 4 push buttons, 4 individual LEDs, and a reset button.

image

The push buttons and slide switches are connected to the FPGA via series resistors to prevent damage from inadvertent short circuits (a short circuit could occur if an FPGA pin assigned to a push button or slide switch was inadvertently defined as an output). The four push buttons are “momentary” switches that normally generate a low output when they are at rest, and a high output only when they are pressed

The four-individual high-efficiency LEDs are anode-connected to the FPGA via 330-ohm resistors, so they will turn on when a logic high voltage is applied to their respective I/O pin. Additional LEDs that are not user-accessible indicate power-on, FPGA programming status, and USB and Ethernet port status.

To connect the LEDs and Push Buttons in your hardware design:

  • Simply drag and drop the LED’s and Push Buttons to the IP canvas.

image

  • Run Connection Automation (RCA) again to auto connect new peripherals to the processor. When Run Connection Automation window opens, click OK.

image


9. Adding a PmodHYGRO Module to the Vivado Project

  • Click on the + icon to add IP
  • Search for PmodHYGRO_v1_0 and double click it to add it to the design.
  • If you can't find it, you have skipped the step of adding the Digilent library repository for Vivado. See step 2.

image

Drag and drop the Pmod Connector JA component from the Board tab to the design.

Click Run Connection Automation, Select All Automation then click OK.


10. Adding a PmodOLED Module to the Vivado Project

  • Click on the + icon to add IP
  • Search for PmodOLED_v1_0 and double click it to add it to the design. 
  • If you can't find it, you have skipped the step of adding the Digilent library repository for Vivado. See step 2.

image

  • Drag and drop the Pmod Connector JB component from the Board tab to the design.
  • Click Run Connection Automation, Select All Automation then click OK.

image


11. Connect all Interrupts

  • Locate Concat IP and double-click to customize, connect two interrupt outputs from PmodHYGRO_0 and interrupt from AXI_Uartlite to Concat inputs. Connect Interrupt output of AXI Interrupt Controller to Interrupt input of MicroBlaze.

image


12. Validate the Block Design

  • Validate the Block Design

image

ARTY S7 50 Environmental Monitor Hardware Diagram


13. Add Constrains for PmodHYGRO

The IP block we are using for the PmodHYGRO module is for an older version of VIVADO and leaves several Pmod JA ports that we have assigned undefined.

  • Add a contrains file using the XMC that we have downloaded.

image

## Pmod Header JA
set_property -dict { PACKAGE_PIN L17   IOSTANDARD LVCMOS33 } [get_ports { ja_pin1_io }]; #IO_L4P_T0_D04_14 Sch=ja_p[1]
set_property -dict { PACKAGE_PIN L18   IOSTANDARD LVCMOS33 } [get_ports { ja_pin2_io }]; #IO_L4N_T0_D05_14 Sch=ja_n[1]
#set_property -dict { PACKAGE_PIN M14   IOSTANDARD LVCMOS33 } [get_ports { ja[2] }]; #IO_L5P_T0_D06_14 Sch=ja_p[2]
#set_property -dict { PACKAGE_PIN N14   IOSTANDARD LVCMOS33 } [get_ports { ja[3] }]; #IO_L5N_T0_D07_14 Sch=ja_n[2]
set_property -dict { PACKAGE_PIN M16   IOSTANDARD LVCMOS33 } [get_ports { ja_pin7_io }]; #IO_L7P_T1_D09_14 Sch=ja_p[3]
set_property -dict { PACKAGE_PIN M17   IOSTANDARD LVCMOS33 } [get_ports { ja_pin8_io }]; #IO_L7N_T1_D10_14 Sch=ja_n[3]
set_property -dict { PACKAGE_PIN M18   IOSTANDARD LVCMOS33 } [get_ports { ja_pin9_io }]; #IO_L8P_T1_D11_14 Sch=ja_p[4]
set_property -dict { PACKAGE_PIN N18   IOSTANDARD LVCMOS33 } [get_ports { ja_pin10_io }]; #IO_L8N_T1_D12_14 Sch=ja_n[4]


14. Create HDL Wrapper for Block Design

  • Under the sources tab, right click design_1 and click Create HDL Wrapper.
  • Vivado can automatically manage the HDL wrapper. Keep the default setting and click OK

15. Build the FPGA Bitstream for FPGA Configuration

  • Click Generate Bitstream
  • Click Yes to run synthesis and implementation before generating the bitstream.
  • This will build our custom embedded processor bitstream that will configure the FPGA. This step will take several minutes the first time.

16. Export Hardware Design for Vitis SDK

  • Select File → Export → Export Hardware….
  • Select Fixed Platform Type setting and Select Include Bitstream
  • Write down where you have saved the xsa, we will need it for Vitis.

17. Launch Vitis IDE & Create Application Project

  • Create Application Project
  • Select the Create a new platform from hardware (XSA) tab and browse to find your design_1_wrapper.xsa file.

image


18. Name the Project and Select Domain

  • Name the project (no spaces) 

image

More complex systems can have multiple processor domains, ours only has one. Keep the default settings

image


19. Create an Empty Application

  • Select Empty Application.

image


20. Download the Source Code

  • Save the following code as main.c

/******************************************************************************/
/*                                                                            */
/* main.c -- Environmental Monitor. Temperature / Humidity                    */
/*  PmodOLED IP + PmodHYGRO                                                   */
/*                                                                            */
/******************************************************************************/
/* Author: Enrique Albertos                                                   */
/* 2022 Public Domain                                                         */
/******************************************************************************/
/* File Description:                                                          */
/*                                                                            */
/* This project initializes and uses the PmodOLED and the PmodHYGRO to        */
/* display temperature and humidity values.                          */
/* Temperature and humidity data are captured from the I2C connection and     */
/* displayed over the serial connection and on the OLED display once per      */
/* second.                                                                    */
/* This application configures UART 16550 to Baud rate 9600. PS7 UART (Zynq)  */
/* is not initialized by this application, since bootrom/bsp configures it to */
/* Baud rate 115200.                                                          */
/*                                                                            */
/*    UART TYPE   BAUD RATE                                                   */
/*    uartns550   9600                                                        */
/*    uartlite    Configurable only in HW design                              */
/*    ps7_uart    115200 (configured by bootrom/bsp)                          */
/*                                                                            */
/******************************************************************************/
/* Revision History:                                                          */
/*                                                                            */
/*    11/06/2022 Enrique Albertos:   Created w/ Vivado 2021.1                 */
/*                                                                            */
/******************************************************************************/
/* Baud Rates:                                                                */
/*                                                                            */
/*    Microblaze: 9600 or what was specified in UARTlite core                 */
/*    Zynq: 115200                                                            */
/*                                                                            */
/******************************************************************************/

/* ------------------------------------------------------------ */
/*                  Include File Definitions                    */
/* ------------------------------------------------------------ */

#include "PmodOLED.h"
#include "PmodHYGRO.h"
#include "sleep.h"
#include "xil_cache.h"
#include "xil_printf.h"
#include "xparameters.h"
#include "xgpio.h"
#include "xil_types.h"

#ifdef __MICROBLAZE__
#define TIMER_FREQ_HZ XPAR_CPU_M_AXI_DP_FREQ_HZ
#else
#define TIMER_FREQ_HZ 100000000
#endif

/* ------------------------------------------------------------ */
/*                  Global Variables                            */
/* ------------------------------------------------------------ */

PmodOLED myOled;
PmodHYGRO myHygro;

/* ------------------------------------------------------------ */
/*                  Forward Declarations                        */
/* ------------------------------------------------------------ */

void DemoInitialize();
void DemoRun();
void DemoCleanup();
void EnableCaches();
void DisableCaches();
void OLED_putFloatVariable(PmodOLED *InstancePtr, int xch, int ych, char * head,
		float value, char * tail);

// To change between PmodOLED and OnBoardOLED is to change Orientation
const u8 orientation = 0x0; // Set up for Normal PmodOLED(false) vs normal
// Onboard OLED(true)
const u8 invert = 0x0; // true = whitebackground/black letters
// false = black background /white letters

#define BTN_MASK 0b1111
#define LED_MASK 0b1111
#define BTN1_MASK 0b0001
#define BTN2_MASK 0b0010
#define BTN3_MASK 0b0100
#define BTN4_MASK 0b1000
#define LED1_MASK 0b0001
#define LED2_MASK 0b0010
#define LED3_MASK 0b0100
#define LED4_MASK 0b1000
#define CELSIUS_LED LED1_MASK
#define FAHRENHEIT_LED LED1_MASK

// Get device IDs from xparameters.h
#define BTN_ID XPAR_AXI_GPIO_0_DEVICE_ID
#define LED_ID XPAR_AXI_GPIO_0_DEVICE_ID
#define BTN_CHANNEL 2
#define LED_CHANNEL 1

XGpio_Config *cfg_ptr;
XGpio led_device, btn_device;



/* ------------------------------------------------------------ */
/*                  Function Definitions                        */
/* ------------------------------------------------------------ */

int main() {
	DemoInitialize();
	DemoRun();
	DemoCleanup();

	return 0;
}

void DemoInitialize() {
	EnableCaches();

	xil_printf("HYGRO Init Started\n\r");
	HYGRO_begin(&myHygro,
	XPAR_PMODHYGRO_0_AXI_LITE_IIC_BASEADDR, 0x40, // Chip address of PmodHYGRO IIC
			XPAR_PMODHYGRO_0_AXI_LITE_TMR_BASEADDR,
			XPAR_PMODHYGRO_0_DEVICE_ID,
			TIMER_FREQ_HZ // Clock frequency of AXI bus, used to convert timer data
			);
	xil_printf("HYGRO Init Done\n\r");

	xil_printf("OLED Init Started\n\r");
	OLED_Begin(&myOled, XPAR_PMODOLED_0_AXI_LITE_GPIO_BASEADDR,
	XPAR_PMODOLED_0_AXI_LITE_SPI_BASEADDR, orientation, invert);
	xil_printf("OLED Init Done\n\r");

	// Initialize LED Device
	cfg_ptr = XGpio_LookupConfig(LED_ID);
	XGpio_CfgInitialize(&led_device, cfg_ptr, cfg_ptr->BaseAddress);

	// Initialize Button Device
	cfg_ptr = XGpio_LookupConfig(BTN_ID);
	XGpio_CfgInitialize(&btn_device, cfg_ptr, cfg_ptr->BaseAddress);

	// Set Button Tristate
	XGpio_SetDataDirection(&btn_device, BTN_CHANNEL, BTN_MASK);

	// Set Led Tristate
	XGpio_SetDataDirection(&led_device, LED_CHANNEL, 0);

}

/* ------------------------------------------------------------ */
/*** DemoRun()
 **
 **   Parameters:
 **      none
 **
 **   Return Value:
 **      none
 **
 **   Errors:
 **      If the demo is shut down without properly exiting, does not reinitialize
 **      properly.
 **
 **   Description:
 **      Displays Temperature each 1 second.
 **      Toggles temp units with button 1 pressed
 **      Exists when button 4 is pressed.
 **      Requires UART connection to terminal program on PC.
 */
void DemoRun() {
	long timeCounterMillis;
	u32 buttonsState;
	int button1State;
	int lastbutton1State;
	float temp_degc, hum_perrh, temp_degf;
	u8 bDegreesCelsius = 1;

	xil_printf("UART, I2C and SPI opened for Environment Monitor\n\r");
	XGpio_DiscreteWrite(&led_device, LED_CHANNEL, LED1_MASK);
	while (1) {
        // read buttons
		buttonsState = XGpio_DiscreteRead(&btn_device, BTN_CHANNEL);

        //if button 4 is pressed exit
        if(buttonsState & BTN4_MASK ) {
        	xil_printf("exiting\r\n");
        	// exit
        	break;
        }

        // check button for toggling temperature units
        button1State = buttonsState & BTN1_MASK;
		//if button 1 low to high edge
		if((button1State != lastbutton1State) && button1State && timeCounterMillis > 100) {
        	xil_printf("toggle units\r\n");
        	// toggle temp units mode
        	bDegreesCelsius = !bDegreesCelsius;
        	// change led indicator
        	if (bDegreesCelsius ) {
        		XGpio_DiscreteWrite(&led_device, LED_CHANNEL, LED1_MASK);
        	} else {
        		XGpio_DiscreteWrite(&led_device, LED_CHANNEL, LED2_MASK);
        	}
        	// force environmental data update
        	timeCounterMillis = 1001;
        }
		lastbutton1State = button1State;

        if( timeCounterMillis > 1000) {
        	timeCounterMillis = 0;
			temp_degc = HYGRO_getTemperature(&myHygro);
			temp_degf = HYGRO_tempC2F(temp_degc);
			hum_perrh = HYGRO_getHumidity(&myHygro);
			xil_printf("Temperature: %d.%02d deg F  Humidity: %d.%02d RH\n\r",
					(int) temp_degf, ((int) (temp_degf * 100)) % 100,
					(int) hum_perrh, ((int) (hum_perrh * 100)) % 100);

			// Turn automatic updating off
			OLED_SetCharUpdate(&myOled, 0);

			if(bDegreesCelsius) {
				// Display Temperature Value in Degrees Celsius
				OLED_putFloatVariable(&myOled, 1, 1, "T: ", temp_degc, " C");
			} else {
				// Display Temperature Value in Degrees Fahrenheit
				OLED_putFloatVariable(&myOled, 1, 1, "T: ", temp_degf, " F");
			}
			// Display Relative Humidity Percentage
			OLED_putFloatVariable(&myOled, 1, 3, "H: ", hum_perrh, " %RH");
			// Update display
			OLED_Update(&myOled);
        }

		usleep(1000);
		timeCounterMillis++;
	}
	xil_printf("Exiting PmodOLED Demo\n\r");
}

/*
 * Displays on the OLED a float variable with a header and a tail
 * ie T: 12.67 C
 * OLED_putFloatVariable(&myOled, 1, 1, "T: ", temp_degc, " C");
 */
void OLED_putFloatVariable(PmodOLED *InstancePtr, int xch, int ych, char * head,
		float value, char * tail) {
	OLED_SetCursor(InstancePtr, xch, ych);
	OLED_PutString(InstancePtr, head);
	OLED_PutChar(InstancePtr, ((int) value / 10) % 10 + 48);
	OLED_PutChar(InstancePtr, ((int) value) % 10 + 48);
	OLED_PutString(InstancePtr, ".");
	OLED_PutChar(InstancePtr, ((int) (value * 10)) % 10 + 48);
	OLED_PutChar(InstancePtr, ((int) (value * 100)) % 10 + 48);
	OLED_PutString(InstancePtr, tail);
}

void DemoCleanup() {
	OLED_End(&myOled);
	DisableCaches();
}

void EnableCaches() {
#ifdef __MICROBLAZE__
#ifdef XPAR_MICROBLAZE_USE_ICACHE
	Xil_ICacheEnable();
#endif
#ifdef XPAR_MICROBLAZE_USE_DCACHE
	Xil_DCacheEnable();
#endif
#endif
}

void DisableCaches() {
#ifdef __MICROBLAZE__
#ifdef XPAR_MICROBLAZE_USE_DCACHE
	Xil_DCacheDisable();
#endif
#ifdef XPAR_MICROBLAZE_USE_ICACHE
	Xil_ICacheDisable();
#endif
#endif
}



This file contains environmental monitor code

Temperature, and Relative Humidity data is captured over an I2C interface and displayed over UART and over an SPI OLED display


21. Import the Source Code

  • Import this main.c file to newly created src directory.

image


22. Build the Project

  • Select environmental_monitor_system then click Build.

image


23. Program the Device

  • Connect the board to your PC via USB.
  • Select Xilinx → Program Device.

image


24. Run the Program

  • Select environmental_monitor_system then click Run → Run As → Launch Hardware.

image


25. Visualizing the Serial UART Data Using Vitis

  • Launch serial Terminal Window -> Terminal
  • Check in the Windows 10 device manager the COM port assigned to your board.

image

Press OK

image


Construction

  • Connect the PmodHYGRO module to the JA Pmod Header. With the Pin 1 connected. The upper row.
  • Connect the PmodOLED module to the JB Pmod Header.
  • Power the board.

image


User Interface

  • Use BTN0 to select temperature units. Toggles between Degrees Celsius and Degrees Fahrenheit
  • Use BTN3 to end the program.
  • LD2 indicates Degrees Celsius Selected
  • LD3 indicates Degrees Fahrenheit Selected
  • RESET button resets Microblaze softprocessor

The OLED display can show the temperature information in two formats, degrees Celsius or degrees Fahrenheit, selectable by pressing a button.

image

When pressing the first button the monitor toggles temperature units between Celsius and Fahrenheit.

image


References

  • 7 Ways to Leave Your Spartan-6 FPGA - Documents - FPGA - element14 Community
  • Arty S7 - Digilent Reference
  • PmodTm - Digilent Reference
  • Pmod HYGRO - Digilent Reference
  • Pmod HYGRO Reference Manual - Digilent Reference
  • Pmod OLED - Digilent Reference
  • Pmod OLED Reference Manual - Digilent Reference
  • Arty-S7 Workshop: Part 2: Building a Custom Microcontroller in Minutes
  • Arty-S7 Workshop: Part 3: Rapid Sensor Prototyping with Digilent Peripheral Modules
  • GitHub - Digilent/digilent-xdc: A collection of Master XDC files for Digilent FPGA and Zynq boards.
  • GitHub - Digilent/vivado-library

"7 Ways to Leave Your Spartan-6" related posts
1 Arty S7 50 First Power Up and Hardware-Only Blinky
2 Arty S7 50 First Baremetal Software Project
3 Arty S7 50 Rapid Prototyping Environmental Monitor
4 Arty S7 50 ArtyBot Pulse Width Modulation (PWM) for Motor Speed Control
5 Arty S7 50 ArtyBot Custom AXI4 Lite IP Peripheral for Sensing Motor Rotational Speed
6 Arty S7 50 ArtyBot How to Store MicroBlaze Program in the Quad-SPI Flash from Vivado
7 Arty S7 50 ArtyBot - Bot Application Framework
8 Arty S7 50 ArtyBot becomes Emubot, an educational robot for young children
9 Arty S7 50 ArtyBot - Color sensing and line follower
10 Arty S7 50 The Spartan-6 Migration Path Game. Learning the Differences Between Spartan-6 and Spartan-7 FPGAs
11 Arty S7 50 ArtyBot ToF Sensor for Obstacle Avoidance. Vivado Hierarchical Blocks
12 "7 Ways to Leave Your Spartan-6 FPGA" program. My summary
13 Arty S7 50 VGA Thermal Imaging Camera
  • Sign in to reply
  • javagoza
    javagoza over 3 years ago in reply to 14rhb

    Thanks for your kind words. Credit goes to Xilinx and Digilent, who have managed to create an environment in which makers and hobbyists feel comfortable.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • genebren
    genebren over 3 years ago

    Great project.  The Pmod modules make it pretty easy to quickly add hardware into a project.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • 14rhb
    14rhb over 3 years ago

    A great demonstration of the Arty S7-50 FPGA board and PMOD units. Very well written up - well donel Smiley

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube