<Back to home

Getting Started Guide

Version 1.0


Table of Contents

  1. Overview
    1. Introduction
    2. Power
    3. LoRa module
    4. Plug and Play Conectors
    5. Expansion Pin Header
  2. Syxsens Pinout
  3. Installing Arduino IDE
  4. Configuring Arduino IDE
  5. Arduino Examples
    1. Blinky
    2. Digital Light Sensor
    3. Atmospheric Sensor
    4. Sound Sensor
    5. Web Server
    6. LoRa Examples
  6. Installing PlatformIO
  7. Flashing the Arduino Bootloader

Overview #back to top

Introduction

Syxsens is a development board designed to build wide area sensor networks for the Internet of Things. The board's main component is an Atmel ATSAMD21G18A microcontroller, the same one featured on the Arduino Zero. This makes Syxsens fully compatible with the Arduino framework, which allows to take advantage of the vast amount of open source software libraries available for sensors and actuators. The following image shows the device components:

Syxsens components

Power

Syxsens is powered by a USB connector which also serves for firmware uploading. The voltage is regulated by a low quiescent current low-dropout regulator, yet capable of providing up to 1A of current for powering demanding sensors and actuators. The circuit is protected from overcurrent faults by a resettable fuse. In addition to the 5V provided by the USB interface, the board can be powered with 3.3V directly on the pin header. When the board is powered, a red LED labeled as "PWR" is turned on. The LED is connected to ground though an 0 Ohm resitor acting as a solder bridge "SB" which can be removed to save power.

LoRa Module

Syxsens also contains a NiceRF LoRa module based on the Semtech SX1278 chip at 433 MHz. The LoRa module is connected to one of the SPI serial interfaces on the MCU, including the DIO0 and DIO1 pins. The rest of the digital input/output pins of the LoRa module are available on the pin headers. The LoRa module antenna is connected to an onboard IPEX connector.

Plug and Play Conectors

Syxsens also features six connectors to plug sensor breakout boards such as the ones provided by Seeed Studio and Elecrow. The sensors can be analog, digital, I2C or UART. The UART connector can also allocate a WiFi module, which allows the board to support cloud connectivity.

Expansion pin header

The rest of ATSAMD21G18A pins can be accessed from the pin header connector on the board which can be used to connect expansion boards or shields. The MCU SWD interface can also be found on the pin headers which allows an external J-Link compatible programmer/debugger to be connected. Furthermore, the digital IOs from the LoRa module can also be found there.

Syxsens Pinout #back to top

Before starting to write code let's take a look at the Syxsens pins and labels.

Syxsens pinout

Installing the Arduino IDE#back to top

In order to program the software that will run on the Syxsens board, you need an Integrated Development Environment (IDE). We will use the Arduino IDE which is very popular and has lots of examples available on the Web.

First, download the Arduino IDE according to your operating system. It is recommended to download the latest version available.

Download Arduino IDE

Download Arduino IDE

Once downloaded, install it like you would install any other software on your operating system. You may run the Arduino IDE to make sure that it installed OK. You will find a window similar to this:

Run Arduino IDE

Configuring Arduino IDE#back to top

Syxsens is fully compatible with Arduino Zero. Therefore we can use it as if it was an Arduino Zero without any problem. First, you need to add the Atmel SAMD Core to the Arduino IDE. Go to:

Tools -> Boards -> Boards Manager

Select Board Manager

Then select the Arduino SAMD Boards package (Cortex M0+) and click in the Install button.

Install SAMD Cortex M0+ package

After installation, you should be able to select in the menu:

Tools -> Board -> Arduino/Genuino Zero (Native USB Port)

Select Arduino Zero

Now you can connect the Syxsens board with the computer using a USB cable. The PWR led should turn on.

Syxsens powered on

When the Syxsens board is connected to the computer, the USB serial driver is loaded automatically on Mac OS and Linux. On Windows, you may be prompted to install drivers. Browse to the Arduino Drivers folder and install the drivers.

Install drivers

Select the USB port where Syxsens is connected:

Tools -> Port -> COMX(Arduino/Genuino Zero (Native USB Port))

Select USB port

You are now ready to program and upload code to Syxsens.

Examples#back to top

Here are a few examples to test the features available in Syxsens.

Blinky

The first example is the blinky demonstration, where the built in LED blinks each second. The built in LED is connected to pin 6.

                                #define LED_BUILTIN 6
                                void setup() {
                                  // Set LED_BUILTIN pin as output.
                                  pinMode(LED_BUILTIN, OUTPUT);
                                }

                                void loop() {
                                  digitalWrite(LED_BUILTIN, HIGH);   // Turn the LED on
                                  delay(1000);                       // Wait for a second
                                  digitalWrite(LED_BUILTIN, LOW);    // Turn the LED off
                                  delay(1000);                       // wait for a second
                                }
                              

Digital Light Sensor

The digital light sensor TSL2561 is an I2C compatible sensor for measuring the intensity of surrounding light. You can find breakout boards for this sensor on the following links:
Crowtail- Digital Light Sensor
Grove - Digital Light Sensor

To program the sensor, we are going to use the Grove - Digital Light Sensor library available here:
Grove - Digital Light Sensor library

Download the zip file containing the library and unzip it into the libraries folder of your Arduino directory. Now let's take a look at the code:

                                #include <Wire.h>
                                #include <Digital_Light_TSL2561.h>

                                void setup()
                                {
                                  Wire.begin();
                                  SerialUSB.begin(9600);
                                  while (!SerialUSB) {
                                    ;//Wait for SerialUSB port to connect
                                  }
                                  TSL2561.init();
                                }

                                void loop()
                                {
                                  SerialUSB.print("The Light value is: ");
                                  SerialUSB.println(TSL2561.readVisibleLux());
                                  delay(1000);
                                }
                                

Atmospheric Sensor

In this example, we are going to use the BME280 sensor to measure temperature, humidity and barometric pressure. Just plug the 4 pin connector from the sensor breakout board to any of the I2C connectors on Syxsens. The sensor breakout boards can be found in the following stores:
Crowtail- BME280 Atmospheric Sensor
Grove - Temp&Humi&Barometer Sensor (BME280)

In order to program the sensor, we will use the SparkFun BME280 Arduino Library available here:
SparkFun BME280 Arduino Library

Download the zip file containing the library. To install the library copy the unzipped folder into the libraries directory of your Arduino folder. Now we are ready to code the example:

                                      #include "SparkFunBME280.h"
                                      #include <Wire.h>

                                      BME280 mySensor;

                                      void setup()
                                      {
                                        Wire.begin();
                                        SerialUSB.begin(9600);
                                        while (!SerialUSB) {
                                          ; //Wait for serial port to connect
                                        }
                                        mySensor.settings.commInterface = I2C_MODE;
                                        mySensor.settings.I2CAddress = 0x77;
                                        mySensor.settings.runMode = 3; //Normal mode
                                        mySensor.settings.tStandby = 0;
                                        mySensor.settings.filter = 0;
                                        mySensor.settings.tempOverSample = 1;
                                        mySensor.settings.pressOverSample = 1;
                                        mySensor.settings.humidOverSample = 1;
                                        delay(10);  //Make sure sensor had enough time to turn on. BME280 requires 2ms to start up.
                                        SerialUSB.println(mySensor.begin(), HEX);

                                        SerialUSB.print("Displaying ID, reset and ctrl regs\n");

                                        SerialUSB.print("ID(0xD0): 0x");
                                        SerialUSB.println(mySensor.readRegister(BME280_CHIP_ID_REG), HEX);
                                        SerialUSB.print("Reset register(0xE0): 0x");
                                        SerialUSB.println(mySensor.readRegister(BME280_RST_REG), HEX);
                                        SerialUSB.print("ctrl_meas(0xF4): 0x");
                                        SerialUSB.println(mySensor.readRegister(BME280_CTRL_MEAS_REG), HEX);
                                        SerialUSB.print("ctrl_hum(0xF2): 0x");
                                        SerialUSB.println(mySensor.readRegister(BME280_CTRL_HUMIDITY_REG), HEX);

                                        SerialUSB.print("\n\n");

                                        SerialUSB.print("Displaying all regs\n");
                                        uint8_t memCounter = 0x80;
                                        uint8_t tempReadData;
                                        for(int rowi = 8; rowi < 16; rowi++ )
                                        {
                                          SerialUSB.print("0x");
                                          SerialUSB.print(rowi, HEX);
                                          SerialUSB.print("0:");
                                          for(int coli = 0; coli < 16; coli++ )
                                          {
                                            tempReadData = mySensor.readRegister(memCounter);
                                            SerialUSB.print((tempReadData >> 4) & 0x0F, HEX);//Print first hex nibble
                                            SerialUSB.print(tempReadData & 0x0F, HEX);//Print second hex nibble
                                            SerialUSB.print(" ");
                                            memCounter++;
                                          }
                                          SerialUSB.print("\n");
                                        }

                                        SerialUSB.print("\n\n");

                                        SerialUSB.print("Displaying concatenated calibration words\n");
                                        SerialUSB.print("dig_T1, uint16: ");
                                        SerialUSB.println(mySensor.calibration.dig_T1);
                                        SerialUSB.print("dig_T2, int16: ");
                                        SerialUSB.println(mySensor.calibration.dig_T2);
                                        SerialUSB.print("dig_T3, int16: ");
                                        SerialUSB.println(mySensor.calibration.dig_T3);

                                        SerialUSB.print("dig_P1, uint16: ");
                                        SerialUSB.println(mySensor.calibration.dig_P1);
                                        SerialUSB.print("dig_P2, int16: ");
                                        SerialUSB.println(mySensor.calibration.dig_P2);
                                        SerialUSB.print("dig_P3, int16: ");
                                        SerialUSB.println(mySensor.calibration.dig_P3);
                                        SerialUSB.print("dig_P4, int16: ");
                                        SerialUSB.println(mySensor.calibration.dig_P4);
                                        SerialUSB.print("dig_P5, int16: ");
                                        SerialUSB.println(mySensor.calibration.dig_P5);
                                        SerialUSB.print("dig_P6, int16: ");
                                        SerialUSB.println(mySensor.calibration.dig_P6);
                                        SerialUSB.print("dig_P7, int16: ");
                                        SerialUSB.println(mySensor.calibration.dig_P7);
                                        SerialUSB.print("dig_P8, int16: ");
                                        SerialUSB.println(mySensor.calibration.dig_P8);
                                        SerialUSB.print("dig_P9, int16: ");
                                        SerialUSB.println(mySensor.calibration.dig_P9);

                                        SerialUSB.print("dig_H1, uint8: ");
                                        SerialUSB.println(mySensor.calibration.dig_H1);
                                        SerialUSB.print("dig_H2, int16: ");
                                        SerialUSB.println(mySensor.calibration.dig_H2);
                                        SerialUSB.print("dig_H3, uint8: ");
                                        SerialUSB.println(mySensor.calibration.dig_H3);
                                        SerialUSB.print("dig_H4, int16: ");
                                        SerialUSB.println(mySensor.calibration.dig_H4);
                                        SerialUSB.print("dig_H5, int16: ");
                                        SerialUSB.println(mySensor.calibration.dig_H5);
                                        SerialUSB.print("dig_H6, uint8: ");
                                        SerialUSB.println(mySensor.calibration.dig_H6);

                                        SerialUSB.println();
                                      }

                                      void loop()
                                      {

                                        SerialUSB.print("Temperature: ");
                                        SerialUSB.print(mySensor.readTempC(), 2);
                                        SerialUSB.println(" degrees C");

                                        SerialUSB.print("Pressure: ");
                                        SerialUSB.print(mySensor.readFloatPressure(), 2);
                                        SerialUSB.println(" Pa");

                                        SerialUSB.print("Altitude: ");
                                        SerialUSB.print(mySensor.readFloatAltitudeMeters(), 2);
                                        SerialUSB.println("m");

                                        SerialUSB.print("%RH: ");
                                        SerialUSB.print(mySensor.readFloatHumidity(), 2);
                                        SerialUSB.println(" %");
                                        delay(1000);
                                      }

Sound Sensor

The sound level sensor can be used to detect noises and activate doors or lights. You can also implement a basic sound level meter to indicate when the environmental noise is so loud that might cause hear loss. In this example we are going to use the breakout board available here:
Grove - Sound Sensor

Plug the sensor board connector to one of the analog inputs, for example A1/A2. Now let's take a look at the code:

                                    const int pinAdc = A1; // A1/A2 connector

                                    void setup()
                                    {

                                      SerialUSB.begin(115200);
                                       while (!SerialUSB) {
                                        ;//Wait for serial port to connect
                                      }
                                    }

                                    void loop()
                                    {
                                        long sum = 0;
                                        for(int i=0; i<32; i++)
                                        {
                                            sum += analogRead(pinAdc);
                                        }

                                        sum >>= 5;

                                        SerialUSB.println(sum);
                                        delay(10);
                                    }
                                  

You can see the analog input waveform with the Arduino Serial Plotter which can be found in the Tools menu.


Web Server

Syxsens can also work as a Web Server and communicate with the Internet with the help of a Wi-Fi module. This allows the board to serve as a bridge between a local sensor network and a cloud server. This way, we can implement Internet of Things applications. In this time, we will use the Wi-Fi module based on the ESP8266 chip. You can find a breakout board with plugabble connector on these sites:
Crowtail- Serial Wifi
Grove - Uart Wifi

Plug the Wi-Fi breakout board to the UART connector on Syxsens. The UART connector is linked to the Serial1 Arduino class. The following code implements a Wi-Fi Access Point (AP). You can use a computer or mobile device to connect to the AP with SSID "ESP_XXXXXX", where XXXXXX varies for each Wi-Fi module. Then, connect to the AP IP address which is shown in the Serial Monitor (usually 192.168.4.1). If everything works correctly you should see "Hello World". Now, let's check out the code:

                                    #define DEBUG true
                                    #define esp8266 Serial1

                                    void setup()
                                    {
                                      SerialUSB.begin(9600);
                                       while (!SerialUSB) {
                                        ; // wait for serial port to connect
                                      }
                                      SerialUSB.println("Syxsens Webserver");
                                      esp8266.begin(115200); // your esp's baud rate might be different
                                      sendData("AT+RST\r\n",2000,DEBUG); // reset module
                                      sendData("AT+CWMODE=2\r\n",1000,DEBUG); // configure as access point
                                      sendData("AT+CIFSR\r\n",1000,DEBUG); // get ip address
                                      sendData("AT+CIPMUX=1\r\n",1000,DEBUG); // configure for multiple connections
                                      sendData("AT+CIPSERVER=1,80\r\n",1000,DEBUG); // turn on server on port 80
                                    }

                                    void loop()
                                    {
                                      if(esp8266.available()) // check if the esp is sending a message
                                      {

                                        while(esp8266.available())
                                        {
                                          // The esp has data so display its output to the serial window
                                          char c = esp8266.read(); // read the next character.
                                          SerialUSB.write(c);
                                        }

                                        if(esp8266.find("+IPD,"))
                                        {
                                         delay(1000);

                                         int connectionId = esp8266.read()-48; // subtract 48 because the read() function returns
                                                                               // the ASCII decimal value and 0 (the first decimal number) starts at 48

                                         String webpage = "

Hello World!

"; String cipSend = "AT+CIPSEND="; cipSend += connectionId; cipSend += ","; cipSend +=webpage.length(); cipSend +="\r\n"; sendData(cipSend,1000,DEBUG); sendData(webpage,1000,DEBUG); String closeCommand = "AT+CIPCLOSE="; closeCommand+=5; // append connection id closeCommand+="\r\n"; sendData(closeCommand,3000,DEBUG); } } } String sendData(String command, const int timeout, boolean debug) { String response = ""; esp8266.print(command); // send the read character to the esp8266 long int time = millis(); while( (time+timeout) > millis()) { while(esp8266.available()) { // The esp has data so display its output to the serial window char c = esp8266.read(); // read the next character. response+=c; } } if(DEBUG) { SerialUSB.print(response); } return response; }

LoRa Examples

Syxsens has a LoRa module on board which is connected to one of the SPI interfaces available on the SAMD21 MCU. In order to use LoRa communications, first download the LoRa library which has been configured to work with the on board LoRa module:
Syxsens LoRa library

Once downloaded, unzip the file in the libraries folder of your Arduino directory and restart Arduino IDE. Now we are ready to check the examples.

LoRa Send

In order to send LoRa raw packets, first the module is initialized with LoRa.begin(). The argument of this function is the frequency of the LoRa module, in this case 434MHz. The packet to send is initialized with the LoRa.beginPacket() function. The packet is filled with data using the print() function which is inherited from the Stream Arduino class. Once the packet is completed, it is finalized and transmitted using the LoRa.endPacket() function.

                                    #include <SPI.h>
                                    #include <LoRa.h>

                                    int counter = 0;

                                    void setup() {
                                      SerialUSB.begin(9600);
                                      SerialUSB.println("LoRa Sender");

                                      if (!LoRa.begin(434E6)) {
                                        SerialUSB.println("Starting LoRa failed!");
                                        while (1);
                                      }
                                    }

                                    void loop() {
                                      SerialUSB.print("Sending packet: ");
                                      SerialUSB.println(counter);

                                      //Send packet
                                      LoRa.beginPacket();
                                      LoRa.print("hello ");
                                      LoRa.print(counter);
                                      LoRa.endPacket();

                                      counter++;

                                      delay(1000);
                                    }
                                  

LoRa Receive

The LoRa receiving procedure begins by initializing the LoRa module using LoRa.begin() and the transmission frequency (434MHz). The program then checks if any packets have arrived and receives them using the LoRa.parsePacket() function. Next, the program reads all the available packets one by one by looping until there are no more packets using the LoRa.available() and LoRa.read() functions. Finally, the packets are printed to the serial monitor along with the received signal strength indicator (RSSI).

                                      #include <SPI.h>
                                      #include <LoRa.h>

                                      void setup() {
                                        SerialUSB.begin(9600);
                                        while (!SerialUSB); //Wait for serial monitor connection

                                        SerialUSB.println("LoRa Receiver");

                                        if (!LoRa.begin(434E6)) {
                                          SerialUSB.println("Starting LoRa failed!");
                                          while (1);
                                        }
                                      }

                                      void loop() {
                                        //Parse packet
                                        int packetSize = LoRa.parsePacket();
                                        if (packetSize) {
                                          //Received a packet
                                          SerialUSB.print("Received packet '");

                                          //Read packet
                                          while (LoRa.available()) {
                                            SerialUSB.print((char)LoRa.read());
                                          }

                                          //Print RSSI of packet
                                          SerialUSB.print("' with RSSI ");
                                          SerialUSB.println(LoRa.packetRssi());
                                        }
                                      }
                                    

Installing PlatformIO#back to top

PlatformIO is an Integrated Development Environment (IDE) that can be used as a more professional alternative to the Arduino IDE. It has support for project folders as well as debugging capabilites. We are now going to install and configure PlatformIO to use with Syxsens. First download the Atom open source text editor from which PlatformIO is based:
Download Atom text editor from here

Open the Atom Welcome Guide and click on Install a Package, then click on Open Installer. In the search bar enter "platformio". From the search results Install the platformio-ide and the platform-ide-terminal packages. Let the installation complete. If you are on Windows you might be prompted to install Python 2.7 separately. Once installed, you are greeted with a welcome screen. You should also have a PlatformIO menu in the toolbar.

PlatformIO Welcome Screen

Creating a project

To create a new project click on the "New Project" button in the welcome screen. For Board chose "Arduino Zero" and select "Arduino" as Framework. Select board and framework Once the project is initialized, open the main.cpp file in the src folder on the Project navigation pane. You may then copy and paste any of the examples above. Make sure you include the Arduino.h header file in the main.cpp code. For example, the blink example on PlatformIO is done like this:

                                              #include <Arduino.h>

                                              #define LED_BUILTIN 6
                                              void setup() {
                                              // Set LED_BUILTIN pin as output.
                                              pinMode(LED_BUILTIN, OUTPUT);
                                              }

                                              void loop() {
                                              digitalWrite(LED_BUILTIN, HIGH);   // Turn the LED on
                                              delay(1000);                       // Wait for a second
                                              digitalWrite(LED_BUILTIN, LOW);    // Turn the LED off
                                              delay(1000);                       // wait for a second
                                              }
                                          

Connect a Syxsens board to the computer using a USB cable, and click on the Upload button on the left toolbar. You should see the orange LED blinking.

Installing libraries

PlatformIO has a built in library manager that allows to install sensor libraries in a easy way. To install a library, click on the Libraries button in the PlatformIO Home or Welcome Screen. Then search for the library you want to install. On the search results click on the library of interest and click on the "Install" button. The library is installed and can be accessed from the main.cpp file. Usually examples are provided. Some modifications to the SERCOM interfaces might be necesary to adapt the library to work with Syxsens. For more information contact support.

Flashing the Arduino Bootloader#back to top

The Arduino bootloader is a firmware image that is flashed into the SAMD21 MCU and allows Syxsens to be programmed from the native USB port. If the bootloader is not present, the only way to program the board is using the SWD pins on the header. The bootloader comes preloaded on the board when the board ships to the user, however sometimes you might need to reflash the bootloader yourself. In order to do that we are going to need a J-Link compatible SWD programmer such as the one the following picture:

Jlink programmer

To use the Jlink programmer, we need to download the Jlink software for Linux and Mac. For Windows, we need to use Atmel Studio.
Download JLink software for Mac and Linux
Download Atmel Studio for Windows

Connect the Jlink device to the SWD pins of the Syxsens board:

Syxsens Jlink hookup
Syxsens pin JLink pin
SWDIO SWDIO (Pin #7)
SWDCLK SWDCLK (Pin #9)
3.3V VTref (Pin #1)
GND GND (Pin #4)

Power up the Syxsens board using a USB cable connected to the micro USB port.

Now we need to flash the bootloader hex file into the MCU, we can use JLinkExe command line tools on Mac and Linux or the Device Programming Wizard from Atmel Studio. The bootloader image can be downloaded from here:
Download Arduino Bootloader HEX file

Once flashed, we disconnect the Syxsens board and the JLink device from the computer and connect the Syxsens board to the USB board again. We should see now that there is a USB interface that can be selected from the Port menu in the Arduino IDE and that corresponds to the newely flashed Arduino bootloader on Syxsens. We can test that everything is OK by uploading a sketch such as the Blinky example from above. If all is good we should see orange LED blinking and we can use the Arduino or PlatformIO IDEs to program our board. This same setup can be used to do professional debugging with Atmel Studio.