Not a member yet? Register now and get started.

lock and key

Sign in to your account.

Account Login

Forgot your password?

Nuts and Volts Feb 2010

A Quick Tour of the 16 Bit Micro Experimenter Module

The 16 Bit Experimenter Module was introduced in the December 2009 issue of Nuts and Volts. The technology is exciting and we are going to introduce, in this article, several of its on board capabilities. Just about each capability discussed will be supplemented with experiments to allow you to gain a better understanding on how you can use the Experimenter for your own applications. All the experiments are written in C code, using our own custom function library .We will try to keep things as straightforward and simple as possible but you may need to brush up on some of the basic syntax of C.
Let’s  kick off it off with a little more in-depth look into the microcontroller itself before launching off on the Experimenter’s LCD display, buttons,  EEPROM, I/O Expansion Bus  (see block diagram) and our supporting software library.

(Click the image for full screen)

The Microcontroller, ICSP, and required Tools

We talked about the PIC24FJ64GA002, the core processor on the Experimenter, in the last article, but let’s take a closer look.  First of all, as Microchip’s lowest cost 16 bit microcontroller, it executes up to 16 Million Instruction per second (MIPS) rate.
The internal peripheral content is impressive: 21 programmable I/O, 500Ksps ADC with up to 10 analog channels, two analog comparators, 5 16-bit timers, 5 input capture, and 5 Output Compare / PWM modules, dual UART, dual SPI and I2C. A real benefit with the 16 Bit Experimenter Module is that you can access to all of these peripherals for your solderless breadboards.
The Experimenter’s In Circuit Serial Programmer (ICSP) is based on the proprietary Microchip six pin serial interfaces. It is incorporated as an external connector on the Experimenter. The ICSP allows the PIC24FJ64GA002 64K flash memory to be reprogrammed many times. For tools, you need to get a hold of Microchip Free MPLAB, their integrated development environment or IDE and their limited free student edition of Microchip’s P24 C Compiler as well as the PICKIT2.

(Click the image for full screen)
Figure 1 PIC24FJGA64002 Block Diagram

The LCD Display and Button Hardware

The display uses a +3.3VDC 16×3 character LCD Display offered by Electronic Assembly.  It is very similar in control to other LCD with an extended feature of built in contrast control (no need for external potentiometers) and very low power.   Designed for compact hand-held devices, it is extremely compact and ultra-flat. The display interfaces to the PIC24F using 4-bit data and two bit command digital interface. Each of four data lines connecting the PIC24F with the LCD are shared with one of the pushbuttons. The PIC24F services the LCD display as needed and when the display is not being used the PIC24F polls the user pushbuttons for activity. The pushbuttons are configured with resistor pull ups and pull downs so as not to interfere with LCD operations even when a button is pressed during a PIC24F write to the LCD.

Driving the Display- LCD Demo

So much for hardware, now here’s the fun part. Let us learn some software functions for driving the LCD and how to use them. Here are the five we will be working with and a description of what they do. Their titles pretty much capture what they do.

  • LCD_Initialize () – initializes the LCD display and makes it ready for output. This needs to be called before any other LCD function is called.
  • clear_display () – clears display and places cursor at row 1 column 1 (top left corner)
  • position_cursor (position) – places cursor at designated position, a number from 0-47
  • write_string_LCD (string name) – writes a string to display at current cursor position ( see explanation in text)
  • write_character_LCD (character) -writes a single character to display at current cursor position

An example project LCDDEMO is supplied. This project shows how to use of each of the above LCD functions and then how to call them from your MAIN file. Let’s walk through the flowchart and then the code. LCDDEMO starts by declaring two strings message# 1 and message# 2. Each message is configured to be under 16 characters to keep the display nice and neat, that is, keeping each message to within a single display row. The next step is to initialize the LCD and clear display contents before use. The next step after this is to position the cursor to beginning of row one (cursor position =0) and write out message #1. We then position the cursor to the beginning of row two (cursor position =16) and write out message #2. Just to keep things interesting we then position the cursor to the middle of line three (cursor position = 36) and write out five characters. If you haven’t figured it out by now cursor positions 0 to 15 correspond to the top row, row #1, of the LCD display. Positions 16-31 are row #2 and Positions 32-47 correspond to the bottom row, or row #3. The LCD is initialized is so that the cursor itself is not visible, and the cursor position automatically advances to the next position when data is written to the display. Any data that is written to the LCD and display must be in ASCII ( American Standard for Information Interchange) format.
Figure 2  LCDDEMO Flowchart

A copy of LCDDEMO Main is shown along with the resulting Experimenter LCD display, once the code is executed. Notice that we have #include “lcd.h” at the top of the file to allow us to reference the LCD library. Try to match up the code to the flowchart to with the code to understand the library syntax. To help you along us there is included lots of comments in the code.

(Click the image for full screen)

Writing to the Experimenter LCD using these library functions is straightforward, and to prove this to yourself try modifying the code to configure your own display messages—you will find that writing your own messages to the LCD on the Experimenter is a snap!

Using the Pushbuttons with the LCD –Button Demo

Pushbuttons are a necessary way to communication with your Experimenter application as it is running.  Let’s review some of the software functions for handling the Experimenter pushbuttons and how to use them. Here are the two functions we will be working with and a description of what they do, again we try to keep things as straightforward as possible.

  • BtnInit () – initializes the Experimenter pushbuttons SW1 to SW4 for operation. This needs to be invoked before any other button process.
  • process_buttons() – returns a value that indicates which  Experimenter pushbutton was depressed
    • If SW1 then  returned value =1
    • If SW2 then returned value =2
    • If SW3 then returned value =3
    • If SW4 then returned value =4
    • Returns value =0 if no button depressed

An example project BUTTONDEMO is supplied that you can use as a template. This project shows how to use of each of the above button functions and then how to call them from your MAIN file. In order to make the demo more meaningful we also included the LCD library discussed earlier. Let’s walk through the whole thing starting with the flowchart. BUTTONDEMO Main declares four unique messages that will be displayed depending on which button is pressed. We then initialize LCD, clear the display, and finally initialize button operation.  You typically do all your initialization up front in the program to get this absolutely necessary step out of the way. BUTTONDEMO then enters a continuous loop that does button processing and then determines which of the four buttons was pressed and does the specific processing for that pressed button. In our case that specific process simply amounts to displaying a message on the LCD that the button was pressed. It is important to note that the message gets displayed after the user presses the button and then releases it (that’s just the way I wrote the button process function).  Keep in mind that for good button processing (i.e.  To respond to the user in a timely matter) you must process all the buttons periodically. This is why BUTTONDEMO is constructed as a continuous loop.
button flow
Figure 3 BUTTONDEMO Flow chart

A copy of BUTTONDEMO MAIN code is shown along with the resulting Experimenter LCD displays for each pushbutton operation. Now we have #include “lcd.h” and #include “button.h” at the top of the file to allow us to reference both the LCD library and the BUTTON libraries. Again try to follow the code and compare against the flowchart. Throughout all these demos we are incrementally building capability for the Experimenter by adding and using one library function after another.

(Click the image for full screen)

The basic structure of BUTTONDEMO makes a good template for any of you applications that may need pushbutton operation. You can simply add to the button specific processing for what you need for your own application (The challenge is going beyond just outputting a message).

EEPROM Hardware

The Experimenter has a 25LC256 EEPROM device that contains 256kbits or 32Kbytes of nonvolatile memory. The 25LC256 is a memory technology that allows us to store data under program control and retain the contents even when power is turned off. This is can be real useful for Experimenter applications requiring password setting or storing data measurements as in a logging function. The 25LC256 uses a serial communication to talk to the Experimenter’s PIC24F Microcontroller. This data interface is called SPI (Serial Peripheral Interface). In our library SPI communication is handled automatically. Each 25LC256 storage word is two bytes. Given the byte size of the 25LC256 this means we can store up to 16K words total. In general, for your experiments, you need to establish what data you want to store and how that data organized over 16K words. In an upcoming article we will actually use this same library capability to configure the Experimenter as a data logging device for temperature.

Working with the EEPROM, LCD, Buttons- EEPROMDEMO

The EEPROM library is really straightforward. Take a quick look at the functions listed below.

  • InitNVM () – initializes the Experimenter EEPROM for access. This must be called first before any other EEPROM library function is called. NVM stands for “Non-Volatile Memory”.
  • iReadNVM ( address)- reads EEPROM at address and returns the 16 bit value stored at that location
  • iWriteNVM (address, data) – writes 16 bit data value to EEPROM at the designated address.

Using the EEPROM library function we do the basic initialization of SPI to access the EEPROM and then read and write from it once it is initialized.
An example project EEPROMDEMO is available for your use. Let’s walk through it. A flowchart is provided. To keep things interesting and more meaningful we use both the pushbuttons and LCD library functions we learned earlier. The demo counts the number of user pushbutton sequences, and then stores this count in EEPROM, and allows for recovery of this count (even when cycling power). All pushbutton actions are at the discretion of the user. The intent of the demo is to allow the user to independently store and update the data (as well as zero it) and then cycle power and examines the result. To make things easy only one address is used 0×1238, but you can try other even address locations ( remember with this 8 bit EEPROM device we need to use even addresses for storage and retrieval of  16 bits.) The result should demonstrate that data contents, as set by the user, can be stored and retrieved using the 25LC256 EEPROM and its library.

(Click the image for full screen)
Figure 4 EEPROMDEMO Flowchart
You need to make sure that the library is included as files in you own project builds and that “# include NVM.H” is part of your main file, and for this demo we also added  “BUTTON.H” and “LCD.H” to use their specific libraries are well. So as not to miss anything we added several new functions in this demo that have not been covered earlier but are worthy of our attention

  • write_array_LCD (array name, number of elements) -writes content of array for a prescribed number of elements to the LCD display starting at the current cursor position. This is a method for dynamically updating the display with real data versus fixed strings. (See explanation in text). This is a member of the LCD function library not previously discussed.
  • binary_to_ASCIIConvert (data) – this function converts binary data to its ASCII equivalent and places the ACSII values in their proper position in an array. The array is typically used as output to the LCD display using the function described above. The processed data is stored in the following memory locations as well inside the array.
    • Bcd10000
    • Bcd1000
    • Bcd100
    • Bcd10
    • Bcdunits

The initialization code for EEPROMDEMO is shown. There are the normal string identification messages Message Button [] (1 to 4), the data variable itself, and several new twists:  a blank array designated count [], variables bcd10000, bcd1000, bcd100, bcdtens and bcdunits.  In addition there is a new prototype function definition binary_to_ASCIIConvert (), –let’s try to put it together. To date we have not actually presented live data to the LCD display— only fixed strings. The use of count [], bcd10000, bcd1000, bcd100, bcdtens and bcdunits variables and binary_to_ASCIIConvert () remedy this. The binary_to_ASCIIConvert () takes data as an argument and then processes it to develop the ASCII equivalent in the bcd10000, bcd1000, bcd100, bcdtens and bcdunits variables as well as in proper position ( most significant to least significant digits) in blank array convert[]. But this is not the whole story so far. We have another LCD library function “write_array_LCD ()”. This function allows a character array like convert [] to be presented on the LCD display like the string arguments earlier. By updating the convert [] with the ASCII results from binary_to_ASCIIConvert () we can use write_array_LCD () to update the LCD display with the latest data values live. To gain a better understandings examine the EEPROMDEMO code shown below and some of Experimenter displays that occur as part of your EEPROMDEMO operation. This program structure of updating the LCD display with live data can be an important part for any of your future Experimenter applications.

var int

(Click the image for full screen)

Analog Anyone? –The I/O Expansion Bus and ADC

This I/O Expansion Bus is the way in which you can hook up and integrate the Experimenter to other electronics on your solderless breadboard. It will become a major player in the articles to follow. The bus consists of ten I/O pins that are completely software configurable. As a rule that we typically “program” our pin I/O functions as needed in the beginning of the program and then “Lock” the program for application use. We will go through several examples in the course of these articles to allow you to get a handle on this programmable feature.
The PIC24 Analog to Digital Converter (ADC) is a 10 bit converter that has up to 11 input channels and performs conversion up to 500K per sec. With the Experimenter 5 of these 11 channels are available to as ADC inputs with the I/O Expansion Bus. They are I/O expansion pins 1, 7, 8, 9, and 10. Using our ADC library we are able to make any of these pins act as an ADC input and perform an ADC conversion. The conversion automatically converts voltage signal at the input of the pin between 0 volts to +3.3 Volts to a numeric ten bit value 0 to 1023 representing that voltage. This capability allows the PIC24F to measure external voltage sources (i.e. like sensor outputs). Let’s try it. An ADCDEMO program using the ADC library is made available. Here we use the library to configure an I/O Expansion pin (in this case pin 10) as an ADC input and then perform a conversion. The conversion is displayed on the LCD in both count and voltage. An external potentiometer (pot) is required to act as a variable voltage source. Hook the wiper of pot to pin 10 and the other sides of the pot to +3.3V and GND. Since the program has a continuous loop the conversion and LCD updates are continuously happening. Turn the pot and watch the results. This program uses “#include ADC.H” and #include LCD.H” to reference needed libraries.

(Click the image for full screen)

The ADC library functions that are used are:

  • InitADC (IOpin) – initializes the designated Expansion bus pin for ADC operation as an input channel. The are only five possible pin available for this use on the I/O expansion and they designed in the code as :
    • pin1, pin7, pin8, pin9, pin10 (make sure to use exact syntax for pin shown here). This function must be called first before any ADC library function. Only one pin can be designated as an input at a time.
  • ReadADC (IOpin) – this function performs an ADC conversion on the input voltage present on the pin (see pin designations shown above) and returns an integer value from 0 to 1023 representing the measured voltage.

Examine the MAIN code using MPLAB IDE, it is well documented. Try changing the pin value to one of the other pins and rebuild and reload the program. Move the pot wiper over to this pin to get readings. The ADC library is an important tool for performing external voltage measurements with the Experimenter. We will use it again in subsequent articles.

DownLoad Code for experiments

Ideas for the future

Ok, we have covered several important subsystems for the Experimenter showing a number of functional capabilities. Each coverage included hardware as well as software examples for you to work on. Working the software examples will help to solidify these capabilities for your considerations in your next project. Within each software project text files are included that fully describe the libraries used for that project.  We are not done, and in fact just touching the surface. There are more features and interesting applications to come.