Created
July 31, 2015 10:06
-
-
Save dwblair/e9cc8776d8d5a53c2fc7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*************************************************** | |
This is an example for our Adafruit FONA Cellular Module | |
Designed specifically to work with the Adafruit FONA | |
----> http://www.adafruit.com/products/1946 | |
----> http://www.adafruit.com/products/1963 | |
----> http://www.adafruit.com/products/2468 | |
----> http://www.adafruit.com/products/2542 | |
These cellular modules use TTL Serial to communicate, 2 pins are | |
required to interface | |
Adafruit invests time and resources providing this open source code, | |
please support Adafruit and open-source hardware by purchasing | |
products from Adafruit! | |
Written by Limor Fried/Ladyada for Adafruit Industries. | |
BSD license, all text above must be included in any redistribution | |
****************************************************/ | |
#include "Adafruit_FONA.h" | |
#include <JeeLib.h> | |
#include <Wire.h> | |
#include <SPI.h> | |
#include <RTClib.h> | |
#include <RTC_DS3231.h> | |
#include<stdlib.h> | |
//sleeping stuff | |
ISR(WDT_vect) { Sleepy::watchdogEvent(); } | |
//RTC stuff | |
RTC_DS3231 RTC; | |
//led | |
#define led 9 | |
//battery stuff | |
#define batteryAnalogMeasurePin A3 | |
#define batteryReadCircuitSwitch 4 | |
//FONA stuff ------------------------ | |
//#define sendto "16512524765" | |
#define sendto "+15075818876" | |
//#define sendto "+16512524765" | |
#define FONA_RX 2 | |
#define FONA_TX 5 | |
#define FONA_RST A1 | |
#define fonaKey A2 | |
#define fonaPowerStatus 10 | |
#define failCountMax 10 | |
// which analog pin to connect | |
#define THERMISTORPIN A0 | |
// resistance at 25 degrees C | |
#define THERMISTORNOMINAL 10000 | |
// temp. for nominal resistance (almost always 25 C) | |
#define TEMPERATURENOMINAL 25 | |
// how many samples to take and average, more takes longer | |
// but is more 'smooth' | |
#define NUMSAMPLES 5 | |
// The beta coefficient of the thermistor (usually 3000-4000) | |
#define BCOEFFICIENT 3950 | |
// the value of the 'other' resistor | |
#define SERIESRESISTOR 9550 | |
// This is to handle the absence of software serial on platforms | |
// like the Arduino Due. Modify this code if you are using different | |
// hardware serial port, or if you are using a non-avr platform | |
// that supports software serial. | |
#ifdef __AVR__ | |
#include <SoftwareSerial.h> | |
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX); | |
SoftwareSerial *fonaSerial = &fonaSS; | |
#else | |
HardwareSerial *fonaSerial = &Serial1; | |
#endif | |
Adafruit_FONA fona = Adafruit_FONA(FONA_RST); | |
//end FONA stuff ------------------------ | |
// debugging -- only do Serial output if debuggin | |
#define debug 1 // 0: don't print anything out; 1: print out debugging statements | |
// how long to sleep between measurements | |
#define sleepSeconds 30 | |
int samples[NUMSAMPLES]; | |
int interruptPin = 1; //corresponds to D2 | |
// conductivity variables | |
long pulseCount = 0; //a pulse counter variable | |
unsigned long pulseTime,lastTime, duration, totalDuration; | |
int samplingPeriod=3; // the number of seconds to measure 555 oscillations | |
int sensorBoard = 8; // the pin that powers the 555 subcircuit | |
void setup() { | |
if (debug) Serial.begin(115200); | |
// begin I2C protocol (necessary for RTC, and any other I2C on board | |
Wire.begin(); | |
// RTC ------------------------- | |
initialize_RTC(); // NOTE: need to initialize I2C first -- but also for any other I2C library | |
// set mode for battery circuit control pin, and turn the circuit off | |
pinMode(batteryReadCircuitSwitch,OUTPUT); | |
pinMode(sensorBoard,OUTPUT); | |
digitalWrite(batteryReadCircuitSwitch, HIGH); | |
// FONA stuff ---------------------------------------------------- | |
// set mode for FONA power status measurement pin | |
pinMode(fonaPowerStatus,INPUT); | |
//set mode for FONA power cycling key | |
pinMode(fonaKey, OUTPUT); | |
// make sure the FONA power cycling key is initially pulled 'high' -- i.e. not triggered | |
digitalWrite(fonaKey, HIGH); //go back to non-trigger | |
// end FONA stuff --------------------------------------------------- | |
// LED ----------------------------------------- | |
//set the led pin mode to output | |
pinMode(led, OUTPUT); | |
pinMode(sensorBoard,OUTPUT); //turns on the 555 timer and thermistor subcircuit | |
digitalWrite(sensorBoard,LOW); //turns on the 555 timer and thermistor subcircuit | |
} | |
void loop () | |
{ | |
uint8_t i; | |
//measure the battery | |
digitalWrite(batteryReadCircuitSwitch, LOW); //turn on battery measurement circuit | |
int batteryLevel = analogRead(batteryAnalogMeasurePin); | |
digitalWrite(batteryReadCircuitSwitch, HIGH); | |
//turn on the sensorBoard system | |
//measure temp | |
//take temp samples | |
// take N samples in a row, with a slight delay | |
for (i=0; i< NUMSAMPLES; i++) { | |
samples[i] = analogRead(THERMISTORPIN); | |
//Serial.println(analogRead(THERMISTORPIN)); | |
delay(10); | |
} | |
//measure conductivity | |
// conductivity -------------------------------------- | |
pulseCount=0; //reset the pulse counter | |
totalDuration=0; //reset the totalDuration of all pulses measured | |
attachInterrupt(interruptPin,onPulse,RISING); //attach an interrupt counter to interrupt pin 1 (digital pin #3) -- the only other possible pin on the 328p is interrupt pin #0 (digital pin #2) | |
pulseTime=micros(); // start the stopwatch | |
delay(samplingPeriod*1000); //give ourselves samplingPeriod seconds to make this measurement, during which the "onPulse" function will count up all the pulses, and sum the total time they took as 'totalDuration' | |
detachInterrupt(interruptPin); //we've finished sampling, so detach the interrupt function -- don't count any more pulses | |
//turn off the remote board | |
//digitalWrite(sensorBoard,HIGH); //turns on the 555 timer and thermistor subcircuit | |
//analyze temp | |
float average; | |
average = 0; | |
for (i=0; i< NUMSAMPLES; i++) { | |
average += samples[i]; | |
} | |
average /= NUMSAMPLES; | |
// convert the value to resistance | |
average = 1023 / average - 1; | |
average = SERIESRESISTOR / average; | |
//Serial.print("Thermistor resistance "); | |
//Serial.println(average); | |
float steinhart; | |
steinhart = average / THERMISTORNOMINAL; // (R/Ro) | |
steinhart = log(steinhart); // ln(R/Ro) | |
steinhart /= BCOEFFICIENT; // 1/B * ln(R/Ro) | |
steinhart += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To) | |
steinhart = 1.0 / steinhart; // Invert | |
steinhart -= 273.15; // convert to C | |
//Serial.print(steinhart); | |
//Serial.println(" *C"); | |
//do the conductivity calculations | |
float freqHertz; | |
if (pulseCount>0) { //use this logic in case something went wrong | |
double durationS=(totalDuration/double(pulseCount))/1000000.; //the total duration, in seconds, per pulse (note that totalDuration was in microseconds) | |
freqHertz=1./durationS; | |
} | |
else { | |
freqHertz=0.; | |
} | |
// Onboard temp from the RTC | |
float rtcTemp = RTC.getTempAsFloat(); | |
//get the time | |
DateTime now = RTC.now(); | |
long unixNow = now.unixtime(); | |
// FONA sending stuff ---------------------- | |
char message[141]; | |
//sprintf(message, "%ld, %d, %d",unixNow,batteryLevel, rtcTempInt); | |
int sensorID=1; | |
int conduct=333; | |
int temp=2333; | |
sprintf(message,"%d, %d, %d, %d",sensorID,batteryLevel,int(steinhart*100),int(freqHertz)); | |
if(debug) Serial.println(freqHertz); | |
if(debug) Serial.println(steinhart); | |
// turn on the FONA | |
power_up_fona(); | |
// initialize the FONA | |
int fonaStatus=initialize_fona(); | |
if (!fonaStatus) { | |
if (debug) Serial.println("FONA not found"); | |
} | |
int networkStatus=fona_find_network(); | |
if ((networkStatus!=1)&&(networkStatus!=5)) { | |
if (debug) Serial.println("Couldn't find network in failCountMax tries. Aborting."); | |
} | |
if (((networkStatus==1)||(networkStatus==5))&&fonaStatus) { //then we're good to send a message! | |
if (debug) { | |
Serial.print(F("Send to #")); | |
Serial.println(sendto); | |
Serial.print(F("Type out one-line message (140 char): ")); | |
Serial.println(message); | |
} | |
// send an SMS! | |
if (!fona.sendSMS(sendto, message)) { | |
if(debug) Serial.println(F("Failed")); | |
} else { | |
if (debug) Serial.println(F("Sent!")); | |
} | |
} | |
//turn off the module (should be on to begin with, but if all has failed, we should turn it off. | |
power_down_fona(); | |
if(debug) { | |
Serial.println("Sleeping ..."); | |
delay(1000); //seems to be necessary not to mess with serial output when sleeping | |
} | |
// PUT ATMEL 328p to SLEEP | |
go_to_sleep_seconds(sleepSeconds); // | |
} | |
// Sleep function | |
void go_to_sleep_seconds(int seconds) { | |
int LOG_INTERVAL_BASE = 1000; // 1 sec | |
for (int k=0;k<seconds;k++) { | |
Sleepy::loseSomeTime(LOG_INTERVAL_BASE); //-- will interfere with serial, so don't use when debugging | |
} | |
} | |
// RTC functions | |
int initialize_RTC() { | |
RTC.begin(); | |
// check on the RTC | |
if (! RTC.isrunning()) { | |
if (debug) Serial.println("RTC is NOT running!"); | |
// following line sets the RTC to the date & time this sketch was compiled | |
RTC.adjust(DateTime(__DATE__, __TIME__)); | |
} | |
DateTime now = RTC.now(); | |
DateTime compiled = DateTime(__DATE__, __TIME__); | |
if (now.unixtime() < compiled.unixtime()) { | |
if(debug) Serial.println("RTC is older than compile time! Updating"); | |
RTC.adjust(DateTime(__DATE__, __TIME__)); | |
} | |
} | |
// Functions for FONA | |
void power_up_fona() { | |
int fonaPower=digitalRead(fonaPowerStatus); | |
if (!fonaPower) { // off, so power up | |
digitalWrite(fonaKey, HIGH); //go back to non-trigger | |
digitalWrite(fonaKey, LOW); //turn on the SMS subcircuit | |
delay(2000); //so now it's on | |
digitalWrite(fonaKey, HIGH); //go back to non-trigger | |
} | |
else { | |
// error! was already on for some reason -- do nothing | |
} | |
} | |
void power_down_fona() { | |
int fonaPower=digitalRead(fonaPowerStatus); | |
if (fonaPower) { // on, so power down | |
digitalWrite(fonaKey, HIGH); //go back to non-trigger | |
digitalWrite(fonaKey, LOW); //turn on the SMS subcircuit | |
delay(2000); //so now it's on | |
digitalWrite(fonaKey, HIGH); //go back to non-trigger | |
} | |
else { | |
// error! was already off for some reason -- do nothing | |
} | |
} | |
int initialize_fona() { | |
int fonaStatus; | |
fonaSerial->begin(4800); | |
if (! fona.begin(*fonaSerial)) { | |
// things are bad -- couldn't find FONA | |
fonaStatus=0; | |
} | |
else { | |
//things are good -- FONA OK | |
fonaStatus=1; | |
} | |
return fonaStatus; | |
} | |
int fona_find_network() { | |
uint8_t n = fona.getNetworkStatus(); | |
int avail = fona.available(); | |
int registerCountDelaySeconds=5; | |
int registerWaitTotalSeconds=0; | |
int failCount=0; | |
while ((n!=1)&&(n!=5)&&(failCount<failCountMax)) { | |
digitalWrite(led, HIGH); //turn on the LED | |
delay(20); | |
digitalWrite(led, LOW); //turn on the LED | |
delay(20); | |
if(debug) { | |
Serial.print(F("Network status ")); | |
Serial.println(n); | |
} | |
n = fona.getNetworkStatus(); | |
//avail = fona.available(); | |
registerWaitTotalSeconds+=registerCountDelaySeconds; | |
delay(registerCountDelaySeconds*1000); | |
failCount=failCount+1; | |
} | |
if (debug) { | |
Serial.print("Network registration time="); | |
Serial.println(registerWaitTotalSeconds); | |
} | |
return n; | |
} | |
String padInt(int x, int pad) { | |
String strInt = String(x); | |
String str = ""; | |
if (strInt.length() >= pad) { | |
return strInt; | |
} | |
for (int i=0; i < (pad-strInt.length()); i++) { | |
str += "0"; | |
} | |
str += strInt; | |
return str; | |
} | |
String int2string(int x) { | |
// formats an integer as a string assuming x is in 1/100ths | |
String str = String(x); | |
int strLen = str.length(); | |
if (strLen <= 2) { | |
str = "0." + str; | |
} else if (strLen <= 3) { | |
str = str.substring(0, 1) + "." + str.substring(1); | |
} else if (strLen <= 4) { | |
str = str.substring(0, 2) + "." + str.substring(2); | |
} else { | |
str = "-9999"; | |
} | |
return str; | |
} | |
void onPulse() | |
{ | |
pulseCount++; | |
//Serial.print("pulsecount="); | |
//Serial.println(pulseCount); | |
lastTime = pulseTime; | |
pulseTime = micros(); | |
duration=pulseTime-lastTime; | |
totalDuration+=duration; | |
//Serial.println(totalDuration); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment