Jump to content

I know this is not a PC build log, but i thought that you might be interrested in this. The CanSat is an Arduino powered mini "satelite" that has to fit within a 330ml soda can.

There is a  primary and a secondary mission. The primary mission is to measure pressure and temperature, and calculate the altitude. The secondary mission is a mission that each group can choose themselves. We chose to have the MPU-9250 sensor as our secondary mission. The MPU-9250 is a board with accelerometers, gyroscopes and magnetometers. We also had the idea to try and put foldable wings on, but we did not have the time we needed to do this. We did make a wing prototype though. 

 

We dropped the CanSat at Andøya Space Center in Norway. We did also have other school work here.

 

 

Photo of our painted can:

Bilde1.png

 

 

 

The wing prototype: (one of the wings is broken)

 

 

Here is a video of the drop from a drone:

 

Here is the code we made. Note: we did not use the code for its full potential as we didnt have the servos connected.

Spoiler

//This program is copyleft, you can use it how you want
// some of this code is from http://www.lucidarme.me/?p=5057

#include <Servo.h> // flight control
#include <Wire.h> // MPU
#include <TimerOne.h> 

bool intFlag = true;
int ti;

//MPU
#define    MPU9250_ADDRESS            0x69
#define    MAG_ADDRESS                0x0C

#define    GYRO_FULL_SCALE_250_DPS    0x00  
#define    GYRO_FULL_SCALE_500_DPS    0x08
#define    GYRO_FULL_SCALE_1000_DPS   0x10
#define    GYRO_FULL_SCALE_2000_DPS   0x18

#define    ACC_FULL_SCALE_2_G        0x00  
#define    ACC_FULL_SCALE_4_G        0x08
#define    ACC_FULL_SCALE_8_G        0x10
#define    ACC_FULL_SCALE_16_G       0x18
//---

//altitude calculation values
// variables
float h;         //altitude
float T1;        //starting temperature
float p;         //pressure
float p1;        //starting pressure
float h1 = 45;  //starting altitude

// constants
float a  = -0.0065;
float g  = 9.81;
float r  = 287.06;
//altitude calculation values

// Servo stuff
Servo lServo;
Servo rServo;
int servoDelay = 150;


// Counter
long int cpt=0;



void setup()
{
  // Arduino initializations
  Wire.begin();
  Serial.begin(250000);
  pinMode(11,OUTPUT);
  
IC2stuff();

timerStuff();
  


  //CanSatStuff
  p1 = pressCalc();
  T1 = tempCalc();

  lServo.attach(9);
  rServo.attach(10);  

  lServo.writeMicroseconds(1500);
  rServo.writeMicroseconds(1500);


  //startup sound
  beep();
  
}





void loop(){
  
  
  
  //while (!intFlag);
  intFlag=false;
  
  // Display time

  Serial.print (millis()-ti,DEC);
  Serial.print ("\t");

  
  // _______________
  // ::: Counter :::
  
  // Display data counter
 Serial.print (cpt++,DEC);
 Serial.print ("\t");
  
 
 
  // ____________________________________
  // :::  accelerometer and gyroscope ::: 

  // Read accelerometer and gyroscope
  uint8_t Buf[14];
  I2Cread(MPU9250_ADDRESS,0x3B,14,Buf);
  
  // Create 16 bits values from 8 bits data
  
  // Accelerometer
  int16_t ax=-(Buf[0]<<8 | Buf[1]);
  int16_t ay=-(Buf[2]<<8 | Buf[3]);
  int16_t az=Buf[4]<<8 | Buf[5];

  // Gyroscope
  int16_t gx=-(Buf[8]<<8 | Buf[9]);
  int16_t gy=-(Buf[10]<<8 | Buf[11]);
  int16_t gz=Buf[12]<<8 | Buf[13];
  
    // Display values
  
  // Accelerometer
  Serial.print ("x"); 
  Serial.print (ax,DEC); 
  Serial.print ("\t");
  Serial.print ("y"); 
  Serial.print (ay,DEC);
  Serial.print ("\t");
  Serial.print ("z"); 
  Serial.print (az,DEC);  
  Serial.print ("\t");
  
  // Gyroscope
  Serial.print ("| x"); 
  Serial.print (gx,DEC); 
  Serial.print ("\t");
  Serial.print ("y"); 
  Serial.print (gy,DEC);
  Serial.print ("\t");
  Serial.print ("z"); 
  Serial.print (gz,DEC);  
  Serial.print ("\t");

  
  // _____________________
  // :::  Magnetometer ::: 

  
  // Read register Status 1 and wait for the DRDY: Data Ready
  
  uint8_t ST1;
  do
  {
    I2Cread(MAG_ADDRESS,0x02,1,&ST1);
  }
  while (!(ST1&0x01));

  // Read magnetometer data  
  uint8_t Mag[7];  
  I2Cread(MAG_ADDRESS,0x03,7,Mag);
  

  // Create 16 bits values from 8 bits data
  
  // Magnetometer
  int16_t mx=-(Mag[3]<<8 | Mag[2]);
  int16_t my=-(Mag[1]<<8 | Mag[0]);
  int16_t mz=-(Mag[5]<<8 | Mag[4]);
  
  
  
  // Magnetometer
  Serial.print ("| x"); 
  Serial.print (mx+200,DEC); 
  Serial.print ("\t");
  Serial.print ("y"); 
  Serial.print (my-70,DEC);
  Serial.print ("\t");
  Serial.print ("z"); 
  Serial.print (mz-700,DEC);  
  Serial.print ("\t");


  //CanSatStuff
  manualControl();
  
  
  p = pressCalc(); 
  
  h = altCalc(T1,p,p1,h1);
  
  float tempC = tempCalc() -273.15 ; // convert temperature from K to C
  //float hPa = p/100; 
  
  transmit(tempC,p,h1,h,T1,p1);

  if(millis()-ti >= 300000){
      analogWrite(11,255);
      delay(250);
      analogWrite(11,0);
  }
  
}


// This function read Nbytes bytes from I2C device at address Address. 
// Put read bytes starting at register Register in the Data array. 
void I2Cread(uint8_t Address, uint8_t Register, uint8_t Nbytes, uint8_t* Data)
{
  // Set register address
  Wire.beginTransmission(Address);
  Wire.write(Register);
  Wire.endTransmission();
  
  // Read Nbytes
  Wire.requestFrom(Address, Nbytes); 
  uint8_t index=0;
  while (Wire.available())
    Data[index++]=Wire.read();
}


// Write a byte (Data) in device (Address) at register (Register)
void I2CwriteByte(uint8_t Address, uint8_t Register, uint8_t Data)
{
  // Set register address
  Wire.beginTransmission(Address);
  Wire.write(Register);
  Wire.write(Data);
  Wire.endTransmission();
}

float tempCalc(){
  int sensorValue = analogRead(A3);

  float volt = bitToVolt(sensorValue);

  float tempCf = volt*100;
  
  float tempC = (1.10249*tempCf)-3.22869;

  float tempK = tempC + 273.15;


  return tempK;
}



float pressCalc(){
  
  int sensorValue = analogRead(A1);
  float p = (90.2256*sensorValue) + 28321.1;
  return p;
  
}



//calculate the altitude
int altCalc(float T1,float p,float p1,float h1){
  
  float x  = T1/a;
  float y  = p/p1;
  float z  = -a*r/g;
  float o  = pow(y,z);
  h  = x*(o-1)+h1;

  return h;
    
}
  




//transmit mission data
void transmit(float tempC, float hPa, float h1,float h,float T1,float p1){

  Serial.print(" | C "); Serial.print(tempC);
  Serial.print(" | p "); Serial.print(hPa);
  Serial.print(" | h1 "); Serial.print(h1); 
  Serial.print(" | h ");  Serial.print(h); 
  Serial.print(" | T1 "); Serial.print(T1);   
  Serial.print(" | p1 "); Serial.println(p1);   
       

}


float bitToVolt(float sV){
 

 float V = (sV/1023)*5;


 return V;
  
}





//Flight control
void manualControl(){
 while (Serial.available()){
    delay(10);
    char  rxChar = (char)Serial.read();

    if(rxChar == 'w'){ //pitch down   
      
      lServo.writeMicroseconds(1000);
      rServo.writeMicroseconds(2000);
      delay(servoDelay);
      lServo.writeMicroseconds(1500);
      rServo.writeMicroseconds(1500);
      
    } else if(rxChar == 's'){ //pitch up
       
      lServo.writeMicroseconds(2000);
      rServo.writeMicroseconds(1000);
      delay(servoDelay);
      lServo.writeMicroseconds(1500);
      rServo.writeMicroseconds(1500);
    
    } else if(rxChar == 'd'){ //roll right
       
      lServo.writeMicroseconds(1000);
      rServo.writeMicroseconds(1000);
      delay(servoDelay);
      lServo.writeMicroseconds(1500);
      rServo.writeMicroseconds(1500);

    } else if(rxChar == 'a'){ //roll left
       
      lServo.writeMicroseconds(2000);
      rServo.writeMicroseconds(2000);
      delay(servoDelay);
      lServo.writeMicroseconds(1500);
      rServo.writeMicroseconds(1500);
      
    } else if(rxChar == 'q'){
      
      analogWrite(11,255);
      delay(250);
      analogWrite(11,0);
    }
  }

  
}

void IC2stuff(){

    // Set accelerometers low pass filter at 5Hz
  I2CwriteByte(MPU9250_ADDRESS,29,0x06);
  // Set gyroscope low pass filter at 5Hz
  I2CwriteByte(MPU9250_ADDRESS,26,0x06);
 
  
  // Configure gyroscope range
  I2CwriteByte(MPU9250_ADDRESS,27,GYRO_FULL_SCALE_1000_DPS);
  // Configure accelerometers range
  I2CwriteByte(MPU9250_ADDRESS,28,ACC_FULL_SCALE_4_G);
  // Set by pass mode for the magnetometers
  I2CwriteByte(MPU9250_ADDRESS,0x37,0x02);
  
  // Request continuous magnetometer measurements in 16 bits
  I2CwriteByte(MAG_ADDRESS,0x0A,0x16);
}

void timerStuff(){
     pinMode(13, OUTPUT);
  Timer1.initialize(10000);         // initialize timer1, and set a 1/2 second period
  Timer1.attachInterrupt(callback);  // attaches callback() as a timer overflow interrupt
  
  
  // Store initial time
  int ti=millis();
}


void callback()
{ 
   intFlag=true;
  digitalWrite(13, digitalRead(13) ^ 1);
}


void beep(){

  analogWrite(11,50);
  delay(250);
  analogWrite(11,0);
  delay(250);
  analogWrite(11,50);
  delay(250);
  analogWrite(11,0);
  delay(250);
  analogWrite(11,50);
  delay(250);
  analogWrite(11,0);
  delay(250);
  analogWrite(11,255);
  delay(250);
  analogWrite(11,0);
 
}

 

 

We've now got three different subjects going on, an Asian fox and motorbike fetish, two guys talking about Norway invasions and then some other people talking about body building... This thread is turning into a free for all fetish infested Norwegian circle jerk.

Link to comment
https://linustechtips.com/topic/678392-school-project-cansat/
Share on other sites

Link to post
Share on other sites

1 minute ago, AverageHardware said:

VERY neat project. GPS?

No, we didnt have GPS. Some other groups did tho, but i dont think they got it to work

We've now got three different subjects going on, an Asian fox and motorbike fetish, two guys talking about Norway invasions and then some other people talking about body building... This thread is turning into a free for all fetish infested Norwegian circle jerk.

Link to comment
https://linustechtips.com/topic/678392-school-project-cansat/#findComment-8729100
Share on other sites

Link to post
Share on other sites

How is it a satellite if it doesn't orbit anything...

NEW PC build: Blank Heaven   minimalist white and black PC     Old S340 build log "White Heaven"        The "LIGHTCANON" flashlight build log        Project AntiRoll (prototype)        Custom speaker project

Spoiler

Ryzen 3950X | AMD Vega Frontier Edition | ASUS X570 Pro WS | Corsair Vengeance LPX 64GB | NZXT H500 | Seasonic Prime Fanless TX-700 | Custom loop | Coolermaster SK630 White | Logitech MX Master 2S | Samsung 980 Pro 1TB + 970 Pro 512GB | Samsung 58" 4k TV | Scarlett 2i4 | 2x AT2020

 

Link to comment
https://linustechtips.com/topic/678392-school-project-cansat/#findComment-8729244
Share on other sites

Link to post
Share on other sites

19 hours ago, Enderman said:

How is it a satellite if it doesn't orbit anything...

It is supposed to be a simulated satelite. It gives understanding in how satelites work. i agree the name is somewhat misleading.

We've now got three different subjects going on, an Asian fox and motorbike fetish, two guys talking about Norway invasions and then some other people talking about body building... This thread is turning into a free for all fetish infested Norwegian circle jerk.

Link to comment
https://linustechtips.com/topic/678392-school-project-cansat/#findComment-8733281
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×