Introduction: Android Control of Non-Arduino Based Micros, PIC Etc

Picture of Android Control of Non-Arduino Based Micros, PIC Etc

This instructable describes how to use the free pfodDesignerV2 to create menus and charts for your non-Arduino based micro project. These menus and charts are then displayed by pfodApp on your Android mobile. No Android programming required.

Half-Duplex operation is supported if your hardware/software does not support Full-Duplex.

These instructions are also available at pfod™ for Non-Arduino based microprocessors

If you want to jump straight to the PIC18F14K22 MPLAB example, goto Step 7.

Outline:

First some background, then a detailed discussion of what you need to do in general to modify the pfodParserC library for your microprocessor so that you can use pfodDesignerV2 to generate your own menus.

Finally two detailed examples are presented using a bare PIC18F14K22 processor and an Adafruit BLE communication module, although you can easily replace the BLE module with a Bluetooth Classic module or an inexpensive WiFi module. The two examples are Turning a Led on and off from your Android mobile, and Sending data back to your mobile for logging and plotting.

Step 1: Background

pfod (Protocol For Operation Discovery) was developed in 2010 on a J2ME phone (Samsung C3110) to control an LED flash light. The first implementation of a pfodParser was in ASM on an Atmel Atiny84 8bit microprocessor. As the conclusion says

Under the pfod protocol, the pfodDevice™ advertises its capabilities to the pfodApp™ so the same pfodApp can be used to control any pfodDevice. The pfod protocol is very simple with minimal message structures and is readily implemented by small micro-processors ...

While pfodApp has moved on to Android and the pfod protocol has expanded to include addition features like menu caching and sliders and charts and additional formatting of fonts sizes and colours, the parser needed on the microprocessor is still very simple.

pfodDesignerV2 WYSIWYG menu design and Unicode support

The latest version of pfodDesignerV2 (V2.0.2181+), which lets you design menus and charts on your Android mobile in a WYSIWYG fashion, now generates C code (C++ compatible) that can be readily used in any small microprocessor to render that menu on pfodApp and handle the user's inputs to control your micro. Check out the detailed pfodDesignerV2 tutorials on this page for how to design pfodApp menus and generate the code. Select the C Code target from the Generate Code screen.

pfodDesignerV2 also supports Unicode characters so you can design non-english menus and include special symbols such as ℃ To enter Unicode into pfodDesignerV2, type in \uxxxx, e.g. \u2103 which will be immediately replaced with the actual symbol i.e. ℃ , provided your Android mobile has the appropriate font installed. When pfodDesignerV2 generates the C code it outputs the Octal representation for the bytes that make up this Unicode character. e.g. \342\204\203. This page, Using Non-ASCII chars in Arduino and other micro-processors, has a Java program that also does this conversion.

The pfodDesignerV2 does not cover all the pfod messages or all the options. For the complete pfod message specification see the pfodSpecification.pdf.

Step 2: Modifying the PfodParserC Library for Your Microprocessor

The pfodParserC Library consists of three (3) C code files and their associated header files, pfodParser.c, pfodParserStream.c and pfodMenu.c. pfodParser.c parses the incoming messages from pfodApp and does not change. The pfodParserStream.c files needs to be customized for your microprocessors UART implementation. The third file, pfodMenu.c is generated for you by pfodDesignerV2 and contains the menus and sub-menus definitions and the main command switch statement to handle the parsed messages from pfodApp.

The pfodParserC Library page contains a zip file and installation instructions for these files. Those files are based on a PIC18F14K22 using the MPLAB IDE. The necessary customization of the library for your particular microprocessor is covered next. If your microprocessor is programmed by the Arduino IDE then an Arduino version of the library is also available.

The pfodParseC Library uses about 84 bytes of RAM and a few kilo-bytes of Program. As you can see the RAM usage is very modest. The program space depends on your compiler and its optimization settings.

Overall approach to using pfodParserC on your microprocessor

  1. Modify the pfodParserStream.c file to work with our micro's I/O so you can send and receive bytes.
  2. Don't touch pfodParser.c at all. It does not change
  3. Use the free pfodDesignerV2 to design the menu you want and then generate the pfodMenu.h and pfodMenu.c files. Replace any existing files with these new ones
  4. Only use the variables and methods exposed in pfodMenu.h in your code (main.c)
  5. Connect a communication module, Bluetooth, Bluetooth LE or WiFi, and use the pfodApp to control your board and log and plot data from it.

Once you are familiar with pfodSpecification.pdf you can make manual changes to the pfodMenu files outside the pfodDesignerV2

Customization the pfodParserC Library

(Also see the pfodParserC Library installation and configuration)

As mentioned above the pfodMenu.c and its header are generated for you by the pfodDesignerV2 by using the C Code target when generating the code for the menu you have designed. The pfodParser.c and its header are constant across the microprocessors. It is only the pfodParserStream.c file that you need to customize to your particular microprocessor and compiler.

The pfodParserStream file handles the I/O for the parser and menu. It only has four (4) methods:-

size_t pfodParser_TXfree(void);
int pfodParser_write(uint8_t c);
size_t pfodParser_RXavailable(void);
int pfodParser_read(void);

The pfodParser uses the pfodParser_read() and pfodParser_RXavailable() to get the bytes to parse from the communication channel module (Bluetooth, BLE, WiFi), usually via the microprocessor's UART. The pfodParser_printXX() methods use the pfodParser_write(uint8_t) and pfodParser_TXfree() methods to write data back to pfodApp.

Because each microprocessor and each circuit has different ports/UARTs/ISP connections to the communication module, you need to first customization the implementation of these four methods to suit your particular set-up.

Here is a typical implementation. (MPLAB / PIC18F14K22 / UART with STDIO redirect) It will be covered in detail in the examples below.

/**
 * This is the interface to the i/o
 * Modify this file to suit your serial/uart connection code
 * 
 */
#include "pfodParserStream.h"
#include "mcc_generated_files/mcc.h"
extern uint8_t pfodParser_connected; // set true (1) when {.} parsed, set false (0) when {!} parsed.
/**
 * return space available for write();
 * @return bytes free, if space is available any non-zero return will do
 */
size_t pfodParser_TXfree(void) {
    return eusartTxBufferRemaining;
} 
int pfodParser_write(uint8_t c) {
    if (!pfodParser_connected) {
        return 1;
    }
    while (pfodParser_TXfree() == 0) {
        // spin
    }
    putch((char)c); // spins if no space available
    return 1;
}
/**
 * return bytes available to read(void)
 * @return bytes available, if bytes are available any non-zero return will do
 */
size_t pfodParser_RXavailable() {
    return eusartRxCount;
}
int pfodParser_read(void) {
    while (pfodParser_RXavailable() == 0) {
        // spin
    }
    return (int)getch(); // spins if not data available
}

In the above example code, MPLAB IDE provides two variables to use for pfodParser_TXfree() and pfodParser_RXavailable() and setting STDIO redirect in the UART configuration, links putch(uint8_t) and getch() to send and receive bytes to the UART.

You need to provide similar support in your microprocessor. You don't need to have a hardware UART, although that is desirable. You can use a half-duplex software UART implementation or an ISP interface. (See below on how to reliably use a half-duplex software UART)

In general, the code avoids the newer C99 features. The exception is uint8_t. If your compiler does not recognize this type add the following typedef to the top of each file

typedef unsigned char uint8_t;

That's all the customization necessary to use pfodParser in your code. See below for how to debug your customization.

Step 3: ​Handling User Commands

Picture of ​Handling User Commands

Once you have customized the pfodParserStream.c file for your set-up, you will want to action the user's commands in your program and perhaps send back some data for logging or plotting.

Your main.c file will typically look something like this..

// other header includes
#include “pfodMenu.h”
void main() {
  // initialize your microprocessor, clock settings, interrupts, I/O
   . . .
  pfodParser_setup();  initialize pfodParser
  while (1) {  // loop here doing your stuff
    pfodParser_parse();   // call this each loop the parse incoming messages 
    // and set the pfodParser global vars with user data and send back menus and data (if any)
   //  you other loop code here which uses the variables set by pfodParser to control your hardware.
   . . .
  }
}

Looking at a simple menu design that just turns a led on and off. (The full MPLAB example to turn a Led on and off is given below)

pfodDesignerV2 generates the following pfodMenu.h file (as well as the pfodMenu.c file). As you can see this file is C++ compatible in case your micro development system is C++ based.

The first comment shows the menu message that will be returned to the pfodApp when pfodApp connects and asks for the main menu by sending the command {.}

/* ===== pfod Command for PIC ====
pfodApp msg {.} --> {,<bg n><b><+3>~PIC Led Control`0~V29|A`0~Led is ~~Off\On~}
 */

The pfodDesignerV2 generates this response for you to match the menu, colours, font size and text you have designed. See the pfodSpecification.pdf for the details. All pfod messages are enclosed by { }

The cmd_A_var holds the user's requested led state, 0 for Off, 1 for On.

extern int cmd_A_var; // name the variable for 'Led is'  0=Off 1=On

So in the while (1) loop of your main code you use this variable to control the led. The LED_RC0.. methods set the micro's output RC0 high or low.

        if (cmd_A_var) {
            LED_RC0_SetHigh(); //sets RC0 output pin high
        } else {
            LED_RC0_SetLow();  //set pin low
        }

The complete code for this MPLAB example is included in a later step.

No plots have been defined in pfodDesignerV2, so just the default pfodParser_sendDataFlag and plot_X_var are defined. These will be discussed in the next section and in second example.

The pfodParser_connected variable can be used to control parts of the code that should only run while there is a connection. This is the variable the is used to ignore pfodParser_printXX() calls when there is no connection to pfodApp.

Finally the PFOD_PARSER_BUFFER_SIZE define sets the size of the pfodParser storage buffer. The pfodSpecification.pdf limits the maximum command from the pfodApp to 255 bytes, but the pfod messages your micro sends to the pfodApp are designed so that you always know exactly the maximum size the pfodApp commands can be. Using this information the pfodDesignerV2 can calculate the maximum length of an incoming message for your designed menu and reduce the allocated RAM accordingly. If you manually add other pfod screens, for example a text input screen, you may need to increase this buffer size.

Step 4: Sending Data to PfodApp for Logging and Plotting

Picture of Sending Data to PfodApp for Logging and Plotting

As mentioned above, all pfod messages are enclosed in { }. Any byte sent by your micro (the pfodDevice) outside of { } is raw data and is automatically logged to a file on your mobile. The pfodApp displays the name of this file when you exit. While you can send any raw data you want, including debugging output, if you want to plot your data you need to send it as CSV (comma separated values).

In the pfodMenu.c file there is the pfodParser_sendData() method. If you did not add a chart to your pfodDesignerV2 design then a minimal method is generated for you to fill in manually.

This method is called at the end of the pfodParser_parse() method. If pfodParser_sendDataFlag is false (0) then it just return. Also if the pfodParser_connected is false (0) the pfodParser_printXX() methods just return without sending any data.

To send data you need to be connected and you need to set pfodParser_sendDataFlag to true (non-0). When you are connected, each time you set pfodParser_sendDataFlag to true, the next call to pfodParser_parse() will send the data and clear the pfodParser_sendDataFlag to false. Typically you would use a timer in your microprocessor to set pfodParser_sendDataFlag to true at regular intervals.

This will be covered in detail in the second example. See the pfodSpecification.pdf for more details on sending data for plotting.

If you add a Chart to your menu in pfodDesignerV2, you automatically get upto 3 plots. You can add more manually if you need. pfodDesignerV2 lets you set labels and hide unused plots and preview the chart. For example if you define a chart with two plots showing, as shown in the picture above, pfodDesignerV2 generates the following pfodParser_sendData() method, as well as a button to show the chart.

void pfodParser_sendData() {<br>  // assigned values to the global plot variables are sent here
  if (!pfodParser_sendDataFlag) {
      return;
  }
  pfodParser_sendDataFlag = 0;
  // send plot data in CSV format
  pfodParser_printLong(plot_X_var);
  pfodParser_printCh(','); pfodParser_printLong(plot_1_var);
  pfodParser_printCh(','); pfodParser_printLong(plot_2_var);
  pfodParser_printCh(','); // Plot 3 is hidden in pfodDesignerV2. No data sent.
  pfodParser_println(); // end of CSV data record
  plot_X_var++; 
}

The pfodMenu.h file is also updated to include the global plot variables plot_1_var and plot_2_var. These variable are defined as volatile so they can be updated from a timer interrupt routine.

To actually send the data, in your main.c you need to assign some values to plot_1_var and plot_2_var and set pfodParser_sendDataFlag to true (non-0). In this example, timer TMR0 is set up to call the TMR0_CallBack() method once a second. (See the second MPLAB PIC plotting example below for details on configuring a PIC timer.)

In that interrupt call back values are assigned to the plot vars and the pfodParser_sendDataFlag to true so then next call to pfodParser_parse() will send this data as a CSV record.

Since TMR0_CallBack() is called from an interrupt, it should be keep as short as possible. Just assign the plot values here, collect and calculate them somewhere else.

Step 5: Sending Updates, Menu Caching, Short Refresh Msgs and Blocking Prints

Your pfodDevice (your micro) cannot force a menu update in pfodApp on your Android mobile. In order to get the menu updated you need to set a menu re-request interval for that menu in pfodDesignerV2.

pfodApp will then re-request the menu regularly and display the latest values. For example if some other part of your code turned the Led off, then update cmd_A_var to reflect this and when pfodApp re-requests the menu it will display the updated Led state on your mobile.

pfodApp caches each menu with a revision string. Then when it re-requests that menu, either at the next connection or re-request interval, pfodApp sends its current menu version as part of the request. pfodParser parses this menu version and compares it to its current version and if they match, pfodParser_parse() only send back a short menu update message instead of the full menu.

For example the full menu may be
{,<+3>~PIC Led Control`0~V26|A`0~Led is ~~Off\On~|B~Plot of Random Data}
but the refresh message is only
{;|A`1}

V26 is the menu version and the refresh message only sends the current value of the Led, its Off/On setting.

This means that while the initial menu may be very long, up to 1024 bytes of text and menu items, it is only sent once and thereafter the much shorter update messages are sent. Because pfodApp saves the cached menu across connection attempts, the full menu is only sent on the very first connection.

The pfodDesignerV2 automatically updates the menu version each time you generate a new set of code. However if you manually update the pfodParser_sendMainMenu() method in the generated pfodMenu.c, you should also change the pfodParser_pfodParser(ver) in the pfodParser_setup() method.

The pfodParser_printXX() are blocking. If there is no space available in the TX buffer, they block until there is. The method pfodParser_TXfree() is used to check if there is any free space. This ensures that no response bytes are lost. Since almost all menu updates are short messages, you only need a small TX buffer to hold the response.

Step 6: Half-Duplex Operation

Ignoring sending raw data, i.e. pfodParser_sendData(), the pfodParserC library is Half-Duplex safe. The pfodDevice, your micro, waits for pfodApp to send a command and then sends just one response. pfodApp does not send any other commands while waiting for the response to the pending one.

If your micro has a half-duplex UART, the simplest approach is to not send any raw data or plot data.

If you need to send some raw data or plot data then the only safe time to send it on a half-duplex connection is after the pfodParser has finished parsing a command and before it send the response. For example, in pfodMenu.c, the beginning of pfodParser_parse() is

void pfodParser_parse() {<br>  uint8_t cmd = pfodParser_parse_RX(); // parse incoming data from connection
  // parser returns non-zero when a pfod command is fully parsed
  if (cmd != 0) { // have parsed a complete msg { to }

Once cmd != 0, the parser has finished parsing the pfodApp's command and the UART can start sending without missing any incoming data. Once the response has been sent the UART must stop sending data and listen for a new command from pfodApp. So if your hardware only has a Half-Duplex UART, you can safely send raw data or CSV records immediately after the statement cmd != 0 statement. i.e. insert a call to pfodParser_sendData() there and remove it from the bottom of the pfodParser_parse() method.

if (cmd != 0) { // have parsed a complete msg { to }<br>    pfodParser_sendData(); // safe to send data here if half-duplex UART

Of course this means that you can only send raw data when the pfodApp sends a command, so set a re-request interval for this menu so that pfodApp regularly re-requests the menu and allows you to send raw data.

Step 7: PIC18F14K22 Example Projects

Here are two examples using MPLAB to program a PIC18F14K22 via PICkit3. The first one turns a Led on and off. The second one sends data back to the pfodApp for logging and plotting.

They use an Adafruit Bluefruit LE UART Friend to connect to the Android mobile running pfodApp via BLE. However you can use any Bluetooth Classic, Bluetooth LE or WiFi connection. For example a SparkFun Bluetooth Mate Silver for Bluetooth Classic or a ESP8266 WiFi base board like Adafruit HUZZAH ESP8266 Breakout when loaded with UART to WiFi server bridge code from this project.

Step 8: Example of Controlling a LED From Your Android Mobile Using PIC18F14K22 and PfodApp™

Picture of Example of Controlling a LED From Your Android Mobile Using PIC18F14K22 and PfodApp™

This is a detailed example of how code a PIC18F14K22 talk to an Adafruit BLE communication module and use pfodApp on your Android mobile to turn an led on and off. As noted below, you can also use Bluetooth or Wifi as the communication.

No Android programming required.

A following example will extend this one to send back data for logging and plotting. In both cases pfodDesignerV2 is used to generate most of the required code.

What you need

The example uses the following items (prices as at Aug 2016 and exclude shipping) :-

  • pfodDesignerV2 V2.0.2181+ (free)
  • pfodApp V2 V2.0.217+ (~US$10)
  • MPLAB X IDE v3.35, MPLAB XC8, MPLAB Code Configurator (free)
  • MICROCHIP DV164130 Development Board, PIC16/18F with PICkit-3 (includes PIC18F14K22 chip) (~US65)
  • Some hookup wires (~US$2) and header pins (~US$1)
  • A USB to Serial cable for initial testing, such as FTDI Serial TTL-232 USB Cable (~US$18) OR an Arduino board (here a Mega 2560 is used loaded with this Serial to Serial 9600 baud sketch)
  • 5V supply for the Development Board. You can use the 5V from the USB to Serial cable
  • A Bluetooth Classic, Bluetooth LE or WiFi board that connects via Serial. Here an Adafruit Bluefruit LE UART Friend (~US18) is used but you can other boards such SparkFun Bluetooth Mate Silver (~US$25) for Bluetooth Classic or a inexpensive ESP8266 Wifi base board like Adafruit HUZZAH ESP8266 Breakout (~US$10) when loaded with UART to WiFi server bridge code from this project.
  • A soldering iron and solder to solder the header pins. (~US$20). Solder wick (~US$3) and flux (~US$10) are also useful.

Step 9: MPLAB Software Setup

  1. From http://www.microchip.com/mplab install the MPLAB IDE and the XC8 compiler. Be aware that the free XC8 compiler is a non-optimizing compiler. The optimizing version costs real money. MPLAB's free C compile is crippleware. By MPLAB's own estimates it generates Hex files that 60% bigger then necessary and up to 4x slower. However it is free and easy to use and the Code Configurator is very convenient. A suggested solution, if you run into problems, is to “different PIC chip, with a faster clock and larger memory”.
  2. From http://www.microchip.com/mplab/mplab-code-configu... install the MPLAB Code Configurator and the PIC10/PIC12/PIC16/PIC18 device library.
  3. Open the MPLAB X IDE and install the Code Configurator from Tools → Plugins.

The completed project files for PIC18F14K22 are available here, LedControl.X.zip If you use those files you can just use File → Open Project and navigate the where you unzipped them.

This example will start with a new empty project.

  1. Open MPLAB X IDE and select File → New Project... and choose Microchip Embedded and Standalone Project.
  2. Click Next and select your device. This example uses PIC18F14K22 from the Advanced 8bit MCU's (PIC18) Family.
  3. Click Next and leave the debug support as NONE.
  4. Click Next and select the "PICkit3 hardware tool.”
  5. Click Next and select the XC8 compiler
  6. Finally enter a project name e.g LedControl

Step 10: Configuring the Clock, UART and LED Drive Pin. Creating Main.c

Picture of Configuring the Clock, UART and LED Drive Pin. Creating Main.c

Select Window → MPLAB Code Configurator → Open/Close to display the Code Configuration panel. It takes a few seconds to initialize the first time.

Set the Internal Oscillator as shown above.

Next scroll down the Device Resources (on the left) to EUSART and click the arrow to open it and double click on EUSART to open its configuration. Set the UART configuration as shown below.

Note: The Redirect STDIO to USART is ticked so that putch() and getch() are connected to the UART. The baud rate here is 9600 to match the Adafruit BLE UART baud rate. Choose a baud rate to match your communication module.

Finally set the GPIO output pin that will drive the LED. The development board used here has already wired RC0 to LED 0. So in the bottom panel, Pin Manager Grid (MCC) click on the GPIO output Port C 0

Also change the Package to PDIP20.
Finally click on Pin Module under Project resources (top left) to show the pin names used and their function. Rename the RC0 pin from IO_RCO to LED_RCO

Checking the Interrupt Settings and Generating the Configuration Files

Click on the Interrupt Module under Project resources (top left) to show the enabled Interrupts.

The EUSART TX and RCI should be enabled. Note: The reminder at the top to enable the Peripheral and Global Interrupts. This will be done next.

To generate the code for these configuration setting, click the Generate button/tab next to the ProjectResources tab. This will prompt you to save this configuration and then generate a number of supporting files under the sub-directory mcc_generated_files. It will also generate a main.c file

Step 11: Enable Interrupts in Main.c and Adding the PfodParser Files

In the MPLAB IDE with the

In order for the UART to work in interrupts mode you need to enable both the global interrupt and the peripheral interrupt. Do this by un-commenting the following two lines in main.c

// Enable the Global Interrupts
INTERRUPT_GlobalInterruptEnable(); // Enable the Peripheral Interrupts INTERRUPT_PeripheralInterruptEnable();

At this point you have set up the UART in interrupt mode linked to getch() and putch() and have set on pin as an output to drive the LED, but no code to actually do anything yet.

Adding the pfodParser files

Unzip the latest pfodParserC library to the same directory that main.c file was created in. This will add three (3) source files and headers:-

  • pfodMenu.c / .h as simple empty menu design generated by pfodDesignerV2
  • pfodParser.c / .h the pfodParser. This file usually never needs to be changed.
  • pfodParserStream.c / .h The .h file never needs to be changed. But you may need to edit the pfodParserStream.c file to match your micros UART setup.

To add these files to your project, click on the Projects tab (top left) and right click on the Source Files and choose Add Existing Item... Highlight the pfodParser... files and add them to the project.

Rebuild the project and check for errors. If you are not using a PIC18F14K22, the most likely change required, if you are using MPLAB Code Configurator, is to fix the references to eusartTxBufferRemaining and eusartRxCount to match the UART you are using. Rebuild and check there are no more errors.

Step 12: Testing the PfodParser I/O and Confirming the PfodParser / PfodMenu Works

Picture of Testing the PfodParser I/O and Confirming the PfodParser / PfodMenu Works

All the pfodParser I/O goes through the pfodParserStream methods, via the pfodParser_printXX() methods, so it is a good idea to test they are working before trying anything else.

Take a copy of your main.c file and replace it with the contents of main_pfodParserStreamTest.c Program your PIC micro. I used a PICkit3 and a simple DV164130 development board.

Before connecting the PICkit 3 to a PC via USB, disconnect any target boards that may be attached to the PICkit 3. Similarly, when starting up or rebooting the host PC, ensure that the PICkit 3 is not connected to a target board.

Connect your PIC micro to a terminal program at 9600, I used TeraTerm. To make the hardware connection to your computer you can use an FTDI Serial TTL-232 USB Cable. I used an Arduino Mega I had available. loaded it with this sketch and wired as shown above.

This test program writes a long counter to the serial out and reads and echos from serial in. The output counter should not miss any numbers and all the input chars should be echoed, but perhaps interspersed with counter output.

Confirming the pfodParser / pfodMenu works

Once you have the pfodParserStream running, you can re-instate your original main.c and test the simple Empty Menu. To do this you need to include pfodMenu.h to the top of your main, call pfodParser_setup() in you main() and then each processing loop, call pfodParser_parse()

#include "mcc_generated_files/mcc.h"
#include "pfodMenu.h" void main(void) { SYSTEM_Initialize(); // Initialize the device INTERRUPT_GlobalInterruptEnable(); // Enable the Global Interrupts INTERRUPT_PeripheralInterruptEnable(); // Enable the Peripheral Interrupts pfodParser_setup(); while (1) { pfodParser_parse(); // your other processing code goes here } }

Re-program your PIC and then when you enter {.} into the terminal, which is what pfodApp sends to request the main menu, you should see the menu returned {,~Initial Empty Menu`0~V19}

Step 13: Connecting to PfodApp on Your Android Mobile

Picture of Connecting to PfodApp on Your Android Mobile

Now that you are sure the PIC program is operating correctly, you can connect up a communication board to the PIC's serial pins and connect to it via pfodApp from your Android mobile.

Here I have used an Adafruit Bluefruit LE UART Friend because is it small, low power and easy to hookup. But you can other boards such SparkFun Bluetooth Mate Silver for Bluetooth Classic or a inexpensive ESP8266 Wifi base board like Adafruit HUZZAH ESP8266 Breakout when loaded with UART to WiFi server bridge code from this project.

Note: You need to ground the Adafruit's CTS line and connect the Adafruit TX to PIC RX pin (RB5) and Adafruit RX to PIX TX pin (RB7).

Then start pfodApp and set up a BLE connection to the Adafruit BLE. See the pfodAppForAndroidGettingStarted for the details. (You can also connect a WiFi or Bluetooth V2 device with pfodApp.) When you connect you will see an “Initial Empty Menu” served by your PIC microprocessor.

Step 14: Turning a Led On/Off From Your Mobile

Picture of Turning a Led On/Off From Your Mobile

Previously, you configured one of the PIC pins as an output and named it LED_RC0. On the development board this output is connected to one of the Leds. To control this led, install pfodDesignerV2 on your mobile, start a new menu, choose Generate Code → Change Target and choose C code. This C code target modifies the pfodDesignerV2 menus to suit.

Then design a menu adding a menu item On/Off Setting or Pulse . Here is a detailed tutorial on using the pfodDesignerV2 to design this menu. With C code target set, you won't have the option in pfodDesignerV2 to set the output pin. That will be done in your main.c next.

Use pfodDesignerV2 to generate the pfodMenu.h / pfodMenu.c files (both written to the one output file pfodDesignerV2.txt). Here are sample pfodMenu.h and pfodMenu.c files to switch the Led on and off. Replace the existing pfodMenu.h and pfodMenu.c files in your project with the contents of these two new files and reprogramming your PIC will show the following menu when you connect.

Note: disconnect the Adafruit's TX/RX lines when reprogramming so it does not get confused.

Connect with pfodApp again and you can click any where in the On/Off button to toggle it. When you disconnect and reconnect pfodApp, it displays the last setting sent to your PIC. Now you need to link this menu item to your LED pin.

Connecting the On/Off menu item to the PIC output pin

The files generated by pfodDesignerV2 are designed so that you only need to work with the methods and variables exposed in the pfodMenu.h header. Open the pfodMenu.h header, the one you just generated from pfodDesignerV2.

The first line shows the menu string returned when the pfodApp sends {.} asking for the main menu. The other entries are well commented. The variable we are interested in here is

int cmd_A_var; // name the variable for 'Led is'  0=Off 1=On

The cmd_A_var is set by the pfodMenu.c code in response to the the command send by pfodApp when the user operates the On/Off menu item.

When the user operates the On/Off button, pfodApp sends the command {A`0} or {A`1}. A is the command associated with the On/Off button and the arguments 0,1 represent Off and On. The cmd_A_var is set with this argument value, when the command arrives. Finally pfodMenu.c sends back a menu update is sent back to the pfodApp to display.

In your main.c file you can use the current value of cmd_A_var to control the Led. MPLAB generates some output macros as part of the Code Configurator. LED_RC0_SetHigh() and LED_RC0_SetLow(). These are defined in pin_manager.h which is automatically and available include in main.c

So using these macros you can edit the main() method to

void main(void) {
SYSTEM_Initialize(); // Initialize the device INTERRUPT_GlobalInterruptEnable(); // Enable the Global Interrupts INTERRUPT_PeripheralInterruptEnable(); // Enable the Peripheral Interrupts pfodParser_setup(); while (1) { pfodParser_parse(); if (cmd_A_var) { LED_RC0_SetHigh(); } else { LED_RC0_SetLow(); } } }

The completed main.c is here. Now when you have reprogrammed your PIC and connect using pfodApp, the menu On/Off button turns the Led On and Off. This complete MPLAB project, LedControl, using the PIC18F14K22 is here.

Step 15: Example of Logging and Plotting Data on Your Android Mobile Using PIC18F14K22 and PfodApp™

Picture of Example of Logging and Plotting Data on Your Android Mobile Using PIC18F14K22 and PfodApp™

This is a detailed example of how code a PIC18F14K22 talk to an Adafruit BLE communication module and use pfodApp on your Android mobile to log and plot data sent from the PIC. No Android programming required.

This example follows on from previous PIC Led Control example. That example needs to be completed first as it sets up the pfodParserC library for your microprocessor. The complete MPLAB project for this example is DataLogging.X.zip

Add a Chart to your Menu

pfodDesignerV2 lets you add a chart with up to three (3) plots to your menu. The tutorial How to Display/Plot Arduino Data on Android covers how to design a chart menu item. In this example you will use the C code target to generate the pfodMenu.h and pfodMenu.c files needed for non-Arduino based processors.

Start with your previous “PIC Led Control” menu design in pfodDesignerV2. Following the example of How to Display/Plot Arduino Data on Android, add a chart button called “Plot of Random Data” containing a chart labelled “PIC Data” with two plots (i.e. hide Plot 3). Plot 1 labelled “Random Data” and Plot 2 labelled “Led setting” with Y axis “LED (On=1)”, Fixed Scale and a Plot Data Variable Range of (-1 to 2)

Generate the C code and replace the existing pfodMenu.h and pfodMenu.c files with the new generated code. Here are the generated pfodMenu.h and pfodMenu.c files.

Do a clean rebuild and re-program your PIC. (Note: disconnect the Adafruit's TX/RX lines when reprogramming so it does not get confused.) Then when you connect with pfodApp you will see your new menu.

Clicking on the “Plot of Random Data” button open the chart with two empty plot. Your PIC is not sending any data yet.

Step 16: Sending Data From the PIC

Picture of Sending Data From the PIC

Looking at the new pfodMenu.h header file you can see the added plot variables

// plotting data variables
extern volatile uint8_t pfodParser_sendDataFlag; // set this to true (1) to send data, it is reset to false (0) by pfodParser_sendData() extern volatile unsigned long plot_X_var; // X axis defaults to an incrementing counter unless your code assigns a value to plot_X_var before each pfodParser_sendData() call. extern volatile int plot_1_var; extern volatile int plot_2_var; // plot 3 is hidden

Looking in the new pfodMenu.c file you can see the updated pfodParser_sendData() method. This method sends the data is CSV (comma separated values) format.

void pfodParser_sendData(void) {
if (!pfodParser_sendDataFlag) { return; } pfodParser_sendDataFlag = 0; // send plot data in CSV format pfodParser_printLong(plot_X_var); pfodParser_printCh(','); pfodParser_printLong(plot_1_var); pfodParser_printCh(','); pfodParser_printLong(plot_2_var); pfodParser_printCh(','); // Plot 3 is hidden in pfodDesignerV2. No data sent. pfodParser_println(); // end of CSV data record plot_X_var++; }

To send data you only need to assign values to the variables plot_X_var, plot_1_var and plot_2_var and then set the pfodParser_sendDataFlag true (non-zero). If you don't assign a value to plot_X_var then pfodParser_sendData() will just send an incrementing counter for the X axis.

Setting up a 1sec Timer

Open the Code Configurator again (Tools → Embedded → Code Configurator Open/Close) and from Device Resources (left hand side) open the Timer section and double click on TMR0. Configure it as shown above. This set the time to call the interrupt method once a second.

Click the Generate tab to re-generate the MPLAB config files. There are now two new files tmr0.h and tmr0.cunder mcc_generated_files. The SYSTEM_Initialize() method now automatically initializes and starts timer TMR0.

Open the tmr0.c file and cut the void TMR0_CallBack(void) method and paste at the bottom on your main.c file.

Setting and Sending the Plot Data

Edit the TMR0_CallBack method to assign values to the plot variables and to set pfodParser_sendDataFlag to non-zero. This example overrides plot_X_var with a sec. counter and just assigns a random value for plot_1_var and assigns the current value of cmd_A_var to plot_2_var.

unsigned long timeSec = 0;
void TMR0_CallBack(void) { timeSec++; plot_X_var = timeSec; plot_1_var = 450+600+(rand()%100); plot_2_var = cmd_A_var; pfodParser_sendDataFlag = 1; // send data once per sec }

The complete edited main.c is here. You need to add stdlib.h to the includes for rand().

Since the TMRO_CallBack() is an interrupt callback method, it should be kept short with little or no calculation in it. Just assign the variables and return.

Now when you connect with pfodApp and turn the led on and off a few times the plot looks like the chart above.

The CSV plot data is also logged to a file on your Android for later downloading and further analysis. The raw data filename is displayed as you exit pfodApp. See pfodAppForAndroidGettingStarted.pdf for more details.

The complete MPLAB project for a PIC18F14K22 is in DataLogging.X.zip

Conclusion

This second MPLAB PIC18F14K22 example builds on the first one to add data logging and plotting. pfodDesignerV2 does most of the coding for you and generates the pfodMenu.h and pfodMenu.c files. You only need to assign values to the plot variables and set the pfodParser_sendDataFlag.

pfodApp automatically saves the data to a file on your mobile for later use. The pfodDesignerV2 does not cover all the screen or plotting options. Check out the complete pfodSpecification.pdf the all the details.

Also check out www.pfod.com.au for other example projects and tutorials.

Comments

DusanKo made it! (author)2016-08-15

I love pFod, had many simple and advanced menu projects using pFod parser on microcontroller and pFod app on android phone. pFod library supports ESP chips as well. There are many examples in library so You basically just copy and paste the code or use pFod designer to generate the whole code for You. At the end, author always helps, if You are stuck (as i was many times by issues with other code, not pFod one). I do recommend using pFod.

I am attaching some of my screenshots of devices i am controlling via pFod app.

Dusan

drmpf (author)DusanKo2016-08-15

Glad to hear pfodApp is meeting your needs.

When you update your projects to pfodAppV2 menus the screen shots will look even better. Rounded buttons, clearer labels, more slider display options.