Home | pfodApps/pfodDevices | WebStringTemplates | Java/J2EE | Unix | Torches | Superannuation | | About Us
 

Forward Logo (image)      

Custom Robot Apps with pfodApp
for Android
No Android Programming Required
DFRobot's Flamewheel example

by Matthew Ford 25th May 2017 (originally posted 25th March 2017)
© Forward Computing and Control Pty. Ltd. NSW Australia
All rights reserved.

The above robot control App is NOT built into pfodApp
The display and controls are completely defined by the sketch you load into your Robot.
You can add extra buttons and controls as you need by editing your sketch. No Android Programming Required.

Introduction

This page covers the design of your own custom Robot control Android apps using pfodApp. No Android programming necessary. DFRobot's Flamewheel robot is used as an example project, but, as you will see below, you can design your own custom control interface.

Robots usually come with apps supplied, but you are then restricted to only what the app can do. However using the general purpose pfodApp you can design your own interface the way you want it and with the added features you want.

pfodApp will connect via and Bluetooth Low Energy (BLE), Bluetooth Classic, WiFi, Ethernet and also SMS. Many robots come with BLE communication, however because there is no BLE UART standard defined, each manufacturer implements his own.

pfodApp currently supports the following manufacturer’s 'standards' :- DFRobot Romeo BLE, DFRobot BLUNO (e.g. Flamewheel etc), Arduino101, BBC micro:bit, RFduno, RedBearLab, Nordic BLE UART, Adafruit BLE UART, Adafruit BLE SPI, HM-10 (e.g. ITEAD BLE Shield)

Parts List:

For this example project you will need (prices as at May 2017, not including shipping) :-
Flamewheel ~ US40 (also 4 x AAA alkaline batteries and an M3 screw driver)
USB A to Micro cable ~US$5
pfodApp ~ US10
An Android mobile - V4.4.2 or higher
Arduino IDE V1.8.2 and a computer to run it on.
pfodParser library

Software

The Flamewheel is powered by a Romeo BLE mini board with has an UNO processor, a motor driver chip and a TI BLE module connected to TX/RX pins. This makes the Arduino side of the BLE connection simple. You just read and write to the Serial connection at 115200 baud. The TI BLE module also handles the USB connection. The Android app side of the BLE connection normally requires a detailed knowledge of Android programming, however pfodApp handles all of that for you. No Android programming required.

BLE Config

My board came with Firmware V1.97 and I left it at that as it seemed to be the latest for this board.

You can configure the TI BLE module via AT commands from the USB connection. (See the BLUNO wiki) :-

1) Open the Arduino IDE, check the Romeo BLE mini has been detected as an UNO on a com port.
2) Open Serial Monitor and set the baud rate to 115200 and set “No Line Endings”. Then type +++ and click Send to get into AT cmd mode the successful response is “Enter AT mode
3) Then change the line endings back to “Both NL & CR” and execute the following commands

AT+VERSION=?
responds
V1.97
AT+SETTING=DEFAULT
responds
OK
AT+BLUNODEBUG=OFF
responds
OK
AT+USBDEBUG=OFF
responds
OK
AT+EXIT
responds
OK

This turns off the BLE debug output to the USB connection. You can turn it on if you want to monitor the BLE messages on the Arduino Serial Monitor.

To compile the sketch, download and install the pfodParser library and load the Flamewheel.ino sketch into your IDE and select Board → Arduino/Genuino UNO and program the Romeo BLE mini.
Programming tip: You can reprogram your Flamewheel after construction. Make sure there is no BLE connection. Remove one battery and plug in the USB to re-program.

That is the software complete.

Hardware

The Flamewheel kit went together easily, but here are a few tips:-

Flamewheel Construction Tips

  1. Put a cloth under the construction to catch dropped screws so they don't bounce away. (Fortunately the kit came with spare screws)

  2. Install A1 and A3 so the writing faces outwards on both, so the cutouts are aligned.

  3. Don't over tighten the self tapping (pointed) screws or you will strip the thread you are making in the wood. The circuit board can be a little loose and the wheels are a press fit and don't need to be screwed down tight

  4. Hold the wheel when tightening the retaining screw (D3) so you don't turn the motor gears in reverse.

  5. In spite of what the video shows – Don't set your robot alight !!

Operation

Download the pfodApp and setup a new BLE connection for the Flamewheel. See pfodAppForAndroidGettingStarted.pdf for details on how to create a new connection.

Then when you connect, pfodApp will load this dwg from your Flamewheel sketch

Put your finger in the center and move it forward of backward to drive the Flamewheel. Move you finger left or right from the center line to turn. If you go to the left or right edge, the Flamewheel will spin on the spot. Anywhere on the Stop line stops the Flamewheel. It will also stop if you lift you finger off the screen.

As mentioned above this dwg and all the controls are completely defined by the sketch you loaded into the Flamewheel, so you can customize the user interface by editing the your Arduino code.
No android programming required. See below for details.

The Sketch Code

The flamewheel.ino sketch has three basic parts.

  1. Loading the menu and drawing,

  2. Processing the user's input

  3. Calculating the left and right wheel speed.

See Custom Arduino Controls for Android for a detailed tutorial on pfodApp dwg support, loading dwgs and creating controls

1) Loading the menu and drawing

When pfodApp connects it send the 'get main menu' command, {.} and the parser parses it the extract the '.' You can see in the loop() code where this is handled and the main menu is sent back.

    if ('.' == cmd) {
      // pfodApp has connected and sent {.} , it is asking for the main menu
      if (!parser.isRefresh()) {
        sendMainMenu(); // send back the menu designed
      } else {
        sendMainMenuUpdate(); // menu is cached just send update
      }
      stop(); // always start stopped


The main menu msg returned is
{,~Flamewheel`0~V1|+A~a}
See the pfodSpecification.pdf for all the details of the pfod messages.

The +A~a defines a dwg menu item, '+', that contains a dwg that can be loaded via the 'a' dwg load cmd. When pfodApp process this response it requests the dwg by sending the {a`0} command.

Further down the loop() you can see

    } else if ('a' == cmd) { // pfodApp is asking to load dwg 'a'
      if (!parser.isRefresh()) { // not refresh send whole dwg
        sendDrawing_a();
      } else { // refresh just update drawing state
        sendDrawingUpdates_a();
      }


which sends back the dwg definition. The supporting
pfodDwgs methods included in the pfodParser library are used to create the dwg.

pfodDwgs dwgs(&parser);  // drawing support
int cols = 23;
int rows = 25;
… … … 
void sendDrawing_a() {
  dwgs.start(cols, rows, dwgs.WHITE); // background defaults to WHITE if omitted i.e. dwgs.start(50,30);
  parser.sendVersion(); // send the parser version to cache this image
  // draw the axies, leave space for the text
  dwgs.line().size(0, rows - 4).offset((cols) / 2.0, 2).send();
  dwgs.line().size(cols / 5.0f, 0).offset(cols / 2.0f - cols / 10.0f, (rows) / 2.0f).send();
  dwgs.line().size(cols / 5.0f, 0).offset(0, (rows) / 2.0f).send();
  dwgs.line().size(cols / 5.0f, 0).offset(cols - cols / 5.0f, (rows) / 2.0f).send();
  // add the labels
  dwgs.label().fontSize(-3).offset(cols / 2.0f, 1).text(F("Forward")).send();
  dwgs.label().fontSize(-3).offset(cols / 2.0f, rows - 1).text(F("Back")).send();
  dwgs.label().fontSize(-5).offset(cols / 2.0f - cols / 5.0f, (rows) / 2.0f).text(F("Stop")).send();
  dwgs.label().fontSize(-5).offset(cols / 2.0f + cols / 5.0f, (rows) / 2.0f).text(F("Stop")).send();
  // define the active touch zone and its cmd
  dwgs.touchZone().cmd(touchZoneCmd).size(cols, rows).filter(dwgs.DOWN + dwgs.DRAG + dwgs.UP).send();
  // close dwg
  dwgs.end();
}

This defines a dwg 23 cols wide by 25 row high. pfodApp will automatically scale the dwg up to width of the mobile's screen. The cols and rows set the touch resolution. As well as drawing some lines and adding some labels, a touchZone is defined that covers the entire dwg.

dwgs.touchZone().cmd(touchZoneCmd).size(cols, rows).filter(dwgs.DOWN + dwgs.DRAG + dwgs.UP).send();

TouchZones are normally invisible but you can turn on Debug on the connections setup screen to make them visible.

The touch filter is set to send a messages when the use puts their finger DOWN, DRAGS their finger or lifts their finger UP. DRAG messages are only sent if there is a change in col,row position touched on the dwg. You choose the dwgs cols,rows size to give you the touch resolution you need while limiting the number of messages sent.

2) Processing the user's input

When the user touches the dwg inside the touchZone, pfodApp sends a command like {V1:A~p`12`7`1}
The pfodParser parser parses this command and returns the first char of the command, i.e. 'A' (The leading V1 is the menu/dwg version string that pfodApp has already cached).
The '
A' command it is handled by this section of the loop() code.

    } else if ('A' == cmd) { // user touched menu item 'A'
      // in the main Menu of Flamewheel
      char dwgCmd = parser.parseDwgCmd(); // parse rest of dwgCmd, return first char of active cmd
      if (dwgCmd == (touchZoneCmd)) {
        colTouched = parser.getTouchedCol();
        rowTouched = parser.getTouchedRow();
        col = colTouched - zeroCol; // + = right
        row = -(rowTouched - zeroRow); // + == forward
        calculateWheelSpeed();
      }
      if (parser.getTouchType() == dwgs.UP) {
        // stop when user lifts finger off dwg
        stop();
      }
      sendDrawingUpdates_a();   // always send back a response or pfodApp will timeout


parser.parseDwgCmd() parses the rest of the command as a dwg command and returns the touchzone cmd 'p'

Once parseDwgCmd() has been called you can pickup the col and row touched with parser.getTouchedCol() and parser.getTouchedRow() i.e. 12 and 7 in this example message. This is location where the user touched in the dwg in the touchzone.

The col and row relative to the center of the dwg is then calculated and calculateWheelSpeed() called to set the left and right wheel speed.

Then the type of touch that triggered this command is retrieved using parser.getTouchType(), 1 in this example, and if it was a finger UP (dwgs.UP == 4) then stop() is called.

Finally sendDrawingUpdates_a() is called to update the dwg if required. You must always respond to every message pfodApp sends or the connection will timeout. In this project the dwg is not updated as the user touches it so the dwg update is empty and sendDrawingUpdates_a() just sends back {+}

As you can see the code to process the user's touch is simple.

3) Calculating the left and right wheel speed

Having calculated the col and row the user touched relative to the dwg center, calculatedWheelSpeed() calculates the left and right wheel speed in the range -255 to +255 as needed by DFRobotRomeoBLEMini. The row sets the speed and the col sets the left / right wheel speed difference. As you move off the center line the speed of one wheel is reduced, reaching zero at the edge.

The code in calculatedWheelSpeed() makes a few adjustments. If the row is not zero, 1 is added/subtracted so that the min speed is ~46 so the motor does not stall at low speed. The scaling factor for the speed is rows * 23 so a value of 11 ~= 255, but the rows +1 goes from 2 to 13. The extra rows top and bottom allow the user to easily place their finger at near the top and bottom edge of the drawing to get maximum speed. The wheelspeed is limited to +/-255

Then the wheel speed is adjusted for starting and reversing. If you go from 0 to 255 in one step, the surge in motor current interferes with the BLE connection, also if you go from 0 to some slow speed the motor sticks and may not start, so when starting the speed always goes from 0 to 128 for 100ms before reverting to the requested speed. Also when the user moves their finger around the center position from forward to back, the code insures that the motor always stops in between again to limit the current surge.

Finally the col value is squared (i.e. col * col) to give the % reduction from wheelspeed for one wheel so that the Flamewheel turns. Using col * col gives a small adjustments either side of the center line for ease of driving in a straight line, but produces stronger turns further from the center. At the edge the Flamewheel just spins on one wheel.

Next Steps

The Flamewheel kit really only needs this one control, but other robots will need other controls, buttons, sliders etc. to adjust settings and perform actions. You can add these extra controls to your sketch and have them displayed on the pfodApp without doing any Android programming.

See Custom Arduino Controls for Android for examples of adding buttons and sliders to a drawing. You also have to option of adding sub-menus and extra menu items below the drawing. These menu items can be buttons, sliders, labels etc. The free pfodDesigner app lets you add these and will then generate the sketch code for you.

Conclusion

This Flamewheel robot controller app illustrates how easy it is for you to create your own custom robot app (no Android Programming required) that connects to a variety of BLE standards all using the same pfodApp.

pfodApp V3 provides a small set of powerful Arduino drawing primitives that let you create your own custom Android controls. The touch zone and touch actions give you control over how user input is handled and can provide the user with immediate feedback for their actions. (This example did not use touch actions see Custom Arduino Controls for Android for examples that do.)

The pfodParser library simplifies creating the drawing messages. The separate pfodDwgControls library contains a number of pre-built controls ready to use, including slider, buttons and on-screen help.

Setting a version string enables caching of the menu and drawing by pfodApp, reducing bandwidth and speeding up display.



AndroidTM is a trademark of Google Inc. For use of the Arduino name see http://arduino.cc/en/Main/FAQ


The General Purpose Android/Arduino Control App.
pfodDevice™ and pfodApp™ are trade marks of Forward Computing and Control Pty. Ltd.


Forward home page link (image)

Contact Forward Computing and Control by
©Copyright 1996-2020 Forward Computing and Control Pty. Ltd. ACN 003 669 994