MANAGING THE ARDUINO CODE


STEP 2 – DOWNLOAD & ORGANIZE THE CODE

The code you’ll be using for this activity has already been written and tested. However, we’re not just going to give you the completed Arduino sketch. That would be too easy! To add a bit of a challenge, we have split the sketch into five blocks of code. Each block contains a portion of the full code and is labeled Block 1 through Block 5. However, these blocks are out of order.

 IMPORTANT:  YOU MUST FIGURE OUT THE CORRECT ORDER OF THE BLOCKS

To accomplish this, consider the following instructions:

  1.  With the IDE open, start with a completely blank sketch.
  2.  Look carefully at the blocks below and try to figure out what the code in each one is doing.
  3.  Based on what you learned earlier about Arduino code, try to determine which blocks go first and last in the sketch. Then try to figure out the proper sequence of the other three blocks in between. Write out the numbers of the blocks in the order they go in the sketch.
  4.  In order from top to bottom, copy the blocks of code from this page and paste them into the empty sketch.
  5.  Do not make any changes to the code at this time!
  6.  When you have all five blocks pasted into the IDE, the International Advisor must check your work before you can move on.
// *********** BLOCK 1 ***********

// ------------------------------------------------
// ---- FUNCTION: DETECTS NEW RADIATION PULSE -----
// ------------------------------------------------
/* This function "onRadiationPulse" is called whenever a new pulse is detected by
the radiation sensor, and simply calls "csvStatus" to print the data to SD card. */

void onRadiationPulse() {

// For each radiation count, write the current values to the SD card
csvStatus(radiationWatch);

// Wait for the data to finish printing before moving on
dataFile.flush();
}
// *********** BLOCK 2 ***********

// ------------------------------------------------
// ------------- FUNCTION: CODE SETUP -------------
// ------------------------------------------------
/* This function "setup" runs only once at the beginning of the code
   and sets up the SD card, GPS board, and radiation sensor. */
   
void setup() {

  // Set Serial to print at a baud rate of 9600
  Serial.begin(9600);
  Serial.println("*** SETTING UP ARDUINO ***");

  
// SETTING UP SD CARD

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

  // Ensure SD card pin is working
  if (!SD.begin(sdCardPin)) {
    Serial.println("SD card not initialized!");
    return; }  
  
  // Test the CSV file
  Serial.println(" - Testing SD file ...");
  dataFile = SD.open("data.csv", FILE_WRITE);
  if (dataFile) {
    Serial.println(" - SD file opened successfully!");
  } else {
    Serial.println(" - File opened unsuccessful!");
    return; }
  dataFile.close();
  
  Serial.println("SD card initialization done!");
  

// SETTING UP GPS BOARD

  Serial.println(" ");
  Serial.println("Initializing GPS board ...");
  
  // Allow GPS data to be read by Arduino at baud rate of 9600
  GPS.begin(9600);     
  
  // Set the type of GPS data to retrieve
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);     
  
  // Set the update rate to 5 Hz
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_5HZ);     
  
  // Request updates on antenna status
  GPS.sendCommand(PGCMD_ANTENNA);     
 
  Serial.println("GPS board initialization done!");


// SETTING UP GEIGER COUNTER

  Serial.println(" ");
  Serial.println("Initializing Geiger counter ...");
  
  // Run the radiationWatch setup code
  radiationWatch.setup();     
  
  Serial.println("Geiger counter initialization done!");

  Serial.println(" ");
  Serial.println("*** ARDUINO SETUP COMPLETE ***"); Serial.println(" ");
  Serial.println("*********************************************"); Serial.println(" ");
  
  
// WRITING THE CSV HEADER LINE

  // Open SD file for writing
  dataFile = SD.open("data.csv", FILE_WRITE); 

  // Write the CSV headers
  dataFile.println("Date,Time(UTC),Lat(DDMM.dddd),Lat(degrees),Lon(DDMM.dddd),Long(degrees),"
  "Altitude(m),Altitude(ft),Radiation Count(last 20 min),Counts Per Minute,Dosage(uSv/hr),Dosage Error(uSv/hr),"
  "Speed(mph),Speed(kts),Heading(degrees clockwise from N),Satellite Fix,Fix Quality,Satellites,");     
  
  // Close SD file for writing
  dataFile.close();  

  
// PRINTING INITIAL RADIATION VALUES
  
  // Call "csvStatus" to print initial radiation values to SD card
  csvStatus(radiationWatch);     
  
  // Wait for the data to finish printing before moving on
  dataFile.flush();     
  
  // Register callback and tells code to call "onRadiationPulse" function anytime a new pulse is detected
  radiationWatch.registerRadiationCallback(&onRadiationPulse);     
  
  // Wait 3 seconds (3000 milliseconds) to begin loop
  delay(3000);     
}
// *********** BLOCK 3 ***********

// ------------------------------------------------
// ----- FUNCTION: WRITES NEW DATA TO SD CARD -----
// ------------------------------------------------
/* This function "csvStatus" is called each time the radiation sensor detects a new
   radiation measurement. It writes data both to Serial (i.e., the computer monitor)
   as well as to the SD card. */
   
void csvStatus(RadiationWatch radiationWatch) {    
  
  // Set the names of several variables that will be used in this function
  static long count; 
  static float cpm;
  static float dose; 
  static float error;


// PRINT TO SERIAL MONITOR FIRST

  // GPS date
  Serial.println(" ");
  Serial.println("--- GPS Measurements ---");
  Serial.print("Date: ");
  if (GPS.month < 10){Serial.print('0');}
  Serial.print(GPS.month, DEC); Serial.print('/');
  if (GPS.day < 10){Serial.print('0');}
  Serial.print(GPS.day, DEC); Serial.print("/20");
  Serial.println(GPS.year, DEC);
    
  // GPS timestamp
  Serial.print("Time: ");
  if (GPS.hour < 10){Serial.print('0');}
  Serial.print(GPS.hour, DEC); Serial.print(':');
  if (GPS.minute < 10){Serial.print('0');}
  Serial.print(GPS.minute, DEC); Serial.print(':');
  if (GPS.seconds < 10){Serial.print('0');}
  Serial.print(GPS.seconds, DEC); Serial.println(" UTC");

  // GPS satellite fix
  Serial.print("Fix: "); Serial.println((int)GPS.fix);
  Serial.print("Quality: "); Serial.println((int)GPS.fixquality);
  Serial.print("Satellites: "); Serial.println((int)GPS.satellites);

  // GPS latitude & longitude
  Serial.print("Latitude (DDMM.dddd, degrees): ");
  if (GPS.lat == 'S'){Serial.print('-');}      
  Serial.print(GPS.latitude, 4);  Serial.print(", "); 
  if (GPS.lat == 'S'){Serial.print('-');}
  Serial.println((int(GPS.latitude) / 100) + (float(int(GPS.latitude) % 100) + (GPS.latitude - float(int(GPS.latitude)))) / float(60), 4);
  Serial.print("Longitude (DDDMM.dddd, degrees): ");
  if (GPS.lon == 'W'){Serial.print('-');} 
  Serial.print(GPS.longitude, 4);  Serial.print(", ");  
  if (GPS.lon == 'W'){Serial.print('-');}
  Serial.println((int(GPS.longitude) / 100) + (float(int(GPS.longitude) % 100) + (GPS.longitude - float(int(GPS.longitude)))) / float(60), 4);
      
  // GPS movement & altitude
  float alt_feet = GPS.altitude*3.28;
  Serial.print("Speed (mph): "); Serial.println(GPS.speed*1.15078, 2);
  Serial.print("Heading (deg clockwise from N): "); Serial.println(GPS.angle, 2);
  Serial.print("Altitude (m MSL, ft MSL): "); Serial.print(GPS.altitude, 2); Serial.print(", "); Serial.println(alt_feet, 2);
  
  // Radiation sensor
  Serial.println(" ");
  Serial.println("--- Radiation Measurements (last 20 minutes) ---");  
  count = radiationWatch.radiationCount();     
  cpm = radiationWatch.cpm();    
  dose = radiationWatch.uSvh();     
  error = radiationWatch.uSvhError();  
  Serial.print("Count: "); Serial.println(count); 
  Serial.print("Counts per minute: "); Serial.println(cpm,3);
  Serial.print("Dosage: "); Serial.print(dose,3); Serial.println(" uSv/hour");
  Serial.print("Dosage error: +/- "); Serial.print(error,3); Serial.println(" uSv/hour"); Serial.println(" ");

  Serial.println("*********************************"); 


// WRITE DATA TO SD CARD
  
  // Open SD file for writing
  dataFile = SD.open("data.csv", FILE_WRITE);     
  
  // GPS date
  if (GPS.month < 10){dataFile.print('0');}
  dataFile.print(GPS.month, DEC); dataFile.print('/');
  if (GPS.day < 10){dataFile.print('0');}
  dataFile.print(GPS.day, DEC); dataFile.print("/20");
  dataFile.print(GPS.year, DEC); dataFile.print(',');

  // GPS timestamp
  if (GPS.hour < 10){dataFile.print('0');}
  dataFile.print(GPS.hour, DEC); dataFile.print(':');
  if (GPS.minute < 10){dataFile.print('0');}
  dataFile.print(GPS.minute, DEC); dataFile.print(':');
  if (GPS.seconds < 10){dataFile.print('0');}
  dataFile.print(GPS.seconds, DEC); dataFile.print(',');

  // Other GPS information
  if (GPS.lat == 'S'){dataFile.print('-');}      
  dataFile.print(GPS.latitude, 4); dataFile.print(',');
  if (GPS.lat == 'S'){dataFile.print('-');}
  dataFile.print((int(GPS.latitude) / 100) + (float(int(GPS.latitude) % 100) + (GPS.latitude - float(int(GPS.latitude)))) / float(60), 4); dataFile.print(',');
  if (GPS.lon == 'W'){dataFile.print('-');} 
  dataFile.print(GPS.longitude, 4); dataFile.print(','); 
  if (GPS.lon == 'W'){dataFile.print('-');}
  dataFile.print((int(GPS.longitude) / 100) + (float(int(GPS.longitude) % 100) + (GPS.longitude - float(int(GPS.longitude)))) / float(60), 4); dataFile.print(',');
  dataFile.print(GPS.altitude, 2); dataFile.print(',');
  dataFile.print(alt_feet, 2); dataFile.print(',');
   
  // Radiation measurements
  dataFile.print(count); dataFile.print(',');
  dataFile.print(cpm, 3); dataFile.print(',');
  dataFile.print(dose, 3); dataFile.print(',');
  dataFile.print(error, 3); dataFile.print(',');

  // GPS speed and direction
  dataFile.print(GPS.speed*1.15078, 2); dataFile.print(',');
  dataFile.print(GPS.speed, 2); dataFile.print(',');
  dataFile.print(GPS.angle, 2); dataFile.print(',');

  // GPS satellite information
  if ((int)GPS.fix == 1){dataFile.print("YES,");} else {dataFile.print("NO,");}
  dataFile.print((int)GPS.fixquality); dataFile.print(',');
  dataFile.print((int)GPS.satellites); dataFile.println(',');
  
  // Close SD file for writing
  dataFile.close();     
}
// *********** BLOCK 4 ***********

// ------------------------------------------------
// ------------- FUNCTION: CODE LOOP --------------
// ------------------------------------------------
/* This function "loop" runs continuously after setup and 
   waits for a new radiation pulse from the sensor. */
   
void loop() {  
  
  // Read data continuously from GPS board, check to see if different from last received data
  char c = GPS.read();   
  if (GPS.newNMEAreceived()) {
    if (!GPS.parse(GPS.lastNMEA()))   
      return; }
  
  // Runs through the radiation code loop checking for new radiation pulses
  radiationWatch.loop();   
}
// *********** BLOCK 5 ***********

/*
NAME
SpaceRadiationCode.uni

DESCRIPTION
This code is used to operate an Arduino Mega 2560 microcontroller as part of the 
Wyoming NASA Space Grant Consortium's high-altitude balloon "Space Radiation" activity.
The code allows the Arduino to obtain Beta and Gamma radiation measurements from a 
connected pocket Gieger radiation sensor. A connected GPS breakout board also allows GPS 
measurements, such as latitude, longitude, and altitude, to be obtained and saved to an
SD card with the radiation measurements. 

WIRING ASSEMBLY
  - GPS BREAKOUT BOARD
     Connect the GPS VIN pin to a 5V Power pin on Arduino
     Connect the GPS GND pin to a GND pin on Arduino
     Connect the GPS TX (transmit) pin to the Digital 11 pin on Arduino
     Connect the GPS RX (receive) pin to the Digital 10 pin on Arduino
     
  - GEIGER RADIATION SENSOR
     Connect the Geiger +V pin to a 5V Power pin on Arduino
     Connect the Geiger GND pin to a GND pin on Arduino
     Connect the Geiger SIG pin to the Digital 2 pin on Arduino
     Connect the Geiger NS pin to the Digital 3 pin on Arduino

  - ETHERNET SHIELD SD CARD 
     The SD card pin uses Digital 4 pin on Arduino, however the Ethernet Shield should 
     already be mounted atop the Arduino (no wiring needed) 
*/

// ------------------------------------------------
// -------- LIBRARIES, DEFINITIONS, & PINS --------
// ------------------------------------------------

// Call the various libraries that are needed to run this code
#include "RadiationWatch.h"
#include "SD.h"
#include "SPI.h"
#include "SoftwareSerial.h"
#include "Adafruit_GPS.h"

// Set the Arduino Digital pins for the radiation sensor (signal pin, noise pin)
RadiationWatch radiationWatch(2, 3);   

// Set the Arduino Digital pin for the SD card (determined by Ethernet Shield) 
const byte sdCardPin = 4;     
   
// Set the Arduino Ditigal pins for the GPS board (TX pin, RX pin)
SoftwareSerial mySerial(11, 10);     
Adafruit_GPS GPS(&mySerial);

// Name to be added to print statements when printing to SD card
File dataFile;

If you’re having trouble, go back and review what you learned earlier about Arduino code. What are some of the first things that need to happen in the sketch? What comes last in the sketch? Where do the setup() and loop() functions go? What about a function’s curly brackets? If you’re still stuck, ask one of the International Advisors for help.

Once the International Advisors check and approve the order of your code, you can move on to the next step.