### Start Fixed-Frequency DAC with Sine Wave Example (Squirrel) Source: https://developer.electricimp.com/api/hardware/fixedfrequencydac/start This code snippet demonstrates how to configure and start the fixed-frequency DAC to output a sine wave with a varying amplitude. It initializes buffers, writes sine wave data to them, configures the DAC with a specific pin and sample rate, and starts the output. A stop function is scheduled to halt the DAC after a set duration. This example is for imp001 or imp002 devices. ```squirrel // Varying amplitude sine wave example for fixed-frequency DAC on imp001 npts <- 4096; amp <- 0xffff >> 1; buffer1 <- blob(npts); buffer2 <- blob(npts); buffer3 <- blob(npts); incr_x <- 2 * PI / (npts - 1); Curr_x <- 0; function writeSineBuffer(buffer) { buffer.seek(0); for (local i = 0 ; i < npts / 2 ; i++) { curr_x += incr_x local a = amp * math.cos(curr_x / 4); local y = (a * math.sin(curr_x) + amp).tointeger(); buffer.writen(y, 'w'); } } function bufferEmpty(buffer) { server.log("bufferEmpty() called"); if (!buffer) { server.log("Warning: buffer underrun"); return; } writeSineBuffer(buffer); hardware.fixedfrequencydac.addbuffer(buffer); } function stop() { server.log("Stopping fixed-frequency DAC"); hardware.fixedfrequencydac.stop(); } server.log("Running sine wave fixed-frequency DAC"); writeSineBuffer(buffer1); writeSineBuffer(buffer2); writeSineBuffer(buffer3); hardware.fixedfrequencydac.configure(hardware.pin1, 512, [buffer1, buffer2, buffer3], bufferEmpty); hardware.fixedfrequencydac.start(); imp.wakeup(20, stop); ``` -------------------------------- ### Start Bluetooth Advertising (iBeacon Example) Source: https://developer.electricimp.com/api/hardware/bluetooth/startadvertise This code snippet demonstrates how to configure an Electric Imp device as an iBeacon transmitter. It defines the iBeacon advertisement data and then calls `bluetooth.startadvertise()` to begin broadcasting. The code also includes logging to display the parsed iBeacon UUID, Major, and Minor values. ```squirrel local iBeacon = "\x02\x01\x06\x1A\xFF\x4C\x00\x02\x15\x92\x77\x83\x0A\xB2\xEB\x49\x0F\xA1\xDD\x7F\xE3\x8C\x49\x2E\xDE\x00\x01\x00\x02\xC5"; local uuid = ""; for (local i = 0 ; i < iBeacon.len() ; i++) { uuid += format("%02x", iBeacon[i]); } server.log("Advertising the following iBeacon:"); server.log("UUID: " + uuid.slice(18,26) + "-" + uuid.slice(26,30) + "-" + uuid.slice(30,34) + "-" + uuid.slice(34,38) + "-" + uuid.slice(38,50)); server.log("Major: " + uuid.slice(50,54)); server.log("Minor: " + uuid.slice(54,58)); bt.startadvertise(iBeacon, 100, 100); ``` -------------------------------- ### Start Bluetooth Advertising with Scan Response Source: https://developer.electricimp.com/api/hardware/bluetooth/startadvertise This example shows how to set up an Electric Imp device for Bluetooth advertising, including custom scan response data. It first defines the iBeacon advertisement package and then constructs a `scanResponse` string containing a service UUID and the device's ID as a local name. Finally, `bluetooth.startadvertise()` is called with both advertisement and scan response data. ```squirrel // Set iBeacon ad package local iBeacon = "\x02\x01\x06\x1A\xFF\x4C\x00\x02\x15\x92\x77\x83\x0A\xB2\xEB\x49\x0F\xA1\xDD\x7F\xE3\x8C\x49\x2E\xDE\x00\x01\x00\x02\xC5"; // Create the scan response: first, the flags local scanResponse = "\x02\x01\x06"; // Add a service UUID // NOTE The second '\x03' is the data type: 'complete list of 16-bit UUIDs' scanResponse += "\x03\x03\xFF\x00"; // Finally, add the device's ID as a local name // NOTE '\x09' is the data type: 'complete local name' local name = hardware.getdeviceid(); local nameDataLength = name.len() + 1; scanResponse += (nameDataLength.tochar() + "\x09" + name); bt.startadvertise(iBeacon, 100, 100, scanResponse); ``` -------------------------------- ### Temperature Sensor I2C Example Source: https://developer.electricimp.com/api/hardware/i2c/configure An example demonstrating the use of I2C to communicate with an SA56004X temperature sensor. It includes configuring the I2C bus, creating a sensor object, and reading temperature values. ```nut const REG_LTHB = "\x00"; const REG_LTLB = "\x22"; const REG_SR = "\x02"; const REG_CONW = "\x09"; const REG_CRW = "\x0A"; const REG_SHOT = "\x0F"; const REG_AM = "\xBF"; class TempSensor { _i2c = null; _addr = null; constructor(i2c, address) { _i2c = i2c; _addr = address; } function get() { // Configure a single shot reading _i2c.write(_addr, REG_CONW + "\xD5"); // Set conversion rate to 1Hz _i2c.write(_addr, REG_CRW + "\x04"); // Ask the sensor to perform a one-shot reading _i2c.write(_addr, REG_SHOT + "\x00"); // Wait for the sensor to finish the reading while ((_i2c.read(_addr, REG_SR, 1)[0] & 0x80) == 0x80); // Get 11-bit signed temperature value in 0.125C steps local hi = _i2c.read(_addr, REG_LTHB, 1)[0]; local lo = _i2c.read(_addr, REG_LTLB, 1)[0]; local temp = (hi << 3) | (lo >> 5); // Convert from a 11-bit integer to a Celsius temperature if (temp & 0x400) { // Negative two's complement value return -((~temp & 0x7FF) + 1) * 0.125; } else { // Positive value return temp * 0.125; } } } // Configure an imp001 i2c bus hardware.i2c89.configure(CLOCK_SPEED_400_KHZ); // Create TempSensor object tempSensor <- TempSensor(hardware.i2c89, 0x98); // Read temperature server.log(tempSensor.get()); ``` -------------------------------- ### Example: Ping-Pong Communication using agent.on() and device.on() (Squirrel) Source: https://developer.electricimp.com/api/agent/on This example illustrates a bidirectional communication flow between an agent and a device using agent.on(), device.on(), agent.send(), and device.send(). The device listens for 'ping' from the agent and responds with 'pong', while the agent listens for 'pong' and sends 'ping' periodically. ```squirrel // Device Code agent.on("pong", returnFromAgent); device.on("ping", startTime); function startTime(time) { device.send("pong", time); } function returnFromAgent(startMillis) { local endMillis = hardware.millis(); local diff = endMillis - startMillis; server.log("Round trip took: " + diff + "ms"); imp.wakeup(5.0, ping); } function ping() { agent.send("ping", hardware.millis()); } ping(); ``` ```squirrel // Agent Code device.on("pong", returnFromAgent); agent.on("ping", startTime); function startTime(time) { // Send the device a 'pong' message immediately device.send("pong", time); } function returnFromAgent(startMillis) { // Handle a 'pong' message from the device local endMillis = hardware.millis(); local diff = endMillis - startMillis; server.log("Round trip took: " + diff + "ms"); imp.wakeup(5.0, ping); } function ping() { // Send a 'ping' message to the device with the current millisecond counter value agent.send("ping", hardware.millis()); } // Start the ping-pong ping(); ``` -------------------------------- ### Start Bluetooth Scan and Handle Advertisements Source: https://developer.electricimp.com/api/hardware/bluetooth/setscanfilter Initiates a Bluetooth scan and provides a callback function to handle received advertisements. The callback dispatches to different handler functions based on the advertisement rule (e.g., AltBeacon, iBeacon). ```squirrel bt.startscan(function (adverts) { foreach (advert in adverts) { if (advert.rule == 0) { handleAltBeacon(advert); } else if (advert.rule == 1) { handleiBeaconA(advert); } else if (advert.rule == 2) { handleiBeaconB(advert); } } }); ``` -------------------------------- ### Device: Configure and Control Fixed Frequency DAC Source: https://developer.electricimp.com/api/hardware/fixedfrequencydac/addbuffer This device code handles the configuration and control of the Fixed Frequency DAC. It defines a callback function for buffer underruns and registers handlers for starting and stopping the DAC based on messages received from the agent. It adapts configuration based on the imp model. ```nut // Define the buffer-processing function function bufferEmpty(buffer) { server.log("bufferEmpty() called"); if (!buffer) { server.log("Warning: buffer underrun"); return; } // Get another buffer agent.send("more.data.please", 1); } // Set up our agent message handlers agent.on("start.fixed.frequency.dac", function(configuration) { server.log("Got start message with " + configuration.buffers.len() + " buffers"); local options = configuration.useALAW ? A_LAW_DECOMPRESS : 0; local type = ("info" in imp) ? imp.info().type : "imp001"; if (type == "imp004m") { // Set the configuration hardware.fixedfrequencydac.configure(hardware.pwmpairKD, configuration.sampleRateHz, configuration.buffers, bufferEmpty, options); } else { // Set the FFDAC pin as specified local pin = null; if (type == "imp001" || type == "imp002") pin = configuration.usePin1 ? hardware.pin1 : hardware.pin5; if (type == "imp003") pin = configuration.usePin1 ? hardware.pinA : hardware.pinC; if (type == "imp006") pin = configuration.usePin1 ? hardware.pinXC : hardware.pinXD; if (type == "imp005") throw "This code will not run on an imp005, which has no FFDAC"; // Set the configuration hardware.fixedfrequencydac.configure(pin, configuration.sampleRateHz, configuration.buffers, bufferEmpty, options); } // Start the DAC hardware.fixedfrequencydac.start(); }); agent.on("stop.fixed.frequency.dac", function(dummy) { // Stop the DAC hardware.fixedfrequencydac.stop(); server.log("Received stop message"); }); ``` -------------------------------- ### Passive iBeacon Scanning with Electric Imp Source: https://developer.electricimp.com/api/hardware/bluetooth/startscan This snippet scans for iBeacons in passive mode, logging each unique beacon found. It initializes Bluetooth, sets passive scan parameters, filters for iBeacon advertisements, and starts scanning. Found beacons are added to a global list and reported. ```squirrel bt <- null; // Beacons beacons <- []; function makePrettyUUID(uuid) { return uuid.slice(0,9) + "-" + uuid.slice(8,12) + "-" + uuid.slice(12,16) + "-" + uuid.slice(16); } function reportBeacon(beacon) { server.log("Beacon added: " + makePrettyUUID(beacon.uuid) + " (" + beacon.majorString + "/" + beacon.minorString + ")"); } function addBeacon(beacon) { beacons.append(beacon); reportBeacon(beacon); } try { // Instantiate BT on imp006 breakout bt = hardware.bluetooth.open(); } catch (err) { server.error(err); return; } // Set scan parameters for passive scanning bt.setscanparams(false, 100, 100); // Filter out advertisements whose 'data' contains the iBeacon preamble bytes // and whose type is ADV_NONCONN_IND bt.setscanfilter([{ "type" : 3, "data" : "\x02\x01\x06\x1A\xFF\x4C\x00\x02\x15" }]); server.log("Scanning..."); bt.startscan(function(adverts) { foreach (advert in adverts) { // Convert payload to hex string local payload = ""; for (local i = 0 ; i < advert.data.len() ; i++) { payload += format("%02x", advert.data[i]); } // This is a beacon so record it local beacon = {}; beacon.uuid <- payload.slice(18, 50); beacon.majorString <- payload.slice(50, 54); beacon.minorString <- payload.slice(54, 58); if (beacons.len() > 0) { local got = false; foreach (aBeacon in beacons) { if (aBeacon.uuid == beacon.uuid && aBeacon.majorValue == beacon.majorValue && aBeacon.minorValue == beacon.minorValue) { got = true; break; } } if (!got) addBeacon(beacon); } else { addBeacon(beacon); } } }); ``` -------------------------------- ### Control Fixed Frequency DAC with Electric Imp Source: https://developer.electricimp.com/api/hardware/fixedfrequencydac/configure This snippet demonstrates how to control a fixed-frequency DAC using the Electric Imp platform. It handles starting and stopping the DAC, adding data buffers, and logging received messages. It relies on the `hardware.fixedfrequencydac` API and agent event listeners. ```squirrel // Start the DAC hardware.fixedfrequencydac.start(); }); agent.on("stop.fixed.frequency.dac", function(dummy) { // Stop the DAC hardware.fixedfrequencydac.stop(); server.log("Received stop message"); }); agent.on("more.data", function(buffer) { // Add the received data buffer to the DAC hardware.fixedfrequencydac.addbuffer(buffer); server.log("Received more data"); }); // Start the process by signalling device readiness agent.send("device.ready", true); ``` -------------------------------- ### hardware.bluetooth.open() Source: https://developer.electricimp.com/api/hardware/bluetooth/open Initializes the imp’s Bluetooth sub-system and readies it for use. Returns a `bluetooth` instance. ```APIDOC ## hardware.bluetooth.open() ### Description Initializes the imp’s Bluetooth sub-system and readies it for use. This method returns an instance of the `bluetooth` class. ### Method `hardware.bluetooth.open(_uart_, _firmware_, _options_) ### Availability Device Only Only available on the imp004m and imp006 (impOS 42) ### Parameters #### imp006 The imp006’s Bluetooth chip is connected on a dedicated UART and its firmware is loaded by impOS. Therefore, `hardware.bluetooth.open()` on the imp006 takes **no arguments**. #### imp004m * **_uart_** (An imp UART object) - The imp UART bus connected to the module’s Bluetooth sub-system **imp004m only**. * **_firmware_** (String or blob) - The Broadcom-proprietary firmware for the Bluetooth sub-system **imp004m only**. * **_options_** (Table) - Optional overrides **imp004m only**. * _mac_ (String) - An alternative MAC address. Must be provided as a 12-character lower-case hexadecimal string. * _baudrate_ (Integer) - The preferred baud rate to use for HCI traffic once bluetooth has booted. ### Returns A new **bluetooth** instance ### Request Example #### imp006 Example ```javascript // Set up BT on imp006 Breakout Board bt <- null; local start = hardware.millis(); try { // Instantiate BT bt = hardware.bluetooth.open(); server.log("BLE initialized after " + (hardware.millis() - start) + " ms"); } catch (err) { server.error(err); server.log("BLE failed after " + (hardware.millis() - start) + " ms"); } ``` #### imp004m Example ```javascript #require "bt_firmware.lib.nut:1.0.0" // Set up BT on imp004m Breakout Board bt <- null; bt_uart <- hardware.uartFGJH; bt_lpo_in <- hardware.pinE; bt_reg_on <- hardware.pinJ; // Boot up BT bt_lpo_in.configure(DIGITAL_OUT, 0); bt_reg_on.configure(DIGITAL_OUT, 1); // Pregnant pause while BT boots... imp.sleep(0.05); local start = hardware.millis(); try { // Instantiate BT bt = hardware.bluetooth.open(bt_uart, BT_FIRMWARE.CYW_43438, {"mac": "76bdac7f672a"}); server.log("BLE initialized after " + (hardware.millis() - start) + " ms"); } catch (err) { server.error(err); server.log("BLE failed after " + (hardware.millis() - start) + " ms"); } ``` ### Response #### Success Response (200) * **bluetooth instance** (object) - A new instance of the `bluetooth` class is returned upon successful initialization. ``` -------------------------------- ### Initialize Bluetooth on imp006 Source: https://developer.electricimp.com/api/hardware/bluetooth/open Initializes the Bluetooth sub-system on an imp006 device. This function requires no arguments as the UART and firmware are handled internally by impOS. It returns a bluetooth instance for further use. ```nut // Set up BT on imp006 Breakout Board bt <- null; local start = hardware.millis(); try { // Instantiate BT bt = hardware.bluetooth.open(); server.log("BLE initialized after " + (hardware.millis() - start) + " ms"); } catch (err) { server.error(err); server.log("BLE failed after " + (hardware.millis() - start) + " ms"); } ``` -------------------------------- ### Generate Varying Amplitude Sine Wave with Fixed-Frequency DAC Source: https://developer.electricimp.com/api/hardware/fixedfrequencydac/stop An example demonstrating the generation of a sinusoidal output with a varying amplitude using the fixed-frequency DAC on an imp001 or imp002. This code configures the DAC, starts playback, and schedules a stop function. It recycles buffers and adds them back in a callback to ensure continuous output. ```squirrel // Varying amplitude sine wave example for fixed-frequency DAC on imp001 npts <- 4096; amp <- 0xffff >> 1; buffer1 <- blob(npts); buffer2 <- blob(npts); buffer3 <- blob(npts); incr_x <- 2 * PI / (npts - 1); curr_x <- 0; function writeSineBuffer(buffer) { buffer.seek(0); for (local i = 0 ; i < npts / 2 ; i++) { curr_x += incr_x local a = amp * math.cos(curr_x / 4); local y = (a * math.sin(curr_x) + amp).tointeger(); buffer.writen(y, 'w'); } } function bufferEmpty(buffer) { server.log("bufferEmpty() called"); if (!buffer) { server.log("Warning: buffer underrun"); return; } writeSineBuffer(buffer); hardware.fixedfrequencydac.addbuffer(buffer); } function stop() { server.log("Stopping fixed-frequency DAC"); hardware.fixedfrequencydac.stop(); } server.log("Running sine wave fixed-frequency DAC"); writeSineBuffer(buffer1); writeSineBuffer(buffer2); writeSineBuffer(buffer3); hardware.fixedfrequencydac.configure(hardware.pin1, 512, [buffer1, buffer2, buffer3], bufferEmpty); hardware.fixedfrequencydac.start(); imp.wakeup(20, stop); ``` -------------------------------- ### Initialize Bluetooth on imp004m Source: https://developer.electricimp.com/api/hardware/bluetooth/open Initializes the Bluetooth sub-system on an imp004m device, requiring a UART object, firmware blob, and optional settings. The firmware can be included as a string or binary data. This function returns a bluetooth instance. ```nut #require "bt_firmware.lib.nut:1.0.0" // Set up BT on imp004m Breakout Board bt <- null; bt_uart <- hardware.uartFGJH; bt_lpo_in <- hardware.pinE; bt_reg_on <- hardware.pinJ; // Boot up BT bt_lpo_in.configure(DIGITAL_OUT, 0); bt_reg_on.configure(DIGITAL_OUT, 1); // Pregnant pause while BT boots... imp.sleep(0.05); local start = hardware.millis(); try { // Instantiate BT bt = hardware.bluetooth.open(bt_uart, BT_FIRMWARE.CYW_43438, {"mac": "76bdac7f672a"}); server.log("BLE initialized after " + (hardware.millis() - start) + " ms"); } catch (err) { server.error(err); server.log("BLE failed after " + (hardware.millis() - start) + " ms"); } ``` -------------------------------- ### gnss-session.assist.load(_statusCallback_, _assistData_) Source: https://developer.electricimp.com/api/gnss-session/assist/load Initializes the gpsOneXTRA assistance data feature for a Quectel cellular modem. This method uploads assistance data to the modem, copies it to the GNSS sub-system, and then deletes the uploaded file. ```APIDOC ## gnss-session.assist.load(_statusCallback_, _assistData_) ### Description Initializes a Quectel cellular modem’s gpsOneXTRA assistance function, which simplifies the application of GNSS assistance data for future GNSS readings. You will need to call **assist.enable()** to begin making use of loaded assist data. This method uploads the supplied assistance data to the modem’s file system, causes the data to be copied into the modem’s GNSS sub-system, and then deletes the uploaded file. ### Availability Device Only available on imps with cellular modems ### Method (This is a client-side method, not a standard HTTP method) ### Endpoint (N/A for client-side methods) ### Parameters #### Path Parameters (N/A) #### Query Parameters (N/A) #### Request Body - **_statusCallback_** (Function) - Required - A handler to receive status information. - **_assistData_** (Blob) - Required - The assistance data. This should be provided as a binary blob. Please refer to your modem’s GNSS documentation to learn how to acquire this data. ### Request Example (N/A for client-side methods without explicit request bodies) ### Response #### Success Response Nothing is returned directly by this method. Status updates are provided via the _statusCallback_. #### Response Example (N/A) ### Error Handling The _statusCallback_ function receives a table with `status` and `restart` keys. `status` indicates success (0) or an error code. `restart` indicates if the modem needs to be power-cycled (non-zero). ### See Also - gnss-session - assist - gnss-session.assist.reset() - gnss-session.assist.enable() - gnss-session.assist.read() ``` -------------------------------- ### I2C Write and Data Formatting Example (Squirrel) Source: https://developer.electricimp.com/api/hardware/i2c/write Demonstrates how to format binary data into Squirrel strings for I2C transmission. Includes examples for sending raw bytes, converting integers, and converting blobs. Squirrel strings support null characters, allowing any binary value to be sent. ```squirrel local sendStringOne = format("%c%c%c", 0xA5, 0xD3, 0x00); local sendStringTwo = integerOne.tochar() + integerTwo.tochar(); locat sendStringThree = blobOne.tostring(); ``` -------------------------------- ### Electric Imp I2C Temperature Sensor Example Source: https://developer.electricimp.com/api/hardware/i2c/read This example showcases how to use the i2c.read() and i2c.write() methods to interface with an SA56004X temperature sensor. It covers device configuration, reading sensor data, and converting raw values to Celsius. It requires the 'I2C' class and impOS™ release 30 or later for error diagnostics. ```squirrel const REG_LTHB = "\x00"; const REG_LTLB = "\x22"; const REG_SR = "\x02"; const REG_CONW = "\x09"; const REG_CRW = "\x0A"; const REG_SHOT = "\x0F"; const REG_AM = "\xBF"; class TempSensor { _i2c = null; _addr = null; constructor(i2c, address) { _i2c = i2c; _addr = address; } function get() { // Configure a single shot reading _i2c.write(_addr, REG_CONW + "\xD5"); // Set conversion rate to 1Hz _i2c.write(_addr, REG_CRW + "\x04"); // Ask the sensor to perform a one-shot reading _i2c.write(_addr, REG_SHOT + "\x00"); // Wait for the sensor to finish the reading while ((_i2c.read(_addr, REG_SR, 1)[0] & 0x80) == 0x80); // Get 11-bit signed temperature value in 0.125C steps local hi = _i2c.read(_addr, REG_LTHB, 1)[0]; local lo = _i2c.read(_addr, REG_LTLB, 1)[0]; local temp = (hi << 3) | (lo >> 5); // Convert from a 11-bit integer to a Celsius temperature if (temp & 0x400) { // Negative two's complement value return -((~temp & 0x7FF) + 1) * 0.125; } else { // Positive value return temp * 0.125; } } } // Configure an imp001 i2c bus hardware.i2c89.configure(CLOCK_SPEED_400_KHZ); // Create TempSensor object tempSensor <- TempSensor(hardware.i2c89, 0x98); // Read temperature server.log(tempSensor.get()); ``` -------------------------------- ### dfsdm.configure() Source: https://developer.electricimp.com/api/hardware/dfsdm/configure Configures the DFSDM object for sampling, setting filter order, decimation rate, integration rate, offset, sampling edge, buffers, and callback function. ```APIDOC ## dfsdm.configure() ### Description Configures the imp004m and (from impOS™ 42) imp006 **dfsdm** object in preparation for sampling. This method allows for fine-tuning of the digital filter for sigma-delta modulators, including setting filter parameters, data processing rates, and callback functions for handling sampled data. ### Method `dfsdm.configure()` ### Endpoint N/A (This is a device-side method) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body * **_filterOrder_** (Integer) - Required - The filter order between 0 and 5. 0 is a fast second-order filter, 1-5 are corresponding filter orders. * **_decimationRate_** (Integer) - Required - The decimation rate between 0 and 1023. 0 bypasses the filter. 1-1023 represent the decimation rate minus 1 (e.g., 31 for a rate of 32). * **_integrationRate_** (Integer) - Required - The integration rate between 0 and 255. 0 bypasses the integrator. 1-255 represent the integration rate minus 1 (e.g., 255 for a rate of 256). * **_offset_** (Integer) - Required - DC offset correction (-8388607 to +8388607). Added to each output sample. * **_rightShift_** (Integer) - Required - Number of bits to shift right (0 to 24). Discards least significant bits. * **_samplingEdge_** (String) - Required - CLK pin edge for DATA sampling. Accepted values: `"RISING-EDGE"`, `"FALLING-EDGE"`. An empty string (`""`) defaults to `"RISING-EDGE"`. * **_bufferArray_** (Array) - Required - An array of blobs (up to eight), each a buffer for sampled data. Blob size must be a multiple of four bytes. * **_callback_** (Function) - Required - Function called when a sample buffer is full. It receives `_sampleBuffer_` (blob) and `_byteCount_` (Integer) as parameters. * **_preprocessors_** (Constant) - Optional - Pre-processing filters. ### Request Example ```javascript dfsdm.configure(0, 31, 255, 0, 4, "RISING-EDGE", [blob1, blob2, blob3], myCallbackFunction, PREPROCESSOR_FILTER_A); ``` ### Response #### Success Response (200) Nothing #### Response Example N/A ``` -------------------------------- ### Get Device GNSS Location using Electric Imp Squirrel Source: https://developer.electricimp.com/api/gnss-session/readposition This code snippet demonstrates how to acquire a GNSS location fix on an Electric Imp imp006 device. It initializes a GNSS session, enables GNSS operations, and recursively attempts to get a location until a fix is found. It requires the `hardware.gnss` API and logs the device's latitude and longitude. Errors during session or read operations are also handled. ```squirrel // Hold a reference to the GNSS Session object gnssSession <- null; // Store device location location <- { "lat": 0, "lon": 0 }; function isGnssEnabled() { // Is GNSS ready to use? if (gnssSession == null) return false; try { local resp = gnssSession.getstate(); return (resp.status == 1); } catch (err) { return false; } } function enableGNSS() { // Is GNSS ready? if (!isGnssEnabled()) { // Check the modem has a GNSS session in place if (gnssSession == null) { // Initiate a session try { gnssSession = hardware.gnss.open(function(result) { server.log("[DEBUG] GNSS Session is " + (result.ready == 0 ? "not ready" : "ready")); if (result.ready == 1) { // We're good to enable GNSS operations enableGNSS(); } }); } catch (error) { // Back off and try again imp.wakeup(1, enableGNSS); } return; } // We have a GNSS session, so enable GNSS operations local resp = gnssSession.enable(); if (resp.status != 0) { // Error enabling GNSS if (resp.status == 504) { // Wait while an ongoing op. completes imp.wakeup(1, enableGNSS); return; } // Can't proceed any further, so report error server.error("Could not enable GNSS (" + resp.status + ")"); return; } } // GNSS is ready, so get the location getLocation(); } function getLocation() { // Use the session to get a location -- // this may not yield results immediately try { gnssSession.readposition(function(resp) { if (resp.status != 0) { // An error is indicated, but this may not be a problem if (resp.status == 516) { // Fix not yet found server.log("[DEBUG] GPS location request in progress..."); } else { server.error("GPS location request failed with error: " + resp.status); } return; } if ("quectel" in resp) { location.lat = resp.quectel.latitude; location.lon = resp.quectel.longitude; server.log(format("Device at %.4f, %.4f", location.lat.tofloat(), location.lon.tofloat())); } }.bindenv(this), 2); // '2' is the co-ordinates display mode: (-)dd.ddddd, (-)dd.ddddd } catch (error) { // Error condition server.error("Modem reported an error:"); server.log(error); } } // Enable GNSS enableGNSS(); ``` -------------------------------- ### gnss.open() - Open GNSS Session Source: https://developer.electricimp.com/api/hardware/gnss/open Attempts to open a session to the modem’s GNSS sub-system. This method is only available on imps with cellular modems and requires a SIM card to be installed. ```APIDOC ## gnss.open(_statusCallback_) ### Description Attempts to open a session to the modem’s GNSS sub-system and prepares it for use. Returns a `gnss-session` object for further interactions. ### Method `gnss.open()` ### Endpoint N/A (This is a device-side API call) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```javascript gnss.open(function(status) { if (status.ready) { // GNSS is ready local session = gnss.open(); // Use session object for further operations } }); ``` ### Response #### Success Response (gnss-session object) - **gnss-session** (object) - An object representing the active GNSS session. #### Response Example ```json { "__gnss_session__": true } ``` ### Error Handling - An exception will be thrown if `gnss.open()` is called again while a session is already open. - Exceptions may be raised if GNSS methods are called before the modem is ready. - Exceptions may be raised while the modem is powering up after a cellular connection retry. ### Status Callback - **_statusCallback_** (Function) - Optional handler for modem readiness notifications. - The callback receives a table with a `ready` key. - `ready` (integer): `0` (not ready) or `1` (ready). ``` -------------------------------- ### i2c.readerror() - Get Last I2C Read Error Source: https://developer.electricimp.com/api/hardware/i2c/readerror This function returns the error code from the most recent I2C read operation. It is particularly useful when `i2c.read()` returns `null`, indicating an error. ```APIDOC ## GET /i2c/readerror ### Description Returns the error code generated by the last I2C read operation. This can help diagnose hardware faults when `i2c.read()` returns `null`. ### Method GET ### Endpoint `/i2c/readerror` ### Parameters #### Query Parameters None #### Request Body None ### Request Example (Not applicable for this read-only function) ### Response #### Success Response (200) - **errorCode** (Integer) - An I2C error code. Returns `0` if no error occurred. #### Response Example ```json { "errorCode": -3 } ``` ### I2C Error Codes | Error | Value | Description | |----------------------------|-------|------------------------------------------------------| | No error | 0 | Method completed successfully | | Controller select error | -1 | Timeout waiting for bus to be released after sending start | | Transmit select error | -2 | Timeout while selecting transmit mode | | Transmit error | -3 | Timeout while sending data | | BTF error | -4 | Timeout waiting for data transfer to complete | | Stop error | -5 | Timeout waiting for stop condition to be detected | | Address clear error | -6 | Timeout waiting for address flag to be cleared | | Address RXNE error | -7 | Timeout waiting for address to be read | | Data RXNE error | -8 | Timeout waiting for data to be read | | Peripheral NACKed error | -9 | Peripheral NACKs the send | | Controller receive select error| -10 | Timeout while selecting multibyte receive mode | | Receive error | -11 | Timeout during multibyte read | | Reselect error | -12 | Timeout waiting for bus to be released after sending start | | Not enabled | -13 | Attempt to read or write from an unconfigured peripheral | ``` -------------------------------- ### bluetooth.startscan(_callback_) Source: https://developer.electricimp.com/api/hardware/bluetooth/startscan Causes the imp to begin scanning for GAP advertisements. A callback function is registered to process any detected advertising data. ```APIDOC ## POST /bluetooth/startscan ### Description This method initiates scanning for GAP advertisements. A callback function is registered to process any detected advertising data. The callback function receives an array of detected advertisements, where each advert contains details like type, signal strength, address, and raw data. ### Method POST ### Endpoint /bluetooth/startscan ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **_callback_** (Function) - Required - A function to process any detected advertising data. This function will receive a single argument: `adverts`, an array of detected advertisements. ### Request Example ```json { "_callback_": "function(adverts) { ... }" } ``` ### Response #### Success Response (200) This method does not return any data directly upon successful execution. The results are delivered asynchronously to the provided callback function. #### Response Example (No direct response body, results are passed to the callback function) ### Advertisement Data Structure (within callback) Each advert in the `adverts` array is a table with the following keys: - **_type_** (Integer) - The type of advertisement detected. - **_rssi_** (Integer) - The signal strength (-127 to 20) of the received data in dBm. - **_address_** (String) - The peer’s address as a 12-character hexadecimal string. - **_addresstype_** (Integer) - 0 if the address is public, 1 if the address is random. - **_data_** (Blob) - The raw data received. Up to 31 bytes in length. - **_time_** (Integer) - The time of receipt by impOS, as an integer millisecond time. - **_rule_** (Integer) - The index of the filter that allowed this advert (zero if default accept-all filter is in use). ### Advertisement Type Constants - _ADV_IND_ (0): Connectable undirected advertisement - _ADV_DIRECT_IND_ (1): Connectable directed advertisement - _ADV_SCAN_IND_ (2): Scannable undirected advertisement - _ADV_NONCONN_IND_ (3): Non-connectable undirected advertisement - _SCAN_RSP_ (4): Scan response **Note:** These constants are not defined in Squirrel; use the integer values in comparisons. ``` -------------------------------- ### RSA Key Generation using OpenSSL Source: https://developer.electricimp.com/api/crypto/verify Commands to generate an RSA private key and extract the corresponding public key using the OpenSSL command-line tool. These keys are required for signing and verifying data. ```bash openssl genrsa -out rsa.key 2048 openssl rsa -pubout < rsa.key > rsa.pub ``` -------------------------------- ### Get Wake Reason using Hardware Object Source: https://developer.electricimp.com/api/hardware Determines the reason why the imp was woken up from a low-power state. This method is part of the hardware object and returns a constant indicating the wake-up cause. ```electricimp-squirrel local reason = hardware.wakereason(); ``` -------------------------------- ### Handle Audio Data with Electric Imp Fixed-Frequency DAC Source: https://developer.electricimp.com/api/hardware/fixedfrequencydac/addbuffer This snippet shows how to set up an event listener for incoming data (`more.data`) on the agent. It adds the received data buffer to the fixed-frequency DAC and logs a message. It also includes code to signal device readiness to the agent. ```squirrel agent.on("more.data", function(buffer) { // Add the received data buffer to the DAC hardware.fixedfrequencydac.addbuffer(buffer); server.log("Received more data"); }); // Start the process by signalling device readiness agent.send("device.ready", true); ``` -------------------------------- ### Agent: Generate and Compress Sinusoidal Wave Source: https://developer.electricimp.com/api/hardware/fixedfrequencydac/addbuffer This agent code generates a sinusoidal wave, compresses it using the A-law algorithm, and packages it into a blob for streaming. It defines constants for amplitude, number of points, and clipping, along with a lookup table for compression. The generated blobs are used to configure the Fixed Frequency DAC. ```nut const AMPLITUDE = 0x3FFF; const NUMBER_POINTS = 1024; const CLIP_VALUE = 32635; const INCR_X = 0.78531475; local streaming = false; local logTable = [ 1,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 ]; function aLawCompress(sample) { local sample = sample == -32768 ? -32767 : sample; local sign = ((~sample) >> 8) & 0x80; if (!sign) sample = -sample; if (sample > CLIP_VALUE) sample = CLIP_VALUE; local compressedValue = 0; if (sample >= 256) { local exponent = logTable[(sample >> 8) & 0x7F]; local mantissa = (sample >> (exponent + 3)) & 0x0F; compressedValue = ((exponent << 4) | mantissa); } else { compressedValue = sample >> 4; } compressedValue = compressedValue ^ (sign ^ 0x55); return compressedValue; } function writeSineBuffer() { // Generate a 1kHz sine wave data as a blob local buffer = blob(); local curr_x = 0; for (local i = 0 ; i < NUMBER_POINTS ; i++) { local a = AMPLITUDE * math.cos(curr_x); curr_x += INCR_X; local y = aLawCompress(a.tointeger()); buffer.writen(y, 'c'); } return buffer; } // Define the DAC configuration local configuration = { "buffers" : [writeSineBuffer(), writeSineBuffer(), writeSineBuffer(), writeSineBuffer()], "sampleRateHz" : 8000, "usePin1" : true, "useALAW" : true } // Set up our device message handlers: // First, deal with requests for more audio data device.on("more.data.please", function(nbuffers) { if (streaming) device.send("more.data", writeSineBuffer()); }); // Second, continue when the device has signalled its readiness device.on("device.ready", function(dummy) { streaming = true; // Tell the DAC to start and send its configuration device.send("start.fixed.frequency.dac", configuration); // Wake after 10s and tell the device to stop the DAC imp.wakeup(10, function() { device.send("stop.fixed.frequency.dac", true); streaming = false; }); }); ```