logo

CANSAT

A CANSAT is a simulation of a real satellite, integrated within the volume and shape of a soft drink can. The challenge for the students is to fit all the major subsystems found in a satellite, such as power, sensors, and a communication system, into this minimal volume. The CANSAT is then launched to an altitude of a few hundred metres by a rocket or dropped from a platform or captive balloon and its mission begins: to carry out a scientific experiment and achieve a safe landing. CANSATs offer a unique opportunity for students to have a first practical experience of a real space project. They are responsible for all aspects: designing the CANSAT, selecting its mission, integrating the components, testing, preparing for launch and then analysing the data.
Components

Things used in this project

Hardware components
3D Printed Mounts x 1
9V Batteriesr x 2
Arduino UNO x 1
BMP 280/180 x 1
Circuit Boards / Bread Boards x 1
DS1307 RTC x 1
GPS Reciever Module x 1
Jumper Wires
Adequate LEDS x 1
MPU 6050 x 1
Peizoelectric Buzzer x 1
SG 90 Servo Moter x 1
SPST SLIDE Switch x 1
SSD 1306 OLED x 1
Voltage Sensor x 1
XBEE S2C x 1

CODE

        
                  #include < SoftwareSerial.h >
                  #include < Adafruit_BMP085.h >
                  #include "I2Cdev.h"
                  #include "MPU6050.h"
                  #include < Wire.h >
                  #include "RTClib.h"
                  
                  Adafruit_BMP085 bmp;
                  
                  static const int RXPin = 4, TXPin = 3;
                  static const uint32_t GPSBaud = 9600;
                  SoftwareSerial ss(RXPin, TXPin);//transmit
                  SoftwareSerial mySerial(10, 11); // RX, TX
                  SoftwareSerial tr(12, 13); // RX, TX,xbee
                  TinyGPSPlus gps;
                  
                  #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
                  #include "Wire.h"
                  #endif
                  
                  MPU6050 accelgyro;
                  int16_t ax, ay, az;
                  int16_t gx, gy, gz;
                  
                  #define OUTPUT_READABLE_ACCELGYRO
                  
                  
                  #define LED_PIN 13
                  
                  bool blinkState = false;
                  RTC_DS1307 rtc;
                  char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
                  int offset =20;// set the correction offset value
                  
                  #include < Servo.h >
                  
                  Servo myservo;
                  int pos = 0;
                  String fline = "",sline = "",tline = "";
                  int x =0;
                  
                  void setup() {
                  // put your setup code here, to run once:
                      myservo.attach(9);
                      Serial.begin(9600);
                      if (!bmp.begin()) {
                          Serial.println("Could not find a valid BMP085 sensor, check wiring!");
                           while (1) {}
                      }
                      ss.begin(GPSBaud);
                      Serial.println(F("FullExample.ino"));
                  
                      Serial.println(F("An extensive example of many interesting TinyGPS++ features"));
                      Serial.print(F("Testing TinyGPS++ library v. ")); Serial.println(TinyGPSPlus::libraryVersion());
                      Serial.println(F("by Mikal Hart"));
                      Serial.println();
                      Serial.println(F("Sats HDOP Latitude Longitude Fix Date Time Date Alt Course Speed Card Distance Course Card Chars Sentences Checksum"));
                 
                      Serial.println(F(" (deg) (deg) Age Age (m) --- from GPS ---- ---- to London ---- RX RX Fail"));
                      Serial.println(F("----------------------------------------------------------------------------------------------------------------------------------------"));
                      Serial.println("Initializing I2C devices...");
                      accelgyro.initialize();
                      Serial.println("Testing device connections...");
                      Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
                      pinMode(LED_PIN, OUTPUT);
                      
                      while (!Serial); // for Leonardo/Micro/Zero
                      
                      if (! rtc.begin()) {
                          Serial.println("Couldn't find RTC");
                          while (1);
                      }
                      if (! rtc.isrunning()) {
                          Serial.println("RTC is NOT running!");
                          rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
                      }
                      while (!Serial) {; 
                          // wait for serial port to connect. Needed for native USB port only
                      }
                      Serial.println("BIOREACTER SYSTEM");
                  
                      // set the data rate for the SoftwareSerial port
                  
                      tr.begin(9600);
                      tr.println("Hello, world?");
                  }
                  
                  void loop() {
                      Serial.print("Temperature = ");
                      Serial.print(bmp.readTemperature());
                      Serial.println(" *C");
                      Serial.print("Pressure = ");
                      Serial.print(bmp.readPressure());
                      Serial.println(" Pa");
                  
                  // Calculate altitude assuming 'standard' barometric
                  // pressure of 1013.25 millibar = 101325 Pascal
                  
                      Serial.print("Altitude = ");
                      Serial.print(bmp.readAltitude());
                      Serial.println(" meters");
                      Serial.print("Pressure at sealevel (calculated) = ");
                      Serial.print(bmp.readSealevelPressure());
                      Serial.println(" Pa");
                  
                  // you can get a more precise measurement of altitude
                  // if you know the current sea level pressure which will
                  // vary with weather and such. If it is 1015 millibars
                  // that is equal to 101500 Pascals.
                      Serial.print("Real altitude = ");
                      Serial.print(bmp.readAltitude(101500));
                      Serial.println(" meters");
                      Serial.println();
                      delay(500);
                      static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
                      printInt(gps.satellites.value(), gps.satellites.isValid(), 5);
                      printFloat(gps.hdop.hdop(), gps.hdop.isValid(), 6, 1);
                      printFloat(gps.location.lat(), gps.location.isValid(), 11, 6);
                      printFloat(gps.location.lng(), gps.location.isValid(), 12, 6);
                      printInt(gps.location.age(), gps.location.isValid(), 5);
                
                      printDateTime(gps.date, gps.time);
                      printFloat(gps.altitude.meters(), gps.altitude.isValid(), 7, 2);
                      printFloat(gps.course.deg(), gps.course.isValid(), 7, 2);
                      printFloat(gps.speed.kmph(), gps.speed.isValid(), 6, 2);
                      printStr(gps.course.isValid() ? TinyGPSPlus::cardinal(gps.course.deg()) : "*** ", 6);
                      unsigned long distanceKmToLondon =
                      (unsigned long)TinyGPSPlus::distanceBetween(
                      gps.location.lat(),
                      gps.location.lng(),
                      LONDON_LAT,
                      LONDON_LON) / 1000;
                      printInt(distanceKmToLondon, gps.location.isValid(), 9);
                      double courseToLondon =
                      TinyGPSPlus::courseTo(
                      gps.location.lat(),
                      gps.location.lng(),
                      LONDON_LAT,
                      LONDON_LON);
                      printFloat(courseToLondon, gps.location.isValid(), 7, 2);
                      const char *cardinalToLondon = TinyGPSPlus::cardinal(courseToLondon);
                      printStr(gps.location.isValid() ? cardinalToLondon : "*** ", 6);
                      
                      printInt(gps.charsProcessed(), true, 6);
                      printInt(gps.sentencesWithFix(), true, 10);
                      printInt(gps.failedChecksum(), true, 9);
                      Serial.println();
                      smartDelay(1000);
                      
                      if (millis() > 5000 && gps.charsProcessed() < 10)
                          Serial.println(F("No GPS data received: check wiring"));
                    }
                  
                  // This custom version of delay() ensures that the gps object
                  // is being "fed".
                  
                  static void smartDelay(unsigned long ms)
                  {
                      unsigned long start = millis();
                      do
                      {
                          while (ss.available())
                          gps.encode(ss.read());
                      } while (millis() - start < ms);
                  }
                  
                  static void printFloat(float val, bool valid, int len, int prec)
                    {
                      if (!valid)
                      {
                          while (len-- > 1)
                          Serial.print('*');
                          Serial.print(' ');
                      }
                      else
                      {
                          Serial.print(val, prec);
                          int vi = abs((int)val);
                          int flen = prec + (val < 0.0 ? 2 : 1); // . and -
                          flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
                          for (int i=flen; i< len; ++i)
                            Serial.print('  ');
                      }
                      smartDelay(0);
                    }
                  
                  static void printInt(unsigned long val, bool valid, int len)
                  
                  {
                      char sz[32] = "*****************";
                   
                      if (valid)
                          sprintf(sz, " %ld ", val);
                          sz[len] = 0;
                  
                      for (int i=strlen(sz); i < len; ++i)
                          sz[i] = ' ';
                    
                      if (len > 0)
                          sz[len-1] = ' ';
                          Serial.print(sz);
                          smartDelay(0);
                  }
                  
                  static void printDateTime(TinyGPSDate &d, TinyGPSTime &t)
                  {
                    if (!d.isValid())
                    {
                        Serial.print(F("********** "));
                    }
                    else
                    {
                        char sz[32];
                        sprintf(sz, "%02d/%02d/%02d ", d.month(), d.day(), d.year());
                        Serial.print(sz);
                    }
                      
                    if (!t.isValid())
                    {
                        Serial.print(F("******** "));
                    }
                    else
                    {
                        char sz[32];
                        sprintf(sz, "%02d:%02d:%02d ", t.hour(), t.minute(), t.second());
                        Serial.print(sz);
                    }
                    printInt(d.age(), d.isValid(), 5);
                    smartDelay(0);
                  }
                  
                  static void printStr(const char *str, int len)
                  {
                      int slen = strlen(str);
                      for (int i=0; i< len; ++i)
                          Serial.print(i< slen ? str[i] : ' ');
                          smartDelay(0);
                          accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
                  
                  #ifdef OUTPUT_READABLE_ACCELGYRO
                 
                  Serial.print("a/g:\t");
                  Serial.print(ax); Serial.print("\t");
                  Serial.print(ay); Serial.print("\t");
                  Serial.print(az); Serial.print("\t");
                  Serial.print(gx); Serial.print("\t");
                  Serial.print(gy); Serial.print("\t");
                  Serial.println(gz);
                  
                  #endif
                  #ifdef OUTPUT_BINARY_ACCELGYRO
                  Serial.write((uint8_t)(ax >> 8)); Serial.write((uint8_t)(ax & 0xFF));
                  Serial.write((uint8_t)(ay >> 8)); Serial.write((uint8_t)(ay & 0xFF));
                  Serial.write((uint8_t)(az >> 8)); Serial.write((uint8_t)(az & 0xFF));
                  Serial.write((uint8_t)(gx >> 8)); Serial.write((uint8_t)(gx & 0xFF));
                  Serial.write((uint8_t)(gy >> 8)); Serial.write((uint8_t)(gy & 0xFF));
                  Serial.write((uint8_t)(gz >> 8)); Serial.write((uint8_t)(gz & 0xFF));
                 
                  #endif
                  
                  blinkState = !blinkState;
                  digitalWrite(LED_PIN, blinkState);
                  
                  DateTime now = rtc.now();
                  Serial.print(now.year(), DEC);
                  Serial.print('/');
                  Serial.print(now.month(), DEC);
                  Serial.print('/');
                  Serial.print(now.day(), DEC);
                  Serial.print(" (");
                  Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
                  Serial.print(") ");
                  Serial.print(now.hour(), DEC);
                  Serial.print(':');
                  Serial.print(now.minute(), DEC);
                  Serial.print(':');
                  Serial.print(now.second(), DEC);
                  Serial.println();
                  Serial.print(" since midnight 1/1/1970 = ");
                  Serial.print(now.unixtime());
                  Serial.print("s = ");
                  Serial.print(now.unixtime() / 86400L);
                  Serial.println("d");
                 
                  // calculate a date which is 7 days and 30 seconds into the future
                  
                  DateTime future (now + TimeSpan(7, 12, 30, 6));
                  Serial.print(" now + 7d + 30s: ");
                  Serial.print(future.year(), DEC);
                  Serial.print('/');
                  Serial.print(future.month(), DEC);
                  Serial.print('/');
                  Serial.print(future.day(), DEC);
                  Serial.print(' ');
                  Serial.print(future.hour(), DEC);
                  Serial.print(':');
                  Serial.print(future.minute(), DEC);
                  Serial.print(':');
                  Serial.print(future.second(), DEC);
                  Serial.println();
                  Serial.println();
                  delay(3000);
                 
                  int volt = analogRead(A0);// read the input
                  double voltage = map(volt,0,1023, 0, 2500) + offset;// map 0-1023 to 0-2500 and add correction offset
                  voltage /=100;// divide by 100 to get the decimal values
                  Serial.print("Voltage: ");
                  Serial.print(voltage);//print the voltge
                  Serial.println("V");
                  delay(500);
                  
                  for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
                  
                  // in steps of 1 degree
                  
                  myservo.write(pos); // tell servo to go to position in variable 'pos'
                  delay(15); // waits 15ms for the servo to reach the position
                  }
                  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
                  
                  myservo.write(pos); // tell servo to go to position in variable 'pos'
                  delay(15); // waits 15ms for the servo to reach the position
                  }
                  unsigned long int gpsl =12345, gpslt =34567;
                  int v=12,temp=20,hmd=23,p = 90, al= 200,ph=6,x=14,y=5,z=8,hr=15,m=30;
                  //thisString =thisString+String(gpsl, DEC)+";"+ String(gpslt, DEC) +";"+String(temp, DEC)+";"+String(ph, DEC)+";"+String(x, DEC);
                  // thisString =thisString+gpsl+";"+ gpslt+";"+temp+";"+ph+";"+x;
                  fline="";
                  fline =fline+ "1"+gpsl+" "+gpslt;
                  sline="";
                  sline = sline+"2"+v+"volt_"+temp+"°_"+hmd+"%_"+p+"Pa_"+al+"m";
                  tline="";
                  tline = tline+"3"+"X: "+x+" Y: "+y+" Z: "+z+" time:"+hr+":"+m;
                  Serial.println(fline);
                  tr.println(fline);delay(2000);
                  tr.println(fline);delay(2000);
                  Serial.println(sline);
                  tr.println(sline);delay(2000);
                  Serial.println(tline);
                  tr.println(tline);delay(2000);
                  }