Version 1.0
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 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.
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.
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.
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.
Before starting to write code let's take a look at the Syxsens pins and labels.
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.
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:
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
Then select the Arduino SAMD Boards package (Cortex M0+) and click in the Install button.
After installation, you should be able to select in the menu:
Tools -> Board -> Arduino/Genuino Zero (Native USB Port)
Now you can connect the Syxsens board with the computer using a USB cable. The PWR led should turn 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.
Select the USB port where Syxsens is connected:
Tools -> Port -> COMX(Arduino/Genuino Zero (Native USB Port))
You are now ready to program and upload code to Syxsens.
Here are a few examples to test the features available in Syxsens.
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 }
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); }
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); }
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.
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; }
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.
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); }
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()); } }
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.
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.
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.
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.
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:
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 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.