Examples

From openCanSat wiki
Jump to: navigation, search

In this section you can find basic examples of the kit's capabilities. Feel free to use pieces of these in your own code. All the examples are included in the openCanSat library which you have already downloaded. Just head over to File > Examples > openCanSat kit

Power monitor (INA 219)

The INA219 is a current shunt and power monitor. The device monitors both shunt voltage drop and bus supply voltage with programmable conversion times and filtering. A programmable calibration value, combined with internal multiplier, enables direct readouts of current in amperes.


#include <Adafruit_INA219.h>
#define Serial SerialUSB

Adafruit_INA219 ina219;

int ms_delay = 500; 

float voltage_shunt = 0;
float voltage_bus = 0;
float current_mA = 0;
float voltage_load = 0;
  
void setup(void) 
{ 
  Serial.begin(115200);

  while(!Serial);
  
  Serial.println("CANSAT kit INA219 test.");
  Serial.println(); 
  
  ina219.begin();
}

void loop(void) 
{
  voltage_shunt = ina219.getShuntVoltage_mV();
  voltage_bus = ina219.getBusVoltage_V();
  current_mA = ina219.getCurrent_mA();
  voltage_load = voltage_bus + (voltage_shunt / 1000);

  Serial.println("Shunt Voltage: " + (String) voltage_shunt + " mV"); 
  Serial.println("Bus Voltage: " + (String) voltage_bus + " V");
  Serial.println("Current: " + (String) current_mA + " mA");  
  Serial.println("Load Voltage: " + (String) voltage_load + " V"); 
  Serial.println(); 

  delay(ms_delay);
}

Initialization

Inclusion of required libraries Adafruit_INA219.h [[1]] which support functions for INA219 Datasheet for INA219.

#include <Adafruit_INA219.h>

We also define official USB serial console for Arduino SAMD core.

#define Serial SerialUSB

We create an object ina219, which will be used to access library methods by a dot notation [[2]].

Adafruit_INA219 ina219;

The number of milliseconds between the measurements is defined by the variable ms_delay.

int ms_delay = 500; 
float voltage_shunt = 0;
float voltage_bus = 0;
float current_mA = 0;
float voltage_load = 0;

After including libraries and defining variables, we can start with a setup function.

Setup

void setup(void) 
{ 

Serial communications start with speed of 115200 baud

Serial.begin(115200);

The following line ensures that the serial comm connects. Comment it out for usage without a USB communication.

while(!Serial);

At the start of our program is nice to have control and information status.

 
Serial.println("CANSAT kit INA219 test.");

Begin communication with ina219.

 
ina219.begin();

The last bracket is for ending a setup loop.

 
}

Loop

 
void loop(void) 
{

Reading values from INA219 into variables.

 
voltage_shunt = ina219.getShuntVoltage_mV();
voltage_bus = ina219.getBusVoltage_V();
current_mA = ina219.getCurrent_mA();
voltage_load = voltage_bus + (voltage_shunt / 1000);

Printing measured values stored in variables into Serial Line.

 
Serial.println("Shunt Voltage: " + (String) voltage_shunt + " mV"); 
Serial.println("Bus Voltage: " + (String) voltage_bus + " V");
Serial.println("Current: " + (String) current_mA + " mA");  
Serial.println("Load Voltage: " + (String) voltage_load + " V"); 
Serial.println();

Delay between next measurement.

 
delay(ms_delay);

Last bracket is for ending a loop.

 
}

Info

More info about understanding the INA219 I2C Current/Power Monitor: [[3]].

Pressure and temperature (BME280)

This is an example of getting temperature, pressure, and humidity from sensor BME280.

Code

#include <Adafruit_BME280.h>
#include <SPI.h>

#define Serial SerialUSB
#define BME280_ADDRESS 0x77
#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME280 bme; 

int ms_delay = 500;

float temperature_bme280 = 0;
float pressure_bme280 = 0;
float altitude_bme280 = 0;
float humidity_bme280 = 0;

void setup() 
{
    Serial.begin(9600); 
    while(!Serial);
    
    Serial.println("CANSAT kit BME280 test started.");
    
    if (!bme.begin(BME280_ADDRESS)) 
    {
        Serial.println("Could not find a valid BME280 sensor, check wiring!");
        return;
    }

    Serial.println();
}

void loop() 
{ 
  temperature_bme280 = bme.readTemperature();
  pressure_bme280 = bme.readPressure() / 100.0F;
  altitude_bme280 = bme.readAltitude(SEALEVELPRESSURE_HPA);
  humidity_bme280 = bme.readHumidity();

  Serial.println("Temperature = " + (String) temperature_bme280 + " °C");  
  Serial.println("Pressure = " + (String) pressure_bme280 + " hPa");
  Serial.println("Approx altitude = " + (String) altitude_bme280 + " m");
  Serial.println("Humidity = " + (String) humidity_bme280 + " %");
  Serial.println();
    
  delay(ms_delay);
}

Initialization

Including of required libraries Adafruit_BME280.h [[4]] which support functions for BME280 Datasheet for BME280.

#include <Adafruit_BME280.h>

We also define official USB serial console for Arduino SAMD core.

#define Serial SerialUSB

The address of BME280 is for CanSat Kit 0x77, we will define BME280_ADDRESS for this value. Also, sea level pressure SEALEVELPRESSURE_HPA is defined as value 1013.25 [[5]].

#define BME280_ADDRESS 0x77
#define SEALEVELPRESSURE_HPA (1013.25)

We create object bme, which will be used to access library methods by a dot notation.

Adafruit_BME280 bme; 

The number of milliseconds between the measurements is defined by the variable ms_delay.

int ms_delay = 500;

Variables for temperature, pressure, altitude and humidity are prepared for reading data from BME280.

float temperature_bme280 = 0;
float pressure_bme280 = 0;
float altitude_bme280 = 0;
float humidity_bme280 = 0;

After including libraries and defining variables, we can start with a setup function.

Setup

void setup() 
{

Serial communications start on baud speed 9600 and program will wait until serial line for communication is ready.

Serial.begin(9600);   
while(!Serial);

At the start of our program is nice to have control and information status.

    
Serial.println("CANSAT kit BME280 test started.");

Begin communication with bme280 on specific define address BME280_ADDRESS (0x77). In case of failure print error info into Serial Line.

     
if (!bme.begin(BME280_ADDRESS)) 
{
  Serial.println("Could not find a valid BME280 sensor, check wiring!");
  return;
}

Print empty line for better orientation in Serial Monitor.

     
Serial.println();

Last bracket is for ending a setup.

     
}

Loop

 
void loop(void) 
{

Reading values from BME280 into variables.

 
temperature_bme280 = bme.readTemperature();
pressure_bme280 = bme.readPressure() / 100.0F;
altitude_bme280 = bme.readAltitude(SEALEVELPRESSURE_HPA);
humidity_bme280 = bme.readHumidity();

Printing measured values stored in variables into Serial Line.

 
Serial.println("Temperature = " + (String) temperature_bme280 + " °C");  
Serial.println("Pressure = " + (String) pressure_bme280 + " hPa");
Serial.println("Approx altitude = " + (String) altitude_bme280 + " m");
Serial.println("Humidity = " + (String) humidity_bme280 + " %");
Serial.println();

Wait time for next measurement in milliseconds.

 
delay(ms_delay);

Last bracket is for ending a loop.

 
}

Info

More information about BME280 accuracy can be found here [[6]].

Pressure and temperature (BMP280)

This is an example of getting temperature, pressure and approximate altitude from sensor BMP280.

Code

#include <Adafruit_BMP280.h>

#define Serial SerialUSB

#define BMP280_ADDRESS 0x76

Adafruit_BMP280 bmp; 

int ms_delay = 2000;

float temperature_bmp280 = 0;
float pressure_bmp280 = 0;
float altitude_bmp280 = 0;

void setup() 
{
  Serial.begin(9600);
  while(!Serial);
  
  Serial.println("CANSAT kit BMP280 test started.");
  
  if (!bmp.begin(BMP280_ADDRESS, BMP280_CHIPID)) 
  {  
    Serial.println("Could not find a valid BMP280 sensor, check wiring!");
    return;
  }

  Serial.println();
}

void loop() 
{
    temperature_bmp280 = bmp.readTemperature();
    pressure_bmp280 = bmp.readPressure();
    altitude_bmp280 = bmp.readAltitude(1013.25);
  
    Serial.println("Temperature = " + (String) temperature_bmp280 + " *C");  
    Serial.println("Pressure = " + (String) pressure_bmp280 + " Pa");
    Serial.println("Approx altitude = " + (String) altitude_bmp280 + " m");
    Serial.println();
    
    delay(ms_delay);
}

Initialization

Including of required libraries Adafruit_BMP280.h [[7]] which support functions for BMP280 [Datasheet for BME280].

#include <Adafruit_BMP280.h>

We also define official USB serial console for Arduino SAMD core.

#define Serial SerialUSB

The address of BMP280 is for CanSat Kit 0x76, we will define BMP280_ADDRESS for this value.

#define BMP280_ADDRESS 0x76

We create object bmp, which will be used to access library methods by a dot notation [[8]].

Adafruit_BMP280 bmp; 

The number of milliseconds between the measurements is defined by the variable ms_delay.

int ms_delay = 2000;

Variables for temperature, pressure, and altitude are prepared for reading data from BMP280.

float temperature_bmp280 = 0;
float pressure_bmp280 = 0;
float altitude_bmp280 = 0;

Setup

void setup() 
{

Serial communications start on baud speed 9600 and program will wait until serial line for communication is ready.

Serial.begin(9600);
while(!Serial);

At the start of our program is nice to have control and information status

Serial.println("CANSAT kit BMP280 test started.");

Begin communication with bme280 on specific define address BMP280_ADDRESS (0x76) and default BMP280_CHIPID from the library. In case of failure print error info into Serial Line.

if (!bmp.begin(BMP280_ADDRESS, BMP280_CHIPID)) 
{  
  Serial.println("Could not find a valid BMP280 sensor, check wiring!");
  return;
}

Print empty line for better orientation in Serial Monitor.

Serial.println();

The last bracket is for ending a setup.

}

Loop

void loop() 
{

Reading values from BMP280 into variables.

temperature_bmp280 = bmp.readTemperature();
pressure_bmp280 = bmp.readPressure();
altitude_bmp280 = bmp.readAltitude(1013.25);

Printing measured values stored in variables into Serial Line.

Serial.println("Temperature = " + (String) temperature_bmp280 + " *C");  
Serial.println("Pressure = " + (String) pressure_bmp280 + " Pa");
Serial.println("Approx altitude = " + (String) altitude_bmp280 + " m");
Serial.println();

Wait time for next measurement in milliseconds.

 
delay(ms_delay);

The last bracket is for ending a loop.

}

Info

More information about BMP280 can be found here [[9]].

Memory (SD card)

This is an example of saving/getting data to/from SD card. Data are written into test.txt, which is saved on SD card. After saving a data, the same file is read.

Code

#include <SPI.h>
#include <SD.h>

#define Serial SerialUSB

File file;
int cs_pin = 35;

void setup()
{
  Serial.begin(115200);
  while(!Serial);

  Serial.println("CANSAT kit SD card test started.");

  if (!SD.begin(cs_pin)) 
  {
   Serial.println("SD card initialization failed!");
   return;
  }

  Serial.println("SD card initialized.");

  file = SD.open("test.txt", FILE_WRITE);

  if (file) 
  {
   Serial.println("Writing to test.txt");
    
   file.println("CANSAT kit SD card test.");
   file.close();
    
   Serial.println("Writing to file finished.");
  }  
  else 
  {
    Serial.println("Error opening test for writing.txt");
  }
}

void loop()
{
}

Initialization

Including of required libraries, SPI.h for correct communication thru Serial Peripheral Interface bus (SPI [[10]]) and SD.h which support functions for controlling SD card[[11]].

#include <SPI.h>
#include <SD.h>

We also define official USB serial console for Arduino SAMD core.

#define Serial SerialUSB

In code is used two variables (file and cs_pin). We will store data in a file, save them to the SD card and then read them. The second one is number of cs_pin(chip select [[12]]) on MainBoard 2.0.

File file;
int cs_pin = 35;

After including libraries and defining variables, we can start with a setup function.

Setup

void setup()
{

Serial communications start on baud speed 115200 and program will wait until serial line for communication is ready.

Serial.begin(115200);
while(!Serial);

At the start of our program is nice to have control and information status.

Serial.println("CANSAT kit SD card test started.");

Try to connect to SD card with set up of CS pin for SPI communication. In case of a problem with the connection, print out the error state and end of setup loop.

if (!SD.begin(cs_pin)) 
{
 Serial.println("SD card initialization failed!");
 return;
}

Information status of successful SD card initialization.

Serial.println("SD card initialized.");

Open the test.txt file on SD card (in case of non-existence this command create the empty text file). This file is open for writing.

file = SD.open("test.txt", FILE_WRITE);

In case that file is opened correctly, there is a control print about writing into a file and after that sentence "CANSAT kit SD card test" is written into a file, after that file is closed. In case of failure, there is again control print about it.

if (file) 
{
 Serial.println("Writing to test.txt");
    
 file.println("CANSAT kit SD card test.");
 file.close();
    
 Serial.println("Writing to file finished.");
} 
 else 
{
 Serial.println("Error opening test for writing.txt");
}

In this case, a file is open for reading data.

file = SD.open("test.txt", FILE_READ);

The first condition is that file was correctly opened. If this condition is fulfilled, then while data are available there are read and right the way written on the serial monitor. After data are read file is closed. At the end there is a control print about actual status is written into a Serial monitor. If the first condition failed, there is an error status written into serial line.

if (file) 
{
 Serial.println("test.txt:");

 while (soubor.available()) 
 {
  Serial.write(file.read());
 }
 soubor.close();
 Serial.println("Reading from file finished.");
} 
else 
{
 Serial.println("Error opening test for reading.txt");
}

Last bracket is for ending a setup loop.

}

Loop

Empty not used loop function. Even then is not used, it is mandatory to have it.

void loop()
{
}

Info

There is no erase data implemented, you can check the possibilities of SD.h library in this section: [[13]]. In other words, how many times you run the program, that many lines with sentence "CANSAT kit SD card test." will be in the file.txt.

Light (LEDs)

This is an example for the switch on/off MLED (red/blue/off) and LED_D13 (on/off).

Code

#define Serial SerialUSB

#define D13_LED 42
#define M_LED 36

int ms_delay = 500; 

void setup() 
{
  Serial.begin(9600);
  while(!Serial);
  
  Serial.println("CANSAT kit LED test.");

  pinMode(D13_LED, OUTPUT);
}

void loop() 
{
  pinMode(M_LED, OUTPUT);
    
  Serial.println("Switch on LED diod D13, MLED red."); 
     
  digitalWrite(D13_LED, HIGH);   
  digitalWrite(M_LED, HIGH); 

  delay(ms_delay);  

  Serial.println("Switch off LED diody D13, switch on MLED blue.");   
  
  digitalWrite(D13_LED, LOW);   
  digitalWrite(M_LED, LOW);  

  delay(ms_delay);    

  Serial.println("Switch off MLED."); 
  
  pinMode(M_LED, INPUT);
  
  delay(ms_delay);  
}

Initialization

We define official USB serial console for Arduino SAMD core.

#define Serial SerialUSB

The pin number of D13_LED is 42 and for M_LED is it 36.

#define D13_LED 42
#define M_LED 36

The number of milliseconds between the different LED states (on/off/color) is defined by the variable ms_delay.

int ms_delay = 500; 

Setup

void setup() 
{

Serial communications start on baud speed 9600 and program will wait until serial line for communication is ready.

Serial.begin(9600);
while(!Serial);

At the start of our program is nice to have control and information status.

Serial.println("CANSAT kit LED test.");

Configures the pin D13_LED to behave as an output, more info [[14]].

pinMode(D13_LED, OUTPUT);

The last bracket is for ending a setup loop.

}

Loop

void loop() 
{

Configures the pin M_LED to behave as an output, more info [[15]].

pinMode(M_LED, OUTPUT);

Control print into Serial Line for more information about the behavior of the code.

 
Serial.println("Switch on LED diod D13, MLED red."); 

Switch on D13_LED and M_LED (red color).

     
digitalWrite(D13_LED, HIGH);   
digitalWrite(M_LED, HIGH); 

Wait time for next state in milliseconds.

     
delay(ms_delay);  

Control print into Serial Line for more information about the behavior of the code.

    
Serial.println("Switch off LED diody D13, switch on MLED blue.");   

Switch off D13_LED and switch on M_LED (blue color).

     
digitalWrite(D13_LED, LOW);   
digitalWrite(M_LED, LOW);  

Wait time for next state in milliseconds.

     
delay(ms_delay);  

Control print into Serial Line for more information about the behavior of the code.

    
Serial.println("Switch off MLED."); 

Configures the pin M_LED to behave as an input (switch off led, because we are not control led anymore), more info [[16]].

    
pinMode(M_LED, INPUT);

Wait time for next state in milliseconds.

     
delay(ms_delay);  

The last bracket is for ending a loop.

     
}

Info

More information about BMP280 can be found here [[17]].

Position (GPS)

Code

Initialization

Setup

Loop

Info

Comunication (RFM69HW)

Code

These examples make use of the basics of sending and receiving data with the RadioHead library. We recommend taking a deeper look at the last two, since they implement a more elegant way of data transmission. Please note that sending abstract variables (i.e. String) can be tricky. For instance, sending a String can be achieved by parsing it, saving it into a char array and then sending that array.

Send

#include <SPI.h>
#include <RH_RF69.h>

#define Serial SerialUSB

const int ss_pin = 43; //radio chip select
const int interupt_pin = 9; //radio interrupt
int ms_delay = 100;

RH_RF69 rf69(ss_pin, interupt_pin); 

void setup() 
{  
  Serial.begin(9600);
  while(!Serial); //required for devices with native USB

  Serial.println("CANSAT kit RFM69_tx test started.");
    
   // initialize the radio
  if (!rf69.init()) {
    Serial.println("Init of RFM69 failed");
  } else {
    Serial.println("Init of RFM69 ok");
  }
  
  // set frequency
  if (!rf69.setFrequency(433.0)) {
    Serial.println("Set frequency failed.");
  } else {
    Serial.println("Set frequency ok.");
  }

  /* set transmit power
   * valid values are from +14 to +20
   * caution: at +20dBm, duty cycle is limited to 1%
   */
  rf69.setTxPower(15); // set transmit power
}

void loop()
{
   // create buffer with data and transmit it
  uint8_t data[20] = "Cansat tx test!";
  if(!rf69.send(data, sizeof(data))) {
      Serial.println("Failed.");
  } else {
      Serial.println("Sended.");
  }
  
  delay(ms_delay); //wait
}

Receive

#include <SPI.h>
#include <RH_RF69.h>

#define Serial SerialUSB

const int ss_pin = 43; //radio chip select
const int interupt_pin = 9; //radio interrupt

RH_RF69 rf69(ss_pin, interupt_pin); //create an RFM69 instance

// the setup function runs once
void setup() 
{
  Serial.begin(9600);
  while(!Serial); //required for devices with native USB

  Serial.println("CANSAT kit RFM69_rx test started.");

  // initialize the radio
  if (!rf69.init()) {
    Serial.println("Init of RFM69 failed");
  } else {
    Serial.println("Init of RFM69 ok");
  }
  
  // set frequency
  if (!rf69.setFrequency(433.0)) {
    Serial.println("Set frequency failed.");
  } else {
    Serial.println("Set frequency ok.");
  }

}

void loop()
{
  if (rf69.available()) {
    uint8_t buf[RH_RF69_MAX_MESSAGE_LEN]; //create a huge buffer for received data
    uint8_t len = sizeof(buf);

    // receive to the buffer and print to serial
    if (rf69.recv(buf, &len)){
      Serial.print("Data received: ");
      Serial.println((char*)buf);
    } else {
      Serial.println("Data receiving failed.");
    }
  }
}

Struct send

#include <SPI.h>
#include <RH_RF69.h>

#define Serial SerialUSB

const int ss_pin = 43; //radio chip select
const int interupt_pin 9; //radio interrupt
int ms_delay = 100;

RH_RF69 rf69(ss_pin, interupt_pin);

// define our own struct with some variables; used to send stuff
typedef struct {
  bool BoolVariable;
  int IntVariable;
} payloadOut;

payloadOut senData; //create the struct variable

void setup() {  
  Serial.begin(9600);
  //while(!Serial); //required for devices with native USB

  Serial.println("CANSAT kit RFM69_tx test started.");
    
   // initialize the radio
  if (!rf69.init()) {
    Serial.println("Init of RFM69 failed");
  } else {
    Serial.println("Init of RFM69 ok");
  }
  
  // set frequency
  if (!rf69.setFrequency(433.0)) {
    Serial.println("Set frequency failed.");
  } else {
    Serial.println("Set frequency ok.");
  }

  /* set transmit power
   * valid values are from +14 to +20
   * caution: at +20dBm, duty cycle is limited to 1%
   */
  rf69.setTxPower(15); // set transmit power

  // load some values into the variables; you'll probably want to do this somewhere in the loop
  senData.BoolVariable = true;
  senData.IntVariable = 123;  
}

void loop()
{
   // create buffer with data and transmit it
  if(!rf69.send((uint8_t *)&senData, sizeof(senData))) {
      Serial.println("Failed");
  } else {
      Serial.println("Sent");
  }
  
  delay(ms_delay); //wait
}

Struct receive

#include <SPI.h>
#include <RH_RF69.h>

#define Serial SerialUSB

const int ss_pin = 43; //radio chip select
const int interupt_pin 9; //radio interrupt

RH_RF69 rf69(ss_pin, interupt_pin); //create an RFM69 instance

// declaration of the structure and its variables
typedef struct {
  bool BoolVariable;
  int IntVariable;
} payloadIn;

//declaration of local variables; we'll put the received data here
bool boolVariable;
int intVariable;

payloadIn recvData;

// the setup function runs once
void setup() 
{
  Serial.begin(9600);
  while(!Serial); //required for devices with native USB

  Serial.println("CANSAT kit RFM69_rx test started.");

  // initialize the radio
  if (!rf69.init()) {
    Serial.println("Init of RFM69 failed");
  } else {
    Serial.println("Init of RFM69 ok");
  }
  
  // set frequency
  if (!rf69.setFrequency(433.0)) {
    Serial.println("Set frequency failed.");
  } else {
    Serial.println("Set frequency ok.");
  }
  
}

void loop() {
  if (rf69.available()) {

    // receive the structure
    uint8_t len = sizeof(payloadIn);
    rf69.recv((uint8_t *)&recvData, &len);
    
    // load data where we want them
    boolVariable = recvData.BoolVariable;
    intVariable = recvData.IntVariable;

    // print the received data to serial
    Serial.println(boolVariable);
    Serial.println(intVariable);
  }
}

Initialization

Inclusion of a required library for communicating over SPI [[18]] and a RadioHead library, providing functions for RFM69HW

#include <SPI.h>
#include <RH_RF69.h>

We also define official USB serial console for Arduino SAMD core

#define Serial SerialUSB

Here, we need to set the radio control pins for the library

const int ss_pin = 43; //radio chip select
const int interupt_pin = 9; //radio interrupt
int ms_delay = 100;

The number of milliseconds between the measurements is defined by the variable ms_delay

int ms_delay = 100;

We create an object rf69, which will be used to access library methods by a dot notation

RH_RF69 rf69(ss_pin, interupt_pin); 

Setup

void setup() 
{

Serial communications start on baud speed 9600 and program will wait until serial line for communication is ready.

Serial.begin(9600);
while(!Serial);

At the start of our program is nice to have control and information status.

Serial.println("CANSAT kit RFM69_struct-rx test started.");

Begins communication with the hardware

if (!rf69.init()) {
    Serial.println("Init of RFM69 failed");
  } else {
    Serial.println("Init of RFM69 ok");
}

The last bracket is for ending a setup loop.

}

Loop

Info