Simblee Concepts

This Tutorial is Retired!

This tutorial covers concepts or technologies that are no longer current. It's still here for you to read and enjoy, but may not be as useful as our newest tutorials.

Pages
Contributors: SFUptownMaker
Favorited Favorite 6

Library Reference

This page is intended to provide a reference to the various commands that are provided in the Simblee libraries. While we will try to provide examples of as many of these as possible, this list will give a strict explanation of each function.

There are ten Simblee-specific libraries: SimbleeAESCOM, SimbleeCloud, SimbleeForMobile, SimbleeGZLL, SimbleeRNG, SimbleeAES, SimbleeBLE, SimbleeCOM, SimbleeForMobileClient, and SimbleeNonBLE. In addition, there are Simblee-compatible versions of three "standard" Arduino libraries: SPI, Servo, and Wire. We won't cover all of these; there just isn't time. We're going to focus on SimbleeForMobile, SimbleeForMobileClient, SimbleeBLE, and SimbleeNonBLE, as these are probably the most widely applicable.

SimbleeNonBLE

Strictly speaking, SimbleeNonBLE isn't really a library; it's created as a library folder to provide example code for Simblee devices that isn't specific to using the Simblee as a BLE device. Thus, there's no need to include "SimbleeNonBLE.h" in any of your code files (indeed, the file is empty). However, there are some functions that are likely to be useful that can be found in the examples folder in this "library".

If anything is different to what you'd normally expect on a "standard" Arduino board, we'll mention it here.

  • analogRead(uint32_t ulPin) -- Returns a uint32_t (range 0-1023) representing the analog voltage on pin ulPin. The Simblee supports analogRead() on pins 1-6 only.

  • analogWrite(uint32_t ulPin, uint32_t ulValue) -- Provides a PWM output on pin ulPin of duty cycle ulValue/255. Unlike most Arduino boards, any pin can be used for analogWrite(), but only up to four at one time.

  • getDeviceId() -- Returns a uint64_t which is unique to this particular Simblee module. The upper and lower uint32_t values comprising this value can be individually accessed via getDeviceIdLow() and getDeviceIdHigh().

  • Simblee_pinWake(uint32_t ulPin, uint32_t dwWake) -- Choose a pin to wake the device from sleep. dwWake can be either HIGH, LOW, or DISABLED.

  • Simblee_pinWakeCallback(uint32_t ulPin, uint32_t dWake, pin_wake_t callback) -- The first two parameters are the same as for Simblee_pinWake(); the third is the name of a function returning type int and receiving one argument, uint32_t pinName. This code will be called upon a pin-based wake up from sleep mode.

  • Simblee_pinWoke(uint32_t ulPin) -- Returns true if the recent wakeup was caused by the pin number passed in.

  • Simblee_resetPinWake(uint32_t ulPin) -- Resets the status of that pin's wakeup register. Must be called before returning to low power mode!

  • Simblee_ULPDelay(uint64_t ms) -- Put the Simblee device into "ultra low-power" mode for ms milliseconds. Macros exist to define the parameter as MILLISECONDS(x), SECONDS(x), MINUTES(x), HOURS(x), or DAYS(x); if you pass the parameter INFINITE the Simblee won't wake up until a predefined pin event occurs. In this mode, the Simblee consumes about 500uA of current. If no callback function is specified and the waking event was a pin input, execution resumes on the line after the Simblee_ULPDelay() function was called. If a callback function exists, all input wakeups will vector to that code rather than executing the code following the Simblee_ULPDelay() call.

  • Simblee_systemOff() -- Put the system into double secret low power mode. In this mode, waking up will take longer and can't be done on a timed basis; however, the power consumption is even further reduced over ultra low power mode, to around 1uA. On power up, execution begins with the callback function specified using the Simblee_pinWakeCallback() function; if you haven't set a callback function, execution is immediately suspended back into low power mode.

  • Simblee_systemReset() -- Software system reset call. Begins execution at the beginning of the sketch; this will cause the Simblee to drop any active connections.

SimbleeForMobile

The SimbleeForMobile library implements the functions necessary to draw objects in the Simblee for Mobile app. This code is resident on the Simblee module and is uploaded when the module connects to the mobile device; it can be cached on the device to reduce load times for future connections.

Common Functions

These four functions must be in every SimbleeForMobile sketch for it to work. The first two must be called and the second two must be defined.

  • SimbleeForMobile.begin() -- Perform initial setup for the library. Typically, this is called at the end of the setup() function.

  • SimbleeForMobile.process() -- Must be called once per loop to handle all the background processes necessary to the interaction between Simblee and host. Typically, the call to this function is the last thing done in the loop() function.

These two functions must be defined in your sketch for it to work; add them to the sketch below setup() and loop().

  • void ui() -- Defines the UI on the host device.

  • void ui_event(event_t &event) -- Called when an event occurs on the host device. The event_t object contains information about what particular type of event occurred; more on this in a later section.

Configuration Variables

Some of these variables are identical to the ones in the SimbleeBLE library; indeed, SimbleeForMobile is built on top of SimbleeBLE. Do not attempt to use both SimbleeBLE and SimbleeForMobile in the same sketch, however.

All of these configuration variables must be set before calling SimbleeForMobile.begin()

  • SimbleeForMobile.deviceName -- Name displayed in the Simblee app. This string's length plus the length of the SimbleeForMobile.advertisementData string must be less than 16 characters long.

  • SimbleeForMobile.advertisementData -- Data displayed in the Simblee app. This string's length plus the length of the SimbleeForMobile.deviceName string must be less than 16 characters long.

  • SimbleeForMobile.txPowerLevel -- int between -20 and +4 representing transmit power, in dBm. Default is +4; only values which a multiples of 4 are allowed.

  • SimbleeBLE.advertisementInterval -- int variable declaring, in ms, the frequency with which to issue advertisement packets. Range from 20ms to 10.24s; the actual range units are in units of 0.625ms, so the actual interval will only be an approximation of this value. If the device is in nonconnectable mode, the actual interval will be a minimum of 100ms. Default is 80ms.

Callback Functions

Certain events (apart from UI events on the host device) will cause a callback function to be activated. Here's a list of those functions; to use any of them, define them in your sketch below the four standard SimbleeForMobile functions.

  • void SimbleeForMobile_onAdvertisement(bool start) -- Called when advertisement starts, or stops, and start reports which event occurred.

  • void SimbleeForMobile_onConnect() -- Called when a host connects to the Simblee device.

  • void SimbleeForMobile_onDisconnect() -- Called when a host disconnects from the Simblee.

  • void SimbleeForMobile_onRSSI(int rssi) -- Called when new RSSI information is available. This is the signal strength at the Simblee, not the host.

UI Drawing Concepts

Now for the good part: how to draw a UI on the host! These functions may be called at any time, in any function; if you call them during the ui() function call, however, they will only be sent once, on connection, which makes the bandwidth usage lower.

A note on position: all objects are created with their upper left corner at the reference location. The upper left corner of the screen is 0,0, and the X and Y coordinate values increase as you move towards the right or bottom edges of the screen. To find the X and Y dimensions of the screen, you may reference the SimbleeForMobile.screenWidth and SimbleeForMobile.screenHeight variables.

It is possible to use the device in either portrait or landscape mode. The mode is selected when SimbleeForMobile.beginScreen() is called. More on this below.

Bookending your UI items with SimbleeForMobile.beginScreen() and SimbleeForMobile.endScreen() within the ui() function allows the Simblee app to determine what portions of the UI the user expects to remain fixed. Anything not between those two function calls will not be cached on the host device and will be reuploaded at every device reconnection.

UI Elements

A note about colors: many of these objects accept one or more parameters of type color_t. color_t variables contain red, green, blue, and alpha channel information, and are returned by the functions rgb(redVal, greenVal, blueVal) and rgba(redVal, greenVal, blueVal, alphaVal). There are also some pre-defined macros for certain colors: BLACK, RED, GREEN, BLUE, YELLOW, MAGENTA, CYAN, WHITE, GRAY, and CLEAR.

Rectangle

UI Rectangle object examples

The simplest object that can be drawn in the UI is a rectangle. Parameters are the x,y coordinates of the upper left corner, x and y dimensions, and color. If so desired, a second color parameter can be passed, and the rectangle will be colored as a gradient from top to bottom.

language:c
uint8_t drawRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, color_t color);
uint8_t drawRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, 
    color_t color, color_t color2);

Text Box

UI Text Box examples

Text boxes can be either numeric or alphanumeric. They are created via overloaded calls to the SimbleeForMobile.drawText() function; height is automatically calculated. Text cannot be made bold, italicized, etc, but the size and color may be altered, and alphanumeric text boxes may contain multiple lines of text (by inserting '\n' characters in the string). Text boxes may only be used for user input by detecting a touch, like a button; for user text value inputs, see "Text Fields", up next.

language:c
uint8_t drawText(uint16_t x, uint16_t y, const char* title);
uint8_t drawText(uint16_t x, uint16_t y, const char* title, color_t color);
uint8_t drawText(uint16_t x, uint16_t y, const char* title, color_t_color,
    uint8_t size);

uint8_t drawText(uint16_t x, uint16_t y, int16_t value);
uint8_t drawText(uint16_t x, uint16_t y, int16_t value, color_t color);
uint8_t drawText(uint16_t x, uint16_t y, int16_t value, color_t color,
    uint8_t size);

Text Field

UI Text field examples

A text field is intended to receive user input in the form of a string or number. Unlike text boxes, width is not automatically calculated and must be supplied to the function after x and y are specified. After width is the last mandatory field, a string which will be the default value upon launch of the script. This string can, of course, be empty, if you don't want to display a default value. Optional parameters are placeholder text, which appears whenever the text field is empty (including when the default text string is empty), color, which is the text color, and background, which is the color of the background inside the field. For a numerical text field, instead of a default string, a default value is entered; however, this means that the placeholder text will never be visible in a numerical text field. Numerical text fields will also cause the keyboard to be brought up in a numerical mode, but the input is not constrained to numbers.

language:c
uint8_t drawTextField(uint16_t x, uint16_t y, uint16_t w, const char* text);
uint8_t drawTextField(uint16_t x, uint16_t y, uint16_t w, const char* text,
    const char* placeholder);
uint8_t drawTextField(uint16_t x, uint16_t y, uint16_t w, const char* text,
    const char* placeholder, color_t color);
uint8_t drawTextField(uint16_t x, uint16_t y, uint16_t w, const char* text,
    const char* placeholder, color_t color, color_t background);

uint8_t drawTextField(uint16_t x, uint16_t y, uint16_t w, int16_t value);
uint8_t drawTextField(uint16_t x, uint16_t y, uint16_t w, int16_t value, 
    const char* placeholder);
uint8_t drawTextField(uint16_t x, uint16_t y, uint16_t w, int16_t value,
    const char* placeholder, color_t color);
uint8_t drawTextField(uint16_t x, uint16_t y, uint16_t w, int16_t value,
    const char* placeholder, color_t color, color_t background);

Button

UI Button examples

Buttons are the simplest default interactive UI element. Unlike text boxes, they can have a specified width, and the title will be centered inside the button. The background of the button is always clear; the text can be colored. The type argument can be either BOX_TYPE or TEXT_TYPE.

language:c
uint8_t drawButton(uint16_t x, uint16_t y, uint16_t w, const char* title);
uint8_t drawButton(uint16_t x, uint16_t y, uint16_t w, const char* title,
    color_t color);
uint8_t drawButton(uint16_t x, uint16_t y, uint16_t w, const char* title,
    color_t color, uint8_t type);

Switch

Switch examples

Switches are on/off toggles; the only valid parameters are location and color. They will change to a more subdued color variation when off.

language:c
uint8_t drawSwitch(uint16_t x, uint16_t y);
uint8_t drawSwitch(uint16_t x, uint16_t y, color_t color);

Segment

Segment examples

Segment objects are a "choose one" option. Aside from the x and y location parameters, the overall width (w) of the object (not of each segment!), the name of a const array of const char\* objects, the number of desired segments (i.e., the number of objects in the array), and, optionally, the color of the object must all be provided.

language:c
// Syntax for specifying segment titles; odd names and values used to show
//  that segment text and title variable names are completely arbitrary.
const char* alice = "blue";
const char* bob = "leopard";
const char* texas = "hematite";

const char* const bullDozer[3] = {alice, bob, texas};

uint8_t drawSegment(uint16_t x, uint16_t y, uint16_t w, const char* const
    *title, uint8_t count);
uint8_t drawSegment(uint16_t x, uint16_t y, uint16_t w, const char* const
    *title, uint8_t count, color_t color);

Slider

Slider examples

For gross adjustments of value (speeds, volumes, etc.) where absolute actual values aren't of great importance, a slider is probably the best choice. Parameters are x and y position, width of the object, minimum and maximum values, and, optionally, color.

language:c
uint8_t drawSlider(uint16_t x, uint16_t y, uint16_t w, int16_t min,
    int16_t max);
uint8_t drawSlider(uint16_t x, uint16_t y, uint16_t w, int16_t min,
    int16_t max, color_t color);

Stepper

Stepper examples

For fine adjustments, a stepper object may be more appropriate. Each press of either of the buttons of a stepper object increments or decrements a value, accordingly; the user may hold the button down to continuously increment or decrement. A textField object should be used if the current value is to be displayed, as the stepper has no means of display itself.

Note that the w parameter is unused and may be set to any value.

language:c
uint8_t drawStepper(uint16_t x, uint16_t y, uint16_t w, int16_t min,
    int16_t max);
uint8_t drawStepper(uint16_t x, uint16_t y, uint16_t w, int16_t min,
    int16_t max, color_t color);

Images

It is possible to include custom images in your Simblee UI; this is not recommended, however, as the image will be stored in the Simblee firmware as a full-size PNG bitmap image meaning that even relatively small images will take up a large chunk of the available code memory in the Simblee. We're not going to go into the full process for doing this; it would take up too much space in this already-large tutorial.

To encode an image, you'll need a program called "xxd". This program will convert a PNG file to a .h file; that file must then be moved into your sketch folder.

Up to 31 images may be stored in this fashion. For an example of using this functionality, see the "Temperature" example included in the Simblee support package.

#### UI Element Update Functions

It's possible to update the position, width, height, and the color(s) of an object after it is created. Most objects can be updated using one of these functions; the id parameter is the value returned by the function called to create the object.

language:c
void updateX(uint8_t id, uint16_t x);
void updateY(uint8_t id, uint16_t y);
void updateOrigin(uint8_t id, uint16_t x, uint16_t y);

void updateW(uint8_t id, uint16_t w);
void updateH(uint8_t id, uint16_t h);
void updateSize(uint8_t id, uint16_t w, uint16_t h);

void updateRect(uint8_t id, uint16_t x, uint16_t y, uint16_t w, uint16_t h);
void updateColor(uint8_t id, color_t color);
void updateColor2(uint8_t id, color_t color2);

textBox and textField have their own specialized update functions which can only be applied to them:

language:c
void updateValue(uint8_t id, int16_t value);
void updateText(uint8_t id, const char *text);

Finally, any object can be shown, or hidden, by using the setVisible() function. Passing true makes the object visible if it is hidden.

language:c
void setVisible(uint8_t id, bool visible);

Reacting to UI Events

Whenever a UI event occurs, the ui_event() function is called. You can specify what an event is using the setEvents() function.

language:c
void setEvents(uint8_t id, uint8_t events);

The events parameter is the logical OR of the constants EVENT_PRESS, EVENT_DRAG, and EVENT_RELEASE. When an object is touched (EVENT_PRESS), dragged, or released, ui_event() is called. Within ui_event(), information about the event is contained in the event object:

  • event.id -- The identifier (value returned by the function which created the object) of the object generating the event.
  • event.type -- The type of the event (one of EVENT_PRESS, EVENT_RELEASE, or EVENT_DRAG)
  • event.value -- The current value of the object.
  • event.text -- The current text of the object (only valid for non-numeric TextField objects)

For image objects, there are two additional event types: EVENT_POSITION and EVENT_COLOR. These behave as the others, but indicate that the returned information is one of the following data chunks.

  • event.x, event.y -- The position within the object (not relative to the absolute screen coordinates) where the event occurred.
  • event.red, event.blue, event.green, event.alpha -- RGBA information about the pixel that was touched (only valid in image objects)

SimbleeBLE

This library controls the more basic elements of the BLE interface: advertisement, iBecon functionality, data transfer, and proximity, for example. You'll need to add #include <SimbleeBLE.h> to the top of your main sketch file to use any of these functions. This is fairly low-level stuff and is not needed to use the Simblee to communicate with the Sibmlee phone app; however, you will likely need it to develop your own phone application.

General BLE Functionality

Some of these things can be useful even when interfacing with the Simblee for Mobile app.

If you wish to set any of these variables, you must do so before calling SimbleeBLE.begin().

  • SimbleeBLE.txPowerLevel -- int between -20 and +4 representing transmit power, in dBm. Default is +4; only values which a multiples of 4 are allowed.

  • SimbleeBLE.customUUID -- this const char\* variable allows the user to change the UUID of the Simblee module. This will break compatability with the Simblee app but may be useful in situations where you are creating your own application.

  • SimbleeBLE.deviceName -- const char\* variable holding the name of the Simblee module. By default, it is "Simblee". The combined length of the device name and advertisement data must be less than or equal to 18; any longer and the name will be truncated to one character to make room for the data.

  • SimbleeBLE.radioActive -- Evaluates to true if the radio is currently transmitting data, and false otherwise. Can be used to delay timing critical code until immediately after the radio has transmitted data to reduce the chances that the radio will interrupt the timing critical code; however, the radio cannot be disabled, so it's up to the user to make sure that the time required is shorter than the time before the next radio packet.

Advertisement

Advertisement is the means by which a peripheral BLE device communicates its existance to central devices in the area which are currently scanning for advertising devices. Advertising comes in four flavors, depending upon whether the advertisement is connectable or not, and whether it is directed or not. The simblee supports only undirected advertising (i.e., broadcast), but it can be connectable or not connectable.

Simblee modules can also only function as peripheral devices, not central. Also, you must not exceed 9600 baud during BLE mode; failure to adhere to this will actually lock up your sketch.

  • SimbleeBLE.advertisementInterval -- int variable declaring, in ms, the frequency with which to issue advertisement packets. Range from 20ms to 10.24s; the actual range units are in units of 0.625ms, so the actual interval will only be an approximation of this value. If the device is in nonconnectable mode, the actual interval will be a minimum of 100ms. Default is 80ms.

  • SimbleeBLE.advertisementData -- const char\* variable pointing to a string containing some data sent out with each advertisement packet. Defaults to "sketch" and is the description that shows up in the Simblee app under the device name. Max 32 characters. The combined length of the device name and advertisement data must be less than or equal to 18; any longer and the name will be truncated to one character to make room for the data.

  • SimbleeBLE_onAdvertisement(bool start) -- This function is automatically called when advertisement is started or stopped; start is true if advertising was started and false if it was stopped. It is not called when an advertising packet is sent out, however.

Connections

These functions and variables control the connection to a host device. Most of these can be ignored for interoperation with the Simblee mobile app; however, the functions called on connection and disconnection may be useful.

These variables must be set before calling SimbleeBLE.begin().

  • SimbleeBLE.connectable -- bool variable used to enable/disable the connectable state of the Simblee.

  • SimbleeBLE_onConnect() -- Called when a new connection to the Simblee is opened.

  • SimbleeBLE_onDisconnect() -- Called when a connection to the Simblee is closed.

  • SimbleeBLE_onRSSi(int RSSI) -- Called when new RSSI (received signal strength indicator) data is available. This is at the Simblee, not at the host. Values range from 0dBm (best) to -127dBm, although the connection will be severed as too unreliable around -92dBm.

  • SimbleeBLE_onReceive(char \*data, int len) -- Called when data has been received from the host.

Note that the above functions are not a part of the SimbleeBLE class; they are defined elsewhere. The following functions are part of the SimbleBLE class.

These functions send various data types back to the host. Again, note that this mechanism is not required when dealing with the Simblee for Mobile app.

  • SimbleeBLE.send(char data)
  • SimbleeBLE.send(const char \*data, int len)
  • SimbleeBLE.sendByte(uint8_t data)
  • SimbleeBLE.sendInt(int data)
  • SimbleeBLE.sendFloat(float data)

  • SimbleeBLE.updateConnInterval(in min_conn_interval_ms, int max_conn_interval_ms) -- Request that the host change the connection interval to some number of milliseconds between the min and max values. The host may reject this or choose a value out of this range entirely, at its discretion.

  • SimbleeBLE.getConnInterval() -- Return an int specifying the current connection interval in milliseconds. Minimum value is 7.5ms, max is 4s.

iBeacon functionality

iBeacon is a protocol developed by Apple for making BLE devices that can be used to transmit small data packets to nearby devices. iBeacons are one-way; the receiving devices cannot communicate back to the iBeacon devices.

As with the advertisement variables, these must be set before calling SimbleeBLE.begin().

  • SimbleeBLE.iBeacon -- bool which enables iBeacon mode.

SimbleeBLE.iBeaconUUID -- array of 16 uint8_t values comprising the UUID to be used in iBeacon mode.

  • SimbleeBLE.iBeaconMajor and Simblee.iBeaconMinor -- These two unsigned short variable values are reported by the iBeacon constantly, along with the UUID and the iBeaconMeasuredPower value. Both default to 0.

  • SimbleeBLE.iBeaconMeasuredPower -- Signal strength of this module as measured at 1m, in dBm. This value is stored as an unsigned 8-bit integer; you'll need to convert the value to hex before writing to the variable. The default value is -59dBm; that converts to 0xC5 in two's complement expressed as hexadecimal. Apps which attempt to determine distance to the module will use this as a base value for calculating the probable distance to the module.