Arduino APIs

The Coral Dev Board Micro is compatible with the core Arduino programming langauge. So a lot of simple Arduino projects can work on the Dev Board Micro without any code changes.

This page describes additional APIs that provide Arduino-style programming for Dev Board Micro hardware, such as the camera and microphone, plus descriptions for features that use standard Arduino libraries, such as GPIOs and the filesystem.

Even the APIs that have custom implementations for the Dev Board Micro are designed to allow code-reuse with other Arduino projects that use similar libraries whenever possible.

To try programming with Arduino for the Dev Board Micro, start by following the guide to Build apps with Arduino.

Camera

The Dev Board Micro includes an on-board camera module with 324 x 324 px resolution. To use the camera with Arduino, you need to use the global instance of the CameraClass object called Camera.

To get started, you just need to call begin() and specify the image format you want, such as the image resolution and rotation.

When you want to capture an image, call grab() and pass it a buffer where the image should be stored.

When you’re done, call end to turn the camera off.

Example:

#include <coralmicro_SD.h>
#include <coralmicro_camera.h>
#include <libs/libjpeg/jpeg.h>

#include <cstdint>
#include <memory>

#include "Arduino.h"

using namespace coralmicro::arduino;

FrameBuffer frame_buffer;

void setup() {
  Serial.begin(115200);
  SD.begin();
  // Turn on Status LED to show the board is on.
  pinMode(PIN_LED_STATUS, OUTPUT);
  digitalWrite(PIN_LED_STATUS, HIGH);
  Serial.println("Arduino Camera!");
  int width = 324;
  int height = 324;

  if (Camera.begin(width, height) != CameraStatus::SUCCESS) {
    Serial.println("Failed to start camera");
    return;
  }

  if (!Camera.grab(frame_buffer) == CameraStatus::SUCCESS) {
    return;
  }

  Serial.println("Saving image as \"image.jpeg\"");
  std::vector<uint8_t> jpeg;
  coralmicro::JpegCompressRgb(frame_buffer.getBuffer(), width, height,
                              /*quality=*/75, &jpeg);

  SDFile imageFile = SD.open("image.jpeg", FILE_WRITE);
  imageFile.write(jpeg.data(), jpeg.size());
  imageFile.close();
}

void loop() {}
namespace coralmicro
namespace arduino
class CameraClass
#include <coralmicro_camera.h>

Exposes the Coral Micro device’s native camera.

You should not initialize this object yourself; instead include coralmicro_camera.h and then use the global Camera instance.

Public Functions

int begin(CameraResolution resolution = CAMERA_R324x324)

Starts the camera.

Parameters

resolution – A CameraResolution value representing the camera’s resolution.

Returns

A CameraStatus value such as SUCCESS once initialization has completed.

int begin(int32_t width = 320, int32_t height = 320, CameraFormat fmt = CameraFormat::kRgb, CameraFilterMethod filter = CameraFilterMethod::kBilinear, CameraRotation rotation = CameraRotation::k270, bool preserve_ratio = false, bool auto_white_balance = true)

Starts the camera.

Parameters
  • width – The resolution width in pixels.

  • height – The resolution height in pixels.

  • fmt – The image format.

  • filter – The bayer filtering method.

  • rotation – The image rotation amount.

  • auto_white_balance – Applies auto white balance if true.

Returns

SUCCESS once initialization has completed.

int grab(uint8_t *buffer)

Grabs a camera frame.

Parameters

buffer – The buffer where the frame will be stored.

Returns

A CameraStatus value such as SUCCESS if a frame was captured from the camera, NOT_INITIALIZED if the camera was not initialized, or FAILURE if a frame was not captured.

int grab(FrameBuffer &buffer)

Grabs a camera frame.

Parameters

buffer – The buffer where the frame will be stored.

Returns

A CameraStatus value such as SUCCESS if a frame was captured from the camera, NOT_INITIALIZED if the camera was not initialized, or FAILURE if a frame was not captured. Note: buffer does not have to be allocated, this function will automatically allocate the memory needed to store the image data.

int setStandby(bool enable)

Changes the camera mode.

Parameters

enable – Sets the camera to standby mode if true, and sets the camera to streaming mode if false.

Returns

A CameraStatus value such as SUCCESS once the camera mode is set.

int setTestPattern(bool enable, bool walking)

Changes the camera’s test pattern. Test pattern data is fake data that replaces camera sensor data when the value is not NONE.

Parameters
  • walking – Sets the test pattern to WALKING_ONES if true, and to NONE if false.

  • enable – Starts test pattern if true, else only set the test pattern.

Returns

A CameraStatus value such as SUCCESS once the pattern has been set.

int setTestPattern(bool enable, coralmicro::CameraTestPattern pattern)

Changes the camera’s test pattern. Test pattern data is fake data that replaces camera sensor data when the value is not NONE.

Parameters
  • pattern – The desired new test pattern.

  • enable – Starts test pattern if true, else only set the test pattern.

Returns

A CameraStatus value such as SUCCESS once the pattern has been set.

int setPreserveRatio(bool preserve_ratio)

Sets whether the image’s aspect ratio is preserved.

Parameters

preserve_ratio – Images will be scaled to preserve aspect ratio if true.

Returns

A CameraStatus value such as SUCCESS once the configuration has been set.

int setPixelFormat(coralmicro::CameraFormat fmt)

Sets the image format.

Parameters

fmt – The image format.

Returns

A CameraSttus value such as SUCCESS once the format has been set.

int discardFrames(int num_frames)

Discards a set amount of frames captured by the camera.

Parameters

num_frames – The amount of frames to discard.

Returns

A CameraStatus value such as SUCCESS once the camera has started discarding frames.

int enableMotionDetection(md_callback_t callback = nullptr, void *cb_param = nullptr)

Enables or disables HW motion detection.

Parameters
  • callback – The function to call when the camera detected motion.

  • cb_param – The callback parameter.

int disableMotionDetection()

Disables motion detection.

int setMotionDetectionWindow(uint32_t x, uint32_t y, uint32_t w, uint32_t h)

Sets the motion detection windows.

Parameters
  • x – The top left x coordinate to monitor motion detection.

  • y – the top left y coordinate to monitor motion detection.

  • w – The width of the window to monitor for motion.

  • h – the height of the window to monitor for motion.

class FrameBuffer
#include <coralmicro_camera.h>

Represents an image’s frame buffer.

Public Functions

FrameBuffer()

Constructs a new frame buffer object without allocating framebuffer pointer.

~FrameBuffer()

Destroys and delete the frame buffer if it is allocated. Note: The buffer must be allocated with new [] and not malloc().

uint32_t getBufferSize()

Gets the frame buffer size.

Returns

The buffer’s size.

uint8_t *getBuffer()

Gets the frame buffer’s data.

Returns

The pointer to the frame buffer’s data.

void setBuffer(uint8_t *buffer, uint32_t frame_size)

Set the frame buffer’s data.

Parameters
  • buffer – The frame buffer pointer to set.

  • frame_size – The frame buffer size to set.

bool hasFixedSize()

Checks if the frame buffer has a fixed size.

Returns

true if the frame buffer has been allocated and the size is known.

bool isAllocated()

Checks if the frame buffer is allocated.

Returns

true if the framebuffer is allocated, else false.

Enums

enum CameraResolution

Supported camera resolutions.

Values:

enumerator CAMERA_R160x120

QQVGA Resolution.

enumerator CAMERA_R320x240

QVGA Resolution.

enumerator CAMERA_R320x320

320x320 Resolution

enumerator CAMERA_R324x324

324x324 Default camera resolution.

enumerator CAMERA_RMAX
enum CameraStatus

Return statuses from camera API functions.

Values:

enumerator FAILURE
enumerator SUCCESS
enumerator NOT_INITIALIZED
enumerator UNIMPLEMENTED

Typedefs

using md_callback_t = void (*)(void *param)

Motion detection callback.

Variables

coralmicro::arduino::CameraClass Camera

This is the global CameraClass instance you should use instead of creating your own instance.

Microphone

The Dev Board Micro includes one on-board pulse-density modulation (PDM) microphone. To use the microphone with Arduino, you need to use the global instance of the global instance of the PDMClass object called Mic.

This API is designed to be code-compatible with projects that use the Arduino PDM library, but it does not support setGain() and setBufferSize().

To get started, specify a callback function with onReceive(), to be notified whenever the microphone has new data to read.

Then call begin() to start recording with the microphone. Inside the function you passed to onReceive(), read the available audio data with read().

The microphone remains powered and processes input whenever there is an active audio callback.

When you’re done with the microphone, call end() to disable the micrphone.

Example:

This code listens to input from the microphone and saves data into a currentSamples buffer.

#include "Arduino.h"
#include "PDM.h"

volatile int samples_read = 0;
std::vector<int32_t> current_samples;

void setup() {
  Serial.begin(115200);
  // Turn on Status LED to show the board is on.
  pinMode(PIN_LED_STATUS, OUTPUT);
  digitalWrite(PIN_LED_STATUS, HIGH);
  Serial.println("Arduino PDM!");

  Mic.onReceive(onPDMData);
  Mic.begin();
}

void loop() {
  if (samples_read) {
    samples_read = 0;
    Serial.println(current_samples[0]);
  }
}

void onPDMData() {
  samples_read = Mic.available();

  if (samples_read) {
    current_samples.clear();
    Mic.read(current_samples, samples_read);
  }
}
namespace coralmicro
namespace arduino
class PDMClass
#include <PDM.h>

Exposes the Coral Micro device’s native PDM microphone.

You should not initialize this object yourself; instead include PDM.h and then use the global Mic instance.

Public Functions

int begin(int sample_rate = 16000, size_t sample_size_ms = 1000, size_t drop_first_samples_ms = 150)

Start recording data with the PDM microphone.

Parameters
  • sample_rate – The sample rate to start, only supports 16000 or 48000.

  • sample_size_ms – Number of ms of data that is stored in the internal buffer.

  • drop_first_samples_ms – Number of ms to drop during begin to avoid distortions.

Returns

0 on failure, 1 on success.

void onReceive(void (*function)(void))

Sets the current audio callback function. The microphone starts as soon as begin() is called, however this function adds an extra callback that gets executed as soon as new data are received. Within the callback, you can call available() and read() to access the microphone data.

Parameters

function – The function to call when audio data is received. The function should not have any arguments and not have a return value.

void end()

Removes the current callback, effectively turning off the microphone.

int available()

Gets the amount of available data in the audio buffer. Data is stored in the buffer as uint32_ts, and the sizes in this function refer to the amount of values in the buffer.

Returns

The amount of data values stored in the underlying buffer that are ready to be read.

int read(std::vector<int32_t> &buffer, size_t size)

Reads data from the audio buffer. Data is stored in the buffer as uint32_ts, and the sizes in this function refer to the amount of values in the buffer.

Parameters
  • buffer – The buffer that will receive the copied audio data.

  • size – The amount of audio data values to copy.

Returns

The amount of audio data values that were copied.

Variables

coralmicro::arduino::PDMClass Mic

This is the global PDMClass instance you should use instead of creating your own instance.

Filesystem

This API allows you to create, read, and write files on the Dev Board Micro flash storage.

This API is designed to be code-compatible with projects that use the Arduino SD library. However, on the Dev Board Micro, these APIs enable reading and writing files on the on-board flash memory (not an SD card).

namespace coralmicro
namespace arduino
namespace SDLib
class File : public Stream
#include <coralmicro_SD.h>

Represents a file in the flash memory filesystem (represented by SDClass).

Public Functions

File(void)
virtual size_t write(uint8_t)

Writes one byte to the file.

Parameters

val – The byte to write.

Returns

The amount of data written.

virtual size_t write(const uint8_t *buf, size_t size)

Writes data to the file.

Parameters
  • buf – The data to write.

  • size – The size of the data.

Returns

The amount of data written.

virtual int read()

Reads one value from the file.

Returns

The value read from the file.

virtual int peek()

Gets the next value in the file, without advancing through the file.

Returns

The next value in the file.

virtual int available()

The amount of data left in the file.

Returns

The amount of data until the end of the file, given the current position.

virtual void flush()

Ensures the data is written to the file.

int read(void *buf, size_t nbyte)

Reads data from the file.

Parameters
  • buf – The buffer to store the data.

  • nbyte – The amount of data to read.

Returns

The amount of data read.

bool seek(size_t pos)

Sets the current position of the reader within the file.

Parameters

pos – The desired index for reading from the file.

size_t position()

Gets the current position of the reader within the file.

Returns

The position of the reader.

size_t size()

Gets the size of the file.

Returns

The size of the file.

void close()

Closes the file.

inline operator bool()

Uses the file object as a bool to determine whether it is open.

Returns

True if the file is open; false otherwise.

char *name()

Gets the name of the file.

Returns

The name of the file.

inline bool isDirectory(void)

Determines whether the file object is a directory.

Returns

True if the file object is a directory, false otherwise.

File openNextFile(uint8_t mode = FILE_READ)

Gets the next file or folder if the current file object is a directory

Parameters

mode – The mode for opening the file.

Returns

The next file object opened with the given mode if it exists. Otherwise, returns an empty file object.

void rewindDirectory(void)

Returns to the first file in the directory.

class SDClass
#include <coralmicro_SD.h>

Exposes the Dev Board Micro’s internal filesystem, treating it as if it were an SD card.

You should not initialize this object yourself; instead include coralmicro_SD.h and then use the global SD instance. begin() and end() are unnecessary calls, because the filesystem is initialized when the device boots up and cannot be deinitialized. Example code can be found in sketches/SDFileSystemTest/.

Public Functions

bool begin(uint8_t csPin = DONT_CARE)

This function is unused and is here to match the Arduino API.

Parameters

csPin – Unused and is here to match the Arduino API.

Returns

True if initialization was successful, false otherwise.

inline bool begin(uint32_t clock, uint8_t csPin)

This function is unused and is here to match the Arduino API.

Parameters
  • csPin – Unused and is here to match the Arduino API.

  • clock – Unused and is here to match the Arduino API.

Returns

True if initialization was successful, false otherwise.

inline void end()

This function is unused and is here to match the Arduino API.

File open(const char *filename, uint8_t mode = FILE_READ)

Opens the file or directory at the given path

Parameters
  • filename – The path of the file object.

  • mode – The mode for opening the file object.

Returns

The opened file object.

inline File open(const String &filename, uint8_t mode = FILE_READ)

Opens the file or directory at the given path

Parameters
  • filename – The path of the file object.

  • mode – The mode for opening the file object.

Returns

The opened file object.

bool exists(const char *filepath)

Determines whether a file or directory exists at the given path.

Parameters

filepath – The path to check for a file.

Returns

True if a file exists at the path; false otherwise.

inline bool exists(const String &filepath)

Determines whether a file or directory exists at the given path.

Parameters

filepath – The path to check for a file.

Returns

True if a file exists at the path, false otheriwse.

bool mkdir(const char *filepath)

Creates a directory at the given path.

Parameters

filepath – The location to make a directory.

Returns

True if a directory was successfully created, false otherwise.

inline bool mkdir(const String &filepath)

Creates a directory at the given path.

Parameters

filepath – The location to make a directory.

Returns

True if a directory was successfully created, false otherwise.

bool remove(const char *filepath)

Removes the file at the given path

Parameters

filepath – The location of the file to remove.

Returns

True if a file was successfully removed, false otherwise.

inline bool remove(const String &filepath)

Removes the file at the given path

Parameters

filepath – The location of the file to remove.

Returns

True if a file was successfully removed, false otherwise.

bool rmdir(const char *filepath)

Removes the directory at the given path

Parameters

filepath – The location of the directory to remove.

Returns

True if a directory was successfully removed, false otherwise.

inline bool rmdir(const String &filepath)

Removes the directory at the given path

Parameters

filepath – The location of the directory to remove.

Returns

True if a directory was successfully removed, false otherwise.

Typedefs

typedef coralmicro::arduino::SDLib::File SDFile

Variables

coralmicro::arduino::SDLib::SDClass SD

This is the global SDClass instance you should use instead of creating your own instance.

I/O pins & LEDs

You can interact with GPIO pins (digital or analog input/output pins) on the Dev Board Micro 12-pin headers with Arduino the same as you would on other Arduino boards, using Arduino APIs such as digitalRead(), digitalWrite(), analogRead(), and analogWrite(). To address these GPIO pins, use the Arduino pin names shown in figure 1.

Likewise, you can use digitalWrite() to toggle the on-board LEDs and digitalRead() to listen for User button presses.

Figure 1. Pinout for the 12-pin headers, LEDs and User button

Once booting is complete, all digital/analog pins are set to a high-Z (floating) state, except for the I2C pins, which default to high. So be sure to call pinMode() before reading or writing values.

Note

All GPIO pins are powered by the 1.8 V power rail, and provide a max current of approximately 6 mA on most pins.

Example:

This code toggles the on-board User LED when you press the on-board User button.

#include "Arduino.h"

int led_pin = PIN_LED_USER;
int button_pin = PIN_BTN;
PinStatus val = LOW;

void setup() {
  Serial.begin(115200);
  // Turn on Status LED to show the board is on.
  pinMode(PIN_LED_STATUS, OUTPUT);
  digitalWrite(PIN_LED_STATUS, HIGH);
  Serial.println("Arduino Button LED!");

  pinMode(led_pin, OUTPUT);
  pinMode(button_pin, INPUT);
}

void loop() {
  val = digitalRead(button_pin);
  digitalWrite(led_pin, val == LOW ? HIGH : LOW);
}

For more information about using digital and analog pins, see the Arduino GPIO documentation.

I2C

You can interact with I2C devices on the Dev Board Micro using the Arduino Wire library.

Only one pair of I2C lines on the 12-pin headers is available in Arduino, so you do not need to specify the pin names. It is assumed that you are connected to D0 and D3 (shown in figure 1).

Example:

This code sends messages to an I2C device that’s connected to D0 and D3.

#include <cstdint>
#include <vector>

#include "Arduino.h"
#include "Wire.h"

namespace {
constexpr int kTargetAddress = 0x42;
constexpr int kTransferSize = 16;
std::vector<uint8_t> buffer(kTransferSize, 0);
}  // namespace

void requestEvent() { Wire.write(buffer.data(), kTransferSize); }

void receiveEvent(int count) {
  for (int i = 0; i < count && i < kTransferSize; ++i) {
    buffer[i] = Wire.read();
    Serial.print(buffer[i]);
  }
  Serial.println();
}

void setup() {
  Serial.begin(115200);
  // Turn on Status LED to show the board is on.
  pinMode(PIN_LED_STATUS, OUTPUT);
  digitalWrite(PIN_LED_STATUS, HIGH);
  Serial.println("Arduino I2C Target Example!");

  Wire.begin(kTargetAddress);
  Wire.onReceive(receiveEvent);
  Wire.onRequest(requestEvent);
}

void loop() {}

SPI

You can interact with Serial Peripheral Interface (SPI) devices connected to the SPI pins on the 12-pin headers (see figure 1), using the APIs described below. The Dev Board Micro must be the controller.

Only one SPI bus available on the 12-pin headers, so you do not need to specify the pin names.

Note

This SPI is designed to be compatible with the Arduino SPI library, but our API is a little different because the Dev Board Micro does not support using SPI from interrupts. Thus, instead of beginTransaction(), you must set the SPISettings with updateSettings() and then call begin(). Also, legacy functions setBitOrder() and setClockDivider() are not supported because you should instead use updateSettings().

To learn more about using SPI with Arduino, read the Arduino & SPI documentation.

Example (from sketches/SPI/):

#include "Arduino.h"
#include "SPI.h"

static uint8_t count = 0;

void setup() {
  Serial.begin(115200);
  // Turn on Status LED to show the board is on.
  pinMode(PIN_LED_STATUS, OUTPUT);
  digitalWrite(PIN_LED_STATUS, HIGH);
  Serial.println("Arduino SPI Example!");

  SPI.begin();
}

void loop() {
  Serial.println("Executing a SPI transaction.");
  if (SPI.transfer(count) == count) {
    Serial.println("Transaction success!");
  } else {
    Serial.println("Transaction failed!");
  }
  count++;
  count %= 255;

  delay(1000);
}
namespace coralmicro
namespace arduino
class HardwareSPI : public arduino::HardwareSPI
#include <SPI.h>

Allows for communication with SPI devices. SPI devices communicate through the use of the transfer functions, which simultaneously exchange data between the two devices, but they cannot be used from within interrupts.

You should not initialize this object yourself; instead include SPI.h and then use the global SPI instance. Code samples can be found in sketches/SPI/ and sketches/SPITranscation/.

Public Functions

uint8_t transfer(uint8_t data)

Exchanges one byte of data with SPI transfer.

Parameters

data – The data for the peripheral device.

Returns

The data received from the peripheral device.

uint16_t transfer16(uint16_t data)

Exchanges two bytes of data with SPI transfer.

Parameters

data – The data for the peripheral device.

Returns

The data received from the peripheral device.

void transfer(void *buf, size_t count)

Exchanges an array of data in-place with SPI transfer.

Parameters
  • buf – The data for the peripheral device. As data is received, the buffer is overwritten.

  • count – The length of the data in bytes.

void updateSettings(arduino::SPISettings settings)

Updates the SPI configuration.

Parameters

settings – The desired SPI configuration. See SPISettings.

void begin()

Initializes SPI.

This function must be called before doing any transfers.

void end()

De-initializes SPI.

Variables

coralmicro::arduino::HardwareSPI SPI

This is the global HardwareSPI instance you should use instead of creating your own instance.

Network

Sockets

These APIs define the basic interface for socket connections, whether using Wi-Fi or Ethernet.

To open a socket as a client or server, you should use the corresponding typedef aliases, corresponding to the type of network connection you’re using: WiFiClient/WiFiServer or EthernetClient/EthernetServer.

namespace coralmicro
namespace arduino
class SocketClient : public arduino::Client
#include <SocketClient.h>

This is not meant to be instantiated directly. Instead use arduino::WiFiClient or arduino::EthernetClient.

Public Functions

inline virtual ~SocketClient()
SocketClient() = default

Initializes a new client socket.

SocketClient(const SocketClient &orig) = delete
SocketClient &operator=(const SocketClient &orig) = delete
inline SocketClient(SocketClient &&orig)
inline SocketClient &operator=(SocketClient &&orig)
int connect(IPAddress ip, uint16_t port) override

Start a socket connection with a server.

Parameters
  • ip – The server’s ip address.

  • port – The server’s port number.

Returns

1 if successful; -1 otherwise.

int connect(const char *host, uint16_t port) override

Starts a socket connection with a server.

Parameters
  • ip – The server’s hostname.

  • port – The server’s port number.

Returns

1 if successful; -1 otherwise.

size_t write(uint8_t c) override

Writes some data to the socket.

Parameters

c – The data to write.

Returns

1 if successful; -1 otherwise.

size_t write(const uint8_t *buf, size_t size) override

Writes an array of data to the socket.

Parameters
  • array – The array of data to write.

  • size – The size of the array.

Returns

The size of the array written if successful; -1 otherwise.

int available() override

Checks if the socket has bytes available to read.

Returns

The number of bytes available to read.

int read() override

Reads some data from the socket.

Returns

The data if successful; -1 otherwise.

int read(uint8_t *buf, size_t size) override

Reads an array of data from the socket.

Parameters
  • The – buffer in which to put the data.

  • The – size of the buffer.

Returns

The size of the array read if successful; -1 otherwise.

void stop() override

Close the socket.

uint8_t connected() override

Checks if the socket is connected.

Returns

True if connected; false otherwise.

operator bool() override

True if the socket is connected; false otherwise.

namespace coralmicro
namespace arduino
class SocketServer : public arduino::Server
#include <SocketServer.h>

This is not meant to be instantiated directly. Instead use arduino::WiFiServer or arduino::EthernetServer.

Public Functions

inline SocketServer(int port)

Initializes a new server socket.

Each server socket can accept just one client connection.

Parameters

The – port number to use.

virtual ~SocketServer()
void begin() override

Starts the socket.

size_t write(uint8_t c) override

Writes some data to the socket.

Parameters

c – The data to write.

Returns

1 if successful; -1 otherwise.

size_t write(const uint8_t *buf, size_t size) override

Writes an array of data to the socket.

Parameters
  • array – The array of data to write.

  • size – The size of the array.

Returns

The size of the array written if successful; -1 otherwise.

SocketClient available()

Waits for and accepts a socket connection from a client. This is a blocking call and returns only when a client has connected to this server socket’s port.

Note: Only one client can connect at a time.

Returns

The client object to read and write with the connected client. Before using the returned client, check if the client is connected (check if the object evaluates true or call arduino::SocketClient::connected()) and check if it has data to read with arduino::SocketClient::available().

Wi-Fi

Note

Requires the Coral Wireless Add-on board.

To use Wi-Fi on the Dev Board Micro:

  1. Connect the Wireless Add-on board.

  2. Use WiFiClass to connect to a Wi-Fi network.

  3. Use WiFiClient to connect to a server, or use WiFiServer to host a server on the board.

namespace coralmicro
namespace arduino
class WiFiClass
#include <WiFi.h>

Allows for scanning for and connecting to Wi-Fi networks.

Connection is initiated with the WiFiClass::begin() functions, which connect to a specified access point. Scanning can be executed via `WiFiClass::scanNetworks() and the results can be retrieved with the SSID/RSSI/encryptionType methods that accept networkItem.

You should not initialize this object yourself, instead include WiFi.h and use the global arduino::WiFi instance.

This API is designed to be code-compatible with projects that use the WiFi class from the Arduino WiFi library.

Example: This code connects to a Wi-Fi network and prints network details.

#include "Arduino.h"
#include "WiFi.h"

const char kSsid[] = "great-access-point";
const char kPsk[] = "letmein";

void printMacAddress(uint8_t* mac) {
  Serial.print(mac[0], HEX);
  Serial.print(":");
  Serial.print(mac[1], HEX);
  Serial.print(":");
  Serial.print(mac[2], HEX);
  Serial.print(":");
  Serial.print(mac[3], HEX);
  Serial.print(":");
  Serial.print(mac[4], HEX);
  Serial.print(":");
  Serial.print(mac[5], HEX);
}

void setup() {
  Serial.begin(115200);
  // Turn on Status LED to show the board is on.
  pinMode(PIN_LED_STATUS, OUTPUT);
  digitalWrite(PIN_LED_STATUS, HIGH);
  Serial.println("Arduino Wi-Fi Connect!");

  int connected = WL_DISCONNECTED;
  if (strlen(kPsk) > 0) {
    connected = WiFi.begin(kSsid, kPsk);
  } else {
    connected = WiFi.begin(kSsid);
  }
  if (connected == WL_CONNECTED) {
    Serial.print("Connected to network ");
    Serial.println(WiFi.SSID());
  } else {
    Serial.println("Failed to connect to network.");
    return;
  }

  uint8_t mac[6];
  WiFi.macAddress(mac);
  uint8_t bssid[6];
  WiFi.BSSID(bssid);
  Serial.print("Our MAC address: ");
  printMacAddress(mac);
  Serial.println();
  Serial.print("Network BSSID: ");
  printMacAddress(bssid);
  Serial.println();

  int32_t rssi = WiFi.RSSI();
  Serial.print("Network RSSI: ");
  Serial.println(rssi);

  IPAddress ip = WiFi.localIP();
  Serial.print("Ip address: ");
  Serial.println(ip);

  WiFi.disconnect();
}

void loop() {}

Public Functions

int begin(const char *ssid)

Connects to an open Wi-Fi network.

Parameters

ssid – The SSID to connect to.

Returns

WL_CONNECTED on success; WL_CONNECT_FAILED otherwise.

int begin(const char *ssid, const char *passphrase)

Connects to a Wi-Fi network using a passphrase.

Parameters
  • ssid – The SSID to connect to.

  • passphrase – The passphrase used to connect to the network.

Returns

WL_CONNECTED on success; WL_CONNECT_FAILED otherwise.

int disconnect()

Disconnects from the associated Wi-Fi network.

Returns

WL_DISCONNECTED on success.

char *SSID()

Retrieves the SSID of the associated Wi-Fi network.

Returns

SSID if the device is connected to a network, empty string otherwise.

char *SSID(uint8_t networkItem)

Retrieves the SSID of the networkItem-th scan result.

Returns

SSID of the scan result.

uint8_t *BSSID(uint8_t *bssid)

Retrieves the BSSID of the access point.

Parameters

bssid – Pointer to memory where BSSID will be stored.

Returns

Address of BSSID on success; nullptr otherwise.

int32_t RSSI()

Retrieves the RSSI of the associated Wi-Fi network.

Returns

RSSI if the device is connected to a network, INT_MIN otherwise.

int32_t RSSI(uint8_t networkItem)

Retrieves the RSSI of the networkItem-th scan result.

Returns

RSSI of the scan result.

uint8_t encryptionType()

Retrieves the encryption type of the associated Wi-Fi network.

Returns

Value from enum encryption_type representing the network security.

uint8_t encryptionType(uint8_t networkItem)

Retrieves the encryption type of the networkItem-th scan result.

Returns

encryption_type representing the network security.

int8_t scanNetworks()

Scans for nearby Wi-Fi networks.

Returns

The number of networks discovered.

uint8_t status()

Retrieves the status of the Wi-Fi connection.

Returns

wl_status_type representing the connection status.

uint8_t *macAddress(uint8_t *mac)

Retrieves the MAC address of the Wi-Fi module.

Parameters

bssid – Pointer to memory where the MAC will be stored.

Returns

Address of MAC on success; nullptr otherwise.

IPAddress localIP()

Retrieves the board’s wifi ip address.

Returns

The wifi ip address of the board.

Typedefs

using WiFiClient = SocketClient

Defines a client-side connection to a server using Wi-Fi.

This is an alias for the arduino::SocketClient class, where all the available functions are defined.

Example:

This code connects to a Wi-Fi network, connects to a server via hostname and port, then sends an HTTP GET request and prints the response.

#include "Arduino.h"
#include "WiFi.h"

namespace {
const char kSsid[] = "great-access-point";
const char kPsk[] = "letmein";
coralmicro::arduino::WiFiClient client;
}  // namespace

void setup() {
  Serial.begin(115200);
  // Turn on Status LED to show the board is on.
  pinMode(PIN_LED_STATUS, OUTPUT);
  digitalWrite(PIN_LED_STATUS, HIGH);
  Serial.println("Arduino WiFiClient!");

  int connected = WL_DISCONNECTED;
  if (strlen(kPsk) > 0) {
    connected = WiFi.begin(kSsid, kPsk);
  } else {
    connected = WiFi.begin(kSsid);
  }
  if (connected == WL_CONNECTED) {
    Serial.print("Connected to network ");
    Serial.println(WiFi.SSID());
  } else {
    Serial.println("Failed to connect to network.");
    return;
  }

  if (!client.connect("www.example.com", 80)) {
    Serial.println("Connection failed.");
    return;
  }
  Serial.println("Connection successful!");

  const char* kHttpGet = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n";
  client.write(reinterpret_cast<const uint8_t*>(kHttpGet), strlen(kHttpGet));
}

void loop() {
  if (client && client.available()) {
    Serial.write(client.read());
  }
}
using WiFiServer = SocketServer

Defines a server using Wi-Fi.

This is an alias for the arduino::SocketServer class, where all the available functions are defined.

Example:

This code starts a server on the board and, when a client connects to it, it prints all data read from the client to the board serial console.

#include "Arduino.h"
#include "WiFi.h"

namespace {
const char kSsid[] = "great-access-point";
const char kPsk[] = "letmein";
coralmicro::arduino::WiFiClient client;
coralmicro::arduino::WiFiServer server(31337);
}  // namespace

void setup() {
  Serial.begin(115200);
  // Turn on Status LED to show the board is on.
  pinMode(PIN_LED_STATUS, OUTPUT);
  digitalWrite(PIN_LED_STATUS, HIGH);
  Serial.println("Arduino WiFiServer!");

  int connected = WL_DISCONNECTED;
  if (strlen(kPsk) > 0) {
    connected = WiFi.begin(kSsid, kPsk);
  } else {
    connected = WiFi.begin(kSsid);
  }
  if (connected == WL_CONNECTED) {
    Serial.print("Connected to network ");
    Serial.println(WiFi.SSID());
  } else {
    Serial.println("Failed to connect to network.");
    return;
  }

  IPAddress ip = WiFi.localIP();

  server.begin();
  Serial.print("Our IP address is ");
  Serial.println(ip);
  Serial.println("Server ready on port 31337");
  // Blocks until a client is connected.
  client = server.available();
}

void loop() {
  // If a client is connected and has data available to read,
  // write the data to the serial console.
  if (client && client.available()) {
    Serial.write(client.read());
    Serial.flush();
  }
}

Enums

enum encryption_type

Common encryption types for networks.

Values:

enumerator ENC_TYPE_WEP
enumerator ENC_TYPE_TKIP
enumerator ENC_TYPE_CCMP
enumerator ENC_TYPE_NONE
enumerator ENC_TYPE_UNKNOWN
enumerator ENC_TYPE_AUTO
enum wl_status_t

Status codes for Wi-Fi.

Values:

enumerator WL_NO_SHIELD
enumerator WL_IDLE_STATUS
enumerator WL_NO_SSID_AVAIL
enumerator WL_SCAN_COMPLETED
enumerator WL_CONNECTED
enumerator WL_CONNECT_FAILED
enumerator WL_CONNECTION_LOST
enumerator WL_DISCONNECTED

Variables

coralmicro::arduino::WiFiClass WiFi

This is the global WiFiClass instance you should use instead of creating your own instance.

Ethernet

Note

Requires the Coral PoE Add-on board.

To use Ethernet on the Dev Board Micro:

  1. Connect the PoE Add-on board.

  2. Call coralmicro::arduino::EthernetClass::begin() to enable the Ethernet connection.

  3. Use EthernetClient to connect to a server, or use EthernetServer to host a server on the board.

namespace coralmicro
namespace arduino
class EthernetClass
#include <Ethernet.h>

Allows for connection of the device to a network via Ethernet. At the moment, this interface only supports networks with DHCP. After a connection is established, information about the connection such as IP address, DNS, and gateway can be retrieved. You should not initialize this object yourself, instead include Ethernet.h and use the global Ethernet instance.

Public Functions

int begin()

Variant of begin that only uses DHCP.

Returns

1 if DHCP was successful; 0 otherwise.

int begin(IPAddress ip)

Initializes an Ethernet connection, using the specified IP address. The DNS server will be the IP address with the final octet as 1. The gateway will be the IP address with the final octet as 1. The subnet mask will be 255.255.255.0.

Parameters

ip – The desired IP address.

Returns

1 if Ethernet is brought up successfully.

int begin(IPAddress ip, IPAddress dns_server)

Initializes an Ethernet connection, using the specified IP address and DNS server. The gateway will be the IP address with the final octet as 1. The subnet mask will be 255.255.255.0.

Parameters
  • ip – The desired IP address.

  • dns_server – The IP address of a DNS server.

Returns

1 if Ethernet is brought up successfully.

int begin(IPAddress ip, IPAddress dns_server, IPAddress gateway)

Initializes an Ethernet connection, using the specified IP address, DNS server, and gateway. The subnet mask will be 255.255.255.0.

Parameters
  • ip – The desired IP address.

  • dns_server – The IP address of a DNS server.

  • gateway – The IP address of the network gateway.

Returns

1 if Ethernet is brought up successfully.

int begin(IPAddress ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet_mask)

Initializes an Ethernet connection, using the specified IP address, DNS server, gateway, and subnet mask.

Parameters
  • ip – The desired IP address.

  • dns_server – The IP address of a DNS server.

  • gateway – The IP address of the network gateway.

  • subnet_mask – The subnet mask for the network.

Returns

1 if Ethernet is brought up successfully.

IPAddress localIP()

Returns the IP address of the device.

Returns

The Ethernet IP address of the device.

IPAddress subnetMask()

Returns the subnet mask of Ethernet connection.

Returns

The subnet mask of the connection.

IPAddress gatewayIP()

Returns the gateway of the Ethernet connection.

Returns

The IP of the network gateway.

IPAddress dnsServerIP()

Returns the primary DNS server of the device.

Returns

The IP of the primary DNS server.

void MACAddress(uint8_t *mac)

Retrieves the MAC address of the Ethernet interface.

Parameters

mac – Pointer to memory where the MAC address will be stored.

EthernetLinkStatus linkStatus()

Returns the status of the Ethernet connection.

Returns

EthernetLinkStatus representing the state of the connection.

Typedefs

using EthernetClient = SocketClient

Defines a client-side connection to a server using Ethernet.

This is an alias for the arduino::SocketClient class, where all the available functions are defined.

Example:

This code enables the Ethernet connection, connects to a server via hostname and port, then sends an HTTP GET request and prints the response.

#include "Arduino.h"
#include "Ethernet.h"

namespace {
coralmicro::arduino::EthernetClient client;
}

void setup() {
  Serial.begin(115200);
  pinMode(PIN_LED_STATUS, OUTPUT);
  digitalWrite(PIN_LED_STATUS, HIGH);
  Serial.println("Arduino EthernetClient!");

  if (!Ethernet.begin()) {
    Serial.println("DHCP failed to get an IP.");
    return;
  }

  if (!client.connect("www.example.com", 80)) {
    Serial.println("Connection failed.");
    return;
  }
  Serial.println("Connection successful!");

  const char* kHttpGet = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n";
  client.write(reinterpret_cast<const uint8_t*>(kHttpGet), strlen(kHttpGet));
}

void loop() {
  if (client && client.available()) {
    Serial.write(client.read());
  }
}
using EthernetServer = SocketServer

Defines a server using Ethernet.

This is an alias for the arduino::SocketServer class, where all the available functions are defined.

Example:

This code starts a server on the board and, when a client connects to it, it prints all data read from the client to the board serial console.

#include "Arduino.h"
#include "Ethernet.h"

namespace {
coralmicro::arduino::EthernetClient client;
coralmicro::arduino::EthernetServer server(31337);
}  // namespace

void setup() {
  Serial.begin(115200);
  pinMode(PIN_LED_STATUS, OUTPUT);
  digitalWrite(PIN_LED_STATUS, HIGH);
  Serial.println("Arduino EthernetServer!");

  if (!Ethernet.begin()) {
    Serial.println("DHCP failed to get an IP.");
    return;
  }

  if (!client.connect("www.example.com", 80)) {
    Serial.println("Connection failed.");
    return;
  }
  Serial.println("Connection successful!");
  IPAddress ip = Ethernet.localIP();

  server.begin();
  Serial.print("Our IP address is ");
  Serial.println(ip);
  Serial.println("Server ready on port 31337");
  // Blocks until a client is connected.
  client = server.available();
}

void loop() {
  // If a client is connected and has data available to read,
  // write the data to the serial console.
  if (client && client.available()) {
    Serial.write(client.read());
    Serial.flush();
  }
}

Enums

enum EthernetLinkStatus

Status of the Ethernet link.

Values:

enumerator Unknown
enumerator LinkON
enumerator LinkOFF

Variables

coralmicro::arduino::EthernetClass Ethernet

This is the global EthernetClass instance you should use instead of creating your own instance.

TensorFlow Lite

To run inference with TensorFlow Lite models in Arduino, you’ll use the same TensorFlow Lite Micro APIs that are used with FreeRTOS apps. Of course, the rest of your code can continue using the Arduino language and other Arduino-style APIs such as Camera.

Example:

This code performs object detection with TensorFlow Lite using images from the camera.

#include <coralmicro_SD.h>
#include <coralmicro_camera.h>

#include <cstdint>
#include <memory>

#include "Arduino.h"
#include "coral_micro.h"
#include "libs/rpc/rpc_http_server.h"
#include "libs/tensorflow/detection.h"

using namespace coralmicro;
using namespace coralmicro::arduino;

namespace {
bool setup_success{false};
int button_pin = PIN_BTN;
int last_button_state = LOW;
int current_button_state = HIGH;
unsigned long last_debounce_time = 0;
constexpr unsigned long kDebounceDelay = 50;

tflite::MicroMutableOpResolver<3> resolver;
const tflite::Model* model = nullptr;
std::vector<uint8_t> model_data;
std::shared_ptr<coralmicro::EdgeTpuContext> context = nullptr;
std::unique_ptr<tflite::MicroInterpreter> interpreter = nullptr;
TfLiteTensor* input_tensor = nullptr;
int model_height;
int model_width;

constexpr char kModelPath[] =
    "/models/tf2_ssd_mobilenet_v2_coco17_ptq_edgetpu.tflite";
std::vector<tensorflow::Object> results;

constexpr int kTensorArenaSize = 8 * 1024 * 1024;
STATIC_TENSOR_ARENA_IN_SDRAM(tensor_arena, kTensorArenaSize);

FrameBuffer frame_buffer;

bool DetectFromCamera() {
  if (Camera.grab(frame_buffer) != CameraStatus::SUCCESS) {
    return false;
  }
  std::memcpy(tflite::GetTensorData<uint8_t>(input_tensor),
              frame_buffer.getBuffer(), frame_buffer.getBufferSize());
  if (interpreter->Invoke() != kTfLiteOk) {
    return false;
  }
  results = tensorflow::GetDetectionResults(interpreter.get(), 0.6f, 3);
  return true;
}

void DetectRpc(struct jsonrpc_request* r) {
  if (!setup_success) {
    jsonrpc_return_error(
        r, -1, "Inference failed because setup was not successful", nullptr);
    return;
  }
  if (!DetectFromCamera()) {
    jsonrpc_return_error(r, -1, "Failed to run classification from camera.",
                         nullptr);
    return;
  }
  if (!results.empty()) {
    const auto& result = results[0];
    jsonrpc_return_success(
        r,
        "{%Q: %d, %Q: %d, %Q: %V, %Q: {%Q: %d, %Q: %g, %Q: %g, %Q: %g, "
        "%Q: %g, %Q: %g}}",
        "width", model_width, "height", model_height, "base64_data",
        frame_buffer.getBufferSize(), frame_buffer.getBuffer(), "detection",
        "id", result.id, "score", result.score, "xmin", result.bbox.xmin,
        "xmax", result.bbox.xmax, "ymin", result.bbox.ymin, "ymax",
        result.bbox.ymax);
    return;
  }
  jsonrpc_return_success(r, "{%Q: %d, %Q: %d, %Q: %V, %Q: None}", "width",
                         model_width, "height", model_height, "base64_data",
                         frame_buffer.getBufferSize(), frame_buffer.getBuffer(),
                         "detection");
}
}  // namespace

void setup() {
  Serial.begin(115200);
  // Turn on Status LED to show the board is on.
  pinMode(PIN_LED_STATUS, OUTPUT);
  digitalWrite(PIN_LED_STATUS, HIGH);
  Serial.println("Arduino Camera Detection!");

  pinMode(button_pin, INPUT);

  SD.begin();
  Serial.println("Loading Model");

  if (!SD.exists(kModelPath)) {
    Serial.println("Model file not found");
    return;
  }

  SDFile model_file = SD.open(kModelPath);
  uint32_t model_size = model_file.size();
  model_data.resize(model_size);
  if (model_file.read(model_data.data(), model_size) != model_size) {
    Serial.print("Error loading model");
    return;
  }

  model = tflite::GetModel(model_data.data());
  context = coralmicro::EdgeTpuManager::GetSingleton()->OpenDevice();
  if (!context) {
    Serial.println("Failed to get EdgeTpuContext");
    return;
  }
  Serial.println("model and context created");

  tflite::MicroErrorReporter error_reporter;
  resolver.AddDequantize();
  resolver.AddDetectionPostprocess();
  resolver.AddCustom(coralmicro::kCustomOp, coralmicro::RegisterCustomOp());

  interpreter = std::make_unique<tflite::MicroInterpreter>(
      model, resolver, tensor_arena, kTensorArenaSize, &error_reporter);

  if (interpreter->AllocateTensors() != kTfLiteOk) {
    Serial.println("allocate tensors failed");
    return;
  }

  if (!interpreter) {
    Serial.println("Failed to make interpreter");
    return;
  }
  if (interpreter->inputs().size() != 1) {
    Serial.println("Bad inputs size");
    Serial.println(interpreter->inputs().size());
    return;
  }

  input_tensor = interpreter->input_tensor(0);
  model_height = input_tensor->dims->data[1];
  model_width = input_tensor->dims->data[2];

  if (Camera.begin(model_width, model_height, coralmicro::CameraFormat::kRgb,
                   coralmicro::CameraFilterMethod::kBilinear,
                   coralmicro::CameraRotation::k270,
                   true) != CameraStatus::SUCCESS) {
    Serial.println("Failed to start camera");
    return;
  }

  Serial.println("Initializing detection server...");
  jsonrpc_init(nullptr, nullptr);
  jsonrpc_export("detect_from_camera", DetectRpc);
  UseHttpServer(new JsonRpcHttpServer);
  Serial.println("Detection server ready!");

  setup_success = true;
  Serial.println("Initialized");
}
void loop() {
  int reading = digitalRead(button_pin);
  if (reading != last_button_state) {
    last_debounce_time = millis();
  }
  if ((millis() - last_debounce_time) > kDebounceDelay) {
    if (reading != current_button_state) {
      current_button_state = reading;
      if (current_button_state == HIGH) {
        Serial.println("Button triggered, running detection...");
        if (!setup_success) {
          Serial.println("Cannot run because of a problem during setup!");
          return;
        }

        if (!DetectFromCamera()) {
          Serial.println("Failed to run detection");
          return;
        }

        Serial.print("Results count: ");
        Serial.println(results.size());
        for (auto result : results) {
          Serial.print("id: ");
          Serial.print(result.id);
          Serial.print(" score: ");
          Serial.print(result.score);
          Serial.print(" xmin: ");
          Serial.print(result.bbox.xmin);
          Serial.print(" ymin: ");
          Serial.print(result.bbox.ymin);
          Serial.print(" xmax: ");
          Serial.print(result.bbox.xmax);
          Serial.print(" ymax: ");
          Serial.println(result.bbox.ymax);
        }
      }
    }
  }
  last_button_state = reading;
}