CanSat project - code for sensors

Hello, we're a class from Norway working on a project for the CanSat competition (Build a GPS-Enabled parachute satellite). We don't have a lot of knowledge within programming and would really appreciate some help. So far we have soldered a shield to the arduino, and implemented the following sensors/items:

Communication radio (APC220) with antenna

  • Pressure sensor (MPX4115)
  • Temperature sensor (LM35DZ)
  • Temperature sensor (NTCLE100E3103JB)
  • Three axis accelerometer (MMA7361L)
  • SD storage card (OpenLog

The problem is that we're not exactly sure how to code for all of these sensors? We need the radio antenna to send us the information, and the SD storage card to log all of the information from the sensors, in case the radio doesn't function properly. All of the sensors must take measurements.

How do we do this, and where do we start? Are there any codes for these on the forums already? Tried searching, but didn't get a lot.
Thanks again for replies!

Already soldered the components but no idea how to talk to them in software? I predict there is some de-soldering in your future.

Can you use the basic demos and examples to talk to each sensor on your Arduino shield? Can you write a program to get the value from one sensor and write it to your computer on the serial monitor? Make sure all the sensors are working individually like this.

The next problem I would attack is the radio communications. Can you get a basic connection to your base station? Now can you send just one byte of data?

Now to the data logging, you are using OpenLog to just make a record of everything that was sent to the radio? That should be easy - check that the expected data is on the SD card after the above experiments.

From this point, you have tested that all the pieces work. Now you need to put it together into one program. Start with the thread pinned at the top of this forum: Planning and Implementing an Arduino Program. Follow those principles and make sure that you split out every logical unit of work (eg "get temperature") into a separate function so that different team members can take responsibility for different functions.

ok... you are going to build something like this:
https://www.narom.no/kursfiler/20121024092121_pens.pdf

i checked the sensor datasheets expec the Temperature sensor NTCLE100E3103JB (couldn´t find a Datasheet). These are analogue sensors so you can try to use the analogRead Sample of the Arduino IDE to read the Sensors. You have to check the Datasheets to calculate the voltage read by the Arduino ADC.

If you were successful in reading every sensor on its own you can use the "blink without delay" sketch to check for sensordata at a specific time (eg. every 10 seconds). store them in seperate values (int / float or maybe an array?) after that you can send the stored data over your serial port (APC220) You don´t want to do that to often because of the limited bandwith of your transmitter.

draw a structure of the software to have a brief map how you want to pack everything in if-statements.

(Build a GPS-Enabled parachute satellite)

where is the GPS??? :stuck_out_tongue_winking_eye:

sry. for my bad english :slight_smile:

EDIT: Please post the schematics!

Hi,
if you go to the vendors of your sensors, they should have sample programs for the arduino, also check the examples in the arduino IDE.

Tom.... :slight_smile:

I wonder how much of that can be found in a smart phone with bluetooth?
Because Arduino can connect to bluetooth and do the rest.

GoForSmoke:
I wonder how much of that can be found in a smart phone with bluetooth?
Because Arduino can connect to bluetooth and do the rest.

Smartphones in Spaaaace!

GoForSmoke:
I wonder how much of that can be found in a smart phone with bluetooth?
Because Arduino can connect to bluetooth and do the rest.

there are no temperature & pressure sensors in Smartphones... but a 10DOF IMU which is used for quadcopter/flightcomputers will do it and you only have to connect them via I2C. (cost about 30$)
you will get acc/gyro/mag/pressure (thumbs up)
The BMP085 Pressure sensor also has a temp-sensor onboard which can be read.

That would be my 1st choice. A mostly all in one sensor array.
But the analogue Snsors will do it for the start -> its an easier approach to learn coding :slight_smile:

I wonder what will happen to the smartphone if you put it in to (nearly) vacuum...
Maybe all the plastics will vaporice in near space. the particles will lay down on surrounding objects, damaging every sensor, solarpanel, ... Anyway, if you are able to get it back, send me a picture :stuck_out_tongue:
fact is -> no one will Transport it for you :stuck_out_tongue:

Be sure the droplet NTC is well ventilated to measure most correct.
(lag gjerne hull i boksedn over NTC'en for å sikre luftstrømmen. Den andre temp-sensoren er for treg)

This code has been used in a previos Cansat competition.

/* koder 
-> program for måling, lagring og overføring av data fra ballong.
---------------------------------------------------------
-> Bruker analoge I/O pin 0..5
-> Analog 0,1,2,3 til sensorer.  4 og 5 til Seriell GPS
-> SD-kort på digitale pinner 10(CS),11(MOSI),12(MISO) og 13(CLK)
----------------------------------------------------------
*/
#include <SoftwareSerial.h> //trengs til comm mot GPS
#include <SD.h> // rutiner til minnekortet
#include <TinyGPS.h> //rutiner for å lese GPS-data
// info for SD.kort
long nexttime;
const int SD_Select = 10; //chipselect for minnebrikken
String melding = ""; //lager til meldingen som skal lagres/sendes
char filnavn[13]="data.csv"; 
//********************************************************
// info for GPS'en 
float breddegrad,lengdegrad,hoyde,hastighet; // til info fra GPS'en
unsigned long alder,datoen,klokken;
int satellitter;
TinyGPS gps; // defineren forekomst av tinygps
SoftwareSerial nss(A4,A5); // rx og tx pinne mot GPS'en
SoftwareSerial radio(2,3); // rx og tx pinne mot radioen
static void gpsdump(TinyGPS &gps);
static bool feedgps();
// har kanhende ikke bruk for alle disse. feks:
// 'alder', 'satellitter','datoen'

void setup()
{ // alle pinner fom 2 tom 10 ut-pinner
//  pinMode(4,OUTPUT);
//  digitalWrite(4,LOW); // start senderen
  nss.begin(4800); //klargjør seriakomm med GPS
  Serial.begin(9600);
  radio.begin(9600);
  if (!SD.begin(SD_Select)) // komm med SD-kort
  { // Serial.println("sd-kort-problem");
    return;
  }  
  File datafil = SD.open(filnavn, FILE_WRITE);
  datafil.println("-----");
  datafil.println("Temp,Pressure,RH,UTC,North,East,Alt,Speed");
  datafil.close();
}
/************************************************************************************************/
static bool feedgps()
{
  nss.listen(); delay(100);
  while (nss.available())
  {if (gps.encode(nss.read())) return true;}
  return false;
}  
/************************************************************************************************/
void loop()
{
  melding="";
  // gjør 3 målinger (analogpin 0 til 3)og lagre dem i meldingen
  // vi måler temperatur, fuktighet og lufttrykk
  // termometer er NTC, HIH4000, MPX5100
  for (int analogPin = 0; analogPin < 3; analogPin++) 
  { int sensor = analogRead(analogPin);
    melding += sensor;  
    melding +=',';
  } 
  // nu ligger det tre verdier her. eks "xxx,yyy,zzz,"
  // les data fra GPS'en og legg den til i meldingen
  // vi trenger klokkeslett,breddegrad,lengddegrad,høyde og antallet satellitter
  bool newdata = false;
  unsigned long start = millis();  // 'gi GPS'en 'mat' i ett sekund
  while (millis() - start < 1000)
   { if (feedgps())  newdata=true; } //mating ferdig
  satellitter=(gps.satellites()); // antall satellitter
  hoyde=(gps.f_altitude()); 
  hastighet=gps.f_speed_kmph(); //hastighet i kilometer/time
  gps.get_datetime(&datoen,&klokken,&alder); // trenger tiden
  gps.f_get_position(&breddegrad, &lengdegrad, &alder);
  feedgps();
  melding+=klokken/100;  melding+=','; //kun hele sekunder
  //deimaltall må 'spesialbehandles'
  int helegrader=int(lengdegrad); // hele grader
  melding +=helegrader;  melding+='.';
  long minutter=1e6*(lengdegrad-helegrader);
  melding +=minutter;  melding+=','; 
  helegrader=int(breddegrad); // hele grader
  melding +=helegrader;  melding+='.';
  minutter=1e6*(breddegrad-helegrader);
  melding +=minutter;  melding+=',';
  melding +=int(hoyde);  melding+=',';
  melding +=int(hastighet); 
  File datafil = SD.open(filnavn, FILE_WRITE);
  datafil.println(melding);
  datafil.close();
  radio.listen(); delay(100);
  radio.println(melding);
  Serial.println(melding);
  while(millis()<nexttime) {} // vent til ett sekund er gått
  nexttime+=1000;  
}

there are no temperature & pressure sensors in Smartphones

utter rubbish.

Thank you all for the replies!

From the help received here by you guys, we've managed to get a code that tests the voltage over every sensor we connected to the arduino. The question is, how do we translate the output we receive in the serial manager, from volts, to the specific values? For example, temperature sensor shows 3 Volts, how can we translate this to the temperature?

/* This program is intended for use as a test program for the CanSat course at NAROM, Andøya Rocket Range.

** Beerware, this code is free to use, but if you use it and happen to meet me, you can buy me a beer
**   by Thomas Gansmoe, Narom AS (www.narom.no / www.rocketrange.no)  */
  
#define BITRATE 9600         //Bitrate for the serial interface (Radio and logger)
#define Vcc 5.0              //Supply voltage


// **** [ Sensor calibration ] *************************************************************

// NTC-sensor variables
#define R1 10000.0            //Value of R1 on the shield
#define NTC_Grad 1           //The gradiant value for the NTC sensor
#define NTC_Off 0            //The offset value for the NTC sensor

// Accelerometer-sensor settings
#define AccSensMode 0        //Accelerometer sensitivity mode. 0 = +- 1.5g, 1 = +- 6g (Not implemented in the code yet)
#define Acc15 0.800          //Acc sensitivity mode 0 = 800 mV/g (from datasheet)
#define Acc6 0.206           //Acc sensitivity mode 1 = 206 mV/g (from datasheet)
#define Acc0 1.65            //Acc 0g voltage (from datasheet)
#define AccxOff 0.0        //Offset values - Calibrated by finding voltage at zero G.
#define AccyOff 0.0
#define AcczOff 0.0

// LM335 Temp sensor
#define TmpOffset 0.0        //Volts at zero degree Celsius
#define TmpSens 100          //Sensitivity. Deg.Celsius /volt

// Pressure sensor
// Not implemented in the code yet

/*******************************************************************************/

int LOOPTIME = 500;         //Interval time in millisecounds
//Configure sensor output format
int OutFormatTmp = 0;       //Sets the output format. (0 = Volt, 1 = Deg.C)
int OutFormatNTC = 0;       //Sets the output format. (0 = Volt, 1 = Deg.C)
int OutFormatPressure = 0;  //Sets the output format. (0 = Volt, 1 = hPa)
int OutFormatAcc = 0;       //Sets the output format. (0 = Volt, 1 = G)

unsigned long time;
long int counter=0, number=0;
float G = 9.81; 

void setup() {
  Serial.begin(BITRATE);
  
}

float SecFromStart(){
  time = millis();
  int sec = time/1000;
  int des = (time%1000)/10;
  float result = (float)sec+((float)des)/100;
  return result;
}

void printdata(){
  Serial.print("Counter: ");
  Serial.print(counter);
  Serial.print(" | Time[s]: ");
  Serial.print(SecFromStart());
    
  PrintTmp(OutFormatTmp);
  PrintNTC(OutFormatNTC);
  PrintPressure(OutFormatPressure);
  PrintAcc(OutFormatAcc);
  
  Serial.println();
}

float BitToVolt(int n){    //Function to convert raw ADC-data (0-255) to volt
  int raw = analogRead(n);
  float volt = (float)raw*5.000/1023;
  return volt;
}

// The LM335 temp sensor 
void PrintTmp(int Format){
  float Tmp, volt = BitToVolt(5);  //Reads Analog5
  Serial.print(" | Temp: ");
  switch (Format){
    case 0:
      Serial.print(volt,3);
      Serial.print(" V");
      break;
    case 1:
      Serial.print((volt - TmpOffset)*TmpSens);
      Serial.print(" Deg.C");
      break;
    }    
  }

// The NTC sensor 
void PrintNTC(int OutFormatNTC){
  float R_NTC;
  float volt = BitToVolt(0);
  if (OutFormatNTC != 0){
    R_NTC = (volt * R1) / (Vcc - volt);
  }
  Serial.print(" | NTC: ");
  switch (OutFormatNTC){
    case 0:
      Serial.print(volt);
      Serial.print(" V");
      break;
    case 1:
      Serial.print(NTC_Off + NTC_Grad * R_NTC);
      Serial.print(" Deg.C");
      break;
    }    
  }
  
// The Pressure sensor (MPX4115)
void PrintPressure(int OutFormatPressure){
  float volt = BitToVolt(1), hPa;
  Serial.print(" | Pressure: ");
  hPa = 10*(volt/(0.009*Vcc)+(0.095/0.009));
      
  switch (OutFormatPressure){
    case 0:
      Serial.print(volt);
      Serial.print(" V");
      break;
    case 1:
      Serial.print(hPa);
      Serial.print(" hPa");
      break;
    }    
  }
  
// The Accelerometer sensor (MMA7361L)
float AccCalc(float volt){
  float mv2, gradient;
  if (AccSensMode == 0){ gradient = Acc15;}
  else {gradient = Acc6;}
  mv2 = (volt-Acc0)/gradient;
  return mv2;
}

void PrintAcc(int OutFormatAcc){
  float voltx = BitToVolt(2)+AccxOff, volty = BitToVolt(3)+AccyOff, voltz = BitToVolt(4)+AcczOff, Gx, Gy, Gz;
  Serial.print(" | Acceleration [x,y,z]: ");
  Gx = AccCalc(voltx);
  Gy = AccCalc(volty);
  Gz = AccCalc(voltz);
  
  switch (OutFormatAcc){
    case 0:
      Serial.print(voltx);
      Serial.print(" V, ");
      Serial.print(volty);
      Serial.print(" V, ");
      Serial.print(voltz);
      Serial.print(" V, ");
      break;
    case 1:
      Serial.print(Gx);
      Serial.print(" G, ");
      Serial.print(Gy);
      Serial.print(" G, ");
      Serial.print(Gz);
      Serial.print(" G ");
      break;
    }    
  }
  

void ReceiveSerial(){
  while (Serial.available()){
    delay(10);
    char RxChar = (char)Serial.read(); 
    switch(RxChar){
      case '1':
        LOOPTIME=1000;
        break;
      case '2':
        LOOPTIME=500;
        break;
      case '5':
        LOOPTIME=200;
        break;
      case 'R':
          counter = 0;
          break;
      case 'V':
          OutFormatNTC = 0;
          OutFormatAcc = 0;
          OutFormatPressure = 0;
          OutFormatTmp = 0;
          break;
      case 'S':
          OutFormatNTC = 1;
          OutFormatAcc = 1;
          OutFormatPressure = 1;
          OutFormatTmp = 1;
          break;
      }
  }
}

  
void loop() {
  long int loop_start = millis(), loop_end;
  printdata();
  ReceiveSerial();  
  counter++;
  loop_end = millis();
  if (LOOPTIME>(loop_end-loop_start)){      //Sets the delay to aquire right loop time
    delay(LOOPTIME-(millis()-loop_start));  
  }
}

you have to refere to the datasheets!
Do the calculation directly in the sketch to optimize bandwith.

e.g. mpx4115 page 4 & 5 of the datasheet
the formula is on the top of page 5.
http://recherche-technologie.wallonie.be/servlet/Repository/mpx4115.pdf?IDR=12260&saveFile=true

...dere skal stille i konkurranse UTEN å vite hva dere har gjort?.. skjerpings! Bruk databladene!
(På Andenes er G=9.82)

SerialQ:
you have to refere to the datasheets!
Do the calculation directly in the sketch to optimize bandwith.

e.g. mpx4115 page 4 & 5 of the datasheet
the formula is on the top of page 5.
http://recherche-technologie.wallonie.be/servlet/Repository/mpx4115.pdf?IDR=12260&saveFile=true

Thanks for the help. This is the first time working with arduino and it's components. Reading from the URL now. Thanks again.

knut_ny:
...dere skal stille i konkurranse UTEN å vite hva dere har gjort?.. skjerpings! Bruk databladene!
(På Andenes er G=9.82)

Heh.. keep in mind this is a completely new topic for us, and we haven't been working with anything like this before. We have several things to focus on. We do know what we have done, but we are seeking explenation and advice for better results and configurations. As time passes, our knowledge and experience expands within the topic. And help from this forum only assists us positively. We do use the sheets but most things are not easly understandable and requires prior knowledge, which isn't exactly the easiest thing to have considering we're starters. We're kind of "on our own" on this project, and the only resource for help is the sheets online, but they don't explain everything. Therefore we seek help here.

And with G=9.82, do you mean earths gravitational acceleration?

And with G=9.82, do you mean earths gravitational acceleration?

No, that would be small g.

Yeh, the g=9.82 is ment for your parachute design.

I will check the datasheets again and will give you a hint this evening.

ok guys,
i did some google-work for you.

MPX4115:

Datasheet

Arduino Sample

LM35DZ:

Datasheet

Arduino Sample

NTCLE100E3103JB:

Datasheet

Arduino Sample

MMA7361L:

Datasheet

Arduino Sample

These informations were pretty easy to get via google ... next time try it yourself : Search "SensorName" + Datasheet or "SensorName" + Arduino.

store the calculated results as floats, format them to send them over the Serial Interace (e.g. #"floatSensor1"/"floatSensor2"/.../.../...|; #23.3/225.0/.../.../...|)

How does your "ground-station" look like? What will you use to catchup the data?

Thanks, i've checked them. Allthough i didn't understand everything, i have a question regarding the NTC temperature sensor. (PS: We're using APC220 to transfer information via radiosignals, and also an SD card to save info from sensors)
By using the code i posted earlier, i receive these values in the serial manager:

Counter: 374 | Time[s]: 187.01 | Temp: 26.39 Deg.C | NTC: 9193.25 Deg.C | Pressure: 1015.73 hPa | Acceleration [x,y,z]: -0.04 G, -0.08 G, 0.73 G

In Volts:

Counter: 416 | Time[s]: 208.01 | Temp: 0.269 V | NTC: 2.39 V | Pressure: 4.10 V | Acceleration [x,y,z]: 1.60 V, 1.57 V, 2.22 V,

The problem is that the NTC is showing 9193.25 Deg.C! I'm not sure why, is there some defect in the NTC temp sensor, or is it just the code that doesn't calculate it correctly? i've tried to manually calculate volt to temp but i've not managed to get to a reasonable number.

Really appreciate the help!

Also, i'm trying to implement the ability to save all the values from the sensors, into the SD card. I tried using some of the code from http://arduino.cc/en/Tutorial/Datalogger but i keep getting errors. I'm not experienced within coding of arduino, and so it's a bit hard. How do i do it, or what part of the code do i use to save everything logged from the sensors, into the SD card?