Title:PEACHSAT
Displayed Name:MBCET/ Trivandrum
Concept / Overview |
---|
Sending a satellite into space is pretty difficult, not to mention expensive, so instead of sending a bunch of satellites into space to tinker with, why not design a single, highly versatile satellite. |
Introduction
Sending a satellite into space is pretty difficult, not to mention expensive, so instead of sending
a bunch of satellites into space to tinker with, why not design a single, highly versatile satellite.
One rationale for miniaturizing satellites is to reduce the cost: heavier satellites require larger rockets
with greater thrust that also has greater cost to finance. In contrast, smaller and lighter satellites require
smaller and cheaper launch vehicles and can sometimes be launched in multiples. They can also be
launched 'piggyback', using excess capacity on larger launch vehicles. Miniaturized satellites allow for
cheaper designs as well as ease of mass production, although few satellites of any size other than
'communications constellations', where dozens of satellites are used to cover the globe, have been massproduced in practice.
Another major reason for developing small satellites is the opportunity to enable missions that a larger
satellite could not accomplish, such as:
● Constellations for low data rate communications
● Using formations to gather data from multiple points
● In-orbit inspection of larger satellites
● University-related research
Space research is important because it challenges us to solve problems and find solutions which can
translate to everyday life here on Earth. The products of space research and space technology are all
around us today. From the ballpoint pen, all the way to GPS, special composite materials, special
surgical equipment and satellite communication.
For a while, only government and military had access to space. However, over the past decade there
has been a rapid increase in commercial and public access to space. Private companies can take risks
that the government and military cannot, which leads to even bolder and newer technologies being
developed. So we are presenting a Nano satellite PEACH-SAT designed using GR-PEACH board.
Abstruct
PEACH-SAT is a satellite designed in 1U CubeSat form-factor so that existing deployment
mechanisms can be used to inject satellite to space. Satellite systems essentially consists of space
segment and ground segment. Space segment contains satellite systems along with associated payloads.
Ground segment consists of RF links and command & Telemetry monitoring section for satellite health
monitoring and Data collection from payload onboard satellites. Given below is the detailed block level
description each sub systems of PEACH-SAT project.
1. PEACH-SAT Subsystems
1.1 Power Subsystem
1.2 Guidance & Attitude control Subsystem
1.3 Onboard Computer Subsystem
1.4 Telemetry & Tele command Subsystem
1.5 Sensors, Payload & RF Beacon Subsystem
1.1 Power Subsystem
Power Subsystem handles all power requirements of the PEACH-SAT. The main source of
power is the solar panels attached to the satellite. Solar photovoltaic cells convert solar energy into
electrical energy. The output of single cell is 2V, 100mA. The cells are connected in series parallel
arrangement to obtain raw bus voltage of about 6V, 500mA. The PV array output is fed to a DC-DC
Converter for obtaining stabilized DC output. The stabilized DC output is used for charging Li-ion
based Battery pack & charging is supervised by a circuit based on CC/CV linear charger TP4056. The
output from battery is given to a DC-DC boost Converter to obtain a raw bus voltage of 12V.A dc-dc
buck converter is used for obtaining 7.5V for Vin input of GR-Peach board. An ACS712 based sensor
is used for measuring main current. Four 12V SPDT (Single Pole Double Throw) relays along with
drivers are used for controlling power to the three reaction wheels and antenna deployment heater
mechanism.
1.2 GUIDANCE & ATTITUDE CONTROL SUBSYSTEM
Guidance & Attitude control Subsystem maintains the orientation of PEACH-SAT stable with
respect to earth using an array of sensors and actuators in closed loop fashion.
The sensor used in IMU (Inertial Measurement Unit) is MPU9150. The IMU is a 9-DOF (Degree of Freedom) sensor with triaxial accelerometer, gyroscope and magnetometer. The outputs are angular acceleration, linear acceleration and magnetic field intensity along three axes Yaw, Pitch & Roll. The IMU Output in I2C protocol is interfaced to I2C bus of GR-PEACH board using SCL & SDA lines. The IMU requires 3.3V and is attached rigidly to the body of satellite using vibration damping material so that error and offset due to ambient noises is minimal.
The data after processing by guidance & control algorithm is used to generate the required control
signals for the actuators. The actuators used are three reaction wheel along three axes Yaw, Pitch &
Roll. The reaction wheels work under principle of conservation of angular momentum. The reaction
wheels are attached to a BLDC (Brushless Direct Current) motor of 7200 rpm and BLDC motor is
connected to a BLDC drive circuit. Three reaction wheels are placed in orthogonal fashion inside
satellite frame. The various control signals used are EN (enable), DIR (Direction) and PWM (Pulse
Width Modulation) to control ON/OFF, direction and speed respectively of each reaction wheels.
1.3 Onboard computer subsystem
Onboard Computer is the brain of the satellite and is responsible for generating the control signals for actuation based on the outputs of the various sensor onboard the PEACH-SAT. OBC algorithm is implemented on the GR-PEACH board. The system is designed as a fault tolerant embedded system so that it can withstand event such as SEU (single event upset) and SEL (single eventlatch up).
A radiation hardened WDT (Watchdog Timer) is implemented to periodically reset the microcontroller board in case of failure such as latch up by using a counter, clocked by a separate clock signal from a crystal oscillator. All sensors and actuators are interfaced to the Board by using interfaces such as UART, SPI, I2C, PWM, ADC and GPIO. Supervisory program is also executed to monitor for any error in execution of tasks.
Onboard Autonomy is implemented to take care of task execution in case of communication blackouts. In case of communication failure or Low power Alarm mode, Radio Transmission is switched off and data is periodically backed up to SD card based storage system in CSV format. Certain signals are routed out from GR-Peach using 74LS244 based buffer.
1.4 Telemetry & Tele command Subsystem
Telemetry Subsystem is used for remote monitoring of satellite parameters and housekeeping information regarding voltage, current and temperature signatures at various critical points. ADS1218 is an 8 channel 24 bit delta-sigma converter with UART interface and can be connected in daisy chained format for expanding the number of analog monitoring channels for monitoring voltage and temperature at various points. Voltage divider with suitable protection network is used for sampling various voltages. LM35 based temperature sensor is used for temperature monitoring and is connected to GR-Peach ADC input. ACS712, a hall-effect sensor based current monitoring IC is used for monitoring the current flow along raw battery power bus.
Tele command Subsystem is used to manually control subsystems on board the satellite from the ground control station. Upon the reception of tele command frames from ground they are decoded by the GR-PEACH board and suitable command are executed by switching the relays ON/OFF. Relays are driven by ULN2803 based 8 channel Darlington driver as commanded by the GPIOs of GR-PEACH board. Tele command system facilitates the isolation of faulty subsystem in satellite so that rest of the systems can function normally, thereby implementing FDIR (Fault Detection, Isolation and Reconfiguration) scheme.
Telemetry & Tele command Subsystem RF link is implemented using XBEE RF modules operating at 2.4GHz. RF Modules must be configured prior to operation to work on pointpoint link by assigning same PAN-ID and proper DH-DL address. RF module at satellite side is
interfaced to GR-PEACH board using the UART interface. For range enhancement high gain patch
antenna is connected to external antenna port of XBEE module via 50 ohm co-axial cable.
1.5 SENSORS, PAYLOAD & RF BEACON SUBSYSTEM
Payloads are the instruments onboard the satellite for the purpose of scientific study and
analysis.
In PEACH-SAT a low-resolution camera is interfaced with the OBC through a NTSC input.
This payload integrates a camera capable of capturing pictures in the visible spectrum at VGA
resolutions (640 x 480).
This can be used for analysis of outer space. Using a radiation sensor the PEACHSAT is capable of counting ionized particles and perform radiation dosimetry.
The radiation measured by this payload will change for each point in the orbit trajectory, allowing to have a baseline reference to correlate with the rest of the satellite's measurements. A hardware counter in the OBC's CPU is used to record the number of ionized particles detected by the device. A four-quadrant sun sensor is constructed out of photodiodes and Trans impedance amplifiers for measuring out emissions from sun.
A catalytic heater based gas analyzer is used for analyzing the gas concentration.
All sensors are interfaced to the OBC through Analog front ends (Sensor AFE).
A standalone UHF RF beacon Transmitter working in 433 MHz band is used for echoing the satellite ID and details in a standard CW Morse code format.
The transmitter is built around the Radiometrix 433MHx RF module.
A high accuracy GPS module is used in peach-sat for obtaining positional information such as latitude, longitude altitude etc. GPS module with built in patch antenna working at 3.3V is connected to OBC via a UART interface.
ISL29023 based ambient light sensor, TMP006 infrared temperature sensor, BMP80 barometric pressure sensor and SHT21 humidity sensor are connected to OBC via I2C link.
An active thermal control system is realized using Peltier module.
Depending on the internal and external cluster temperature direction of current in Peltier is reversed using a DPDT (Double pole double throw relay) to obtain required heating/cooling effect.
A laser module is provided for conducting one way differential Doppler ranging demo and can be activated upon the tele command on/off relay activation.
2. Ground Subsystem
Ground subsystem consists of antennas and receiver subsystem. The telemetry and tele command section consists of XBEE module paired with the one on the PEACH-SAT.
GUI (graphical User Interface) for Tele command uploading and telemetry viewing is implemented in processing based GUI.
For listening to the beacon Transmission from PEACH-SAT, an SDR (Software Defined radio) is configured around RTL-SDR 2832U Dongle.
For the beacon transmitter signal Reception, a Qadrifilar helix Antenna and LNA (low noise amplifier) is connected to the SDR antenna input via an SMA connector. Antenna is attached on a servo motor based pan/tilt assembly which is 3-D printed.
A Morse code reader android app is used for decoding Morse code beacon signal from peach-sat.
2-1 Peach-Sat Firmware
PEACH-SAT firmware is developed in Renesas online IDE. Libraries are used for peripherals such as GPS, I2C sensors etc. Pins for interface and their mode of operation is given in the initialization section of code. All communication interface such as I2C, UART and their parameters are specified in the setup section of code. A round robin scheduler RTOS called Toppers ASP kernel is used for multitasking application. The Code is well commented and each task and interface is given as a separate function so that debugging process is simplified. Also in each function terminal printing serial messages are given for ease of debugging.
2-2 Peach-Sat Assembly
PEACH-SAT engineering model is developed using commercial off the shelf components. Acrylic sheet is used as a platform for various stage integration. Uniform holes grid spaced at 1cm are put on acrylic sheet using laser engraver so that sub-assemblies and PCB can easily be tied or screwed to the sheet. Different Layers are stacked on to each other using M3 nut and bolts. In each stages all connections are terminated using D-connectors for the ease of assembly and debugging or checkout operation. Each stage is checked and verified by checkout systems consisting of GPIO simulators, voltmeter and ammeter to ensure proper working operation. Finally main wire harness for interconnecting each stage is fabricated and integration and testing is done.
2-3 Problems Faced
PEACH-SAT development opened lot of challenges to solve such as problems of noise e and ground loop. To prevent ground lifting due to ground loop formation and crosstalk separate ground for analog, digital and RF is devised and finally all grounds are terminate in a single point. To prevent the problems of relay chatter and switching effects decoupling is provided in each supply entry point. All RF connections are made using 50 ohm RF cable to avoid problem of signal reflections.
2-4 Peach-Sat Upgrades
PEACH-SAT can be enhanced by adding more sensors and payloads. Right now only an analog black and white camera is used for imaging purpose, which pose certain limitations on imaging. Only Ethernet based streaming of NTSC camera image is demonstrated. On board image acquisition and sending using ZigBee transceiver firm ware needs to be developed along with picture framing GUI in ground station.
Conclusion
PEACH-SAT makes it possible for everyone to do his or her own space exploration.
Space exploration is no longer reserved for the NASA and the billion dollar companies.
It is now possible for everyone to be on what has been said to be the final frontier.
This is actually the perfect time to take part in this revolution and for everyone to contribute to the space technology and exploration.
PEACH-SAT offers the chance for everyday people to control a satellite for different purposes such as exploration, entertainment and experiments.
It takes advantage of the existing technologies and platforms so that more and more people can participate in the space technology.
With more and more people participating, the space industry is likely to go on through countless innovations.
Subsystem Schematics
Source Code
PEACH-SAT SOURCE CODE #include#include #include #include "syssvc/serial.h" #include "syssvc/syslog.h" #include "kernel_cfg.h" #include "arduino_app.h" #include "arduino_main.h" /* GR-PEACH Sketch Template V1.00 */ #include //checkout 20*4 lcd display #include LiquidCrystal lcd(29,28,27,26,25,24); //I2C BUS #include //GPS PARSER LIBRARY #include TinyGPSPlus gps; // SD CARD FOR DATA LOGGING #include //ISL29023 SENSOR LIBRARY #define ISL29023_ADDR 0x44 #define CMD1 0 #define CMD2 1 #define DATALSB 2 #define DATAMSB 3 float lux; //BMP180 SENSOR LIBRARY #include SFE_BMP180 pressure; double baseline; int a; //SHT21 SENSOR LIBRARY #include //TMP006 IR THERMOPILE SENSOR #include #include // Constants for calculating object temperature #define TMP006_B0 -0.0000294 #define TMP006_B1 -0.00000057 #define TMP006_B2 0.00000000463 #define TMP006_C2 13.4 #define TMP006_TREF 298.15 #define TMP006_A2 -0.00001678 #define TMP006_A1 0.00175 #define TMP006_S0 6.4 // * 10^-14 // Configuration Settings #define TMP006_CFG_RESET 0x8000 #define TMP006_CFG_MODEON 0x7000 #define TMP006_CFG_1SAMPLE 0x0000 #define TMP006_CFG_2SAMPLE 0x0200 #define TMP006_CFG_4SAMPLE 0x0400 #define TMP006_CFG_8SAMPLE 0x0600 #define TMP006_CFG_16SAMPLE 0x0800 #define TMP006_CFG_DRDYEN 0x0100 #define TMP006_CFG_DRDY 0x0080 // Registers to read thermopile voltage and sensor temperature #define TMP006_VOBJ 0x00 #define TMP006_TAMB 0x01 #define TMP006_CONFIG 0x02 #define TMP006_ADDR 0x40 float object_temp,sensor_temp; //MPU9150 IMU #define MPU9150_ADDR 0x68 #define CMD_1 1 #define CMD_2 0 #define DATA_LSB 6 #define DATA_MSB 9 int ax,ay,az,gx,gy,gz,mx,my,mz; //DEBUG LEDS BLINK INTERVAL #define INTERVAL 2500 //misc variables //peltier duration int duration_peltier = 0; //temperature variables float tempF,tempC; //telemetry variables int field[60]; uint8_t idx = 0; bool done = false; float ch_val[6]; float RAW_LIPO_VOLTAGE; float RAW_LIPO_CURRENT; float RAW_12_V; float RAW_7V5; float RAW_5_V; float RAW_3V3; //REACTION WHEEL SPEED VARIABLES int yaw_speed = 0; int pitch_speed = 0; int roll_speed = 0; //Beacon system variables and functions #define N_MORSE (sizeof(morsetab)/sizeof(morsetab[0])) #define SPEED (33) //default 12 25 still stable 35 working #define DOTLEN (1200/SPEED) #define DASHLEN (3*(1200/SPEED)) struct t_mtab { char c, pat; } ; struct t_mtab morsetab[] = { {'.', 106}, {',', 115}, {'?', 76}, {'/', 41}, {'A', 6}, {'B', 17}, {'C', 21}, {'D', 9}, {'E', 2}, {'F', 20}, {'G', 11}, {'H', 16}, {'I', 4}, {'J', 30}, {'K', 13}, {'L', 18}, {'M', 7}, {'N', 5}, {'O', 15}, {'P', 22}, {'Q', 27}, {'R', 10}, {'S', 8}, {'T', 3}, {'U', 12}, {'V', 24}, {'W', 14}, {'X', 25}, {'Y', 29}, {'Z', 19}, {'1', 62}, {'2', 60}, {'3', 56}, {'4', 48}, {'5', 32}, {'6', 33}, {'7', 35}, {'8', 39}, {'9', 47}, {'0', 63} } ; //rtc module variables #define DS3231_I2C_ADDRESS 0x68 //SENSOR ANALOG VALUES int sun_sensor_value = 0; int gas_sensor_value = 0; int radiation_sensor_value = 0; //AUXILLARY RELAY FOR DEPLOYMENT MECHANISM CONTROL #define AUXILLARY_RELAY_CONTROL_PIN P3_8 //REACTION WHEEL ON/OFF CONTROL RELAYS #define YAW_REACTION_WHEEL_ENABLE_RELAY_PIN P3_11 #define PITCH_REACTION_WHEEL_ENABLE_RELAY_PIN P3_10 #define ROLL_REACTION_WHEEL_ENABLE_RELAY_PIN P3_9 //REACTION WHEEL DIRECTION CONTROL RELAYS #define YAW_REACTION_WHEEL_DIRECTION_RELAY_PIN P3_15 #define PITCH_REACTION_WHEEL_DIRECTION_RELAY_PIN P3_14 #define ROLL_REACTION_WHEEL_DIRECTION_RELAY_PIN P3_13 //REACTION WHEEL SPEED CONTROL PWM PINS #define YAW_REACTION_WHEEL_SPEED_CONTROL_PIN P4_7 #define PITCH_REACTION_WHEEL_SPEED_CONTROL_PIN P4_6 #define ROLL_REACTION_WHEEL_SPEED_CONTROL_PIN P4_5 //TELECOMMAND RELAY CONTROL PINS #define BEACON_TRANSMITTER_CONTROL_RELAY_PIN P2_7 #define ZIGBEE_TRANSCIEVER_CONTROL_RELAY_PIN P2_6 #define GPS_MODULE_CONTROL_RELAY_PIN P2_5 #define SENSOR_SUBSYSTEM_CONTROL_RELAY_PIN P2_4 #define TELEMETRY_SUBSYSTEM_CONTROL_RELAY_PIN P2_3 #define CAMERA_SUBSYSTEM_CONTROL_RELAY_PIN P2_2 #define PELTIER_SUBSYSTEM_CONTROL_RELAY_PIN P2_1 #define LASER_SUBSYSTEM_CONTROL_RELAY_PIN P2_0 //PELTIER MODULE HEAT/COOL CONTROL PIN #define PELTIER_HEAT_COOL_CONTROL_RELAY_PIN P3_12 //INTERNAL TEMPERATURE SENSOR PIN #define INTERNAL_TEMPERATURE_SENSOR_PIN A4 //BEACON SUBSYSTEM INPUT PIN #define BEACON_SUBSYSTEM_TX_PIN P4_4 //SENSOR SUBSYSTEM PINS #define SUN_SENSOR_PIN A0 #define GAS_SENSOR_PIN A1 #define RADIATION_SENSOR_PIN A2 //DEBUG LEDS & SWITCH PINS #define RED_LED_PIN P6_13 #define GREEN_LED_PIN P6_14 #define BLUE_LED_PIN P6_15 #define USER_LED_PIN P6_12 #define SWITCH_PIN P6_0 void PINMODE_DEFINTION() { //AUXILLARY RELAY FOR DEPLOYMENT MECHANISM CONTROL pinMode(AUXILLARY_RELAY_CONTROL_PIN , OUTPUT); //REACTION WHEEL ON/OFF CONTROL RELAYS pinMode(YAW_REACTION_WHEEL_ENABLE_RELAY_PIN , OUTPUT); pinMode(PITCH_REACTION_WHEEL_ENABLE_RELAY_PIN , OUTPUT); pinMode(ROLL_REACTION_WHEEL_ENABLE_RELAY_PIN , OUTPUT); //REACTION WHEEL DIRECTION CONTROL RELAYS pinMode(YAW_REACTION_WHEEL_DIRECTION_RELAY_PIN , OUTPUT); pinMode(PITCH_REACTION_WHEEL_DIRECTION_RELAY_PIN , OUTPUT); pinMode(ROLL_REACTION_WHEEL_DIRECTION_RELAY_PIN , OUTPUT); //REACTION WHEEL SPEED CONTROL PWM PINS pinMode(YAW_REACTION_WHEEL_SPEED_CONTROL_PIN , OUTPUT); pinMode(PITCH_REACTION_WHEEL_SPEED_CONTROL_PIN , OUTPUT); pinMode(ROLL_REACTION_WHEEL_SPEED_CONTROL_PIN , OUTPUT); //TELECOMMAND RELAY CONTROL PINS pinMode(BEACON_TRANSMITTER_CONTROL_RELAY_PIN , OUTPUT); pinMode(ZIGBEE_TRANSCIEVER_CONTROL_RELAY_PIN , OUTPUT); pinMode(GPS_MODULE_CONTROL_RELAY_PIN , OUTPUT); pinMode(SENSOR_SUBSYSTEM_CONTROL_RELAY_PIN , OUTPUT); pinMode(TELEMETRY_SUBSYSTEM_CONTROL_RELAY_PIN , OUTPUT); pinMode(CAMERA_SUBSYSTEM_CONTROL_RELAY_PIN , OUTPUT); pinMode(PELTIER_SUBSYSTEM_CONTROL_RELAY_PIN , OUTPUT); pinMode(LASER_SUBSYSTEM_CONTROL_RELAY_PIN , OUTPUT); //PELTIER MODULE HEAT/COOL CONTROL PIN pinMode(PELTIER_HEAT_COOL_CONTROL_RELAY_PIN , OUTPUT); //BEACON SUBSYSTEM TX PIN pinMode(BEACON_SUBSYSTEM_TX_PIN , OUTPUT); //DEBUG LEDS & SWITCH pinMode(RED_LED_PIN , OUTPUT); pinMode(GREEN_LED_PIN , OUTPUT); pinMode(BLUE_LED_PIN , OUTPUT); pinMode(USER_LED_PIN , OUTPUT); pinMode(SWITCH_PIN , INPUT); } void PINMODE_INITIALISATION() { //AUXILLARY RELAY FOR DEPLOYMENT MECHANISM CONTROL digitalWrite(AUXILLARY_RELAY_CONTROL_PIN , LOW); //REACTION WHEEL ON/OFF CONTROL RELAYS digitalWrite(YAW_REACTION_WHEEL_ENABLE_RELAY_PIN , LOW); digitalWrite(PITCH_REACTION_WHEEL_ENABLE_RELAY_PIN , LOW); digitalWrite(ROLL_REACTION_WHEEL_ENABLE_RELAY_PIN , LOW); //REACTION WHEEL DIRECTION CONTROL RELAYS digitalWrite(YAW_REACTION_WHEEL_DIRECTION_RELAY_PIN , LOW); digitalWrite(PITCH_REACTION_WHEEL_DIRECTION_RELAY_PIN , LOW); digitalWrite(ROLL_REACTION_WHEEL_DIRECTION_RELAY_PIN , LOW); //REACTION WHEEL SPEED CONTROL PWM PINS digitalWrite(YAW_REACTION_WHEEL_SPEED_CONTROL_PIN , LOW); digitalWrite(PITCH_REACTION_WHEEL_SPEED_CONTROL_PIN , LOW); digitalWrite(ROLL_REACTION_WHEEL_SPEED_CONTROL_PIN , LOW); //TELECOMMAND RELAY CONTROL PINS digitalWrite(BEACON_TRANSMITTER_CONTROL_RELAY_PIN , LOW); digitalWrite(ZIGBEE_TRANSCIEVER_CONTROL_RELAY_PIN , LOW); digitalWrite(GPS_MODULE_CONTROL_RELAY_PIN , LOW); digitalWrite(SENSOR_SUBSYSTEM_CONTROL_RELAY_PIN , LOW); digitalWrite(TELEMETRY_SUBSYSTEM_CONTROL_RELAY_PIN , LOW); digitalWrite(CAMERA_SUBSYSTEM_CONTROL_RELAY_PIN , LOW); digitalWrite(PELTIER_SUBSYSTEM_CONTROL_RELAY_PIN , LOW); digitalWrite(LASER_SUBSYSTEM_CONTROL_RELAY_PIN , LOW); //PELTIER MODULE HEAT/COOL CONTROL PIN digitalWrite(PELTIER_HEAT_COOL_CONTROL_RELAY_PIN , LOW); //BEACON SUBSYSTEM TX PIN digitalWrite(BEACON_SUBSYSTEM_TX_PIN , LOW); //DEBUG LEDS digitalWrite(RED_LED_PIN , LOW); digitalWrite(GREEN_LED_PIN , LOW); digitalWrite(BLUE_LED_PIN , LOW); digitalWrite(USER_LED_PIN , LOW); } void AUXILLARY_RELAY_ON() { Serial.println("AUXILLARY_RELAY_ON"); digitalWrite(AUXILLARY_RELAY_CONTROL_PIN , HIGH); } void AUXILLARY_RELAY_OFF() { Serial.println("AUXILLARY_RELAY_OFF"); digitalWrite(AUXILLARY_RELAY_CONTROL_PIN , LOW); } void YAW_REACTION_WHEEL_ON() { Serial.println("YAW_REACTION_WHEEL_ON"); digitalWrite(YAW_REACTION_WHEEL_ENABLE_RELAY_PIN , HIGH); } void YAW_REACTION_WHEEL_OFF() { Serial.println("YAW_REACTION_WHEEL_OFF"); digitalWrite(YAW_REACTION_WHEEL_ENABLE_RELAY_PIN , LOW); } void PITCH_REACTION_WHEEL_ON() { Serial.println("PITCH_REACTION_WHEEL_ON"); digitalWrite(PITCH_REACTION_WHEEL_ENABLE_RELAY_PIN , HIGH); } void PITCH_REACTION_WHEEL_OFF() { Serial.println("PITCH_REACTION_WHEEL_OFF"); digitalWrite(PITCH_REACTION_WHEEL_ENABLE_RELAY_PIN , LOW); } void ROLL_REACTION_WHEEL_ON() { Serial.println("ROLL_REACTION_WHEEL_ON"); digitalWrite(ROLL_REACTION_WHEEL_ENABLE_RELAY_PIN , HIGH); } void ROLL_REACTION_WHEEL_OFF() { Serial.println("ROLL_REACTION_WHEEL_OFF"); digitalWrite(ROLL_REACTION_WHEEL_ENABLE_RELAY_PIN , LOW); } void YAW_REACTION_WHEEL_CW() { Serial.println("YAW_REACTION_WHEEL_CW"); digitalWrite(YAW_REACTION_WHEEL_DIRECTION_RELAY_PIN , HIGH); } void YAW_REACTION_WHEEL_CCW() { Serial.println("YAW_REACTION_WHEEL_CCW"); digitalWrite(YAW_REACTION_WHEEL_DIRECTION_RELAY_PIN , LOW); } void PITCH_REACTION_WHEEL_CW() { Serial.println("PITCH_REACTION_WHEEL_CW"); digitalWrite(PITCH_REACTION_WHEEL_DIRECTION_RELAY_PIN , HIGH); } void PITCH_REACTION_WHEEL_CCW() { Serial.println("PITCH_REACTION_WHEEL_CCW"); digitalWrite(PITCH_REACTION_WHEEL_DIRECTION_RELAY_PIN , LOW); } void ROLL_REACTION_WHEEL_CW() { Serial.println("ROLL_REACTION_WHEEL_CW"); digitalWrite(ROLL_REACTION_WHEEL_DIRECTION_RELAY_PIN , HIGH); } void ROLL_REACTION_WHEEL_CCW() { Serial.println("ROLL_REACTION_WHEEL_CCW"); digitalWrite(ROLL_REACTION_WHEEL_DIRECTION_RELAY_PIN , LOW); } void BEACON_TRANSMITTER_ON() { Serial.println("BEACON_TRANSMITTER_ON"); digitalWrite(BEACON_TRANSMITTER_CONTROL_RELAY_PIN , HIGH); } void BEACON_TRANSMITTER_OFF() { Serial.println("BEACON_TRANSMITTER_OFF"); digitalWrite(BEACON_TRANSMITTER_CONTROL_RELAY_PIN , LOW); } void ZIGBEE_TRANSCIEVER_ON() { Serial.println("ZIGBEE_TRANSCIEVER_ON"); digitalWrite(ZIGBEE_TRANSCIEVER_CONTROL_RELAY_PIN , HIGH); } void ZIGBEE_TRANSCIEVER_OFF() { Serial.println("ZIGBEE_TRANSCIEVER_OFF"); digitalWrite(ZIGBEE_TRANSCIEVER_CONTROL_RELAY_PIN , LOW); } void GPS_MODULE_ON() { Serial.println("GPS_MODULE_ON"); digitalWrite(GPS_MODULE_CONTROL_RELAY_PIN , HIGH); } void GPS_MODULE_OFF() { Serial.println("GPS_MODULE_OFF"); digitalWrite(GPS_MODULE_CONTROL_RELAY_PIN , LOW); } void SENSOR_SUBSYSTEM_ON() { Serial.println("SENSOR_SUBSYSTEM_ON"); digitalWrite(SENSOR_SUBSYSTEM_CONTROL_RELAY_PIN , HIGH); } void SENSOR_SUBSYSTEM_OFF() { Serial.println("SENSOR_SUBSYSTEM_OFF"); digitalWrite(SENSOR_SUBSYSTEM_CONTROL_RELAY_PIN , LOW); } void TELEMETRY_SUBSYSTEM_ON() { Serial.println("TELEMETRY_SUBSYSTEM_ON"); digitalWrite(TELEMETRY_SUBSYSTEM_CONTROL_RELAY_PIN , HIGH); } void TELEMETRY_SUBSYSTEM_OFF() { Serial.println("TELEMETRY_SUBSYSTEM_OFF"); digitalWrite(TELEMETRY_SUBSYSTEM_CONTROL_RELAY_PIN , LOW); } void CAMERA_SUBSYSTEM_ON() { Serial.println("CAMERA_SUBSYSTEM_ON"); digitalWrite(CAMERA_SUBSYSTEM_CONTROL_RELAY_PIN , HIGH); } void CAMERA_SUBSYSTEM_OFF() { Serial.println("CAMERA_SUBSYSTEM_OFF"); digitalWrite(CAMERA_SUBSYSTEM_CONTROL_RELAY_PIN , LOW); } void PELTIER_SUBSYSTEM_ON() { Serial.println("PELTIER_SUBSYSTEM_ON"); digitalWrite(PELTIER_SUBSYSTEM_CONTROL_RELAY_PIN , HIGH); } void PELTIER_SUBSYSTEM_OFF() { Serial.println("PELTIER_SUBSYSTEM_OFF"); digitalWrite(PELTIER_SUBSYSTEM_CONTROL_RELAY_PIN , LOW); } void LASER_SUBSYSTEM_ON() { Serial.println("LASER_SUBSYSTEM_ON"); digitalWrite(LASER_SUBSYSTEM_CONTROL_RELAY_PIN , HIGH); } void LASER_SUBSYSTEM_OFF() { Serial.println("LASER_SUBSYSTEM_OFF"); digitalWrite(LASER_SUBSYSTEM_CONTROL_RELAY_PIN , LOW); } void PELTIER_SUBSYSTEM_COOL(int duration_peltier) { Serial.println("PELTIER_SUBSYSTEM_COOL"); digitalWrite(PELTIER_HEAT_COOL_CONTROL_RELAY_PIN , HIGH); delay(200); PELTIER_SUBSYSTEM_ON(); delay(duration_peltier); PELTIER_SUBSYSTEM_OFF(); delay(duration_peltier); } void PELTIER_SUBSYSTEM_HEAT(int duration_peltier) { Serial.println("PELTIER_SUBSYSTEM_HEAT"); digitalWrite(PELTIER_HEAT_COOL_CONTROL_RELAY_PIN , LOW); delay(200); PELTIER_SUBSYSTEM_ON(); delay(duration_peltier); PELTIER_SUBSYSTEM_OFF(); delay(duration_peltier); } void SUBSYSTEM_TEST_SEQUENCE() { Serial.println("TESTING SEQUENCE START"); delay(INTERVAL); AUXILLARY_RELAY_ON(); delay(INTERVAL); AUXILLARY_RELAY_OFF(); delay(INTERVAL); YAW_REACTION_WHEEL_ON(); delay(INTERVAL); YAW_REACTION_WHEEL_OFF(); delay(INTERVAL); PITCH_REACTION_WHEEL_ON(); delay(INTERVAL); PITCH_REACTION_WHEEL_OFF(); delay(INTERVAL); ROLL_REACTION_WHEEL_ON(); delay(INTERVAL); ROLL_REACTION_WHEEL_OFF(); delay(INTERVAL); YAW_REACTION_WHEEL_CW(); delay(INTERVAL); YAW_REACTION_WHEEL_CCW(); delay(INTERVAL); PITCH_REACTION_WHEEL_CW(); delay(INTERVAL); PITCH_REACTION_WHEEL_CCW(); delay(INTERVAL); ROLL_REACTION_WHEEL_CW(); delay(INTERVAL); ROLL_REACTION_WHEEL_CCW(); delay(INTERVAL); BEACON_TRANSMITTER_ON(); delay(INTERVAL); BEACON_TRANSMITTER_OFF(); delay(INTERVAL); ZIGBEE_TRANSCIEVER_ON(); delay(INTERVAL); ZIGBEE_TRANSCIEVER_OFF(); delay(INTERVAL); GPS_MODULE_ON(); delay(INTERVAL); GPS_MODULE_OFF(); delay(INTERVAL); SENSOR_SUBSYSTEM_ON(); delay(INTERVAL); SENSOR_SUBSYSTEM_OFF(); delay(INTERVAL); TELEMETRY_SUBSYSTEM_ON(); delay(INTERVAL); TELEMETRY_SUBSYSTEM_OFF(); delay(INTERVAL); CAMERA_SUBSYSTEM_ON(); delay(INTERVAL); CAMERA_SUBSYSTEM_OFF(); delay(INTERVAL); LASER_SUBSYSTEM_ON(); delay(INTERVAL); LASER_SUBSYSTEM_OFF(); delay(INTERVAL); PELTIER_SUBSYSTEM_HEAT(500); delay(INTERVAL); PELTIER_SUBSYSTEM_COOL(500); delay(INTERVAL); Serial.println("TESTING SEQUENCE END"); } //RTC MODULE FUNCTIONS // Convert normal decimal numbers to binary coded decimal byte decToBcd(byte val) { return( (val/10*16) + (val%10) ); } // Convert binary coded decimal to normal decimal numbers byte bcdToDec(byte val) { return( (val/16*10) + (val%16) ); } void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year) { // sets time and date data to DS3231 Wire.beginTransmission(DS3231_I2C_ADDRESS); Wire.write(0); // set next input to start at the seconds register Wire.write(decToBcd(second)); // set seconds Wire.write(decToBcd(minute)); // set minutes Wire.write(decToBcd(hour)); // set hours Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday) Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31) Wire.write(decToBcd(month)); // set month Wire.write(decToBcd(year)); // set year (0 to 99) Wire.endTransmission(); } void readDS3231time(byte *second, byte *minute, byte *hour, byte *dayOfWeek, byte *dayOfMonth, byte *month, byte *year) { Wire.beginTransmission(DS3231_I2C_ADDRESS); Wire.write(0); // set DS3231 register pointer to 00h Wire.endTransmission(); Wire.requestFrom(DS3231_I2C_ADDRESS, 7); // request seven bytes of data from DS3231 starting from register 00h *second = bcdToDec(Wire.read() & 0x7f); *minute = bcdToDec(Wire.read()); *hour = bcdToDec(Wire.read() & 0x3f); *dayOfWeek = bcdToDec(Wire.read()); *dayOfMonth = bcdToDec(Wire.read()); *month = bcdToDec(Wire.read()); *year = bcdToDec(Wire.read()); } void displayTime() { byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; // retrieve data from DS3231 readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year); // send it to the serial monitor Serial.print(hour, DEC); // convert the byte variable to a decimal number when displayed Serial.print(":"); if (minute<10) { Serial.print("0"); } Serial.print(minute, DEC); Serial.print(":"); if (second<10) { Serial.print("0"); } Serial.print(second, DEC); Serial.print(" "); Serial.print(dayOfMonth, DEC); Serial.print("/"); Serial.print(month, DEC); Serial.print("/"); Serial.print(year, DEC); Serial.print(" Day of week: "); switch(dayOfWeek){ case 1: Serial.println("Sunday"); break; case 2: Serial.println("Monday"); break; case 3: Serial.println("Tuesday"); break; case 4: Serial.println("Wednesday"); break; case 5: Serial.println("Thursday"); break; case 6: Serial.println("Friday"); break; case 7: Serial.println("Saturday"); break; } } //BEACON SUBSYSTEM CODES void dash() { analogWrite(BEACON_SUBSYSTEM_TX_PIN , 128) ;//128 default delay(DASHLEN); analogWrite(BEACON_SUBSYSTEM_TX_PIN , 0) ; delay(DOTLEN) ; } void dit() { analogWrite(BEACON_SUBSYSTEM_TX_PIN , 128) ;//128 default delay(DOTLEN); analogWrite(BEACON_SUBSYSTEM_TX_PIN , 0) ; delay(DOTLEN); } void send(char c) { int i ; if (c == ' ') { Serial.print(c) ; delay(7*DOTLEN) ; return ; } for (i=0; i ': idx++; ready = true; break; default: ; // skip } return ready; } //TELEMTRY DATA ACQUISITION FUNCTION void acquire_telemetry_data() { if (Serial5.available() > 0) { done = parsePacket(Serial5.read()); } if (done) { float RAW_LIPO_VOLTAGE = field[0] * ( ( 6 *3.3 ) / 1023.0 ); float RAW_LIPO_CURRENT = field[1] * ( ( 3.3 ) /( 0.66 * 1023.0) ); float RAW_12_V = field[2] * ( ( 6 *3.3 ) / 1023.0 ); float RAW_7V5 = field[3] * ( ( 3 *3.3 ) / 1023.0 ); float RAW_5_V = field[4] * ( ( 2 *3.3 ) / 1023.0 ); float RAW_3V3 = field[5] * ( ( 2 *3.3 ) / 1023.0 ); Serial.print("RAW_LIPO_VOLTAGE : "); Serial.print(RAW_LIPO_VOLTAGE); Serial.println(""); Serial.print("RAW_LIPO_CURRENT : "); Serial.print(RAW_LIPO_CURRENT); Serial.println(""); Serial.print("RAW_12_V : "); Serial.print(RAW_12_V); Serial.println(""); Serial.print("RAW_7V5 : "); Serial.print(RAW_7V5); Serial.println(""); Serial.print("RAW_5_V : "); Serial.print(RAW_5_V); Serial.println(""); Serial.print("RAW_3V3 : "); Serial.print(RAW_3V3); Serial.println(""); } } //TELECOMMAND DECODING void decode_telecommand_data() { if (Serial0.available() > 0) { done = parsePacket(Serial0.read()); } if (done) { char ch = field[0]; if(ch == 'A') {AUXILLARY_RELAY_ON();} if(ch == 'B') {AUXILLARY_RELAY_OFF();} if(ch == 'C') {YAW_REACTION_WHEEL_ON();} if(ch == 'D') {YAW_REACTION_WHEEL_OFF();} if(ch == 'E') {PITCH_REACTION_WHEEL_ON();} if(ch == 'F') {PITCH_REACTION_WHEEL_OFF();} if(ch == 'G') {ROLL_REACTION_WHEEL_ON();} if(ch == 'H') {ROLL_REACTION_WHEEL_OFF();} if(ch == 'I') {YAW_REACTION_WHEEL_CW();} if(ch == 'J') {YAW_REACTION_WHEEL_CCW();} if(ch == 'K') {PITCH_REACTION_WHEEL_CW();} if(ch == 'L') {PITCH_REACTION_WHEEL_CCW();} if(ch == 'M') {ROLL_REACTION_WHEEL_CW();} if(ch == 'N') {ROLL_REACTION_WHEEL_CCW();} if(ch == 'O') {BEACON_TRANSMITTER_ON();} if(ch == 'P') {BEACON_TRANSMITTER_OFF();} if(ch == 'Q') {ZIGBEE_TRANSCIEVER_ON();} if(ch == 'R') {ZIGBEE_TRANSCIEVER_OFF();} if(ch == 'S') {GPS_MODULE_ON();} if(ch == 'T') {GPS_MODULE_OFF();} if(ch == 'U') {SENSOR_SUBSYSTEM_ON();} if(ch == 'V') {SENSOR_SUBSYSTEM_OFF();} if(ch == 'W') {TELEMETRY_SUBSYSTEM_ON();} if(ch == 'X') {TELEMETRY_SUBSYSTEM_OFF();} if(ch == 'Y') {CAMERA_SUBSYSTEM_ON();} if(ch == 'Z') {CAMERA_SUBSYSTEM_OFF();} if(ch == '1') {LASER_SUBSYSTEM_ON(); } if(ch == '2') {LASER_SUBSYSTEM_OFF(); } if(ch == '3') {PELTIER_SUBSYSTEM_HEAT(500); } if(ch == '4') {PELTIER_SUBSYSTEM_COOL(500); } } } // Telemetry GUI int inByte = 0; // incoming serial byte void establishContact() { while (Serial0.available() <= 0) { Serial0.write('A');// send a capital A delay(300); } } void send_telemetry_values_GUI() { // if we get a valid byte, read analog ins: if (Serial0.available() > 0) { // get incoming byte: inByte = Serial0.read(); // send sensor values via zigbee Serial0.write(amap(RAW_LIPO_VOLTAGE,0,25,0,225)); Serial0.write(amap(RAW_LIPO_CURRENT,0,25,0,225)); Serial0.write(amap(RAW_12_V,0,25,0,225)); Serial0.write(amap(RAW_7V5,0,25,0,225)); Serial0.write(amap(RAW_5_V,0,25,0,225)); Serial0.write(amap(RAW_3V3,0,25,0,225)); } } // GPS DATA PARSER void display_GPS_Info() { Serial.print(F("Location: ")); if (gps.location.isValid()) { Serial.print(gps.location.lat(), 6); Serial.print(F(",")); Serial.print(gps.location.lng(), 6); } else { Serial.print(F("INVALID")); } Serial.print(F(" Date/Time: ")); if (gps.date.isValid()) { Serial.print(gps.date.month()); Serial.print(F("/")); Serial.print(gps.date.day()); Serial.print(F("/")); Serial.print(gps.date.year()); } else { Serial.print(F("INVALID")); } Serial.print(F(" ")); if (gps.time.isValid()) { if (gps.time.hour() < 10) Serial.print(F("0")); Serial.print(gps.time.hour()); Serial.print(F(":")); if (gps.time.minute() < 10) Serial.print(F("0")); Serial.print(gps.time.minute()); Serial.print(F(":")); if (gps.time.second() < 10) Serial.print(F("0")); Serial.print(gps.time.second()); Serial.print(F(".")); if (gps.time.centisecond() < 10) Serial.print(F("0")); Serial.print(gps.time.centisecond()); } else { Serial.print(F("INVALID")); } Serial.println(); } //MEASURE INTERNAL TEMPERATURE SENSOR VALUE void measure_internal_temperature() { tempC = analogRead(INTERNAL_TEMPERATURE_SENSOR_PIN) / 9.31; tempF =((1.8*tempC)+32); Serial.print("INTERNAL TEMP C : "); Serial.println(tempC); Serial.print("INTERNAL TEMP F : "); Serial.println(tempF); } //MEASURE SUN SENSOR VALUE void measure_sun_sensor_value() { sun_sensor_value = amap(analogRead(SUN_SENSOR_PIN),0,4095,0,100); Serial.print("SUN SENSOR VALUE : "); Serial.println(sun_sensor_value); } //MEASURE GAS SENSOR VALUE void measure_gas_sensor_value() { gas_sensor_value = amap(analogRead(GAS_SENSOR_PIN),0,4095,0,100); Serial.print("GAS SENSOR VALUE : "); Serial.println(gas_sensor_value); } //MEASURE RADIATION SENSOR VALUE void measure_radiation_sensor_value() { radiation_sensor_value = amap(analogRead(RADIATION_SENSOR_PIN),0,4095,0,100); Serial.print("RADIATION VALUE : "); Serial.println(radiation_sensor_value); } //MPU 9150 FUNCTIONS void initialize_MPU9150_IMU() { unsigned char i2cdata[2]; i2cdata[0] = CMD_1; i2cdata[1] = 0b10100000; Wire.beginTransmission(MPU9150_ADDR); Wire.write(i2cdata[0]); Wire.write(i2cdata[1]); Wire.endTransmission(); i2cdata[0] = CMD_2; i2cdata[1] = 0b00000011; Wire.beginTransmission(MPU9150_ADDR); Wire.write(i2cdata[0]); Wire.write(i2cdata[1]); Wire.endTransmission(); } void acquire_MPU9150_IMU() { unsigned char i2cdata[9]= {0,1,2,3,4,5,6,7,8}; unsigned int RAWVAL; i2cdata[0] = DATA_MSB; Wire.beginTransmission(MPU9150_ADDR); Wire.write(i2cdata[0]); Wire.endTransmission(); Wire.beginTransmission(MPU9150_ADDR); Wire.requestFrom((int)MPU9150_ADDR, 1); while (Wire.available()) { i2cdata[0] = Wire.read(); } Wire.endTransmission(); RAWVAL = ((unsigned int)i2cdata[0])<<8; RAWVAL = ((unsigned int)i2cdata[1])<<8; i2cdata[0] = DATA_LSB; Wire.beginTransmission(MPU9150_ADDR); Wire.write(i2cdata[0]); Wire.endTransmission(); Wire.beginTransmission(MPU9150_ADDR); Wire.requestFrom((int)MPU9150_ADDR, 1); while (Wire.available()) { i2cdata[0] = Wire.read(); } Wire.endTransmission(); RAWVAL |= i2cdata[0]; ax = i2cdata[0]; ay = i2cdata[1]; az = i2cdata[2]; gx = i2cdata[3]; gy = i2cdata[4]; gz = i2cdata[5]; mx = i2cdata[6]; my = i2cdata[7]; mz = i2cdata[8]; Serial.print("Accelerometer X Value : "); Serial.println(i2cdata[0]); Serial.print("Accelerometer Y Value : "); Serial.println(i2cdata[1]); Serial.print("Accelerometer Z Value : "); Serial.println(i2cdata[2]); Serial.print("Gyroscope X Value : "); Serial.println(i2cdata[3]); Serial.print("Gyroscope Y Value : "); Serial.println(i2cdata[4]); Serial.print("Gyroscope Z Value : "); Serial.println(i2cdata[5]); Serial.print("Magnetometer X Value : "); Serial.println(i2cdata[6]); Serial.print("Magnetometer Y Value : "); Serial.println(i2cdata[7]); Serial.print("Magnetometer Z Value : "); Serial.println(i2cdata[8]); } //BMP180 PRESSURE SENSOR //acquire BMP 180 pressure altitude() double getPressure() { char status; double T,P,p0,a; status = pressure.startTemperature(); if (status != 0) { delay(status); status = pressure.getTemperature(T); if (status != 0) { status = pressure.startPressure(3); if (status != 0) { delay(status); status = pressure.getPressure(P,T); if (status != 0) { return(P); } else Serial.println("error retrieving pressure measurement\n"); } else Serial.println("error starting pressure measurement\n"); } else Serial.println("error retrieving temperature measurement\n"); } else Serial.println("error starting temperature measurement\n"); } ///main bmp 180 function void acquire_BMP_180_pressure_altitude() { if (pressure.begin()) Serial.println("BMP180 init success"); else { Serial.println("BMP180 init fail (disconnected?)\n\n"); while(1); // Pause forever. } // Get the baseline pressure: baseline = getPressure(); Serial.print("baseline pressure: "); Serial.print(baseline); Serial.println(" mb"); double a,P; P = getPressure(); a = pressure.altitude(P,baseline); Serial.print("relative altitude: "); if (a >= 0.0) Serial.print(" "); // add a space for positive numbers Serial.print(a,1); Serial.print(" meters, "); if (a >= 0.0) Serial.print(" "); // add a space for positive numbers Serial.print(a*3.28084,0); Serial.println(" feet"); } //SHT21 HUMIDITY SENSOR void acquire_SHT_21_humidity_temperature() { Serial.print("Humidity(%RH): "); Serial.print(SHT2x.GetHumidity()); Serial.print(" Temperature(C): "); Serial.println(SHT2x.GetTemperature()); } //ISL29023 LIGHT SENSOR void initialize_ISL29023_ambient_light_sensor() { unsigned char i2cdata[2]; i2cdata[0] = CMD1; i2cdata[1] = 0b10100000; Wire.beginTransmission(ISL29023_ADDR); // start transmission to device Wire.write(i2cdata[0]); // send register address Wire.write(i2cdata[1]); // send data to write Wire.endTransmission(); // end transmission i2cdata[0] = CMD2; i2cdata[1] = 0b00000011; Wire.beginTransmission(ISL29023_ADDR); // start transmission to device Wire.write(i2cdata[0]); // send register address Wire.write(i2cdata[1]); // send data to write Wire.endTransmission(); } void acquire_ISL29023_ambient_light() { unsigned char i2cdata[6] ; unsigned int light; float lux; i2cdata[0] = DATAMSB; Wire.beginTransmission(ISL29023_ADDR); // start transmission to device Wire.write(i2cdata[0]); // send register address Wire.endTransmission(); // end transmission Wire.beginTransmission(ISL29023_ADDR); // start transmission to device Wire.requestFrom((int)ISL29023_ADDR, 1); // send data n-bytes read/ while (Wire.available()) { i2cdata[0] = Wire.read(); // receive DATA } Wire.endTransmission(); // end transmission light = ((unsigned int)i2cdata[0])<<8; i2cdata[0] = DATALSB; Wire.beginTransmission(ISL29023_ADDR); // start transmission to device Wire.write(i2cdata[0]); // send register address Wire.endTransmission(); Wire.beginTransmission(ISL29023_ADDR); // start transmission to device Wire.requestFrom((int)ISL29023_ADDR, 1); while (Wire.available()) { i2cdata[0] = Wire.read(); // receive DATA } Wire.endTransmission(); // end transmission light |= i2cdata[0]; // this is a bit lame, ideally use data read back from the device // to scale accordingly lux = (64000 * (float)light)/65536; Serial.print("lux : "); Serial.println(lux); } //TMP006 IR TEMPERATURE SENSOR void initialize_TMP006_sensor() { Wire.beginTransmission(TMP006_ADDR); Wire.write(TMP006_CONFIG); // sends register address to write to Wire.write(TMP006_CFG_8SAMPLE | TMP006_CFG_MODEON | TMP006_CFG_DRDYEN>>8); // write data Wire.write(TMP006_CFG_8SAMPLE | TMP006_CFG_MODEON | TMP006_CFG_DRDYEN); Wire.endTransmission(); } // Read raw sensor temperature int16_t readRawDieTemperature() { uint16_t data; Wire.beginTransmission(TMP006_ADDR); Wire.write(TMP006_TAMB); // send register address to read from Wire.endTransmission(); Wire.beginTransmission(TMP006_ADDR); Wire.requestFrom(TMP006_ADDR,2); // request 2 bytes of data data = Wire.read(); // receive data data <<= 8; data |= Wire.read(); Wire.endTransmission(); data >>= 2; return data; } // Read raw thermopile voltage int16_t readRawVoltage() { uint16_t data; Wire.beginTransmission(TMP006_ADDR); Wire.write(TMP006_VOBJ); // send register address to read from Wire.endTransmission(); Wire.beginTransmission(TMP006_ADDR); Wire.requestFrom(TMP006_ADDR,2); // request 2 bytes of data data = Wire.read(); // receive data data <<= 8; data |= Wire.read(); Wire.endTransmission(); data >>= 2; return data; } // Calculate object temperature based on raw sensor temp and thermopile voltage void readObjTempC() { double Tdie = readRawDieTemperature(); double Vobj = readRawVoltage(); Vobj *= 156.25; // 156.25 nV per LSB Vobj /= 1000000000; // nV -> V Tdie *= 0.03125; // convert to celsius Tdie += 273.15; // convert to kelvin // Equations for calculating temperature found in section 5.1 in the user guide double tdie_tref = Tdie - TMP006_TREF; double S = (1 + TMP006_A1*tdie_tref + TMP006_A2*tdie_tref*tdie_tref); S *= TMP006_S0; S /= 10000000; S /= 10000000; double Vos = TMP006_B0 + TMP006_B1*tdie_tref + TMP006_B2*tdie_tref*tdie_tref; double fVobj = (Vobj - Vos) + TMP006_C2*(Vobj-Vos)*(Vobj-Vos); double Tobj = sqrt(sqrt(Tdie * Tdie * Tdie * Tdie + fVobj/S)); Tobj -= 273.15; // Kelvin -> *C float object_temp = Tobj; Serial.print("Object Temperature: "); Serial.print(object_temp); Serial.println("*C"); } // Caculate sensor temperature based on raw reading void readDieTempC() { double Tdie = readRawDieTemperature(); Tdie *= 0.03125; // convert to celsius float sensor_temp = Tdie; Serial.print("Sensor Temperature: "); Serial.print(sensor_temp); Serial.println("*C"); } // MEASURE ALL SENSORS AND GPS VALUE void measure_sensor_subsystem_data() { measure_internal_temperature(); measure_sun_sensor_value(); measure_gas_sensor_value(); measure_radiation_sensor_value(); initialize_MPU9150_IMU(); acquire_MPU9150_IMU(); acquire_BMP_180_pressure_altitude(); acquire_SHT_21_humidity_temperature(); initialize_ISL29023_ambient_light_sensor(); acquire_ISL29023_ambient_light(); initialize_TMP006_sensor(); readObjTempC(); readDieTempC(); while (Serial4.available() > 0) { if (gps.encode(Serial4.read())) { display_GPS_Info(); } } } // log all sensor data to sd card in csv format void log_data_to_SD_card() { File file = SD.open("data.csv", FILE_WRITE); if (file) { byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; // retrieve data from DS3231 readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year); // date file.print(year); file.print("/"); file.print(month); file.print("/"); file.print(dayOfMonth); file.print(","); // time file.print(hour); file.print(":"); file.print(minute); file.print(":"); file.print(second); file.print(","); // data file.print(tempC); file.print(","); file.print(tempF); file.print(","); file.print(sun_sensor_value); file.print(","); file.print(gas_sensor_value); file.print(","); file.print(radiation_sensor_value); file.print(","); file.print(ax); file.print(","); file.print(ay); file.print(","); file.print(az); file.print(","); file.print(gx); file.print(","); file.print(gy); file.print(","); file.print(gz); file.print(","); file.print(mx); file.print(","); file.print(my); file.print(","); file.print(mz); file.print(","); file.print(a); file.print(","); file.print(a*3.28084); file.print(","); file.print(SHT2x.GetHumidity()); file.print(","); file.print(SHT2x.GetTemperature()); file.print(","); file.print(lux); file.print(","); file.print(object_temp); file.print(","); file.print(sensor_temp); file.print(","); file.print(gps.location.lat()); file.print(","); file.print(gps.location.lng()); file.println(); file.close(); } } void setup() { Serial.begin(115200); Serial.println("PEACH SAT v1.0"); PINMODE_DEFINTION(); PINMODE_INITIALISATION(); //SUBSYSTEM_TEST_SEQUENCE(); // set up the LCD's number of columns and rows: lcd.begin(20,4); lcd.print("PEACH-SAT"); //12 bit mode referenced to 3.3v analogReference(RAW12BIT); //TELEMETRY SUBSYTEM UART INTERFACE //6 channel 10 bit ADC //OUTPUT Structure : Serial5.begin(9600); //ZIGBEE TELEMETRY TELECOMMAND TRANCIEVER SUBSYTEM UART INTERFACE Serial0.begin(9600); //GPS RECEIVER UART INTERFACE Serial4.begin(9600); if (!SD.begin()) { Serial.println("SD CARD ERROR"); // error while(1); } AUXILLARY_RELAY_ON(); // deploy antenna delay(INTERVAL); AUXILLARY_RELAY_OFF(); delay(INTERVAL); TELEMETRY_SUBSYSTEM_ON(); delay(INTERVAL); ZIGBEE_TRANSCIEVER_ON(); delay(INTERVAL); BEACON_TRANSMITTER_ON(); delay(INTERVAL); GPS_MODULE_ON(); delay(INTERVAL); SENSOR_SUBSYSTEM_ON(); delay(INTERVAL); CAMERA_SUBSYSTEM_ON(); delay(INTERVAL); YAW_REACTION_WHEEL_ON(); delay(INTERVAL); PITCH_REACTION_WHEEL_ON(); delay(INTERVAL); ROLL_REACTION_WHEEL_ON(); delay(INTERVAL); LASER_SUBSYSTEM_ON(); delay(INTERVAL); LASER_SUBSYSTEM_OFF(); delay(INTERVAL); // set the initial time here: // DS3231 seconds, minutes, hours, day, date, month, year //setDS3231time(30,13,10,7,14,1,17); Wire.begin(); displayTime(); establishContact(); } void loop()//guidance { analogWrite(YAW_REACTION_WHEEL_SPEED_CONTROL_PIN,amap((ax*gx)/mx,0,100,0,255)); analogWrite(PITCH_REACTION_WHEEL_SPEED_CONTROL_PIN,amap((ay*gy)/my,0,100,0,255)); analogWrite(ROLL_REACTION_WHEEL_SPEED_CONTROL_PIN,amap((az*gz)/mz,0,100,0,255)); delay(10); } void loop1()//telemetry { acquire_telemetry_data(); send_telemetry_values_GUI(); } void loop2()//data logging { measure_sensor_subsystem_data(); log_data_to_SD_card(); } void loop3()//beacon transmission { TransmitMorse(); } void loop4()//telecommand { decode_telecommand_data(); } /* * Cyclic Handler * * This handler is called every 10 [ms] as specified in * multitask_arduino.cfg. */ void cyclic_handler(intptr_t exinf) { irot_rdq(LOOP_PRI); /* change the running loop. */ }
Demo Video
2nd prize for GR Peach Design Contest 2016 in India