SFF

SODAQ Small Form Factor (SFF)

Menu
Getting Started
Features
Pinout
Pin definitions
Schematics
Examples

Overview

The SODAQ Small Form Factor (SFF) is the SODAQ SARA in a small package.

Install the latest SODAQ SAMD boardfiles.
See Arduino setup page

Microcontroller ATSAMD21G18, 32-Bit ARM Cortex M0+
Compatibility Arduino M0 Compatible
Size 50 x 25.4mm
Operating Voltage 3.3V
I/O Pins 14
Analog Output Pin 10-bit DAC
External Interrupts Available on all pins
DC Current per I/O pin 7 mA
Flash Memory 256 KB
SRAM 32KB
EEPROM Up to 16KB by emulation
Clock Speed 48 MHz
Power 5V USB power and/or 3.7 LiPo battery
Charging Solar charge controller, up to 500mA charge current
LED RGB LED
NB-IoT uBlox SARA N2XX, R4XX Series
GPS uBlox EVA 8M
Accelerometer/Magneto LSM303AGR
USB MicroUSB Port

Some things like the onboard LED and the RGB LED are used on multiple boards. To make it more easy you can use the definition name.

Example:
pinMode(13, OUTPUT) and pinMode(LED_BUILTIN, OUTPUT) will do the same.

Pin description Pin number Definition
Red LED LED_RED
Green LED LED_GREEN
Blue LED LED_BLUE
GPS Enable GPS_ENABLE
GPS Timepulse GPS_TIMEPULSE
Power Pin SARA SARA_ENABLE
Change voltage pin SARA (3.3V – 1.8V) SARA_R4XX_TOGGLE
MISO (SPI) MISO
SS (SPI) SS
MOSI (SPI) MOSI
SCK (SPI) SCK
Accelrometer Interrupt 1 ACCEL_INT1
Accelrometer Interrupt 2 ACCEL_INT2
Magnetometer Interrupt MAG_INT

The R4 and N2 modules work on a different baudrate.
The N2 modules work on 3.3V and the R4 on 1.8V.

R4XX N2XX
Baudrate 115200 9600
SARA_R4XX_TOGGLE LOW HIGH

  

SODAQ-SARA-SFF-page1
SODAQ-SARA-SFF-page2

 

#include <Arduino.h>

//#define R4XX // Uncomment when you use the ublox R4XX module

#define DEBUG_STREAM SerialUSB
#define MODEM_STREAM Serial1

#if defined(R4XX)
unsigned long baud = 115200;  //start at 115200 allow the USB port to change the Baudrate
#else 
unsigned long baud = 9600;  //start at 9600 allow the USB port to change the Baudrate
#endif

void setup() 
{

 // Turn the power to the SARA module on.
 // we have a powerswitch on board to switch the power to the SARA on/of when needed
 // in most applications we keep the power on all the time  
pinMode(SARA_ENABLE, OUTPUT);  
digitalWrite(SARA_ENABLE, HIGH);


#ifdef R4XX
    // Turn the nb-iot module on
    // The R4XX module has an on/off pin. You can toggle this pin or keep it low to
    // switch on the module
    pinMode(SARA_R4XX_TOGGLE, OUTPUT);
    digitalWrite(SARA_R4XX_TOGGLE, LOW);
#endif
  


  // Start communication
  DEBUG_STREAM.begin(baud);
  MODEM_STREAM.begin(baud);
}

// Forward every message to the other serial
void loop() 
{
  while (DEBUG_STREAM.available())
  {
    MODEM_STREAM.write(DEBUG_STREAM.read());
  }

  while (MODEM_STREAM.available())
  {     
    DEBUG_STREAM.write(MODEM_STREAM.read());
  }
  
  // check if the USB virtual serial wants a new baud rate
  // This will be used by the UEUpdater to flash new software
  if (DEBUG_STREAM.baud() != baud) {
    baud = DEBUG_STREAM.baud();
    MODEM_STREAM.begin(baud);
  }
}

Vodafone NL – UDP

Required module: N2XX
Commands are tested on the Vodafone NL NB-IoT network
Vodafone does support plain UDP packages
Setup

AT+CSCON=1
//Give URC's of when the sara module has communication with the base station, useful for debugging
AT+CEREG=5
//Give URC's of the netwok registration status, useful for debugging and knowing whether you have received the power save timers
AT+NPSMR=1
//Give URC's whenever the module sleeps and awakens, useful for knowing whenever you want into low power
AT+CPSMS=1,,,"00000001","00000001"
//Enable power save mode, request RPTAU of 10 seconds and request RAT of 2 seconds
//Note that the above values are requested, you will receive some set timers from the network after connection, look for the last two variables with CEREG URC.
AT+NCONFIG="CR_0354_0338_SCRAMBLING","TRUE" //Enable Scrambling, necessary for Vodafone
AT+NCONFIG="CR_0859_SI_AVOID","FALSE" //Specific setting for Vodafone
AT+CFUN=0 //Disable antenna
AT+CGDCONT=1,"IP","nb.inetd.gdsp" //Set vodafone PDP settings
AT+CFUN=1 //Enable antenna
AT+NBAND=20 //Set band to 20 (Vodafone uses 20)
AT+CFUN=0 //Turn antenna off
AT+CFUN=1 //Turn antenna on (this appears to force a refresh and works best in practice)
AT+COPS=1,2,"20404" //Connect to Vodafone

Now make sure you actually have connection to the base station.
Periodically check for base station signal strength and whether GPRS is attached
Wait for connection

AT+CSQ //Check for signal strength, the first or second variable should not be 99
AT+CGATT? //Check for GPRS attachment, should return 1

For sending an UDP package you need to open a socket after having connection
Socket

AT+NSOCR="DGRAM",17,16666,0 //Create a socket on port 16666 for sending and receiving datagrams (UDP)

Now that you’re connected, transmit a message
Transmit

AT+NSOSTF=0,"YOUR_SERVER_IP",YOUR_SERVER_PORT,0x200,12,"48656c6c6f20576f726c6421" //Send Hello world! , immediately stop transmitting after sending the command
//Make sure to enter your own ip and port!

T-Mobile NL – CoAP

Required module: N2XX

AT+NCONFIG="CR_0354_0338_SCRAMBLING","TRUE"
AT+NCONFIG="CR_0859_SI_AVOID","FALSE"
AT+CFUN=0
AT+NCDP="172.27.131.100"
AT+CGDCONT=0,"IP","cdp.iot.t-mobile.nl"
AT+CFUN=1
AT+NBAND=8
AT+COPS=1,2,"20416"
AT+CSQ
AT+CGATT?
AT+NSMI=1 // Send Message indicator
AT+NNMI=1 // Receive Message indicator
AT+NMGS=11,"48656c6c6f20576f726c64"

T-Mobile NL – UDP

Required module: N2XX
Commands are tested on the T-Mobile NL NB-IoT network

Setup

AT+CSCON=1
//Give URC's of when the sara module has communication with the base station, useful for debugging
AT+CEREG=5
//Give URC's of the netwok registration status, useful for debugging and knowing whether you have received the power save timers
AT+NPSMR=1
//Give URC's whenever the module sleeps and awakens, useful for knowing whenever you want into low power
AT+CPSMS=1,,,"00000001","00000001"
//Enable power save mode, request RPTAU of 10 seconds and request RAT of 2 seconds
//Note that the above values are requested, you will receive some set timers from the network after connection, look for the last two variables with CEREG URC.
AT+NCONFIG="CR_0354_0338_SCRAMBLING","TRUE" //Enable Scrambling
AT+NCONFIG="CR_0859_SI_AVOID","FALSE" //Specific setting for Vodafone
AT+CFUN=0 //Disable antenna
AT+CGDCONT=0,"IP","cdp.iot.t-mobile.nl" //Set vodafone PDP settings
AT+CFUN=1 //Enable antenna
AT+NBAND=8 //Set band to 8 (T-Mobile uses 8)
AT+CFUN=0 //Turn antenna off
AT+CFUN=1 //Turn antenna on (this appears to force a refresh and works best in practice)
AT+COPS=1,2,"20416" //Connect to T-Mobile

Now make sure you actually have connection to the base station.
Periodically check for base station signal strength and whether GPRS is attached
Wait for connection

AT+CSQ //Check for signal strength, the first or second variable should not be 99
AT+CGATT? //Check for GPRS attachment, should return 1

For sending an UDP package you need to open a socket after having connection
Socket

AT+NSOCR="DGRAM",17,16666,0 //Create a socket on port 16666 for sending and receiving datagrams (UDP)

Now that you’re connected, transmit a message
Transmit

AT+NSOSTF=0,"172.27.131.100",15683,0x200,12,"48656c6c6f20576f726c6421" //Send Hello world! , immediately stop transmitting after sending the command
//Make sure to enter your own ip and port!

Required module: R4XX
After uploading the passthrough sketch use the following commands to send a message
These commands communicate on the LTE-M Network of KPN NL

AT+CFUN=15
ATE0
AT+URAT=7
AT+CEREG=3
AT+CMEE=2
AT+CGDCONT=1,"IP","internet.m2m"
AT+COPS=1,2,"20408"
AT+CSQ (Wait for CSQ 99,99 means no signal)
AT+CGATT? (Wait for attach, 1 = attached)
AT+USOCR=17
AT+USOST=0,"YOURUDPSERVERIP",YOURUDPSERVERPORT,4,"Yes!"

Required module: R4XX
After uploading the passthrough sketch use the following commands to send a message
These commands communicate on the NB-IoT UDP Network of T-Mobile NL
Note: Your device must be registered as a UDP device and not as CoAP.

AT+URAT=8
AT+URAT?
AT+CMEE=2
AT+CGDCONT=1,"IP","cdp.iot.t-mobile.nl"
AT+CGDCONT?
AT+CFUN=1
AT+COPS=1,2,"20416"
AT+CSQ
AT+CREG=2
AT+CREG?
AT+CGPADDR
AT+USOCR=17
AT+USOST=0,"172.27.131.100",15683,4,"Data"
AT+USOCL=0

Required module: R4XX
After uploading the passthrough sketch use the following commands to send a message
These commands communicate on the NB-IoT Network of Vodafone NL

AT+URAT=8
AT+URAT?
AT+CMEE=2
AT+CGDCONT=1,"IP","nb.inetd.gdsp"
AT+CGDCONT?
AT+CFUN=1
AT+COPS=1,2,"20404"
AT+CSQ
AT+CREG=2
AT+CREG?
AT+CGPADDR
AT+USOCR=17
AT+USOST=0,"37.97.216.22",3000,4,"Data"
AT+USOCL=0

LSM303AGR

Download the Sodaq_LSM303AGR library from the Arduino Library Manager or from our GitHub.

/* Example for using the accelerometer with the Sodaq_LSM303AGR library */
/* The example is tested on an Arduino M0 and a Sodaq Explorer with a Sodaq NB-IoT shield */
/* This code prints accelerometer readings every second and registers whether the board is flipped by interrupt */
#include <Arduino.h>
#include <Sodaq_LSM303AGR.h>

Sodaq_LSM303AGR AccMeter;

// Print the debug information on the SerialUSB 
#define USB SerialUSB

// The interrupt pin for the Accelerometer is attached to D4
#define ACC_INT_PIN ACCEL_INT1

// Threshold for interrupt trigger
double threshold = -0.8;
int now = millis();

void setup() {
    USB.begin(9600);
    while ((!USB) && (millis() < 10000)) {
        // Wait 10 seconds for the Serial Monitor
    }

    // Start the I2C bug
    Wire.begin();

    AccMeter.rebootAccelerometer();
    delay(1000);

    // Enable the Accelerometer
    AccMeter.enableAccelerometer();

    // Attach interrupt event fot the Accelerometer
    pinMode(ACC_INT_PIN, INPUT);
    attachInterrupt(ACC_INT_PIN, interrupt_event, RISING);

    // Enable interrupts on the SAMD 
    GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(GCM_EIC) |
        GCLK_CLKCTRL_GEN_GCLK1 |
        GCLK_CLKCTRL_CLKEN;

    // If Z goes below threshold the interrupt is triggered
    AccMeter.enableInterrupt1(AccMeter.ZLow, threshold, 0, AccMeter.PositionRecognition);
}

void loop() {

    // Print sensor readings every second
    if ((now + 1000) < millis())
    {
        now = millis();
        read_AccMeter();
    }
}

void read_AccMeter()
{
    USB.print("x = ");
    USB.print(AccMeter.getX());

    USB.print("\ty = ");
    USB.print(AccMeter.getY());

    USB.print("\tz = ");
    USB.println(AccMeter.getZ());
}

void interrupt_event()
{
    // Do not print in an interrupt event when sleep is enabled.
    USB.println("Board flipped");
}

On the baseboard there is an userbutton attached to pin 2. The following sketch will lit the green led when the button is pushed.

#define BUTTON 2

void setup() {
  // Start serial connection
  SerialUSB.begin(9600);
  // Configure the button as an input and enable the internal pull-up resistor
  pinMode(BUTTON, INPUT_PULLUP);
  pinMode(LED_GREEN, OUTPUT);
}

void loop() {
  // Read the button value into a variable
  int sensorVal = digitalRead(BUTTON);
  // Print out the value of the button
  SerialUSB.println(sensorVal);

  // Turn on the LED when the Button is pushed
  if (sensorVal == HIGH) {
    digitalWrite(LED_GREEN, HIGH);
  }
  else {
    digitalWrite(LED_GREEN, LOW);
  }
}

Required items:
SODAQ SARA SFF
SODAQ SARA SFF BASEBOARD
PIR
LED

/*macro definitions of PIR motion sensor pin and LED pin*/
#define PIR_MOTION_SENSOR 8 //Use pin 8 to receive the signal from the module
#define LED 0 // Use pin 0 to activate the buzzer
#define POWER_SWITCH 3 // Use pin 3 to enable the switch row on the baseboard

void setup()
{
  SerialUSB.begin(9600);

  pinMode(PIR_MOTION_SENSOR, INPUT);
  pinMode(LED, OUTPUT);
  pinMode(POWER_SWITCH, OUTPUT);

  // Turn on the switched row
  digitalWrite(POWER_SWITCH, HIGH);
}

void loop()
{
  if (digitalRead(PIR_MOTION_SENSOR)) {
    SerialUSB.println("Movement detected!");
    digitalWrite(LED, HIGH);
  }
  else {
    digitalWrite(LED, LOW);
  }

  delay(200);
}

Required items:
SODAQ SARA SFF
SODAQ SARA SFF BASEBOARD
TPH

Connect the TPH sensor to one of the two I2C connectors.

Install the required libraries:

include library

lib1

lib2

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME280 bme; // I2C

void setup() {
  SerialUSB.begin(9600);
  SerialUSB.println(F("BME280 test"));

  if (!bme.begin()) {
    SerialUSB.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }
}

void loop() {
  SerialUSB.print("Temperature = ");
  SerialUSB.print(bme.readTemperature());
  SerialUSB.println(" *C");

  SerialUSB.print("Pressure = ");

  SerialUSB.print(bme.readPressure() / 100.0F);
  SerialUSB.println(" hPa");

  SerialUSB.print("Approx. Altitude = ");
  SerialUSB.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
  SerialUSB.println(" m");

  SerialUSB.print("Humidity = ");
  SerialUSB.print(bme.readHumidity());
  SerialUSB.println(" %");

  SerialUSB.println();
  delay(2000);
}

Required items:
SODAQ SARA SFF
SODAQ SARA SFF BASEBOARD
Ultrasonic Ranger
Buzzer

Install the required libraries:

include library

#include "Ultrasonic.h"

#define POWER_SWITCH 3 // Use pin 3 to enable the switch row on the baseboard
#define BUZZER 8
#define MIN_DISTANCE 20 // cm

Ultrasonic ultrasonic(0);

void setup()
{
  SerialUSB.begin(9600);

  pinMode(BUZZER, OUTPUT);
  pinMode(POWER_SWITCH, OUTPUT);

  // Turn on the switched row
  digitalWrite(POWER_SWITCH, HIGH);
}

void loop()
{
  long RangeInInches;
  long RangeInCentimeters;

  SerialUSB.println("The distance to obstacles in front is: ");

  //RangeInInches = ultrasonic.MeasureInInches();
  //SerialUSB.print(RangeInInches);//0~157 inches
  //SerialUSB.println(" inch");
  //delay(250);

  RangeInCentimeters = ultrasonic.MeasureInCentimeters(); // two measurements should keep an interval
  SerialUSB.print(RangeInCentimeters);//0~400cm
  SerialUSB.println(" cm");

  if (RangeInCentimeters < MIN_DISTANCE)
  {
    SerialUSB.println("You are too close!");
    digitalWrite(BUZZER, HIGH);
  }
  else {
    digitalWrite(BUZZER, LOW);
  }

  delay(250);
}

#include <Wire.h>
#include <Sodaq_wdt.h>
#include <Sodaq_LSM303AGR.h>

Sodaq_LSM303AGR accelerometer;

void setup() {

  // Bootup delay to programm the board.
  delay(5000);

  Wire.begin();// I2C for the accelerometer

  // Disable the LSM303AGR
  accelerometer.disableAccelerometer();
  accelerometer.disableMagnetometer();

  pinMode(MAG_INT, OUTPUT);
  pinMode(GPS_ENABLE, OUTPUT);
  pinMode(SARA_ENABLE, OUTPUT);

  digitalWrite(MAG_INT, LOW); // we need to make this low otherwise this pin on the LSM303AGR starts leaking current
  digitalWrite(GPS_ENABLE, LOW); // low=poweredoff, high=poweredon
  digitalWrite(SARA_ENABLE, LOW); // low=poweredoff, high=poweredon

  //this code is needed to setup watchdogtimer and to make MCU sleep
  sodaq_wdt_enable(WDT_PERIOD_8X); // watchdog expires in ~8 seconds
  sodaq_wdt_reset(); // restting the watchdog

  initSleep();

  SerialUSB.flush();
  SerialUSB.end();
  USBDevice.detach();
  USB->DEVICE.CTRLA.reg &= ~USB_CTRLA_ENABLE; // Disable USB
}

void loop() {
  sodaq_wdt_reset(); // restting the watchdog
  //digitalWrite(LED_BUILTIN, HIGH);
  //sodaq_wdt_safe_delay(10);
  //digitalWrite(LED_BUILTIN, LOW);

  systemSleep();
}

/**
  Initializes the CPU sleep mode.
*/
void initSleep()
{
  // Set the sleep mode
  SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
}

/**
  Powers down all devices and puts the system to deep sleep.
*/
void systemSleep()
{

  __WFI(); // SAMD sleep

}

/** Note: When your board is in sleep, or does not react anymore. You can get it back to life to double press the reset button.
*/

In the latest update we made the SODAQ Universal Tracker ready for the SODAQ SARA SFF.

NB-IoT UDP
The tracker software only works with UDP and NOT with CoAP.

 

Need Help?

Ask your question on our forum.