/* Testing of: Arduino for FACT Gareth Hughes 2013-10-30 Dom Neise 2014-09 Using: Arduino Ethernet GSM Overlay LSM303: Magnetic field and accelerometer YL-38: Light Sensor Function: Will reply to an SMS stating the position, movement and light level. If lighlevel gets above a certain threshold will send a warning SMS every 1 min. Modifications by Dom: - In order to find our why the resulting binary is soo large, I enclosed most of the code in precompiler #ifdef-#endif constructs. The 4 #define USE_ statements in the beginning can be commented in and out in order to create a binary, that e.g. does not need the GSM shield to be attached. - printHelp function can now be given a reference to the EthernetClient that should recieve the help message, that way to clients can be connected and will not get their mutual help messages anymore. */ //#define USE_WIRE #define USE_ETH //#define USE_LSM #define USE_GSM #include #include #ifdef USE_GSM #include #endif #ifdef USE_WIRE #include #endif #ifdef USE_LSM #include #endif #ifdef USE_ETH EthernetServer server = EthernetServer(23); #endif //bool sentHeader = false; // PIN Number for the SIM #define PINNUMBER "" #define NUMLEN 15 char message[18]; // Array to hold SMS message char senderNumber[NUMLEN]; // Array to hold the number a SMS is retreived from // -------------- GSM stuff -------------------------------------------- #ifdef USE_GSM GSM gsmAccess; GSM_SMS sms; byte gsmStatus = -1; // -1 : unknown bool use_gsm = false; #endif // -------------- Light sensor stuff ----------------------------------- int iLight = 9999; // light level // -------------- Compass stuff ---------------------------------------- #ifdef USE_LSM LSM303 compass; #endif int heading = -9999; // Continual heading reading float pitch = -9999.; // Pitch relative to horizon void setup() { // this is to begin (ethz) ethernet //Ethernet.begin(mac, ip, dnserver, gatew, smask); // initialize serial communications and wait for port to open: Serial.begin(9600); #ifdef USE_ETH //ETH byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0xB5, 0xE3 }; byte ip[] = { 192, 33, 103, 241 }; //LA PALMA //byte mac[] = { 0xFA, 0xC7, 0xBB, 0xFF, 0x33, 0x33 }; //byte ip[] = { 10, 0, 100, 202 }; Ethernet.begin(mac, ip); server.begin(); Serial.print("Chat server address:"); Serial.println(Ethernet.localIP()); #else Serial.println("No ethernet this time :-("); #endif // Start the Wire communication #ifdef USE_WIRE Wire.begin(); #endif // Initialize the Compass #ifdef USE_LSM compass.init(); compass.enableDefault(); // Calibration values. Use the Calibrate example program to get the values for your compass. // ETH Calibration values // compass.m_min.x = -700; compass.m_min.y = -695; compass.m_min.z = -635; // compass.m_max.x = +293; compass.m_max.y = +551; compass.m_max.z = 606; // La Palma calibration values compass.m_min.x = -389; compass.m_min.y = -423; compass.m_min.z = -420; compass.m_max.x = +510; compass.m_max.y = +420; compass.m_max.z = +315; #endif } void loop() { #ifdef USE_GSM if (use_gsm && gsmStatus==GSM_READY) { // user wants us to use GSM, and GSM seems to be okay. checkForSms(); } else if (use_gsm && gsmStatus!=GSM_READY) { // user wants us to use GSM, but it's not yet okay, // so we try to connect to GSM network. gsmStatus = gsmAccess.begin(PINNUMBER); } else if (!use_gsm && gsmStatus!=-1) { // user does NOT want us to use GSM, but we seem to be connected, // so let's shut it down. gsmAccess.shutdown(); // since there is no dedicated 'GSM_SHUTDOWN' status, we simply use -1. gsmStatus = -1; } else { // user does NOT want us to use GSM and GSM seems to be down .. // so we don't do anything. } #else checkForSms(); #endif #ifdef USE_ETH checkForEthernetClient(); #endif } void checkForEthernetClient() { #ifdef USE_ETH EthernetClient client = server.available(); if( !client ){ return; } if( client.available() ) { //if(!sentHeader) //{ //printHelp(client); //sentHeader = true; //} int c = client.read(); switch( c ) { case 'q': //sentHeader = false; delay(1); // give the web browser time to receive the data client.stop(); // close the connection: break; case 'h': printHelp(client); break; case 'd': generateMessage(); client.println(message); break; case 'g': use_gsm = true; break; case 'G': use_gsm = false; break; case 's': printStatus(client, true); break; //case 'p': //digitalWrite(9, HIGH); //server.println("Park"); //break; } } #endif } void printHelp( #ifdef USE_ETH EthernetClient &c #endif ) { #ifdef USE_ETH c.println(); c.println("FACT GSM"); c.println("h help"); c.println("q quit"); c.println("g/G en-/disable GSM"); c.println("s status"); c.println(); c.println("d direction"); //c.println("p Park Tel"); c.println(); #endif } void printStatus( #ifdef USE_ETH EthernetClient &c, #endif bool print_via_serial ) { #ifdef USE_ETH c.print("use_gsm: "); c.println(use_gsm); c.print("gsmStatus: "); c.println(gsmStatus); #endif if (print_via_serial) { Serial.print("use_gsm: "); Serial.println(use_gsm); Serial.print("gsmStatus: "); Serial.println(gsmStatus); } } void checkForSms() { #ifdef USE_GSM if( sms.available() ) { // Get remote number sms.remoteNumber(senderNumber, NUMLEN); if( sms.peek()=='P' ) { Serial.println("I P"); generateMessage(); sendSMS(); } sms.flush(); } #else Serial.println("I *would* now check for SMS."); #endif } void sendSMS() { #ifdef USE_GSM sms.beginSMS(senderNumber); sms.print(message); sms.endSMS(); #endif } void get_heading_pitch() { #ifdef USE_LSM compass.read(); heading = compass.heading((LSM303::vector){0,-1,0}) - 90 - 24; if( heading < 0 ) heading = heading + 360; pitch = atan(compass.a.x/sqrt(pow(compass.a.y,2.)+pow(compass.a.z,2.))); pitch *= 180.0/3.1415; pitch += 13.; pitch = 90. - pitch; #endif } // Generate SMS void generateMessage() { get_heading_pitch(); // Read light level iLight = analogRead(0); // Setup message sprintf(message,"%d %d %d\n",heading,(int)pitch,iLight); }