5: UART and XBee

The UART or Universal Asynchronous Receiver Transmitter, is the method microcontrollers use to transmit or receive asynchronous serial data (not SPI, I2C, etc). Here, we’ll be communicating wirelessly between the PIC32 and a serial communication program like PuTTY or minicom. XBee’s will be doing the wireless work. Note that the easiest (but certainly not the only) way to connect an XBee to your computer is to use an XBee ‘explorer board‘. Ours have come from sparkfun and take a whole minute and a half to set up.

XBee’s are great little wireless transceivers that use the zigbee standard. They’re cheap, low power, have tons of documentation, and are easy to use with tons of different devices. They’re mostly used in control applications since the maximum data rate is only about 250 kbit/s. Currently, the XBee pros can transmit up to 1500 meters in particular environments!

Slideshow:
Fullscreen:
Download:

/* ===========================================================================
* PIC32 Tutorial 5 – Transmitting into the Air: UART and the XBee Wireless Module
* ===========================================================================
* Rodrigo S. Bismonte II and Sean Klaiber
* last updated August 2011
*
* with info from the Northwestern Mechatronics Wiki page on the NU32v2:
*
* and Lucio Di Jasio’s book “Programming 32-bit Microcontrollers in C: Exploring the PIC32″
* and the informative engineer at ladyada.net about configuring XBees:
*
*
* Objectives:
* -Read the analog value of a potentiometer wired to pin AN15.
* -Remap this value to the range of printed ASCII values (33 to 126)
* -Send this value through UART into an XBee wireless module
* -Have a second XBee wireless module receive the value, and print out the corresponding
* ASCII value on a computer through HyperTerminal/PuTTy (Windows) or Terminal (Mac).
* -Display the same value as an 8-bit binary number on an LED bar connected to
* pins RD0 – RD7.
* *** Don’t forget a current-limiting resistor network for the LED bar!!! ***
*
* *** The schematic for wiring up an XBee to work properly with the UBW32 is included ***
* *** in XBee-CUI32.pdf ***
*
* *** The schematic for wiring up an XBee to accept an FTDI cable is included in ***
* *** XBee-FTDI.pdf. (The triangle-shaped components in the schematic is a single buffer***
* *** in a 5v compliant buffer chip 74AHC125N). The chip has 4 buffers in it and serves ***
* *** as a level converter–USB to Serial signals are 5V, and the XBee operates in 3.3V***
*
* Tutorial covers:
* -Setup the UART module on the CUI32/UBW32.
* -Configuring the XBee modules
* -#pragma
*
* ============== NOTES on the Universal Asynchronous Receiver/Transmitter (UART) ===============
*
* The CUI32/UBW32 have two Universal Asynchronous Receiver/Transmitter (UART) peripheral modules. They
* are connected to pins RD2/RD3 (for CUI32 UART1), RF2/RF8 (for UBW32 UART1), and RF4/RF5 (for both UART2).
* UART is one of the serial interface modules available on the CUI32. It is ASYNCHRONOUS, which means
* that the two devices communicating need not be using the same clock.
*
* The PIC32′s UART module is capable of 8-bit or 9-bit data transmission with even, odd, or no
* parity bits and one or two stop bits. It also has a fully integrated Baud Rate Generator (BRG)
* and can range from 76 bps to 20 Mbps at 80MHz.
*
* The UART Peripheral Module has several peripheral library functions specified in the
* Peripheral Library Guide (.pdf). For the scope of this tutorial, only OpenUARTx(), putcUARTx(),
* BusyUARTx(), ReadUARTx(), and putsUARTx(), where x is either 1 or 2, depending on which UART
* module is used.
*
* OpenUARTx(config1, config2, ubrg);
* -Opens and configures the UART module. The parameters [config1] and [config2] are the
* bit-wise OR’d bit-masks given in page 233 to page 235. The parameter [ubrg] is the value
* that will set the baud rate.
* BusyUARTx();
* -Checks if the UART module is busy. Returns a 1 if it is busy and 0 otherwise.
* ReadUARTx();
* -Reads the value in the UART receive buffer.
* putcUARTx(data);
* -The same function as WriteUARTx(data). The [data] parameter is an unsigned int.
* putsUARTx(string);
* -Function places a string (or array of characters) into the transmit buffer.
*
* The difference between putsUARTx(string) and putcUARTx(data) is that putcUARTx(data) can only
* send out one character at a time, while putsUARTx(string) allows you to transmit a string of
* such characters.
*
*
* ========================== NOTES on XBee Wireless Transciever Modules ========================
*
* A very informative tutorial on initially setting up the XBee wireless modules can be found in
* . XBee’s can be connected to the computer
* using either using a USB to serial base unit like Sparkfun’s “XBee Explorer USB” or making the
* circuit specified in XBee-FTDI.pdf. This tutorial supposes using Hyperterminal in Windows, but
* the XBee modules can be configured using Digi’s XCTU program. On Mac and Linux systems, serial
* terminal emulators like “screen” and “minicom” will work.
*
* *** NOTE that in order for this system to work, both XBee’s must be set exactly the same: ***
* 8 bits of data, no parity bit, 1 stop bit, at 9600 baud or (8N1 @ 9600 baud)
*
* ================================= NOTES on #pragma directive ================================
*
* #pragma directives are often used in embedded systems to provide information to the compiler
* specific to the device being programmed. The directive is machine specific in the sense that
* it may not apply to all machines that can be programmed. Note that #pragma’s are compiler
* dependent and non-portable. Fortunately, all of our programming is done with MPLAB…
*
* =========================================================================
*/
#include <p32xxxx.h>
#include <plib.h>
 
#pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF
#pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1
 
#define DESIRED_BAUDRATE (9600)
#define SYSCLK (80000000L)
 
#define CONFIG1 (ADC_MODULE_ON | ADC_FORMAT_INTG32 | ADC_CLK_AUTO | ADC_AUTO_SAMPLING_ON)
#define CONFIG2 (ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_ON | ADC_SAMPLES_PER_INT_1 | ADC_ALT_BUF_OFF | ADC_ALT_INPUT_OFF)
#define CONFIG3 (ADC_CONV_CLK_INTERNAL_RC | ADC_SAMPLE_TIME_15)
#define CONFIGPORT (ENABLE_AN15_ANA)
#define CONFIGSCAN (SKIP_SCAN_AN0 | SKIP_SCAN_AN1 | SKIP_SCAN_AN2 | SKIP_SCAN_AN3 | SKIP_SCAN_AN4 | SKIP_SCAN_AN5 | SKIP_SCAN_AN6 | SKIP_SCAN_AN7 | SKIP_SCAN_AN8 | SKIP_SCAN_AN9 | SKIP_SCAN_AN10 | SKIP_SCAN_AN11 | SKIP_SCAN_AN12 | SKIP_SCAN_AN13 | SKIP_SCAN_AN14)
 
unsigned char data;
int pbClk;
 
void initializeADC(){
        CloseADC10(); // Generally, you should disable the ADC before setup.
 
        SetChanADC10( ADC_CH0_NEG_SAMPLEA_NVREF);
        OpenADC10( CONFIG1, CONFIG2, CONFIG3, CONFIGPORT, CONFIGSCAN);
        // Setup for the ADC10.
        EnableADC10(); // Enables the ADC10.
        while( !mAD1GetIntFlag() ) {}; // mAD1GetIntFlag() checks the interrupt flag for the AD10.
        // Waits till a conversion is finished so that there’s
        // values in the ADC result registers.
}
 
void initializeLEDBar(){
        TRISDCLR = 0xFF; // Sets pins RD0 to RD7 as digital outputs.
}
 
void initializeUART(){
        // Optimize PIC32 performance and return peripheral bus frequency
        pbClk=SYSTEMConfig( SYSCLK, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);
 
        // Enable UART2 and set baud rate to DESIRED_BAUDRATE=9600
        OpenUART2( UART_EN, UART_RX_ENABLE | UART_TX_ENABLE, pbClk/16/DESIRED_BAUDRATE-1);
 
        while( BusyUART2()); // Wait until the UART module is free
        putsUART2( “Turning the potentiometer will change characters on screen!);
}
 
int main(){
        initializeUART(); // Initialize the UART module
        initializeADC(); // Initialize the ADC10
        initializeLEDBar(); // Initialize pins RD0 – RD7 as digital outputs
 
        while( 1){
                // Map the 10 bit analog value to a value between 33 and 126, and bit-mask it to 8-bits
                data = ( (ReadADC10(0)/11) + 33) & 0xFF;
                LATD = data; // Latch the data to the port D pins
 
                while( BusyUART2()); // Wait until UART2 module is not busy
                putcUART2( data); // Transmit ‘data’ through UART
                putcUART2(13); // Transmit ’13′ (carriage return)
        }
 
        return 1;
}

Take me home! -> pic32_tut5_uart_xbee.c

3 thoughts on “5: UART and XBee

  1. Thank you very much for this tutorial. I’m working on a fryer for KFC and it has to have wireless networking using XBee from Digi International. I spend the last week just trying to get the UART working with the XBee, but was not having any luck, until I saw your code “5: UART and XBee”

    Thanks again!!!!

    James

  2. THANKS A LOT. it is more helpful.I expect more concepts from you in PIC32MX795F512L like I2C, CAN, ETHERNET likewise.

Leave a Reply

Your email address will not be published. Required fields are marked *